Checkout context

Link the Bridge SDK to a backend-created checkout session and read the full checkout context — priced items, selected currency, available payment methods, and the customer's saved cards — to render a dynamic, server-driven checkout.

Your backend owns the checkout. It creates a checkout session with its secret key — pricing the offer, selecting the currency, and identifying the customer. The Bridge SDK then links to that session in the browser and reads its context: the priced items, the selected currency, the merchant's available payment methods, and the customer's saved cards.

This lets you render a single, dynamic checkout UI driven entirely by the server. The browser never decides what is charged, in what currency, or which payment methods are allowed — it only reads and renders.

The SDK is initialized with a public key (pk_…). Public keys are restricted to client-safe scopes and are safe to ship in browser code. The checkout session is created server-side with a secret key (sk_…), which must never appear in the browser. See Authentication.

How it works

The checkout session is the source of truth. Your server creates and mutates it; the SDK links to it by id and reads its context to render the UI.

Pass the backend-created checkoutSessionId to the bridge constructor. After init() resolves, the bridge is linked to that checkout and can read its context.

import { TokeflowBridge } from '@tokeflow_com/bridge-js';

const tokeflow = new TokeflowBridge({
  publicKey: 'pk_live_mer_xxx',
  checkoutSessionId: 'cks_a1b2c3d4e5', // created by your backend
});

await tokeflow.init();

The checkoutSessionId is created by your server and passed to the browser — for example, embedded in the rendered page or fetched by your frontend from your own API. Do not create checkout sessions from client code.

Read the context

