Skip to main content

Web checkout

One parameter — redirectTarget — decides how the checkout appears.

ValueWhat the customer seesReturns a promise?
_self (default)Leaves your site, comes back to returnUrlNo — the page navigates away
_blankOpens in a new tabNo
_topBreaks out of any surrounding iframeNo
_modalPopup over your page, never leavesYes
DOM elementRendered inline in that elementYes

Redirect​

The page navigates away. Handle the result at your returnUrl.

const gateway = await load({ mode: 'sandbox' });
gateway.checkout({ paymentSessionId, redirectTarget: '_self' });
// nothing after this line runs — the browser has left

The gateway appends order_id and payment_status to your return URL.

The page stays. You must handle the promise.

const result = await gateway.checkout({ paymentSessionId, redirectTarget: '_modal' });

if (result.dismissed) {
// customer closed the popup without paying
} else if (result.paymentDetails?.paymentStatus === 'SUCCESS') {
// still confirm on your server before shipping
}

Inline​

Renders inside an element you control. The checkout reports its height as the customer moves between screens, and the SDK resizes the frame to match.

function InlineCheckout({ paymentSessionId }) {
const box = useRef(null);

useEffect(() => {
let cancelled = false;
load({ mode: 'sandbox' }).then((gateway) => {
if (cancelled || !box.current) return;
gateway.checkout({ paymentSessionId, redirectTarget: box.current });
});
return () => { cancelled = true; };
}, [paymentSessionId]);

return <div ref={box} />;
}

Which should you use?​

_modal. The customer never leaves your site, you get a promise, and you keep control of what happens next. Use _self only when a popup blocker is a real concern — some in-app browsers block them.

Domain whitelisting​

Register every domain that will open the checkout, in the dashboard. This is enforced by the browser, not just by us:

Content-Security-Policy: frame-ancestors 'self' https://yoursite.com

An origin you never registered cannot render the checkout at all — the browser refuses to create the frame before any JavaScript runs. That means a leaked paymentSessionId is useless from someone else's website.

Blank checkout in development?

You forgot to whitelist the origin. Check the browser console for a frame-ancestors violation. Remember http://localhost:3000 and http://127.0.0.1:3000 are different origins — register both if you use both.