Checkout sessions

Checkout sessions create Flint-hosted payment pages for a single buyer. Each session is backed by an order: pass order_id to collect payment for an order you already created, quick_pay_item to have Flint create a simple one-time order for you, or subscription_plan_id to run hosted subscription signup from a subscription plan. The create response returns a tokenized buyer-facing url you redirect or link the buyer to.

Sessions are single-use. Generic sessions are short-lived (24 hours by default); invoice-owned sessions last for the life of the invoice's payment link. A session is open until the buyer completes payment, a mixed terminal attempt settles only part of the balance, you close it, it expires, or its source invalidates it. Terminal statuses are paid, partially_paid, closed, expired, and invalidated; terminal_reason explains the exact transition, including payment_succeeded and payment_partially_succeeded. Flint allows only one active session per order at a time. Creating another session for the same order returns CHECKOUT_SESSION_ALREADY_EXISTS unless you explicitly compare and replace the current session with replace_checkout_session_id. A hosted session pays the order with one payment method, so creating one for an order with more than one unpaid payment leg returns CHECKOUT_SPLIT_PAYMENT_UNSUPPORTED. Configuration (theme, tipping, customer collection requirements, redirects, legal links, expiration, and for an embedded session its page_origin) is fixed at creation on POST /v1/checkout-sessions. The invoice and return launch routes can replace page_origin on a reused embedded session, and a new embedded session they create inherits it from the earlier session when you omit it; see Collect an invoice or a return balance. page_origin is the origin of the page that renders an embedded checkout, such as https://shop.example.com. It is the only origin that can show the session's gift card challenge, and it grants no API access. While a session is open, a read of that one session returns gift_card_challenge.url, where the buyer completes the challenge; see Apply gift cards. Afterward, your API key can update metadata and external_reference_id. While the session is open, the session's checkout credential can save the buyer's email and phone as buyer_contact and the buyer's time zone as timezone, and on a subscription plan session either credential can send the buyer's interval and quantity as subscription_terms. A read with the checkout credential also returns save_payment_method_offered, which says whether checkout offers the buyer the option to save the card they type, save_payment_method_requires_verification, which says whether the buyer must first confirm their email with a code, and, once the checkout acts for a customer, customer_prefill; see Saved payment details. It also returns merchant_support, the support email, phone, and help page the merchant set; see Show how to reach the merchant. The checkout credential requests and confirms that code with the customer verification routes, and confirming returns the only credential that acts for the customer; see Confirm the buyer's email.

Note:

Start with the Checkout sessions guide. Not sure whether you need a checkout session, a payment link, or an invoice? See Payment links vs checkout sessions vs invoices.

For a gift card purchase without a customer identity, request an emailed code with purpose: "gift_card_purchase" through the session's customer verification route. This purpose is available on an open, unfunded order with gift card purchase lines and does not require saving a payment method. Confirm the code and use the returned checkout credential before payment. The purchaser and gift card recipient can have different email addresses.

The Checkout session object#

Every field on a checkout session, as returned by retrieve and carried by the endpoints below.

Attributes

active_payment_attemptobject
buyer_contactobject

Contact the buyer entered in checkout before paying, saved with the session's checkout credential. Omitted until the buyer saves or clears a field. When a checkout session payment omits buyer_contact.email or buyer_contact.phone, Flint uses these values. Flint clears the contact 30 days after the session ends, and when a customer linked to the session is deleted.

checkout_session_idstringRequired
closed_reasonstring

The note supplied when the checkout session was closed. It is not shown to the buyer.

created_atstring

RFC3339 timestamp.

custom_textobject
customerobject or null
customer_collectionobject
customer_prefillobject

Contact and default addresses of the customer the checkout acts for, with the recipient name on its default shipping address: the customer the merchant created the session for, or the customer whose email the buyer confirmed in it. Present only on reads with the session's checkout credential while the session is open and acts for a customer.

delivery_method_idsarray of stringRequired