Call tokeflow.checkout.getContext() to fetch and cache the full checkout context. It returns three top-level objects: checkout (the session and its priced items), paymentMethods (what the merchant can accept), and savedInstruments (the linked customer's saved cards).

const context = await tokeflow.checkout.getContext();

console.log(context.checkout.selectedCurrency); // 'BRL'
console.log(context.paymentMethods.cards);      // true
console.log(context.savedInstruments.length);   // 0 or more

Example context

{
  "checkout": {
    "id": "cks_a1b2c3d4e5",
    "merchantId": "mrc_a1b2c3d4e5",
    "offerId": "ofr_a1b2c3d4e5",
    "customerId": "cust_a1b2c3d4e5",
    "customerEmail": "jane@acme.com",
    "customerName": "Jane Doe",
    "selectedCurrency": "BRL",
    "status": "customer_identified",
    "externalSessionId": "sess_external_42",
    "expiresAt": "2026-05-20T18:00:00Z",
    "completedAt": null,
    "createdAt": "2026-05-19T12:00:00Z",
    "updatedAt": "2026-05-19T12:05:00Z",
    "items": [
      {
        "id": "cki_a1b2c3d4e5",
        "checkoutSessionId": "cks_a1b2c3d4e5",
        "offerId": "ofr_a1b2c3d4e5",
        "currency": "BRL",
        "amount": 9900,
        "firstChargeAmount": null,
        "quantity": 1,
        "installments": 1,
        "createdAt": "2026-05-19T12:00:00Z"
      }
    ]
  },
  "paymentMethods": {
    "cards": true,
    "pix": true,
    "applePay": false,
    "googlePay": false,
    "cardBrands": ["visa", "mastercard"],
    "installmentsSupported": true,
    "installmentOptions": {
      "credit_card": { "min": 1, "max": 12 }
    }
  },
  "savedInstruments": [
    {
      "id": "pi_a1b2c3d4e5",
      "instrumentType": "card",
      "brand": "visa",
      "last4": "4242",
      "expMonth": 12,
      "expYear": 2030
    }
  ]
}

checkout

The checkout session the SDK is rendering. Amounts are snapshots taken at session time, in minor units (cents). The status follows the checkout session lifecycle.

FieldTypeDescription
idstringCheckout session id (cks_…).
merchantIdstringMerchant that owns the session (mrc_…).
offerIdstringThe offer being purchased (ofr_…).
customerIdstring | nullLinked customer (cust_…), or null until identified.
customerEmailstring | nullCustomer email, or null until identified.
customerNamestring | nullCustomer name, or null until identified.
selectedCurrencystring | nullISO 4217 currency selected for the session (e.g. "BRL").
statusstringOne of initiated, customer_identified, payment_pending, completed, expired, abandoned.
externalSessionIdstring | nullYour own session/account reference, if set.
expiresAtstring | nullISO 8601 expiry timestamp.
completedAtstring | nullISO 8601 timestamp set when the session completes.
createdAtstringISO 8601 creation timestamp.
updatedAtstringISO 8601 last-update timestamp.
itemsarrayThe priced line items (see below).

Each entry in items:

FieldTypeDescription
idstringLine item id (cki_…).
checkoutSessionIdstringParent checkout session id (cks_…).
offerIdstringThe priced offer (ofr_…).
currencystringISO 4217 currency code.
amountintegerPrice snapshot in minor units (e.g. 9900 = R$99.00).
firstChargeAmountinteger | nullFirst-charge snapshot in minor units, set when the offer has a setup charge; otherwise null.
quantityintegerQuantity of this line.
installmentsintegerInstallments selected by the customer (1 = single charge).
createdAtstringISO 8601 creation timestamp.

paymentMethods

The payment methods the merchant can accept, resolved from its routing configuration. Use these to render only the options the merchant actually supports.

FieldTypeDescription
cardsbooleanCard payments are accepted.
pixbooleanPIX is accepted.
applePaybooleanApple Pay is accepted.
googlePaybooleanGoogle Pay is accepted.
cardBrandsstring[]Accepted card brands (e.g. ["visa", "mastercard"]).
installmentsSupportedbooleanWhether installments are available.
installmentOptionsobjectInstallment min/max keyed by payment method (e.g. { "credit_card": { "min": 1, "max": 12 } }).

savedInstruments

A returning customer's saved payment options — slim and client-safe. The array is empty when no customer is linked or the customer has no saved instruments. These never include sensitive identifiers; they carry only what you need to render a "pay with saved card" choice.

FieldTypeDescription
idstringSaved payment instrument id (pi_…).
instrumentTypestringThe kind of instrument (e.g. "card").
brandstring | nullCard brand (e.g. "visa"), or null.
last4string | nullLast four digits, or null.
expMonthinteger | nullExpiry month (1–12), or null.
expYearinteger | nullFour-digit expiry year, or null.

Methods

The Checkout module is available at tokeflow.checkout after init().

MethodReturnsDescription
getContext()Promise<CheckoutContext>Fetch and cache the checkout context. Rejects with NO_CHECKOUT_SESSION if no session is linked.
getCachedContext()CheckoutContext | nullReturn the cached context synchronously (no network call); null if not yet fetched.
refresh()Promise<CheckoutContext>Re-fetch the context after your backend mutates the checkout (identifies the customer, changes items, and so on).
hasCheckoutSession()booleanWhether a checkout session is linked to this bridge.

Cached vs. fresh reads

getContext() caches its result. Reach for getCachedContext() when you need the already-fetched context synchronously — for example, during a render — without triggering a network call.

// First read: network fetch + cache
const context = await tokeflow.checkout.getContext();

// Later, synchronously (no network):
const cached = tokeflow.checkout.getCachedContext();
if (cached) {
  renderSummary(cached.checkout.items);
}

Refresh after backend mutations

The checkout context is a snapshot. When your backend mutates the session — identifies the customer, changes line items, or switches the currency — call refresh() to pull the latest state.

// e.g. after your server identifies the customer on the checkout
const updated = await tokeflow.checkout.refresh();
console.log(updated.checkout.customerEmail);   // now populated
console.log(updated.savedInstruments.length);  // saved cards now available

Identifying the customer server-side and then calling refresh() is how saved cards appear: savedInstruments is populated only once a customer is linked to the session.

Handling no linked session

If the bridge was created without checkoutSessionId, the checkout calls have nothing to read. getContext() rejects with the NO_CHECKOUT_SESSION error code; guard with hasCheckoutSession() or catch the error.

import { TokeflowErrorCode } from '@tokeflow_com/bridge-js';

if (!tokeflow.checkout.hasCheckoutSession()) {
  // No checkout linked — fall back to a standalone tokenization flow.
}

try {
  const context = await tokeflow.checkout.getContext();
} catch (error) {
  if (error.code === TokeflowErrorCode.NO_CHECKOUT_SESSION) {
    // The bridge was initialized without `checkoutSessionId`.
  }
}

getContext() always reflects server state. Treat amounts, currency, and available payment methods as authoritative — never let the browser override what the server priced or enabled.

React

Use the useCheckout() hook to fetch, cache, and re-render the checkout context. It requires checkoutSessionId to be set in the TokeflowProvider config.

import { TokeflowProvider, useCheckout } from '@tokeflow_com/bridge-js/react';

function App() {
  return (
    <TokeflowProvider
      config={{
        publicKey: 'pk_live_mer_xxx',
        checkoutSessionId: 'cks_a1b2c3d4e5', // from your backend
      }}
    >
      <CheckoutSummary />
    </TokeflowProvider>
  );
}

function CheckoutSummary() {
  const { context, isLoading, error, refresh } = useCheckout();

  if (error) return <p>{error.message}</p>;
  if (isLoading || !context) return <p>Loading…</p>;

  const { checkout, paymentMethods, savedInstruments } = context;

  return (
    <div>
      <ul>
        {checkout.items.map((item) => (
          <li key={item.id}>
            {item.offerId} — {item.amount} {item.currency} × {item.quantity}
          </li>
        ))}
      </ul>

      {paymentMethods.cards && <p>Card payments available</p>}
      {paymentMethods.pix && <p>PIX available</p>}

      {savedInstruments.length > 0 && (
        <ul>
          {savedInstruments.map((pi) => (
            <li key={pi.id}>
              {pi.brand} •••• {pi.last4} — {pi.expMonth}/{pi.expYear}
            </li>
          ))}
        </ul>
      )}

      <button onClick={() => refresh()}>Refresh</button>
    </div>
  );
}

The useCheckout() hook returns:

FieldTypeDescription
contextCheckoutContext | nullThe fetched context, or null while loading or before fetch.
isLoadingbooleanWhether the initial fetch is in flight.
errorTokeflowError | nullThe fetch error, if any (e.g. NO_CHECKOUT_SESSION).
refresh() => Promise<CheckoutContext>Re-fetch the context after a backend mutation.

Next steps

On this page