Deploy Ladill Give / deploy (push) Successful in 44s
Standardize customer-facing Ladill Pay checkout shells across products, open them on all viewports, and escape iframe callbacks back to the product flow.
93 lines
3.1 KiB
PHP
93 lines
3.1 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers\Public;
|
|
|
|
use App\Http\Controllers\Controller;
|
|
use App\Models\GiveDonation;
|
|
use App\Models\QrCode;
|
|
use App\Services\Give\GiveDonationService;
|
|
use App\Support\LadillLink;
|
|
use Illuminate\Http\JsonResponse;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\View\View;
|
|
use RuntimeException;
|
|
|
|
class DonationController extends Controller
|
|
{
|
|
public function __construct(private GiveDonationService $donations) {}
|
|
|
|
public function store(Request $request, string $shortCode): JsonResponse
|
|
{
|
|
$qrCode = QrCode::query()
|
|
->where('short_code', $shortCode)
|
|
->where('type', QrCode::TYPE_CHURCH)
|
|
->where('is_active', true)
|
|
->firstOrFail();
|
|
|
|
if (! $qrCode->acceptsOrders()) {
|
|
return response()->json(['error' => 'This giving page does not accept donations.'], 422);
|
|
}
|
|
|
|
$validated = $request->validate([
|
|
'customer_name' => ['required', 'string', 'max:120'],
|
|
'customer_email' => ['nullable', 'email', 'max:200'],
|
|
'customer_phone' => ['required', 'string', 'max:30'],
|
|
'items' => ['required', 'array', 'min:1'],
|
|
'items.*.name' => ['required', 'string', 'max:200'],
|
|
'items.*.price' => ['required', 'numeric', 'min:0.01'],
|
|
'items.*.qty' => ['required', 'integer', 'min:1', 'max:1'],
|
|
]);
|
|
|
|
try {
|
|
$result = $this->donations->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 {
|
|
$donation = $this->donations->complete($reference);
|
|
} catch (\Throwable) {
|
|
return view('public.payment-return', [
|
|
'redirect' => LadillLink::url($shortCode),
|
|
]);
|
|
}
|
|
|
|
return view('public.payment-return', [
|
|
'redirect' => route('qr.public.donation.confirmed', [
|
|
'shortCode' => $shortCode,
|
|
'reference' => $donation->payment_reference,
|
|
], absolute: true),
|
|
]);
|
|
}
|
|
|
|
public function confirmed(string $shortCode, string $reference): View
|
|
{
|
|
$donation = GiveDonation::query()
|
|
->with('qrCode')
|
|
->where('payment_reference', $reference)
|
|
->where('status', GiveDonation::STATUS_PAID)
|
|
->whereHas('qrCode', fn ($q) => $q->where('short_code', $shortCode))
|
|
->firstOrFail();
|
|
|
|
return view('public.qr.donation-confirmed', [
|
|
'donation' => $donation,
|
|
'qrCode' => $donation->qrCode,
|
|
]);
|
|
}
|
|
}
|