Skip to main content
Embedded mode renders RadiumOne Checkout inside an <iframe> on your own page instead of redirecting the full browser tab. Your page listens for postMessage events to react to the outcome, but — exactly as with redirect mode — you still confirm the final result from your server. Embedded mode uses the same branding as redirect mode, except it has no header — so your logo and merchant name don’t appear.
Embedded mode requires allowed_domains. Creating a session with mode: "embed" when your account has no usable allowed_domains entry returns 422 embed:origins_not_configured — the create fails outright rather than handing back a session that would render as a blank iframe. Register your embedding page’s domain first — see Sandbox and API keys.
Frame origins are derived from allowed_domains at create time, using the same host-or-subdomain rule as success_url/cancel_url: registering shop.example.com also covers checkout.shop.example.com. Wildcard entries (for example *.example.com) are accepted when configured but never matched — list every exact host you embed on. Sessions created before this release don’t have frame origins snapshotted and may still render blank for their remaining lifetime (up to the session TTL) regardless of your current allowed_domains — this resolves itself as those sessions expire. If the iframe stays blank on a newly created session, see Fix embedded checkout that won’t load.

How it works

  1. Your server creates a checkout session with mode: "embed".
  2. Your page renders an <iframe> pointed at checkout_url and attaches a message listener.
  3. The iframe posts CHECKOUT_READY once the card form loads, then CHECKOUT_RESIZE as its content height changes.
  4. The shopper enters their card in the iframe. If they navigate away or close the tab without paying, see Handle abandoned checkouts — no event is posted for this case.
  5. The iframe posts an outcome event (CHECKOUT_COMPLETE, CHECKOUT_PENDING, CHECKOUT_DECLINED, CHECKOUT_EXPIRED, or CHECKOUT_ERROR).
  6. RadiumOne sends your webhook endpoint the authoritative payment.* event.
  7. Your parent page calls your server, which confirms the result before you navigate the shopper onward.

Steps

1

Create a session in embed mode

Add "mode": "embed" to the create-session request body. The response shape is identical to redirect mode.
Retrying create with the same order_reference returns the same session as long as the amount and currency match — other changed fields are silently ignored. A different amount or currency, while the original session is still payable, is rejected with 409 session:idempotency_conflict instead. Either way this only lasts the session’s TTL (5–60 minutes) — after that, the same order_reference creates a new session. Check your own order isn’t already paid before creating one — see Prevent duplicate payments.
2

Render the iframe and listen for events

Point the iframe at checkout_url and add a message listener. Always check both event.origin (the RadiumOne Checkout host) and event.data.source before trusting a message — never rely on source alone, since any page can post a same-shaped message.
See the embedded events reference for the full event/payload list. If your listener never fires, see Debug missing embedded checkout events. If the iframe never renders at all, see Fix embedded checkout that won’t load.
3

Confirm the result server-side

On any outcome event, call your own server, which confirms the payment with an authenticated GET /api/v1/checkout/sessions/{id} request or waits for the webhook — see Verify the payment result. Only then navigate the shopper to your own order-confirmation page.
Treat any client-side redirect or callback as a hint only. Always confirm the final payment status from your server, using an authenticated GET request or a webhook — never from a query parameter or browser postMessage alone.

Content Security Policy

Your page’s CSP needs frame-src set to the RadiumOne Checkout host so the browser allows the iframe to load:
Use https://checkout-sandbox.radiumone.io in sandbox and https://checkout.radiumone.io in production. Also avoid a strict Referrer-Policy (such as no-referrer) on the embedding page if you rely on referrer-based analytics inside the iframe — RadiumOne Checkout does not require a specific Referrer-Policy from your page, but a very strict setting can affect your own iframe integration.
Firefox: window.location.ancestorOrigins (used to detect the parent frame’s origin) isn’t available in Firefox. The iframe falls back to the origin of your success_url, so make sure success_url shares your embedding page’s origin, or the iframe won’t be able to verify it’s allowed to message that parent.

Handle the result

Never treat a CHECKOUT_COMPLETE (or any other) event as proof of payment — postMessage isn’t authenticated and any page can attempt to send a same-shaped message. Confirm with your server, exactly as in Verify the payment result. A CHECKOUT_ERROR event means the attempt didn’t go through — see Handle payment service outages during checkout for how to confirm nothing was charged before letting the shopper retry.

Test your integration

See Test your integration for sandbox scenarios, including embedded-mode events.

Go-live notes

  • Register your production embedding domain(s) with RadiumOne before going live.
  • Confirm your CSP allows the RadiumOne Checkout host in frame-src.
  • Confirm fulfilment server-side — never from a postMessage event.
See the full go-live checklist.

Next steps

Embedded events reference

Full event and payload reference.

Verify the payment result

Confirm the outcome server-side before fulfilling.

Handle failures

Ten common failure scenarios and what to do for each.
Last modified on September 15, 2026