<?php namespace App\Http\Controllers; use App\Models\{Cart, Order, OrderItem, Payment}; use Illuminate\Http\Request; use Illuminate\Support\Str; class CheckoutController extends Controller { private function userCart(): Cart { return Cart::firstOrCreate(['user_id' => auth()->id()]); } public function show() { $cart = $this->userCart()->load('items.product'); abort_if($cart->items->isEmpty(), 404); $subtotalCents = $cart->items->sum(fn($i) => $i->quantity * $i->unit_price_cents); return view('checkout.show', compact('cart', 'subtotalCents')); } public function placeOrder(Request $request) { $cart = $this->userCart()->load('items.product'); abort_if($cart->items->isEmpty(), 404); $validated = $request->validate([ 'customer_name' => ['required','string','max:100'], 'customer_phone' => ['required','string','max:30'], 'address_line1' => ['required','string','max:200'], 'address_line2' => ['nullable','string','max:200'], 'city' => ['required','string','max:100'], 'state' => ['required','string','max:100'], 'postcode' => ['required','string','max:20'], 'country' => ['required','string','max:2'], ]); $user = auth()->user(); $user->customerProfile()->updateOrCreate( ['user_id' => $user->id], [ 'phone' => $validated['customer_phone'], 'address_line1' => $validated['address_line1'], 'address_line2' => $validated['address_line2'] ?? null, 'city' => $validated['city'], 'state' => $validated['state'], 'postcode' => $validated['postcode'], 'country' => $validated['country'], ] ); $subtotalCents = $cart->items->sum(fn($i) => $i->quantity * $i->unit_price_cents); $order = Order::create([ 'user_id' => auth()->id(), 'order_no' => 'ORD-' . strtoupper(Str::random(10)), 'subtotal_cents' => $subtotalCents, 'total_cents' => $subtotalCents, 'status' => 'payment_pending', 'customer_name' => $validated['customer_name'], 'customer_phone' => $validated['customer_phone'], ]); foreach ($cart->items as $item) { OrderItem::create([ 'order_id' => $order->id, 'product_id' => $item->product_id, 'quantity' => $item->quantity, 'unit_price_cents' => $item->unit_price_cents, 'line_total_cents' => $item->quantity * $item->unit_price_cents, ]); } $payment = Payment::create([ 'order_id' => $order->id, 'provider' => 'fpx', 'status' => 'initiated', 'reference' => null, 'payload' => [ 'note' => 'FPX not integrated yet. Add credentials later in config/fpx.php', ], ]); // Clear cart $cart->items()->delete(); // For now redirect to placeholder "FPX redirect" page/route return redirect()->route('payments.fpx.redirect', $order); } // Placeholder: in real FPX this would generate payload + redirect user to FPX public function fpxRedirect(Order $order) { abort_unless($order->user_id === auth()->id(), 403); return view('payments.fpx_redirect', [ 'order' => $order, 'fpxConfig' => config('fpx'), ]); } // Placeholder callback endpoint public function fpxCallback(Request $request) { // Later: verify signature, update payment + order status return response()->json([ 'message' => 'FPX callback received (stub).', 'data' => $request->all(), ]); } }