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 wantBuildGuide
Your own checkout UI, Flint owning the order and paymentAn embedded checkout sessionBuild your own checkout
Your own order history, subscriptions, returns, saved cardsA customer session against /v1/meBuild your own customer account
BothBoth, in that orderBelow

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 tokenCustomer session
Question it answers"Is this the buyer paying for this order?""Which buyer is this?"
ScopeOne checkout session and the one order it ownsOne customer, across all their data
Sent asX-Checkout-Session-ID + X-Checkout-Session-SecretAuthorization: Bearer flint_cses_...
Minted byCreating a checkout sessionPOST /v1/customer-sessions, after you authenticate the buyer
LifetimeThe session's, plus a narrow recovery window60 minutes, refreshable for 7 days
Can move moneyYes, on its orderNo
Survives the purchaseRead-only, then not at allYes, 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:

  1. Your app knows the buyer, because they signed into your storefront.
  2. Look up or create their Flint customer and set customer_id on the order.
  3. 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.email is 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_id as 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.

Rate this doc