Simplify Paystack checkout handoff
Deploy Ladill Merchant / deploy (push) Successful in 45s

This commit is contained in:
isaacclad
2026-07-24 08:25:28 +00:00
parent 27f67f239b
commit ef8b230ece
2 changed files with 9 additions and 29 deletions
@@ -854,17 +854,13 @@
this._activeCode = accessCode; this._activeCode = accessCode;
this.launching = true; this.launching = true;
this.error = ''; this.error = '';
// Wait for the bottomsheet/modal body to lay out, then open Paystack // Paystack owns its secure checkout popup. Do not pin or reparent
// and pin its body iframe over that loading area (no reparent). // its iframe into the Ladill sheet: that produces a loader followed
var start = function () { // by a second checkout layer in some browsers.
if (token !== store._launchToken) return; var start = function () {
armPaystackMount();
setPaystackContainActive(true);
watchPaystackIframes();
waitForPinTarget(1200).then(function () {
if (token !== store._launchToken) return; if (token !== store._launchToken) return;
return loadInlineJs(); watchPaystackIframes();
}).then(function (PaystackPop) { loadInlineJs().then(function (PaystackPop) {
if (token !== store._launchToken) return; if (token !== store._launchToken) return;
if (!PaystackPop) throw new Error('Paystack unavailable'); if (!PaystackPop) throw new Error('Paystack unavailable');
try { try {
@@ -873,25 +869,14 @@
} }
} catch (e) {} } catch (e) {}
activePopup = null; activePopup = null;
armPaystackMount(); setPaystackContainActive(false);
setPaystackContainActive(true);
syncPaystackMountBox();
// PaystackPop constructor appends iframes to document.body.
// We leave them there and pin checkout over our sheet body.
var popup = new PaystackPop(); var popup = new PaystackPop();
activePopup = popup; activePopup = popup;
ensurePaystackContained(document);
popup.resumeTransaction(accessCode, { popup.resumeTransaction(accessCode, {
onLoad: function () { onLoad: function () {
if (token !== store._launchToken) return; if (token !== store._launchToken) return;
store.launching = false; store.launching = false;
ensurePaystackIframePermissions(document); ensurePaystackIframePermissions(document);
ensurePaystackContained(document);
// Alpine swaps header/spinner; re-measure then re-pin.
setTimeout(function () { ensurePaystackContained(document); }, 0);
setTimeout(function () { ensurePaystackContained(document); }, 50);
setTimeout(function () { ensurePaystackContained(document); }, 150);
setTimeout(function () { ensurePaystackContained(document); }, 400);
}, },
onSuccess: function (transaction) { onSuccess: function (transaction) {
if (token !== store._launchToken) return; if (token !== store._launchToken) return;
@@ -921,10 +906,6 @@
store.error = (err && err.message) ? String(err.message) : 'Could not open secure payment.'; store.error = (err && err.message) ? String(err.message) : 'Could not open secure payment.';
}, },
}); });
setTimeout(function () { ensurePaystackContained(document); }, 0);
setTimeout(function () { ensurePaystackContained(document); }, 50);
setTimeout(function () { ensurePaystackContained(document); }, 200);
setTimeout(function () { ensurePaystackContained(document); }, 500);
}).catch(function (err) { }).catch(function (err) {
if (token !== store._launchToken) return; if (token !== store._launchToken) return;
store.launching = false; store.launching = false;
@@ -1121,7 +1102,7 @@
$watch('returnUrl', () => runSync()); $watch('returnUrl', () => runSync());
$nextTick(() => runSync()); $nextTick(() => runSync());
" "
x-show="showSheet" x-show="showSheet && $store.ladillPayCheckout && ($store.ladillPayCheckout.frameable || $store.ladillPayCheckout.error)"
x-cloak x-cloak
data-ladill-pay-sheet data-ladill-pay-sheet
x-effect="document.documentElement.style.overflow = showSheet ? 'hidden' : ''" x-effect="document.documentElement.style.overflow = showSheet ? 'hidden' : ''"
@@ -28,8 +28,7 @@ class ResponsivePaystackSheetTest extends TestCase
$this->assertStringContainsString('LadillPayCheckout', $html); $this->assertStringContainsString('LadillPayCheckout', $html);
$this->assertStringContainsString('resumeTransaction', $html); $this->assertStringContainsString('resumeTransaction', $html);
$this->assertStringContainsString('js.paystack.co/v2/inline.js', $html); $this->assertStringContainsString('js.paystack.co/v2/inline.js', $html);
$this->assertStringContainsString('Starting secure checkout', $html); $this->assertStringContainsString('Paystack owns its secure checkout popup', $html);
$this->assertStringContainsString('not in a separate browser', $html);
// Must not push Paystack to a separate browser as the primary path. // Must not push Paystack to a separate browser as the primary path.
$this->assertStringNotContainsString('Continue to Paystack', $html); $this->assertStringNotContainsString('Continue to Paystack', $html);
$this->assertStringNotContainsString('window.open(', $html); $this->assertStringNotContainsString('window.open(', $html);