Immutable delivery method assignment captured when the checkout was created.

delivery_pinned_dependenciesarray of object

Merchant-only immutable configuration lineage used to evaluate delivery quotes.

delivery_selection_requiredbooleanRequired

Whether the order has at least one remaining quote-resolved fulfillment choice that must be selected before payment.

expirationobject
expires_atstring

RFC3339 timestamp.

external_reference_idstring

Caller-owned identifier for this resource in an external system.

fulfillmentone of

Current fulfillment choices for Flint-owned pricing. Checkout credentials receive the fields available to buyers; merchant credentials also receive configuration lineage and diagnostics. External pricing reports requires_explicit_quote; reading this field does not request a delivery quote. Omitted when the session is not open, has no order, or Flint cannot read its delivery.

gift_card_challengeobject

Where the buyer completes a gift card challenge for this checkout. Returned on single-session reads, session create and update responses, checkout launch results, and customer verification confirmation results while the session is open and can show the challenge. Omitted from lists, webhooks, expanded resources, and delivery selection results.

invoiceobject or null
invoice_idstring
legalobject
merchant_idstring
merchant_supportobject

How the buyer can reach the merchant for help: the support email, phone, and URL the merchant set. Present only on reads with the session's checkout credential, and only when the merchant set at least one of them. Show it where your checkout tells the buyer to contact the merchant, such as an expired or closed checkout, or your receipt.

metadatamap of string
orderobject or null
order_idstring
originenum
  • virtual_terminal
  • payment_link
  • checkout
  • api
  • subscription
page_originstring

Origin of the page that renders this embedded checkout. Omitted when not set.

payment_collectionobject
payment_intent_idsarray of string
payment_intentsarray of object
payment_linkobject or null
payment_link_idstring
payment_method_saveobject

The card the buyer saved with this checkout's payment by giving a mobile phone number, and whether they confirmed it. Present only on reads with the session's checkout credential, after a payment that paid the order in full, or that was approved for the merchant to capture later, and saved a card this way. A checkout whose payment is approved stays open until the capture.

paymentsobject
problemsarray of objectRequired

Named conditions that affect checkout completion. Follow each problem's remediation action instead of reconstructing delivery lifecycle rules in the client. When Flint cannot read the checkout's delivery, the read still succeeds and reports delivery_selection_stale; its remediation says whether reading the session again can succeed, and its next action's reason_code names the error.

promotion_configobject
recovery_expires_atstring or null

RFC3339 deadline for the restricted payment-attempt recovery window.

recovery_modebooleanRequired

Whether this terminal session credential is temporarily restricted to recovering its owning payment attempt.

recovery_payment_attempt_idstring

Payment attempt that this checkout credential may recover while recovery_mode is true.

redirectsobject
save_payment_method_offeredboolean

Whether checkout offers the buyer the option to save the card they type for faster checkout at this merchant. Present only on reads with the session's checkout credential. When true and save_payment_method_requires_verification is false, PayOrder accepts save_payment_method: true for one newly collected card. False when the merchant turned checkout.saved_payment_details off, customer accounts are merchant hosted, card is not an available payment option, the checkout collects an invoice, a subscription, or a return, or the checkout acts for no customer and Flint cannot email the buyer a verification code.

save_payment_method_phone_offeredboolean

Whether the buyer can save the card they type by giving a US or Canadian mobile phone number with the payment, in save_payment_method_phone on POST /v1/orders/{order_id}/pay, and confirming it with a texted code after paying. Present only on reads with the session's checkout credential. True while Flint can send texts and either save_payment_method_requires_verification is true, so the number replaces confirming an email before paying, or the checkout acts for the customer whose email the buyer confirmed with this credential, so the number joins that customer's saved details once the buyer confirms it.

save_payment_method_requires_verificationboolean

