Embedded hosted checkout
Embedded hosted checkout lets your page keep its layout while COPE renders the payment form inside an iframe. Your site owns the surrounding experience. COPE owns the checkout route, payment collection, tax finality, order creation, and buyer-facing terminal states. Use embedded checkout when you need a custom storefront or in-page checkout modal. Use redirect checkout when the simplest integration is enough or when a browser blocks the iframe flow.Requirements
Before creating embedded checkout sessions:- Create a Checkout SDK publishable key for the COPE business.
- Register every parent page origin that may host the iframe, for example
https://shop.example.com. - Use an origin only: scheme, host, and optional port. Do not include a path, query string, fragment, or userinfo.
- Use HTTPS in production.
http://localhostis only for development and test environments. - Register the success and cancel URLs used for redirect-based completion or fallback. They are matched as complete URL strings, not as origins — see redirect URLs.
checkout({ embed_origin }). https://shop.example.com and https://www.shop.example.com are different origins.
Embed origins and redirect URLs are separate allowlists with different matching rules. An embed origin is scheme, host, and optional port only. A redirect URL is the entire URL, including its path and any query string.
Create an iframe checkout
mountCheckout() refuses to mount when checkout.embedOrigin is missing or does not exactly match window.location.origin. It also refuses an embedCheckoutUrl — or a checkoutUrl used for fallback: "redirect" — whose origin is not the configured checkoutBaseUrl.
Mounting a phone offer
An offer is created on your server, not in the browser, so there is no cart to build and noCheckoutResult to pass. The offer response carries the fields
mountCheckout() actually needs:
offer.public_url as checkoutUrl if you use fallback: "redirect". The SDK
will not derive one: an offer’s recovery page is /offers/:uuid, which renders the
offer’s state, while the hosted checkout route would refuse in exactly the cases the
fallback exists for — and it would carry the offer’s payment-capable access token
into the address bar.
The iframe, the handshake and the events are identical to a cart checkout. Two
sections below do not apply to offers: Test your integration builds a cart, and
the embed_origin troubleshooting row points at checkout() — for an offer, send
embed_origin on create-offer instead.
Mount behavior
mountCheckout() creates the iframe for you:
srcischeckout.embedCheckoutUrl.titledefaults toCOPE checkout.allowis set topayment *for browser wallet support.referrerPolicyis set tono-referrer.widthis set to100%.min-heightis set to720px.- No
sandboxattribute is added by the SDK.
Fallbacks
Setfallback: "redirect" for buyer-safe recovery if the iframe does not complete the trusted ready handshake before readyTimeoutMs.
fallback: "error", the SDK calls:
Events
The iframe sends sanitized events to the SDK. Callback payloads do not include checkout credentials, payment client secrets, or buyer PII.onMessage when you need the raw sanitized event stream:
onSuccess and onCancel are convenience callbacks derived from terminal events.
Only a live completed fires onSuccess. already_completed means the checkout was
paid before this iframe mounted — a refresh after success, or a re-opened offer
link — so fulfilment must not run again; processing means an asynchronous rail
accepted the payment but the order is not final yet.
Security model
Embedded checkout has two layers of authorization:- COPE validates
embed_originagainst the business checkout embed domain allowlist when checkout is created. - The iframe route validates the same embed contract before rendering checkout UI.
targetOrigin; it never uses *. It accepts iframe messages only when:
event.originmatches the checkout iframe origin.event.sourceis the mounted iframe window.event.data.sourceiscope.checkout.event.data.versionis1.
/checkout/embed/:token is intended for iframe rendering.
Test your integration
Use a development or staging page that matches the origin you registered for the COPE business. Exercise the full flow before launch:- Create a cart.
- Add a product and payment plan.
- Set buyer identity.
- Reprice.
- Create checkout with
embed_origin. - Mount the iframe and inspect the postMessage conversation.