Open Paystack from the Pay click gesture, not after fetch.
Deploy Ladill Hosting / deploy (push) Successful in 1m17s
Deploy Ladill Hosting / deploy (push) Successful in 1m17s
Paystack blocks iframes, so checkout uses a popup beside the sheet/modal chrome. Opening about:blank on the user tap keeps that window from being blocked after the async initiate response.
This commit is contained in:
@@ -10,8 +10,9 @@
|
||||
|
||||
Paystack (checkout.paystack.com) sends X-Frame-Options: SAMEORIGIN and cannot be
|
||||
embedded. Same-origin URLs (e.g. MoMo waiting pages) still load in an iframe.
|
||||
External checkouts open in a named window, with an in-sheet Continue CTA as a
|
||||
user-gesture fallback when the popup is blocked after an async fetch.
|
||||
External checkouts open in a named window. Call LadillPayCheckout.prepare()
|
||||
synchronously in the Pay click handler (before await fetch) so the popup is not
|
||||
blocked after the async response. An in-sheet Continue CTA remains as fallback.
|
||||
--}}
|
||||
@php
|
||||
$audience = $audience ?? 'buyer';
|
||||
@@ -42,6 +43,9 @@
|
||||
(function () {
|
||||
if (window.LadillPayCheckout) return;
|
||||
|
||||
var PENDING_NAME = 'ladill_pay_checkout';
|
||||
var pendingWindow = null;
|
||||
|
||||
function isFrameable(url) {
|
||||
if (!url) return false;
|
||||
try {
|
||||
@@ -51,12 +55,50 @@
|
||||
}
|
||||
}
|
||||
|
||||
function writePendingPlaceholder(win) {
|
||||
if (!win) return;
|
||||
try {
|
||||
win.document.open();
|
||||
win.document.write('<!DOCTYPE html><html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Payment</title></head><body style="margin:0;min-height:100vh;display:grid;place-items:center;font-family:system-ui,sans-serif;background:#f8fafc;color:#475569"><p style="font-size:0.95rem">Opening secure checkout…</p></body></html>');
|
||||
win.document.close();
|
||||
} catch (e) {}
|
||||
}
|
||||
|
||||
function prepare() {
|
||||
cancel();
|
||||
try {
|
||||
var win = window.open('about:blank', PENDING_NAME, 'width=480,height=720');
|
||||
if (win && !win.closed) {
|
||||
pendingWindow = win;
|
||||
writePendingPlaceholder(win);
|
||||
return win;
|
||||
}
|
||||
} catch (e) {}
|
||||
pendingWindow = null;
|
||||
return null;
|
||||
}
|
||||
|
||||
function cancel() {
|
||||
if (pendingWindow && !pendingWindow.closed) {
|
||||
try { pendingWindow.close(); } catch (e) {}
|
||||
}
|
||||
pendingWindow = null;
|
||||
}
|
||||
|
||||
function openCheckout(url) {
|
||||
if (!url) return null;
|
||||
try {
|
||||
if (pendingWindow && !pendingWindow.closed) {
|
||||
pendingWindow.location = url;
|
||||
var win = pendingWindow;
|
||||
pendingWindow = null;
|
||||
return win;
|
||||
}
|
||||
pendingWindow = null;
|
||||
// Named window (no noopener) so payment-return can redirect window.opener.
|
||||
return window.open(url, 'ladill_pay_checkout', 'width=480,height=720');
|
||||
return window.open(url, PENDING_NAME, 'width=480,height=720');
|
||||
} catch (e) {
|
||||
pendingWindow = null;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -83,6 +125,7 @@
|
||||
if (!url) return;
|
||||
this.frameable = isFrameable(url);
|
||||
if (this.frameable) {
|
||||
cancel();
|
||||
this.popupBlocked = false;
|
||||
return;
|
||||
}
|
||||
@@ -114,6 +157,8 @@
|
||||
|
||||
window.LadillPayCheckout = {
|
||||
isFrameable: isFrameable,
|
||||
prepare: prepare,
|
||||
cancel: cancel,
|
||||
open: openCheckout,
|
||||
ensureStore: ensureStore,
|
||||
};
|
||||
@@ -183,12 +228,12 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="min-h-0 flex-1 overflow-y-auto overscroll-contain">
|
||||
<iframe x-show="$store.ladillPayCheckout?.frameable"
|
||||
:src="showSheet && $store.ladillPayCheckout?.frameable ? checkoutUrl : ''"
|
||||
<iframe x-show="$store.ladillPayCheckout.frameable"
|
||||
:src="showSheet && $store.ladillPayCheckout.frameable ? checkoutUrl : ''"
|
||||
class="h-full min-h-[60dvh] w-full border-0"
|
||||
allow="payment *"
|
||||
title="{{ $iframeTitle }}"></iframe>
|
||||
<div x-show="!$store.ladillPayCheckout?.frameable"
|
||||
<div x-show="!$store.ladillPayCheckout.frameable"
|
||||
class="flex min-h-[60dvh] flex-col items-center justify-center gap-4 px-6 py-10 text-center">
|
||||
<div class="flex h-12 w-12 items-center justify-center rounded-full bg-indigo-50 text-indigo-600" aria-hidden="true">
|
||||
<svg class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke-width="1.75" stroke="currentColor">
|
||||
@@ -197,14 +242,14 @@
|
||||
</div>
|
||||
<div class="max-w-xs space-y-1">
|
||||
<p class="text-sm font-semibold text-slate-800"
|
||||
x-text="$store.ladillPayCheckout?.popupBlocked ? 'Continue in a secure payment window' : 'Complete payment in the secure window'"></p>
|
||||
x-text="$store.ladillPayCheckout.popupBlocked ? 'Continue in a secure payment window' : 'Complete payment in the secure window'"></p>
|
||||
<p class="text-xs leading-snug text-slate-500">
|
||||
<span x-show="!$store.ladillPayCheckout?.popupBlocked">A Paystack window should be open. If you do not see it, tap continue below.</span>
|
||||
<span x-show="$store.ladillPayCheckout?.popupBlocked">Your browser blocked the popup. Tap continue to open Paystack.</span>
|
||||
<span x-show="!$store.ladillPayCheckout.popupBlocked">A Paystack window should be open. If you do not see it, tap continue below.</span>
|
||||
<span x-show="$store.ladillPayCheckout.popupBlocked">Your browser blocked the popup. Tap continue to open Paystack.</span>
|
||||
</p>
|
||||
</div>
|
||||
<button type="button"
|
||||
@click="$store.ladillPayCheckout?.continueTo(checkoutUrl)"
|
||||
@click="$store.ladillPayCheckout.continueTo(checkoutUrl)"
|
||||
class="inline-flex w-full max-w-xs items-center justify-center rounded-xl bg-indigo-600 px-4 py-3 text-sm font-semibold text-white hover:bg-indigo-700">
|
||||
Continue to Paystack
|
||||
</button>
|
||||
@@ -251,13 +296,13 @@
|
||||
</button>
|
||||
</div>
|
||||
<div class="min-h-0 flex-1 overflow-y-auto overscroll-contain">
|
||||
<iframe x-show="$store.ladillPayCheckout?.frameable"
|
||||
:src="showSheet && $store.ladillPayCheckout?.frameable ? checkoutUrl : ''"
|
||||
<iframe x-show="$store.ladillPayCheckout.frameable"
|
||||
:src="showSheet && $store.ladillPayCheckout.frameable ? checkoutUrl : ''"
|
||||
class="h-full min-h-0 w-full border-0"
|
||||
style="min-height: 28rem"
|
||||
allow="payment *"
|
||||
title="{{ $iframeTitle }}"></iframe>
|
||||
<div x-show="!$store.ladillPayCheckout?.frameable"
|
||||
<div x-show="!$store.ladillPayCheckout.frameable"
|
||||
class="flex h-full min-h-[28rem] flex-col items-center justify-center gap-4 px-8 py-12 text-center">
|
||||
<div class="flex h-12 w-12 items-center justify-center rounded-full bg-indigo-50 text-indigo-600" aria-hidden="true">
|
||||
<svg class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke-width="1.75" stroke="currentColor">
|
||||
@@ -266,14 +311,14 @@
|
||||
</div>
|
||||
<div class="max-w-sm space-y-1">
|
||||
<p class="text-sm font-semibold text-slate-800"
|
||||
x-text="$store.ladillPayCheckout?.popupBlocked ? 'Continue in a secure payment window' : 'Complete payment in the secure window'"></p>
|
||||
x-text="$store.ladillPayCheckout.popupBlocked ? 'Continue in a secure payment window' : 'Complete payment in the secure window'"></p>
|
||||
<p class="text-xs leading-snug text-slate-500">
|
||||
<span x-show="!$store.ladillPayCheckout?.popupBlocked">A Paystack window should be open. If you do not see it, click continue below.</span>
|
||||
<span x-show="$store.ladillPayCheckout?.popupBlocked">Your browser blocked the popup. Click continue to open Paystack.</span>
|
||||
<span x-show="!$store.ladillPayCheckout.popupBlocked">A Paystack window should be open. If you do not see it, click continue below.</span>
|
||||
<span x-show="$store.ladillPayCheckout.popupBlocked">Your browser blocked the popup. Click continue to open Paystack.</span>
|
||||
</p>
|
||||
</div>
|
||||
<button type="button"
|
||||
@click="$store.ladillPayCheckout?.continueTo(checkoutUrl)"
|
||||
@click="$store.ladillPayCheckout.continueTo(checkoutUrl)"
|
||||
class="inline-flex w-full max-w-xs items-center justify-center rounded-xl bg-indigo-600 px-4 py-3 text-sm font-semibold text-white hover:bg-indigo-700">
|
||||
Continue to Paystack
|
||||
</button>
|
||||
|
||||
Reference in New Issue
Block a user