Whether the buyer must confirm their email with a code before the checkout can save their card or use their saved cards. Present only on reads with the session's checkout credential. True when save_payment_method_offered is true and the checkout acts for no customer for this credential: the merchant created it without one, and either the buyer has not confirmed an email with this credential, or the customer whose email they confirmed has since changed that email or been deleted. A credential other than the one a confirmation returned, such as the hosted checkout link opened on another device, reads true. Send the code with POST /v1/checkout-sessions/{checkout_session_id}/customer-verifications. False while the checkout acts for a customer, and whenever save_payment_method_offered is false.

setup_collectionobject
statusenumRequired
  • open
  • paid
  • partially_paid
  • expired
  • closed
  • invalidated
subscription_plan_idstring
subscription_termsobject

Renewal terms a subscription checkout commits the buyer to. Frozen when the session's order was created, so later plan changes do not alter them. Absent when the checkout starts no subscription.

superseding_checkout_session_idstring
surfaceenumRequired
  • hosted
  • embedded
taxobject
terminal_reasonenum
  • payment_succeeded
  • payment_partially_succeeded
  • expired
  • api
  • order_mutated
  • superseded
  • invoice_paid_elsewhere
  • invoice_voided
  • invoice_uncollectible
  • invoice_balance_changed
themeobject
tipobject
updated_atstring

RFC3339 timestamp.

urlstring

Hosted checkout URL that carries a one-time launch credential. Send the buyer here to pay. Returned for a hosted session on every launch result: create, payment-link resolve, and invoice and return-resolution checkout. Reads return it only to a credential that can manage checkout sessions. Omitted for embedded sessions.

JSON
{
  "checkout_session_id": "cs_123",
  "created_at": "2026-03-17T14:30:00Z",
  "customer_collection": {
    "require_email": true
  },
  "delivery_method_ids": null,
  "delivery_selection_required": false,
  "gift_card_challenge": {
    "url": "https://checkout.withflintpay.com/gift-card-challenge/opaque-frame-token"
  },
  "merchant_id": "mer_123",
  "metadata": {
    "campaign": "spring_launch"
  },
  "order_id": "ord_123",
  "origin": "api",
  "payments": {
    "enabled_payment_options": [
      "card",
      "apple_pay",
      "google_pay"
    ],
    "payment_note": "Thank you for your purchase."
  },
  "problems": [],
  "promotion_config": {
    "codes_enabled": true
  },
  "recovery_mode": false,
  "redirects": {
    "cancel_redirect_url": "https://example.com/canceled",
    "success_redirect_url": "https://example.com/success"
  },
  "status": "open",
  "surface": "hosted",
  "theme": {
    "primary_color": "#0f766e",
    "title": "Spring Gala Checkout"
  },
  "updated_at": "2026-03-17T14:30:00Z",
  "url": "https://checkout.withflintpay.com/checkout/cs_123#checkout_token=tok_123"
}

List checkout sessions#

GET/v1/checkout-sessions

Requires scope checkouts.checkout_sessions.read or checkouts.checkout_sessions.write

Returns a paginated list of checkout sessions for the authenticated merchant.

Query parameters

page_sizeinteger

Page size, default 20, max 100.

page_tokenstring

Cursor returned by the previous list response.

statusenum

Filter by checkout session status.

  • open
  • paid
  • partially_paid
  • expired
  • closed
  • invalidated
order_idstring

Filter by Flint order ID.

payment_link_idstring

Filter by Flint payment link ID.

customer_idstring

Filter by Flint customer ID.

originenum

Filter by checkout session origin.

  • virtual_terminal
  • payment_link
  • checkout
  • api
  • subscription
external_reference_idstring

Exact-match filter on the caller-owned external reference ID.

querystring

Search across checkout session ID, external reference ID, metadata, and payment notes. Text fields match any part of the value, and %, _ and \ are ordinary characters, not wildcards. IDs match from the start and need the type prefix, such as ord_01.

sort_byenum

Sort field.

  • created_at
  • updated_at
sort_directionenum

Sort direction.

  • asc
  • desc
created_afterstring

RFC3339 lower bound for created_at.

