Mintcash
Guides

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:

MessagePayloadWhen 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:

statusokWhat happenedWhat to do
succeededtrueThe charge was confirmed (directly, or after a 3DS challenge)Close the modal, show your confirmation. Wait on the webhook to fulfill
pendingfalseThe attempt is settling asynchronously and the page stopped waiting — in flight, not failedKeep the session open; your webhook delivers the final outcome
declinedfalseThe provider declined the chargeShow a failure state and finish the session
failedfalseVerification (3DS) failedShow a failure state and finish the session
expiredfalseThe session is no longer activeShow 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 *. Check event.origin anyway; other scripts on your page can post messages too.
  • Expect mintcash:resize to fire multiple times per session. mintcash:checkout arrives 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.

Card number4242 4242 4242 424Your card number is incomplete.
Expiry12 / 30
CVC•••
Page
Font & spacing
Accent
Inputs
Errors
PreviewNot part of the theme — controlled by your account's save-cards setting, or per payment via saveCardEnabled.
Theme to send to your account manager
Type or paste a theme and the preview follows

See also