Embed the checkout
Render the hosted payment page inside an iframe on your own site, and the postMessage events it sends your page.
If you'd rather keep customers on your own site instead of sending them away to the full hosted page, you can render the exact same hosted payment page inside an iframe. The customer fills in their card without ever leaving your checkout, and PCI scope still stays out of your stack.
This works for every flow that returns a redirectUrl: one-time payments and subscription first charges alike. The integration is identical to the redirect flow: you still create the payment or subscription, get back a redirectUrl, and fulfil on the webhook. The only difference is that instead of a 302, you point an iframe at that URL.
<iframe
src="{{redirectUrl from POST /payments or POST /subscriptions}}"
width="100%"
height="600"
frameborder="0"
allow="payment"
></iframe>Register your embed origins first
For security, the payment page refuses to render inside a frame unless the
embedding site's origin is registered on your merchant account. Tell your
account manager which origins (e.g. https://your-shop.example) will host the
iframe before shipping — until then the browser will block the frame.
Inside an iframe the page adapts automatically: 3DS challenges render in-frame, and instead of navigating away the page signals completion to your parent window via postMessage. Listen for these messages (always check event.origin is the MintCash payment page origin):
window.addEventListener("message", (event) => {
const msg = event.data;
if (msg?.type === "mintcash:checkout") {
// msg.ok === true only when msg.status === "succeeded"
// msg.status: "succeeded" | "pending" | "declined" | "failed" | "expired"
}
if (msg?.type === "mintcash:resize") {
iframe.style.height = `${msg.height}px`; // keep the frame sized to content
}
});Message reference
The page sends two message types:
| Message | Payload | When it fires |
|---|---|---|
mintcash:checkout | { ok, status } | When the charge attempt reaches an outcome — see the status table below |
mintcash:resize | { height } | Once on load, then whenever the form's rendered height settles after a change. Useful to avoid inner scrollbars |
mintcash:checkout statuses, and what to do with each:
status | ok | What happened | What to do |
|---|---|---|---|
succeeded | true | The charge was confirmed (directly, or after a 3DS challenge) | Close the modal, show your confirmation. Wait on the webhook to fulfill |
pending | false | The attempt is settling asynchronously and the page stopped waiting — in flight, not failed | Keep the session open; your webhook delivers the final outcome |
declined | false | The provider declined the charge | Show a failure state and finish the session |
failed | false | Verification (3DS) failed | Show a failure state and finish the session |
expired | false | The session is no longer active | Show a failure state and finish the session |
Delivery details worth knowing:
- Messages are posted only to the origins registered on your merchant account — never broadcast with
*. Checkevent.originanyway; other scripts on your page can post messages too. - Expect
mintcash:resizeto fire multiple times per session.mintcash:checkoutarrives once per attempt outcome, and after a terminal status (declined,failed,expired) no further messages follow for that session. - In standalone (redirect) mode nothing is posted — the messages exist only when the page is framed.
Treat the postMessage as a UI signal only — update your page, close the modal, show your own confirmation. Fulfilment still happens exclusively on the webhook — payment.succeeded for one-time payments, subscription.succeeded for subscriptions.
Make it look like yours
The framed page picks up your merchant account's theme automatically — accent color and its ink, page background, body text, font, panel padding, and the input fields' colors, labels, and borders, down to the button ring and error colors. Play with the knobs below to see how the embedded checkout would look on your site, then copy the resulting theme and send it to your account manager to apply it.
saveCardEnabled.See also
- Accept a one-time payment — the flow behind the framed page
- Set up a subscription — first charges collected on the same page
- Customize the payment page — theming and fully custom checkouts