created_beforestring

RFC3339 upper bound for created_at.

updated_afterstring

RFC3339 lower bound for updated_at.

updated_beforestring

RFC3339 upper bound for updated_at.

expires_afterstring

RFC3339 lower bound for expires_at.

expires_beforestring

RFC3339 upper bound for expires_at.

Response · 200

dataarray of objectRequired
metaobject
next_page_tokenstring
request_idstring
curl https://api.withflintpay.com/v1/checkout-sessions \
  -H "Flint-Version: 2026-09-07" \
  -H "Authorization: Bearer YOUR_API_KEY"
JSON
{
  "data": [
    {
      "checkout_session_id": "cs_123",
      "created_at": "2026-03-17T14:30:00Z",
      "customer_collection": {
        "require_email": true
      },
      "delivery_method_ids": null,
      "delivery_selection_required": false,
      "merchant_id": "mer_123",
      "metadata": {
        "campaign": "spring_launch"
      },
      "order_id": "ord_123",
      "origin": "api",
      "payments": {
        "enabled_payment_options": [
          "card",
          "apple_pay",
          "google_pay"
        ],
        "payment_note": "Thank you for your purchase."
      },
      "problems": [],
      "promotion_config": {
        "codes_enabled": true
      },
      "recovery_mode": false,
      "redirects": {
        "cancel_redirect_url": "https://example.com/canceled",
        "success_redirect_url": "https://example.com/success"
      },
      "status": "open",
      "surface": "hosted",
      "theme": {
        "primary_color": "#0f766e",
        "title": "Spring Gala Checkout"
      },
      "updated_at": "2026-03-17T14:30:00Z",
      "url": "https://checkout.withflintpay.com/checkout/cs_123#checkout_token=tok_123"
    }
  ],
  "next_page_token": "example",
  "request_id": "bce56cba-0827-44aa-bb56-4f200ba15ee6"
}

Create checkout session#

POST/v1/checkout-sessionsIdempotent

Requires scope checkouts.checkout_sessions.write

Creates a hosted or embedded checkout session for an order, quick-pay charge, or subscription plan signup. Creation never implicitly replaces an open order session. To replace one, send order_id with replace_checkout_session_id set to the expected current session; the compare-and-swap replacement and collection-lock transfer commit atomically.

Request body

Send exactly one of these

custom_textobject
customer_collectionobject
delivery_method_idsarray of string

Immutable delivery method assignment for this checkout. When omitted, uses settings.checkout.default_delivery_method_ids if the order has items to deliver, or no methods otherwise. An explicit empty array assigns no methods.

expirationobject
external_reference_idstring

Caller-owned identifier for this resource in an external system.

legalobject
metadatamap of string
order_idstringRequired
page_originstring

Origin of the page where you render this embedded checkout, such as https://shop.example.com. Only this origin can show the checkout's gift card challenge and receive its result. It does not let the browser call the Flint API. Accepted only when surface is embedded. Use HTTPS and a lowercase DNS hostname. Do not include a path, query, fragment, or default port. In test mode, localhost, names ending in .localhost, and 127.0.0.1 also work over HTTP or HTTPS.

paymentsobject
promotion_configobject
redirectsobject
replace_checkout_session_idstring

Expected current open checkout session to replace atomically. Allowed only with order_id. A stale value returns CHECKOUT_SESSION_CURRENT_CHANGED and the current session ID; active payment work returns CHECKOUT_PAYMENT_RESOLVING.

subscription_termsobject
surfaceenum

Defaults to hosted when omitted. Use embedded for a merchant-owned presentation.

  • hosted
  • embedded
taxobject
themeobject
tipobject

Response · 201

dataobjectRequired

The checkout session and the credential to operate it. For hosted checkout, send the buyer to checkout_session.url. For embedded checkout, pass checkout_access.checkout_auth_token to your checkout client.

