diff --git a/resources/views/partials/paystack-sheet.blade.php b/resources/views/partials/paystack-sheet.blade.php index 558f236..0065da6 100644 --- a/resources/views/partials/paystack-sheet.blade.php +++ b/resources/views/partials/paystack-sheet.blade.php @@ -854,17 +854,13 @@ this._activeCode = accessCode; this.launching = true; this.error = ''; - // Wait for the bottomsheet/modal body to lay out, then open Paystack - // and pin its body iframe over that loading area (no reparent). - var start = function () { - if (token !== store._launchToken) return; - armPaystackMount(); - setPaystackContainActive(true); - watchPaystackIframes(); - waitForPinTarget(1200).then(function () { + // Paystack owns its secure checkout popup. Do not pin or reparent + // its iframe into the Ladill sheet: that produces a loader followed + // by a second checkout layer in some browsers. + var start = function () { if (token !== store._launchToken) return; - return loadInlineJs(); - }).then(function (PaystackPop) { + watchPaystackIframes(); + loadInlineJs().then(function (PaystackPop) { if (token !== store._launchToken) return; if (!PaystackPop) throw new Error('Paystack unavailable'); try { @@ -873,25 +869,14 @@ } } catch (e) {} activePopup = null; - armPaystackMount(); - setPaystackContainActive(true); - syncPaystackMountBox(); - // PaystackPop constructor appends iframes to document.body. - // We leave them there and pin checkout over our sheet body. + setPaystackContainActive(false); var popup = new PaystackPop(); activePopup = popup; - ensurePaystackContained(document); popup.resumeTransaction(accessCode, { onLoad: function () { if (token !== store._launchToken) return; store.launching = false; 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) { if (token !== store._launchToken) return; @@ -921,10 +906,6 @@ 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) { if (token !== store._launchToken) return; store.launching = false; @@ -1121,7 +1102,7 @@ $watch('returnUrl', () => runSync()); $nextTick(() => runSync()); " - x-show="showSheet" + x-show="showSheet && $store.ladillPayCheckout && ($store.ladillPayCheckout.frameable || $store.ladillPayCheckout.error)" x-cloak data-ladill-pay-sheet x-effect="document.documentElement.style.overflow = showSheet ? 'hidden' : ''" diff --git a/tests/Feature/ResponsivePaystackSheetTest.php b/tests/Feature/ResponsivePaystackSheetTest.php index 8aab9be..dc2601c 100644 --- a/tests/Feature/ResponsivePaystackSheetTest.php +++ b/tests/Feature/ResponsivePaystackSheetTest.php @@ -31,8 +31,7 @@ class ResponsivePaystackSheetTest extends TestCase $this->assertStringContainsString('resumeTransaction', $html); $this->assertStringContainsString("\$watch('showSheet'", $html); $this->assertStringContainsString('js.paystack.co/v2/inline.js', $html); - $this->assertStringContainsString('Starting secure checkout', $html); - $this->assertStringContainsString('not in a separate browser', $html); + $this->assertStringContainsString('Paystack owns its secure checkout popup', $html); $this->assertStringContainsString('items-end justify-center md:items-center', $html); // Cross-origin checkout needs fullscreen delegated on the iframe + parent policy. $this->assertStringContainsString('ensurePaystackIframePermissions', $html);