502 lines
18 KiB
PHP
502 lines
18 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers;
|
|
|
|
use App\Models\Transaksi;
|
|
use App\Models\Pesanan;
|
|
use App\Services\MidtransService;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Support\Str;
|
|
use Illuminate\Support\Facades\Storage;
|
|
use Illuminate\Support\Facades\Auth;
|
|
use Illuminate\Support\Facades\Log;
|
|
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
|
|
use Illuminate\Routing\Controller;
|
|
|
|
class TransaksiController extends Controller
|
|
{
|
|
use AuthorizesRequests;
|
|
|
|
protected $midtransService;
|
|
|
|
public function __construct(MidtransService $midtransService)
|
|
{
|
|
$this->middleware('auth');
|
|
$this->midtransService = $midtransService;
|
|
}
|
|
|
|
public function index()
|
|
{
|
|
$query = Transaksi::with(['pesanan.barang', 'user']);
|
|
|
|
// Filter berdasarkan tanggal
|
|
if (request('start_date')) {
|
|
$query->whereDate('created_at', '>=', request('start_date'));
|
|
}
|
|
if (request('end_date')) {
|
|
$query->whereDate('created_at', '<=', request('end_date'));
|
|
}
|
|
|
|
// Filter berdasarkan status
|
|
if (request('status')) {
|
|
$query->where('status', request('status'));
|
|
}
|
|
|
|
$transaksi = $query->latest()->paginate(10);
|
|
|
|
return view('admin.transaksi.index', compact('transaksi'));
|
|
}
|
|
|
|
public function create(Pesanan $pesanan)
|
|
{
|
|
try {
|
|
// Load relasi barang
|
|
$pesanan->load('barang');
|
|
|
|
// Debug logging
|
|
Log::info('Transaksi Create Debug', [
|
|
'pesanan_id' => $pesanan->id,
|
|
'pesanan_user_id' => $pesanan->user_id,
|
|
'auth_user_id' => Auth::id(),
|
|
'has_transaksi' => $pesanan->transaksi ? true : false
|
|
]);
|
|
|
|
// Pastikan pesanan milik user yang sedang login
|
|
if ((int)$pesanan->user_id !== Auth::id()) {
|
|
return response()->json([
|
|
'error' => 'Unauthorized action'
|
|
], 403);
|
|
}
|
|
|
|
// Jika sudah ada transaksi, gunakan transaksi yang ada
|
|
if ($pesanan->transaksi) {
|
|
$transaksi = $pesanan->transaksi;
|
|
|
|
// Dapatkan snap token baru
|
|
$snapToken = $this->midtransService->getSnapToken([
|
|
'transaction_details' => [
|
|
'order_id' => $transaksi->kode_transaksi,
|
|
'gross_amount' => $transaksi->total_pembayaran
|
|
],
|
|
'item_details' => [
|
|
[
|
|
'id' => (string)$pesanan->barang_id,
|
|
'price' => (int)$pesanan->total_harga,
|
|
'quantity' => 1,
|
|
'name' => $pesanan->barang->nama_barang,
|
|
'category' => 'Electronics'
|
|
]
|
|
],
|
|
'customer_details' => [
|
|
'first_name' => $transaksi->nama_penerima,
|
|
'email' => Auth::user()->email ?: 'guest@example.com',
|
|
'phone' => $transaksi->no_telp,
|
|
'billing_address' => [
|
|
'address' => $transaksi->alamat
|
|
]
|
|
]
|
|
]);
|
|
|
|
return response()->json([
|
|
'snap_token' => $snapToken
|
|
]);
|
|
}
|
|
|
|
// Generate kode transaksi
|
|
$kodeTransaksi = 'TRX' . date('YmdHis') . rand(100, 999);
|
|
|
|
// Gunakan total_harga langsung dari pesanan
|
|
$totalPembayaran = (int)$pesanan->total_harga;
|
|
|
|
// Validasi total pembayaran
|
|
if ($totalPembayaran < 1) {
|
|
return response()->json([
|
|
'error' => 'Total pembayaran harus lebih besar dari 0'
|
|
], 400);
|
|
}
|
|
|
|
// Buat transaksi baru
|
|
$user = Auth::user();
|
|
$transaksi = Transaksi::create([
|
|
'user_id' => Auth::id(),
|
|
'pesanan_id' => $pesanan->id,
|
|
'kode_transaksi' => $kodeTransaksi,
|
|
'total_pembayaran' => $totalPembayaran,
|
|
'status' => 'menunggu_pembayaran',
|
|
'nama_penerima' => $user->name ?? 'Guest',
|
|
'no_telp' => $user->no_telp ?? '-',
|
|
'alamat' => $user->alamat ?? '-'
|
|
]);
|
|
|
|
// Siapkan item details
|
|
$itemDetails = [];
|
|
|
|
// Tambahkan item barang
|
|
if ($pesanan->barang) {
|
|
$itemDetails[] = [
|
|
'id' => (string)$pesanan->barang_id,
|
|
'price' => (int)$pesanan->total_harga,
|
|
'quantity' => 1,
|
|
'name' => $pesanan->barang->nama_barang,
|
|
'category' => 'Electronics'
|
|
];
|
|
}
|
|
|
|
// Debug log untuk memeriksa total harga
|
|
Log::info('Total Harga Debug', [
|
|
'total_pembayaran' => $totalPembayaran,
|
|
'item_details' => $itemDetails,
|
|
'transaksi_id' => $transaksi->id,
|
|
]);
|
|
|
|
// Dapatkan Snap token dari Midtrans dengan order_id yang sama
|
|
$snapToken = $this->midtransService->getSnapToken([
|
|
'transaction_details' => [
|
|
'order_id' => $transaksi->kode_transaksi,
|
|
'gross_amount' => $totalPembayaran // Gunakan totalPembayaran yang sudah termasuk ongkir
|
|
],
|
|
'item_details' => $itemDetails,
|
|
'customer_details' => [
|
|
'first_name' => $transaksi->nama_penerima,
|
|
'email' => Auth::user()->email ?: 'guest@example.com',
|
|
'phone' => $transaksi->no_telp,
|
|
'billing_address' => [
|
|
'address' => $transaksi->alamat
|
|
]
|
|
]
|
|
]);
|
|
|
|
return response()->json([
|
|
'snap_token' => $snapToken
|
|
]);
|
|
} catch (\Exception $e) {
|
|
Log::error('Error creating transaction: ' . $e->getMessage());
|
|
return response()->json([
|
|
'error' => 'Terjadi kesalahan saat memproses pembayaran: ' . $e->getMessage()
|
|
], 500);
|
|
}
|
|
}
|
|
|
|
public function store(Request $request)
|
|
{
|
|
$request->validate([
|
|
'pesanan_id' => 'required|exists:pesanan,id',
|
|
'nama_penerima' => 'required|string|max:255',
|
|
'no_telp' => 'required|string|max:15',
|
|
'alamat' => 'required|string',
|
|
'metode_pembayaran' => 'required|in:transfer,cod',
|
|
'catatan_pengiriman' => 'nullable|string'
|
|
]);
|
|
|
|
$pesanan = Pesanan::findOrFail($request->pesanan_id);
|
|
|
|
// Pastikan pesanan milik user yang sedang login
|
|
if ($pesanan->user_id !== Auth::id()) {
|
|
return back()->with('error', 'Anda tidak memiliki akses ke pesanan ini');
|
|
}
|
|
|
|
// Pastikan pesanan masih pending
|
|
if ($pesanan->status !== 'pending') {
|
|
return back()->with('error', 'Pesanan tidak dapat diproses untuk pembayaran');
|
|
}
|
|
|
|
// Generate kode transaksi
|
|
$kodeTransaksi = 'TRX' . date('YmdHis') . rand(100, 999);
|
|
|
|
// Gunakan total_harga langsung dari pesanan
|
|
$totalPembayaran = (int)$pesanan->total_harga;
|
|
|
|
// Buat transaksi baru
|
|
$transaksi = Transaksi::create([
|
|
'user_id' => Auth::id(),
|
|
'pesanan_id' => $pesanan->id,
|
|
'kode_transaksi' => $kodeTransaksi,
|
|
'total_pembayaran' => $totalPembayaran,
|
|
'metode_pembayaran' => $request->metode_pembayaran,
|
|
'status' => 'menunggu_pembayaran',
|
|
'nama_penerima' => $request->nama_penerima,
|
|
'no_telp' => $request->no_telp,
|
|
'alamat' => $request->alamat,
|
|
'catatan_pengiriman' => $request->catatan_pengiriman
|
|
]);
|
|
|
|
// Update status pesanan menjadi diproses
|
|
$pesanan->update(['status' => 'diproses']);
|
|
|
|
return redirect()->route('transaksi.show', $transaksi)
|
|
->with('success', 'Transaksi berhasil dibuat. Silakan lakukan pembayaran.');
|
|
}
|
|
|
|
public function show(Transaksi $transaksi)
|
|
{
|
|
// Pastikan transaksi milik user yang sedang login
|
|
if ($transaksi->user_id !== Auth::id()) {
|
|
return abort(403, 'Unauthorized action.');
|
|
}
|
|
|
|
$transaksi->load(['pesanan.barang']);
|
|
return view('transaksi.show', compact('transaksi'));
|
|
}
|
|
|
|
public function uploadBukti(Request $request, Transaksi $transaksi)
|
|
{
|
|
$request->validate([
|
|
'bukti_pembayaran' => 'required|image|max:2048'
|
|
]);
|
|
|
|
if ($transaksi->user_id !== Auth::id()) {
|
|
return abort(403, 'Unauthorized action.');
|
|
}
|
|
|
|
if ($transaksi->status !== 'menunggu_pembayaran') {
|
|
return back()->with('error', 'Bukti pembayaran tidak dapat diupload');
|
|
}
|
|
|
|
// Upload bukti pembayaran
|
|
$path = $request->file('bukti_pembayaran')->store('bukti_pembayaran', 'public');
|
|
|
|
$transaksi->update([
|
|
'bukti_pembayaran' => $path,
|
|
'status' => 'menunggu_konfirmasi'
|
|
]);
|
|
|
|
return back()->with('success', 'Bukti pembayaran berhasil diupload');
|
|
}
|
|
|
|
public function confirmPayment(Request $request, Transaksi $transaksi)
|
|
{
|
|
if ($transaksi->status !== 'menunggu_konfirmasi') {
|
|
return back()->with('error', 'Status transaksi tidak valid');
|
|
}
|
|
|
|
$transaksi->update(['status' => 'dibayar']);
|
|
$transaksi->pesanan->update(['status' => 'diproses']);
|
|
|
|
return back()->with('success', 'Pembayaran berhasil dikonfirmasi');
|
|
}
|
|
|
|
public function callback(Request $request)
|
|
{
|
|
try {
|
|
$payload = $request->all();
|
|
$transaksi = $this->midtransService->handleCallback((object) $payload);
|
|
|
|
return response()->json([
|
|
'success' => true,
|
|
'message' => 'Callback berhasil diproses',
|
|
'data' => $transaksi
|
|
]);
|
|
} catch (\Exception $e) {
|
|
return response()->json([
|
|
'success' => false,
|
|
'message' => $e->getMessage()
|
|
], 400);
|
|
}
|
|
}
|
|
|
|
public function finish(Request $request)
|
|
{
|
|
try {
|
|
Log::info('Finish Callback', [
|
|
'order_id' => $request->order_id,
|
|
'transaction_status' => $request->transaction_status,
|
|
'payment_type' => $request->payment_type,
|
|
'all_params' => $request->all()
|
|
]);
|
|
|
|
$transaksi = Transaksi::where('kode_transaksi', $request->order_id)->first();
|
|
|
|
if (!$transaksi) {
|
|
Log::error('Transaksi tidak ditemukan', [
|
|
'order_id' => $request->order_id,
|
|
'snap_token' => $request->snap_token
|
|
]);
|
|
return redirect()->route('pesanan.index')
|
|
->with('error', 'Transaksi tidak ditemukan. Silakan hubungi admin dengan kode transaksi: ' . $request->order_id);
|
|
}
|
|
|
|
// Update status transaksi
|
|
$transaksi->update([
|
|
'status' => 'dibayar',
|
|
'payment_type' => $request->payment_type,
|
|
'transaction_status' => $request->transaction_status
|
|
]);
|
|
|
|
// Update status pesanan
|
|
$transaksi->pesanan->update(['status' => 'diproses']);
|
|
|
|
return view('transaksi.success', [
|
|
'transaksi' => $transaksi,
|
|
'payment_type' => $request->payment_type,
|
|
'transaction_status' => $request->transaction_status
|
|
]);
|
|
} catch (\Exception $e) {
|
|
Log::error('Error in finish callback: ' . $e->getMessage(), [
|
|
'order_id' => $request->order_id,
|
|
'exception' => $e
|
|
]);
|
|
|
|
return redirect()->route('pesanan.index')
|
|
->with('error', 'Terjadi kesalahan saat memproses pembayaran. Silakan hubungi admin.');
|
|
}
|
|
}
|
|
|
|
public function unfinish(Request $request)
|
|
{
|
|
try {
|
|
Log::info('Unfinish Callback', [
|
|
'order_id' => $request->order_id,
|
|
'transaction_status' => $request->transaction_status,
|
|
'payment_type' => $request->payment_type,
|
|
'all_params' => $request->all()
|
|
]);
|
|
|
|
$transaksi = Transaksi::where('kode_transaksi', $request->order_id)->first();
|
|
|
|
if (!$transaksi) {
|
|
Log::error('Transaksi tidak ditemukan', [
|
|
'order_id' => $request->order_id
|
|
]);
|
|
return redirect()->route('pesanan.index')
|
|
->with('error', 'Transaksi tidak ditemukan. Silakan hubungi admin dengan kode transaksi: ' . $request->order_id);
|
|
}
|
|
|
|
// Update status transaksi menjadi pending
|
|
$transaksi->update([
|
|
'status' => 'menunggu_pembayaran',
|
|
'payment_type' => $request->payment_type,
|
|
'transaction_status' => $request->transaction_status
|
|
]);
|
|
|
|
// Tampilkan halaman pending dengan informasi pembayaran
|
|
return view('transaksi.pending', [
|
|
'transaksi' => $transaksi,
|
|
'payment_type' => $request->payment_type,
|
|
'transaction_status' => $request->transaction_status,
|
|
'message' => 'Pembayaran Anda belum selesai. Silakan selesaikan pembayaran Anda.'
|
|
]);
|
|
} catch (\Exception $e) {
|
|
Log::error('Error in unfinish callback: ' . $e->getMessage(), [
|
|
'order_id' => $request->order_id,
|
|
'exception' => $e
|
|
]);
|
|
|
|
return redirect()->route('pesanan.index')
|
|
->with('error', 'Terjadi kesalahan saat memproses pembayaran. Silakan hubungi admin.');
|
|
}
|
|
}
|
|
|
|
public function error(Request $request)
|
|
{
|
|
$transaksi = Transaksi::where('kode_transaksi', $request->order_id)->first();
|
|
|
|
if (!$transaksi) {
|
|
return redirect()->route('pesanan.index')->with('error', 'Transaksi tidak ditemukan');
|
|
}
|
|
|
|
return view('transaksi.error', [
|
|
'transaksi' => $transaksi
|
|
]);
|
|
}
|
|
|
|
public function getSnapToken(Pesanan $pesanan)
|
|
{
|
|
try {
|
|
// Cek apakah pesanan memiliki transaksi
|
|
$transaksi = $pesanan->transaksi;
|
|
if (!$transaksi) {
|
|
return response()->json([
|
|
'error' => 'Tidak ada transaksi yang sedang menunggu pembayaran'
|
|
], 400);
|
|
}
|
|
|
|
// Pastikan pesanan milik user yang sedang login
|
|
if ((int)$pesanan->user_id !== Auth::id()) {
|
|
return response()->json([
|
|
'error' => 'Unauthorized action'
|
|
], 403);
|
|
}
|
|
|
|
// Siapkan item details
|
|
$itemDetails = [];
|
|
|
|
// Ambil semua item dari pesanan
|
|
foreach ($pesanan->items as $item) {
|
|
$itemDetails[] = [
|
|
'id' => (string)$item->barang_id,
|
|
'price' => (int)$item->harga,
|
|
'quantity' => $item->jumlah,
|
|
'name' => $item->barang->nama_barang,
|
|
'category' => 'Electronics'
|
|
];
|
|
}
|
|
|
|
// Debug log untuk memeriksa total harga
|
|
Log::info('Total Harga Debug', [
|
|
'total_pembayaran' => $transaksi->total_pembayaran,
|
|
'item_details' => $itemDetails,
|
|
'transaksi_id' => $transaksi->id,
|
|
]);
|
|
|
|
// Dapatkan Snap token dari Midtrans dengan order_id yang sama
|
|
$snapToken = $this->midtransService->getSnapToken([
|
|
'transaction_details' => [
|
|
'order_id' => $transaksi->kode_transaksi,
|
|
'gross_amount' => (int)$transaksi->total_pembayaran
|
|
],
|
|
'item_details' => $itemDetails,
|
|
'customer_details' => [
|
|
'first_name' => $transaksi->nama_penerima,
|
|
'email' => Auth::user()->email ?: 'guest@example.com',
|
|
'phone' => $transaksi->no_telp,
|
|
'billing_address' => [
|
|
'address' => $transaksi->alamat
|
|
]
|
|
]
|
|
]);
|
|
|
|
return response()->json([
|
|
'snap_token' => $snapToken
|
|
]);
|
|
} catch (\Exception $e) {
|
|
Log::error('Error getting snap token: ' . $e->getMessage());
|
|
return response()->json([
|
|
'error' => 'Terjadi kesalahan saat memproses pembayaran: ' . $e->getMessage()
|
|
], 500);
|
|
}
|
|
}
|
|
|
|
public function updateStatus(Request $request)
|
|
{
|
|
try {
|
|
$transaksi = Transaksi::where('kode_transaksi', $request->order_id)->first();
|
|
|
|
if (!$transaksi) {
|
|
return response()->json([
|
|
'error' => 'Transaksi tidak ditemukan'
|
|
], 404);
|
|
}
|
|
|
|
// Update status transaksi
|
|
$transaksi->update([
|
|
'status' => 'dibayar',
|
|
'payment_type' => $request->payment_type,
|
|
'transaction_status' => $request->transaction_status
|
|
]);
|
|
|
|
// Update status pesanan
|
|
$transaksi->pesanan->update(['status' => 'diproses']);
|
|
|
|
return response()->json([
|
|
'success' => true,
|
|
'message' => 'Status transaksi berhasil diupdate'
|
|
]);
|
|
} catch (\Exception $e) {
|
|
Log::error('Error updating transaction status: ' . $e->getMessage());
|
|
return response()->json([
|
|
'error' => 'Terjadi kesalahan saat mengupdate status transaksi'
|
|
], 500);
|
|
}
|
|
}
|
|
}
|