metaobject
request_idstring
curl -X POST https://api.withflintpay.com/v1/checkout-sessions \
  -H "Flint-Version: 2026-09-07" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: a-unique-key" \
  -d '{
    "customer_collection": {
      "require_email": true
    },
    "metadata": {
      "campaign": "spring_launch"
    },
    "payments": {
      "enabled_payment_options": [
        "card",
        "apple_pay",
        "google_pay"
      ],
      "payment_note": "Thank you for your purchase."
    },
    "promotion_config": {
      "codes_enabled": true
    },
    "quick_pay_item": {
      "amount_money": {
        "amount": 2500,
        "currency": "USD"
      },
      "name": "Service Fee"
    },
    "redirects": {
      "cancel_redirect_url": "https://example.com/canceled",
      "success_redirect_url": "https://example.com/success"
    },
    "theme": {
      "primary_color": "#0f766e",
      "title": "Spring Gala Checkout"
    }
  }'

Get checkout session#

GET/v1/checkout-sessions/{checkout_session_id}

Requires scope checkouts.checkout_sessions.read or checkouts.checkout_sessions.write

Returns a single checkout session by ID.

Path parameters

checkout_session_idstringRequired

Flint checkout session ID.

Query parameters

expandarray of enum

Supported expansions: customer, invoice, order, payment_intents, payment_link. Expansion requires checkouts.checkout_sessions.read plus the read scope for each expanded resource. Limits: at most 10 unique expand paths per request; path depth at most 2. To-many expansions are capped at 20 related objects per path. Repeat expand, for example expand=customer&expand=invoice, or pass one comma-separated value.

  • customer
  • invoice
  • order
  • payment_intents
  • payment_link

Response · 200

dataobjectRequired
metaobject
request_idstring
curl https://api.withflintpay.com/v1/checkout-sessions/cs_123 \
  -H "Flint-Version: 2026-09-07" \
  -H "Authorization: Bearer YOUR_API_KEY"
JSON
{
  "data": {
    "checkout_session_id": "cs_123",
    "created_at": "2026-03-17T14:30:00Z",
    "customer_collection": {
      "require_email": true
    },
    "delivery_method_ids": null,
    "delivery_selection_required": false,
    "gift_card_challenge": {
      "url": "https://checkout.withflintpay.com/gift-card-challenge/opaque-frame-token"
    },
    "merchant_id": "mer_123",
    "metadata": {
      "campaign": "spring_launch"
    },
    "order_id": "ord_123",
    "origin": "api",
    "payments": {
      "enabled_payment_options": [
        "card",
        "apple_pay",
        "google_pay"
      ],
      "payment_note": "Thank you for your purchase."
    },
    "problems": [],
    "promotion_config": {
      "codes_enabled": true
    },
    "recovery_mode": false,
    "redirects": {
      "cancel_redirect_url": "https://example.com/canceled",
      "success_redirect_url": "https://example.com/success"
    },
    "status": "open",
    "surface": "hosted",
    "theme": {
      "primary_color": "#0f766e",
      "title": "Spring Gala Checkout"
    },
    "updated_at": "2026-03-17T14:30:00Z",
    "url": "https://checkout.withflintpay.com/checkout/cs_123#checkout_token=tok_123"
  },
  "request_id": "bce56cba-0827-44aa-bb56-4f200ba15ee6"
}

Update checkout session#

PATCH/v1/checkout-sessions/{checkout_session_id}Idempotent

Requires scope checkouts.checkout_sessions.write

Updates the mutable fields of a checkout session. A merchant credential can update metadata and external_reference_id, including after the session ends. On a session with a subscription_plan_id, either credential can send subscription_terms with the buyer's billing interval and quantity while the session is open and no payment is in progress; a change reprices the signup order and releases the delivery selection. The session's own checkout credential can also send buyer_contact and timezone while the session is open. The buyer_contact field saves the email and phone the buyer entered; send a contact field as null to clear it. The timezone field records the buyer's IANA time zone, which Flint uses for times in the emails it sends the buyer. Saving the same values again changes nothing.

