Embedding the flow

How the embed works

The health survey and the payment form are Truemed-hosted pages, and they carry Truemed branding, so the customer can see that Truemed is handling the clinical questions and the card details. You embed them in an iframe on your page, modal style, which means the customer does not go through a full-page redirect at any point in this integration: not at signup, not at renewal, and not when a card expires.

You opt in with use_iframe: true on create_payment_token, and the redirect_url that comes back is the src for your frame rather than somewhere to send the browser. Inside that one frame the customer takes the survey and then enters both cards; the two steps advance on their own, so you do not have to swap the src or manage the sequence.

1<iframe src={redirectUrl} allow="payment" width="100%" height="800" />

When the flow finishes, the framed page calls window.parent.postMessage() with { success, redirectUrl }. That is your signal to close the frame and carry on. redirectUrl is the success_url or failure_url you supplied, handed back so your page can route as it sees fit. Nothing navigates unless you decide it should.

1window.addEventListener("message", (event) => {
2 if (event.origin !== "https://app.truemed.com") return; // required
3 const { success, redirectUrl } = event.data;
4 if (success === undefined) return; // not a completion message
5 closeTruemedFrame();
6 success ? continueSignup() : handleCancelled(redirectUrl);
7});

The origin to compare against is the Truemed app host for the environment you are in. It is the only Truemed value that belongs in your frontend config; the frame URL itself always arrives as redirect_url on the create call. Sandbox and production hosts are listed in Before you begin.

Your page will receive messages from more than one source, so be deliberate about which you act on. When a customer’s bank triggers a 3D Secure challenge, Stripe’s authentication frame posts its own messages to your page alongside Truemed’s. Ignoring anything that does not carry success is enough to stay correct, but checking event.origin is what actually protects you, because a shape check cannot tell a Truemed message apart from one a hostile page deliberately mimics.

The embedded flow is in production. The whole sequence runs end to end from a plain parent page on a different origin: survey, dual-card capture, Stripe Elements nested inside our frame, and the completion message back to the parent, with the parent page never navigating once.

3D Secure works inside the frame. If the bank challenges the card, the challenge renders in the embedded flow, three frames deep, your page inside ours inside the bank’s, and the customer completes it right there. There is no redirect, no popup, and nothing extra for you to build. Leave the frame enough room for the bank’s screen.

Sizing. The survey is multi-step and the card form is taller than a typical modal, so give the frame room to breathe and let it scroll internally rather than clipping it.

What embedding does not change, and what we cannot change: the card details go to Truemed and into our Stripe account. That is what lets Truemed hold the HSA/FSA authority, run the eligibility split, and keep the card usable for every later unattended charge. The frame changes where the form appears rather than who handles the card, and there is no variant of this integration where card data lands in your vault instead. We would rather be flat about that now than have the iframe imply otherwise.

Need help?

Your Truemed contact is the fastest route for anything specific to your channel: turnaround figures, menu classification, customer-facing wording, and enabling the flow in sandbox and production. For anything else, email merchants@truemed.com. The full API reference covers every call this guide names.