Deploy Ladill Merchant / deploy (push) Successful in 1m5s
Standardize customer-facing Ladill Pay checkout shells across products, open them on all viewports, and escape iframe callbacks back to the product flow.
99 lines
3.3 KiB
PHP
99 lines
3.3 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers\Public;
|
|
|
|
use App\Http\Controllers\Controller;
|
|
use App\Models\QrCode;
|
|
use App\Models\QrSaleOrder;
|
|
use App\Services\Merchant\MerchantSaleService;
|
|
use App\Support\LadillLink;
|
|
use App\Support\Qr\QrTypeCatalog;
|
|
use Illuminate\Http\JsonResponse;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\View\View;
|
|
use RuntimeException;
|
|
|
|
class SaleOrderController extends Controller
|
|
{
|
|
public function __construct(private MerchantSaleService $sales) {}
|
|
|
|
public function store(Request $request, string $shortCode): JsonResponse
|
|
{
|
|
$qrCode = QrCode::query()
|
|
->where('short_code', $shortCode)
|
|
->whereIn('type', QrTypeCatalog::storefrontTypes())
|
|
->where('is_active', true)
|
|
->firstOrFail();
|
|
|
|
if (! $qrCode->acceptsOrders()) {
|
|
return response()->json(['error' => 'This QR code does not accept orders.'], 422);
|
|
}
|
|
|
|
if (empty($qrCode->content()['accepts_payment'])) {
|
|
return response()->json(['error' => 'Online payments are not enabled for this storefront.'], 422);
|
|
}
|
|
|
|
$validated = $request->validate([
|
|
'customer_name' => ['required', 'string', 'max:120'],
|
|
'customer_email' => ['nullable', 'email', 'max:200'],
|
|
'customer_phone' => ['required', 'string', 'max:30'],
|
|
'shipping_fee' => ['nullable', 'numeric', 'min:0', 'max:10000'],
|
|
'items' => ['required', 'array', 'min:1'],
|
|
'items.*.name' => ['required', 'string', 'max:200'],
|
|
'items.*.price' => ['required', 'numeric', 'min:0'],
|
|
'items.*.qty' => ['required', 'integer', 'min:1', 'max:100'],
|
|
]);
|
|
|
|
try {
|
|
$result = $this->sales->initiateOrder($qrCode, $validated);
|
|
} catch (RuntimeException $e) {
|
|
return response()->json(['error' => $e->getMessage()], 422);
|
|
}
|
|
|
|
return response()->json([
|
|
'checkout_url' => $result['checkout_url'],
|
|
'callback_url' => $result['callback_url'],
|
|
]);
|
|
}
|
|
|
|
public function callback(Request $request, string $shortCode): View
|
|
{
|
|
$reference = trim((string) $request->query('reference', ''));
|
|
if ($reference === '') {
|
|
return view('public.payment-return', [
|
|
'redirect' => LadillLink::url($shortCode),
|
|
]);
|
|
}
|
|
|
|
try {
|
|
$order = $this->sales->completeOrder($reference);
|
|
} catch (\Throwable) {
|
|
return view('public.payment-return', [
|
|
'redirect' => LadillLink::url($shortCode),
|
|
]);
|
|
}
|
|
|
|
return view('public.payment-return', [
|
|
'redirect' => route('qr.public.order.confirmed', [
|
|
'shortCode' => $shortCode,
|
|
'reference' => $order->payment_reference,
|
|
], absolute: true),
|
|
]);
|
|
}
|
|
|
|
public function confirmed(string $shortCode, string $reference): View
|
|
{
|
|
$order = QrSaleOrder::query()
|
|
->with('qrCode')
|
|
->where('payment_reference', $reference)
|
|
->where('status', QrSaleOrder::STATUS_PAID)
|
|
->whereHas('qrCode', fn ($q) => $q->where('short_code', $shortCode))
|
|
->firstOrFail();
|
|
|
|
return view('public.qr.order-success', [
|
|
'order' => $order,
|
|
'qrCode' => $order->qrCode,
|
|
]);
|
|
}
|
|
}
|