Path parameters

checkout_session_idstringRequired

Flint checkout session ID.

Request body

buyer_contactobject

Checkout session credentials only. Saves the contact the buyer entered while the session is open. A patch object: omitted fields are unchanged, and null clears a field. A merchant credential that sends buyer_contact receives CHECKOUT_SESSION_UPDATE_FIELD_NOT_ALLOWED.

external_reference_idstring

Caller-owned identifier for this resource in an external system.

metadatamap of string or null

Caller-owned metadata. Omit this field to leave metadata unchanged. Send an object to merge by key, set a key to null to remove it, or set metadata to null to clear all metadata. An empty object makes no change. Empty strings are stored. Keys starting with flint_ are reserved and cannot be written through the public API.

subscription_termsobject

Subscription plan sessions only. The billing interval and quantity the buyer chose from subscription_terms.billing_interval_options and quantity_options. Send billing_interval and billing_interval_count together. Accepted from your API key or the checkout credential.

timezonestring

Checkout credentials only. A valid IANA timezone, such as America/Toronto, used for Flint-sent receipts. Omission keeps the previous observation; null is invalid.

Response · 200

Same response as Get checkout session.

curl -X PATCH https://api.withflintpay.com/v1/checkout-sessions/cs_123 \
  -H "Flint-Version: 2026-09-07" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: a-unique-key" \
  -d '{
    "buyer_contact": {
      "email": "ada@example.com",
      "phone": "+14155551234"
    }
  }'
curl -X POST https://api.withflintpay.com/v1/checkout-sessions/cs_123/close \
  -H "Flint-Version: 2026-09-07" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: a-unique-key" \
  -d '{
    "reason_message": "Merchant closed stale session"
  }'

Send a checkout verification code#

POST/v1/checkout-sessions/{checkout_session_id}/customer-verificationsIdempotent

Requires a checkout session id or a checkout session secret

