Embedded checkout (iFrame)
Embedded checkout (iFrame)
The iFrame is an alternative presentation of the standard flow—the same eligibility survey, card entry, statuses, and webhooks as the hosted redirect, just rendered inline on your page instead of sending the customer to a Truemed-hosted page. Use it when you want customers to stay on your site through checkout.
It works for both entry points:
- One-time payments —
create_payment_session, for a single checkout. - Subscriptions —
create_payment_token, where the customer takes the survey and stores their cards once, and you charge on your own schedule afterwards.
Everything you build for the redirect flow still applies—creating the session or token, handling the webhook, and fulfilling on it. Only two things change:
Fulfillment is unchanged: the payment_session_complete webhook with status: captured is still the
source of truth. The postMessage success flag is only for updating your own UI.
Enable the iFrame
Add the optional use_iframe parameter to
create_payment_session or
create_payment_token. When use_iframe
is true, the redirect_url in the response is an iframe-compatible URL you render inline instead of
redirecting to.
If every checkout on your integration is embedded, ask your Truemed contact to enable it on your sales channel instead. The returned URL is then always iframe-compatible and you can leave the parameter out of your requests entirely.
Subscriptions: the whole signup happens in one frame
On create_payment_token the customer takes the
health survey and then enters their cards. Both steps render inside the same frame, one after the
other—you set src once and do not swap it between steps or manage the sequence. The message arrives
when the customer has finished storing their cards, and your page never navigates along the way.
Example request
Example response
Environments and local development
There is nothing to install and nothing to configure on your side. No SDK, no publishable key in the
browser, and no origin to register with us before you can start — you set an iframe src and add one
listener.
Two values differ between environments:
You never hardcode the frame’s URL; it arrives as redirect_url on the create call. The origin is the
only Truemed value that belongs in your frontend config, so one setting per environment covers it.
Sandbox API keys come from the sandbox dashboard at dev.truemed.com/developers/api-keys. Keys are not shared across environments.
Running against localhost
A page served from http://localhost can embed the sandbox flow with no setup on either side. We send
no X-Frame-Options header and no frame-ancestors policy on the framed pages, and those pages
authenticate on identifiers already present in the URL rather than on cookies—so third-party-cookie
rules and browser privacy settings have no bearing on the embed. A local page behaves the same as your
production page.
We do not post height or resize messages. The completion message is the only one you receive from us, so give the frame generous height and let it scroll internally rather than trying to size it to its contents.
If a create call returns 404
A 404 with {"error": "Page not found"} means the API key is wrong, or the sales channel is not
enabled for the endpoint you are calling. We return 404 rather than 401 so that an unauthenticated
caller cannot map which endpoints exist, which makes a credentials problem read like a bad path. If the
path is right, check the key and the environment before you check the URL.
Handling iFrame responses
Set the iframe element’s src to redirect_url and Truemed’s survey and checkout render inside it.
The embedded page never navigates your page and cannot remove its own iframe—when the customer
finishes, Truemed posts a single completion message to your window via the browser’s
postMessage API. That message
is your signal to remove the iframe and update your page.
The completion message
The completion message is the only message Truemed sends. Its data is a plain object:
Check event.origin before you act on a message. Your page receives messages from anything it frames,
including the payment provider during a 3D Secure challenge, and any page on the internet can frame
yours and post a message that looks exactly like ours. Comparing the origin against the Truemed origin
is the only check that tells our message apart from an imitation of it. The origin for each
environment is in the table above, and it differs between sandbox and production—read it from your
environment config rather than hardcoding one, or the wrong build will discard every message we send.
Pair it with event.source !== iframe.contentWindow if your page can open checkout more than once,
so a completion message is only ever handled by the frame that is currently open.
Apple Pay requires allow="payment" on the iframe and HTTPS on the parent page. Card payments and Link work without it.
3D Secure
If the customer’s bank asks them to authenticate, the 3D Secure challenge renders inside the embedded flow and the customer completes it there. There is no redirect, no popup, and nothing extra to build.
Give the frame enough height for it—the challenge is the bank’s own screen, and a short frame makes it
awkward to use. Note that your message listener will also receive events from the authentication
provider while the challenge is open, which is one reason to be deliberate about which messages you act
on (see below).