Deploy Ladill Mini / deploy (push) Successful in 1m39s
Use the shared Inline sheet, hold busy until payment UI opens, and avoid locking page scroll during the handoff.
127 lines
6.0 KiB
PHP
127 lines
6.0 KiB
PHP
@props([
|
|
'id',
|
|
'title' => 'Add credits',
|
|
'description' => '',
|
|
'topupAction',
|
|
'minTopup' => 5,
|
|
'suggestedAmount' => 10,
|
|
'ladillWalletBalance' => 0,
|
|
'serviceBalance' => null,
|
|
'serviceBalanceLabel' => 'Current balance',
|
|
'openOnLoad' => false,
|
|
'returnUrl' => null,
|
|
])
|
|
|
|
@php
|
|
// Single-wallet (siloing step 2): there is one Ladill wallet, so "pay from
|
|
// wallet into service credits" is a meaningless round-trip — top up the one
|
|
// wallet directly (Paystack). Transfer option removed.
|
|
$canPayFromWallet = false;
|
|
@endphp
|
|
|
|
<x-modal :name="$id" :show="$openOnLoad" maxWidth="md">
|
|
<div class="flex min-h-full flex-col sm:min-h-0">
|
|
<div class="border-b border-slate-100 px-5 py-4 pr-12 sm:px-6 sm:pr-14">
|
|
<h2 class="text-lg font-semibold text-slate-900">{{ $title }}</h2>
|
|
@if($description)
|
|
<p class="mt-1 text-sm text-slate-500">{{ $description }}</p>
|
|
@endif
|
|
</div>
|
|
|
|
<form action="{{ $topupAction }}" method="POST" class="flex flex-1 flex-col p-5 sm:p-6"
|
|
x-data="{
|
|
method: 'paystack',
|
|
showSheet: false,
|
|
checkoutUrl: '',
|
|
loading: false,
|
|
errorMsg: '',
|
|
async submitTopup(event) {
|
|
if (this.method !== 'paystack') return;
|
|
|
|
event.preventDefault();
|
|
this.loading = true; window.LadillPayCheckout?.prepare?.();
|
|
this.errorMsg = '';
|
|
|
|
try {
|
|
const res = await fetch(event.target.action, {
|
|
method: 'POST',
|
|
headers: { 'Accept': 'application/json' },
|
|
body: new FormData(event.target),
|
|
});
|
|
const data = await res.json();
|
|
if (!res.ok || data.error || !data.checkout_url) {
|
|
this.errorMsg = data.error || 'Unable to start payment. Please try again.';
|
|
this.loading = false;
|
|
return;
|
|
}
|
|
|
|
this.checkoutUrl = data.checkout_url;
|
|
this.accessCode = data.access_code || '';
|
|
this.publicKey = data.public_key || '';
|
|
this.returnUrl = data.callback_url || '';
|
|
this.showSheet = true; // loading cleared when payment UI opens (ladill-pay-opened)
|
|
} catch (error) {
|
|
window.LadillPayCheckout?.cancel?.(); this.errorMsg = 'Network error. Please try again.';
|
|
this.loading = false;
|
|
}
|
|
},
|
|
}"
|
|
@submit="submitTopup($event)">
|
|
@csrf
|
|
@if($returnUrl)
|
|
<input type="hidden" name="return_url" value="{{ $returnUrl }}">
|
|
@endif
|
|
|
|
@if($serviceBalance !== null)
|
|
<div class="mb-4 rounded-xl border border-slate-200 bg-slate-50 px-4 py-3 text-center">
|
|
<p class="text-xl font-bold text-slate-900">GHS {{ number_format((float) $serviceBalance, 2) }}</p>
|
|
<p class="text-xs text-slate-500">{{ $serviceBalanceLabel }}</p>
|
|
</div>
|
|
@endif
|
|
|
|
<div x-show="errorMsg" x-cloak class="mb-4 rounded-lg border border-red-200 bg-red-50 px-3 py-2 text-xs text-red-700" x-text="errorMsg"></div>
|
|
|
|
<div>
|
|
<label class="text-sm font-medium text-slate-700">Amount (GHS)</label>
|
|
<input type="number" name="amount" min="{{ $minTopup }}" max="5000" step="0.01"
|
|
value="{{ $suggestedAmount }}"
|
|
class="mt-1.5 block w-full rounded-xl border border-slate-200 px-3 py-2.5 text-sm focus:border-indigo-400 focus:ring-1 focus:ring-indigo-400"
|
|
required>
|
|
<p class="mt-1.5 text-xs text-slate-500">Minimum GHS {{ number_format($minTopup, 2) }}</p>
|
|
</div>
|
|
|
|
<input type="hidden" name="payment_method" value="paystack" @if($canPayFromWallet) x-model="method" @endif>
|
|
|
|
@if($canPayFromWallet)
|
|
<div class="mt-4">
|
|
<p class="mb-2 text-xs font-medium text-slate-600">Payment method</p>
|
|
<div class="flex rounded-xl border border-slate-200 bg-white p-0.5 text-sm">
|
|
<button type="button" @click="method = 'paystack'"
|
|
:class="method === 'paystack' ? 'bg-indigo-600 text-white' : 'text-slate-600'"
|
|
class="flex-1 rounded-lg py-2 font-medium transition">Paystack</button>
|
|
<button type="button" @click="method = 'wallet'"
|
|
:class="method === 'wallet' ? 'bg-indigo-600 text-white' : 'text-slate-600'"
|
|
class="flex-1 rounded-lg py-2 font-medium transition">Wallet (GHS {{ number_format($ladillWalletBalance, 2) }})</button>
|
|
</div>
|
|
</div>
|
|
@else
|
|
<p class="mt-4 text-xs text-slate-500">Pay with Paystack.</p>
|
|
@endif
|
|
|
|
<div class="mt-6 flex flex-col gap-2 sm:mt-auto sm:flex-row sm:justify-end">
|
|
<button type="button" @click="$dispatch('close-modal', '{{ $id }}')"
|
|
data-close-modal="{{ $id }}"
|
|
class="hidden rounded-xl border border-slate-200 px-4 py-2.5 text-sm font-medium text-slate-700 hover:bg-slate-50 sm:inline-flex">
|
|
Cancel
|
|
</button>
|
|
<button type="submit" :disabled="loading"
|
|
class="btn-primary w-full sm:w-auto">
|
|
<span x-text="loading ? 'Processing…' : 'Add credits'">Add credits</span>
|
|
</button>
|
|
</div>
|
|
|
|
@include('partials.paystack-sheet')
|
|
</form>
|
|
</div>
|
|
</x-modal>
|