Sends the buyer a six-digit code that confirms they control an email address or a mobile phone number, so the checkout can save their card or use the details they saved at this merchant before. Only the session's own checkout credential can call it, and no payment attempt may be in progress. With channel email, Flint emails the code, while the session is open and save_payment_method_requires_verification is true. With purpose save_payment_method, whose default channel is email, Flint sends a code to any valid address. With purpose use_saved_payment_methods and channel email, Flint sends one only when a customer with that email has saved details, cards saved by email or with a mobile phone number, and the response is the same either way, so it never reveals whether the email shops at the merchant. The emailed code opens only the cards saved by email; confirming it when there are none still binds the checkout to the customer, so the buyer can save a card with their own number, which replaces the customer's saved number. With channel sms and purpose use_saved_payment_methods, Flint texts the code to the mobile phone number saved with that email's details at the merchant, and returns channel sms and phone_last_digits. Always offer the emailed code beside it. When the email has no details saved with a number, or Flint cannot text now, it texts nothing and returns CUSTOMER_VERIFICATION_TEXT_UNAVAILABLE; offer the emailed code instead. This answer tells anyone who types the email whether it has details saved with a number at the merchant, and the number's last two digits. A texted code opens only the cards saved with that number, and an emailed code opens only the cards saved by email. Every text reads "Your Flint Pay verification code is: " and the code, and names Flint Pay rather than the merchant, so the prompt for the code should say it comes from Flint Pay. A new text to a number ends the code any other checkout, at any merchant, texted to it, so only the latest texted code for a number works. With purpose use_saved_payment_methods and channel auto, its default, a checkout asks as the buyer leaves the email field, and Flint sends the code the way the email's details were saved: it texts the mobile phone number they carry, as channel sms does, or, when they carry none, emails a code when the email has cards saved by email. The response's channel says which. For an email with neither, or past a cap, it sends nothing and returns CUSTOMER_VERIFICATION_NOT_SENT; show nothing about saved details then. So this answer tells anyone who types the email whether it has saved details at the merchant; name channel email for an answer that doesn't. While an emailed code a checkout sent this way still works, another auto request for the same email answers with that code and sends nothing; request channel email to send another. With purpose confirm_saved_payment_method, after a payment that sent save_payment_method_phone, Flint sends the code that confirms the saved card: channel sms texts the number given with the payment, and channel email emails the customer's email, only when it is the email the payment was made with; otherwise it refuses the request with a 409, and the texted code confirms the card. The response shows that email masked, such as a•••@example.com. Send no email with it. It works on the paid session, or the open one whose payment is approved for the merchant to capture later, until payment_method_save.status leaves pending. A texted code saves the card with the number when the payment created the customer, when the buyer confirmed the customer's email in this checkout, or when the number is already the customer's saved number and a card saved with it is active. Otherwise payment_method_save.email_confirmation_required becomes true, and an emailed code finishes the save. A card saved with a number makes it the customer's saved number: the cards saved with the number it replaces are removed, with payment_method.removed. An emailed code works for 15 minutes and a texted code for 10, each for 5 tries, and a new request replaces the checkout's earlier codes. A checkout can request 5 emailed codes and 6 text lookups with 3 texts before paying, and 3 of each channel to confirm a saved card; codes can be requested for one email 3 times in 15 minutes and 10 times in 24 hours at the merchant; one number gets 3 texts in 10 minutes and 10 in 24 hours; one network can have 10 texts sent and 10 codes emailed by channel auto, and make 30 text and auto requests together, an hour, and 20 requests of any kind a minute. A text request over a cap on texts, the checkout's, the network's, or the number's, returns CUSTOMER_VERIFICATION_TEXT_UNAVAILABLE, like an email with no number to text; over a cap on text requests, it returns CUSTOMER_VERIFICATION_LIMIT_REACHED for the checkout and CUSTOMER_VERIFICATION_RATE_LIMITED for the network. A merchant's checkouts can send 1,000 texts in 24 hours; past that, text requests return CUSTOMER_VERIFICATION_TEXT_UNAVAILABLE. After 10 wrong tries in 24 hours, or 30 in 7 days, across the codes for one email at the merchant or texted to one number, Flint sends that email or number no codes and accepts none of its codes. In a sandbox, Flint sends no texts: a texted code's request answers as if it texted the number, and to confirm it, 000000 is a wrong code, 999999 returns CUSTOMER_VERIFICATION_UNAVAILABLE, and any other six digits confirm it. Emailed codes arrive as in live mode.

Path parameters

checkout_session_idstringRequired

Flint checkout session ID.

Request body

channelenum

How the code reaches the buyer. Omit it to use the purpose's default: auto for use_saved_payment_methods, and email for gift_card_purchase and save_payment_method. email emails the code. With use_saved_payment_methods, it answers the same whether or not the email has saved details. sms texts it: for use_saved_payment_methods, to the mobile phone number saved with the email's details; for confirm_saved_payment_method, to the number given with the payment. auto, for use_saved_payment_methods only, lets Flint pick from the email's saved details: it texts the number they carry, or, when they carry none, emails the code when the email has cards saved by email, and sends nothing otherwise, returning CUSTOMER_VERIFICATION_NOT_SENT. The response's channel says which. Required for confirm_saved_payment_method, which takes sms or email, and gift_card_purchase and save_payment_method take only email.

  • email
  • sms
  • auto
emailstring

Email the buyer typed, with no surrounding spaces. Customers are matched by email without regard to case. Required for gift_card_purchase, save_payment_method, and use_saved_payment_methods, and not allowed for confirm_saved_payment_method.

purposeenumRequired

