Skip to main content
When a customer types their card number into Macropay checkout, those digits go straight into a sandboxed, cross-origin iframe and are tokenized inside a PCI DSS Level 1 compliant vault. The card number, expiry, and CVC never reach your origin, your backend, or Macropay’s. What you and the acquirer see is a non-sensitive token — never the raw PAN.
This is the same capture layer whether you ship a hosted Checkout Link, drop in the embedded checkout, or build a custom UI on Checkout Sessions. One iframe, one PCI posture, three integration styles.

Why tokenization in a vault matters

The card form lives in iframes served from a vault domain, not from your page. Every keystroke is intercepted there, exchanged for a token, and only the token crosses back to Macropay to authorize the charge. The practical payoff:
Because Macropay is the Merchant of Record, the PCI burden, tax remittance, and chargeback handling all sit with us. Tokenization is the mechanism; MoR is the coverage.

What gets captured

The form renders three independent fields, each in its own sandboxed iframe:
  1. Card number — with live brand detection. A row of brand icons on the right edge lights up the detected network as the customer types.
  2. Expiry (MM/YY)
  3. CVC
Splitting the form into separate iframes keeps each field individually focusable, tabbable, and validatable, while every field stays cross-origin from your page. Tokenization runs as a single vault call on submit; Macropay receives the resulting token and nothing else.

Embedding the form

How much you do depends on which surface you choose:

Hosted link or embed

Using a Checkout Link or the embedded checkout? The vault iframes are already inside Macropay’s hosted checkout. Nothing to wire up.

Your own UI

Building on Checkout Sessions? Mount the <CheckoutForm /> React component from @macropayments/checkout and the card form appears, fully orchestrated.
For a custom UI, the component handles iframe orchestration, inline validation, and tokenization for you:
You wire up onConfirmed to route the buyer after the charge clears. You never receive — or have to protect — the raw card data.

Theming the fields

Vault iframes don’t accept style updates after they mount, so a theme switch re-mounts them in the new color scheme. Macropay watches the <html class="dark"> toggle through a debounced MutationObserver and does the re-mount for you.
Macropay’s hosted checkout (links + embed) renders light-mode only by design. The card fields stay on a crisp light surface for every merchant, even if you set data-macropay-checkout-theme="dark" on a link — the rest of the page goes dark, the card form stays light. This keeps brand-icon contrast and field affordances correct across every device and OS theme.Building your own UI on Checkout Sessions? You can opt the card fields into a dark theme — just know you own the contrast for the brand-icon row and the field error states.
Inside the form, the visual states are tuned to sit pixel-aligned next to your own inputs:
  • Interaction states — focus, hover, error, and disabled are driven by stateful classes on the wrapper, not :focus selectors. The iframe takes focus, so the wrapper reflects it.
  • Borders and rings — border color, ring width, and transitions match Macropay’s Input atom, so the card fields line up beside the Cardholder Name input.
  • Brand row — non-matching brands fade to 0.25 opacity while the detected brand pops to full opacity.

Supported card brands

The on-screen brand row shows live indicators for the four most common networks: Visa, Mastercard, American Express, and Discover. Tokenization also covers Diners Club, JCB, UnionPay, Maestro, Hipercard, and Elo — buyers can pay with any of those even though the icon row stays focused on the major four. Which cards actually clear is governed by Macropay’s acquirer and the buyer’s billing country, not by the iframe.

Wallets

When the browser supports them, Apple Pay and Google Pay appear above the card form. The wallet sheet skips the card iframes entirely: Apple or Google hands back a tokenized payment method that Macropay relays straight to the acquirer.
Wallets keep working even if the card vault is unreachable, because they route through the browser rather than the iframe. For embedded checkout, wallets need a one-time domain validation — see enabling wallet payment methods.

FAQ

The visible chrome — border, padding, radius, shadow — is yours to re-skin with Tailwind classes on the wrapper. The text inside the iframe (font family, size, color) is limited to a small set of style tokens the vault exposes, which Macropay tunes to match the wrapper. Open a support request if you need a non-default token.
Split fields let each input be tabbable, focusable, and validated on its own while keeping every keystroke cross-origin from your page. One field, one iframe, one isolation boundary.
Yes. Each iframe is labelled and exposes its validation state to assistive tech. Errors render below a field only after blur, and only when the field is non-empty and invalid — no shouting while the customer is still typing.
The customer sees a “card capture is unavailable” message and the submit button stays disabled. Wallets (Apple Pay / Google Pay) still work because they go through the browser. Macropay monitors vault uptime and posts any incidents to its status page.