Build a headless storefront
Flint has two surfaces you can own outright: the checkout where a buyer pays, and the account where they come back afterward. They are independent choices, and most merchants want one before the other.
This page is the map. The two guides it points at are the work.
| You want | Build | Guide |
|---|---|---|
| Your own checkout UI, Flint owning the order and payment | An embedded checkout session | Build your own checkout |
| Your own order history, subscriptions, returns, saved cards | A customer session against /v1/me | Build your own customer account |
| Both | Both, in that order | Below |
Neither requires the other. You can run a fully custom checkout and still send buyers to Flint's hosted account, or keep hosted checkout and build the account yourself. Nothing in Flint couples them.
What both share is the boundary: your backend holds the credentials and your browser code talks to your backend. Flint does not accept requests from merchant origins on either surface.
Two credentials, and why they are not interchangeable#
This is the thing to get straight before writing code. The credentials look similar and answer completely different questions.
| Checkout auth token | Customer session | |
|---|---|---|
| Question it answers | "Is this the buyer paying for this order?" | "Which buyer is this?" |
| Scope | One checkout session and the one order it owns | One customer, across all their data |
| Sent as | X-Checkout-Session-ID + X-Checkout-Session-Secret | Authorization: Bearer flint_cses_... |
| Minted by | Creating a checkout session | POST /v1/customer-sessions, after you authenticate the buyer |
| Lifetime | The session's, plus a narrow recovery window | 60 minutes, refreshable for 7 days |
| Can move money | Yes, on its order | No |
| Survives the purchase | Read-only, then not at all | Yes, that is the point |
The asymmetry that catches people: a customer session carries no payment authority. A signed-in buyer paying an invoice from your account UI does not pay through /v1/me; they get a checkout session, exactly as Flint's own hosted account does. And a checkout credential cannot read the buyer's other orders, because it is bound to one.
So an account page that needs to take money creates a checkout, and a checkout that needs to know the buyer is told at order creation. They meet at the order, not at the credential.
Keep a signed-in buyer signed in through checkout#
If you build both, this is the seam.
Flint learns who the buyer is from customer_id on the order, not from the checkout credential. Set it before you create the checkout session:
- Your app knows the buyer, because they signed into your storefront.
- Look up or create their Flint customer and set
customer_idon the order. - Create the checkout session.
Do that and their saved payment methods resolve inside checkout, and the completed order is already attached to the account they will see later. Skip it and you get a guest order that has to be reconciled afterward.
Setting the customer on an order that already has an open checkout session is a merchant-side change, so it invalidates that session. Do it first, or expect to create a replacement.
Turning a guest purchase into an account#
Guests are normal. Someone buys without an account and later wants to see the order.
The mechanism is the customer record, not a credential. A guest checkout collects a buyer email, and if it resolves to a customer, the order is attached to that customer. When the buyer later creates an account in your system, associate your user with that Flint customer, and their history is already there.
Two constraints worth knowing before you design around this:
Customer.emailis immutable after creation. Changing a buyer's email is a two-step request-and-confirm flow (POST /v1/me/email-change-requests, then/confirm), not a profile write. Matching purely on a mutable email will drift.- A resource ID is not proof of ownership. Flint's email links carry
flint_resource_idas a routing hint. Deciding which buyer may see an order is your job, done with your own session, before you mint a customer session. Flint enforces ownership after that point, never before.
Where to start#
Build the checkout first if buyers cannot pay you the way you want. Build the account first if they can pay but cannot see anything afterward.
If you are doing both, do checkout first: it forces the backend-for-frontend and the credential handling that the account surface then reuses.
Related#
- Build your own checkout
- Build your own customer account
- Securing a headless checkout: the trust boundary both surfaces share.
- Customer sessions: minting, refresh, and revocation.
- Customer accounts: the hosted account and how far branding goes before you build.