gift_card_purchase: the buyer confirms their email before funding a gift card purchase; Flint emails a code without saving a payment method. save_payment_method: the buyer asked to save the card they are paying with; Flint emails a code to any valid address. use_saved_payment_methods: the buyer asked to use details they saved at this merchant before. By auto, the default, Flint texts or emails a code the way the email's details were saved, and sends nothing when it has none. By email, Flint sends a code only when a customer with this email has saved details, an active card saved by email or with a mobile phone number, and the response is the same either way. By sms, Flint texts the number saved with the email's details. confirm_saved_payment_method: after a payment that sent save_payment_method_phone, the buyer confirms the card it saved.

  • gift_card_purchase
  • save_payment_method
  • use_saved_payment_methods
  • confirm_saved_payment_method

Response · 201

dataobjectRequired

A request for a checkout verification code. A request with channel email reads the same whether or not Flint sent a code.

metaobject
request_idstring
curl -X POST https://api.withflintpay.com/v1/checkout-sessions/cs_123/customer-verifications \
  -H "Flint-Version: 2026-09-07" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: a-unique-key" \
  -d '{
    "email": "ada@example.com",
    "purpose": "use_saved_payment_methods"
  }'

Confirm a checkout verification code#

POST/v1/checkout-sessions/{checkout_session_id}/customer-verifications/{customer_verification_id}/confirmIdempotent

Requires a checkout session id or a checkout session secret

Checks the code the buyer typed. A right code makes the checkout act for the customer with that email, and creates the customer, with a customer.created event, when none exists. The checkout can then save the buyer's card with save_payment_method on POST /v1/orders/{order_id}/pay, and list and pay with that customer's saved cards. The order's customer does not change until the payment succeeds. Only the checkout_auth_token in the response acts for that customer. Send it as X-Checkout-Session-Secret from then on. Every other credential for the session, including earlier checkout_auth_token values and hosted checkout links, keeps working for the checkout and acts for no customer, so it lists no saved cards and pays with none. A buyer who opens the link on another device confirms an email there to use them, and from then on only that device's new credential acts for a customer. If the response is lost after the code was accepted, the credential you sent still works. Send the same code again with it while the code is valid, which counts as another try and returns a new credential for the same customer, or request a new code. A wrong, expired, or replaced code returns CUSTOMER_VERIFICATION_CODE_INVALID, and so does a used code once the checkout was confirmed again, any code after its 5th try, any code for an email past its limit on wrong tries, or a code whose email's customer changed its email or was deleted after the code was sent. If the checkout stops offering saved payment details before the code is confirmed, such as when the merchant turns them off, the request returns CUSTOMER_VERIFICATION_NOT_OFFERED. A credential that already acts for a customer gets CHECKOUT_CUSTOMER_ALREADY_AUTHORIZED, and confirming never replaces a customer the merchant named. Once the customer whose email the buyer confirmed changes that email or is deleted, the checkout acts for no customer, and the buyer can confirm the customer's new email or another one. A checkout opened from a checkout reminder link acts for no customer the buyer confirmed earlier, so its buyer confirms an email again. A texted code for saved details binds the checkout the same way, but the new credential opens only the cards saved with that number: it lists and pays with no card saved by email, and reads no customer details. A texted code checks once, so after a lost answer request a new code. A code for purpose confirm_saved_payment_method keeps the session's credential, so the response has no checkout_access, and its checkout_session carries payment_method_save. A texted code saves the card with the number when the number already opens the customer's saved details or the customer has none yet; otherwise payment_method_save.email_confirmation_required turns true, and an emailed code finishes the save. An emailed code alone saves the card by email.

Path parameters

checkout_session_idstringRequired

Flint checkout session ID.

customer_verification_idstringRequired

The customer_verification_id the code request returned.

Request body

codestringRequired

The six-digit code from the email or the text.

Response · 200

dataobjectRequired

The checkout after a confirmed code, and the credential that acts for the customer with the confirmed email.

metaobject
request_idstring
curl -X POST https://api.withflintpay.com/v1/checkout-sessions/cs_123/customer-verifications/cscv_01K6ZQ4TE3M8Q2N7W5V1R9X0YB/confirm \
  -H "Flint-Version: 2026-09-07" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: a-unique-key" \
  -d '{
    "code": "482913"
  }'

Was this helpful?