Make Mini Pay never fail silently.
Deploy Ladill Mini / deploy (push) Successful in 48s

Use form POST fallback, re-register Alpine Pay handler in Blade, timeout fetch, and always full-page navigate for MoMo so the waiting page is not blank in the Paystack iframe.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
isaacclad
2026-07-13 23:04:28 +00:00
co-authored by Cursor
parent 53a83b84c5
commit a2bf4f435f
3 changed files with 158 additions and 43 deletions
+15 -7
View File
@@ -15,6 +15,7 @@ window.QRCodeStyling = QRCodeStyling;
import qrcode from 'qrcode-generator';
window.qrcode = qrcode;
window.Alpine = Alpine;
Alpine.plugin(collapse);
registerLadillClipboard(Alpine);
@@ -224,6 +225,9 @@ Alpine.data('miniPaymentLanding', (config = {}) => ({
this.errorMsg = '';
this.loading = true;
const controller = new AbortController();
const timer = setTimeout(() => controller.abort(), 45000);
try {
const res = await fetch(config.payUrl, {
method: 'POST',
@@ -234,33 +238,37 @@ Alpine.data('miniPaymentLanding', (config = {}) => ({
'X-Requested-With': 'XMLHttpRequest',
},
body: JSON.stringify({ amount: value, customer_phone: phone }),
signal: controller.signal,
});
const data = await res.json().catch(() => ({}));
const apiError = typeof data.error === 'string'
? data.error
: (typeof data.message === 'string' ? data.message : '');
if (!res.ok || apiError) {
this.errorMsg = apiError || 'Could not start payment. Please try again.';
this.loading = false;
this.errorMsg = apiError || (`Could not start payment (${res.status}). Please try again.`);
return;
}
if (!data.checkout_url) {
this.errorMsg = 'Could not start payment. Please try again.';
this.loading = false;
return;
}
// MoMo waiting page must be full-page (prompt + status poll), not the Paystack iframe sheet.
// MoMo waiting page must be full-page — never trap it in the Paystack iframe
// (cross-origin iframe is blank / looks like "Pay did nothing").
const useSheet = data.provider !== 'mtn_momo' && window.innerWidth < 768;
if (useSheet) {
this.checkoutUrl = data.checkout_url;
this.showSheet = true;
this.loading = false;
} else {
window.location.href = data.checkout_url;
window.location.assign(data.checkout_url);
return;
}
} catch (e) {
this.errorMsg = 'Network error. Please try again.';
this.errorMsg = e?.name === 'AbortError'
? 'Payment is taking too long. Please try again.'
: 'Network error. Please try again.';
} finally {
clearTimeout(timer);
this.loading = false;
}
},