NIM_E31222518/app/Http/Controllers/TransaksiController.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);
}
}
}