API Reference

CheckoutSession

API reference for the CheckoutSession class — a framework-agnostic state machine for the checkout lifecycle.

The CheckoutSession class orchestrates the complete checkout flow from customer info through payment and confirmation. It enforces valid state transitions, emits events, and works on any JavaScript runtime. The flow dynamically adapts based on the channel and fulfillment type.

Constructor

new CheckoutSession(config: CheckoutSessionConfig)

CheckoutSessionConfig

PropertyTypeRequiredDescription
paymentProviderPaymentProviderYesPayment gateway instance
amountnumberYesOrder total amount
currencystringYesISO currency code
channelCheckoutChannelNoSales channel (default: 'web')
fulfillmentCheckoutFulfillmentNoFulfillment type (smart default from channel)
expiresInnumberNoSession TTL in milliseconds
orderIdstringNoExternal order reference
returnUrlstringNo3DS redirect return URL
cancelUrlstringNoPayment cancellation URL
webhookUrlstringNoPer-transaction webhook URL

CheckoutChannel

type CheckoutChannel = 'web' | 'pos' | 'agent' | 'link'

CheckoutFulfillment

type CheckoutFulfillment = 'shipping' | 'local_delivery' | 'pickup' | 'none'

Smart Defaults

ChannelDefault Fulfillment
webshipping
posnone
agentnone
linknone

Explicit fulfillment always overrides the channel default.

Properties

All properties are read-only getters:

PropertyTypeDescription
stateCheckoutStateCurrent state machine state
channelCheckoutChannelResolved sales channel
fulfillmentCheckoutFulfillmentResolved fulfillment type
customerInfoCheckoutCustomerInfo | nullCustomer details
shippingAddressAddress | nullShipping address
billingAddressAddress | nullBilling address
shippingMethodIdstring | nullSelected shipping method
paymentSessionPaymentSession | nullCurrent payment session
amountnumberOrder amount
currencystringCurrency code
orderIdstring | nullOrder ID
errorError | nullLast error

Methods

setCustomerInfo(info)

setCustomerInfo(info: CheckoutCustomerInfo): void

Set customer details. Transitions from idle to info.

CheckoutCustomerInfo:

FieldTypeRequired
emailstringYes
firstNamestringYes
lastNamestringYes
phonestringNo

setShippingAddress(address, billingAddress?)

setShippingAddress(
  address: Omit<Address, 'id' | 'isDefault'>,
  billingAddress?: Omit<Address, 'id' | 'isDefault'>
): void

Set shipping address. Transitions from info to shipping. If billingAddress is omitted, the shipping address is used for billing.

Only required when fulfillment is shipping or local_delivery. For pickup or none, skip this step and call submitPayment() directly.

setShippingMethod(methodId)

setShippingMethod(methodId: string): void

Set the shipping method. Does not trigger a state transition. Must be in shipping state.

setAmount(amount)

setAmount(amount: number): void

Update the order amount. Can be called before payment is submitted.

setOrderId(orderId)

setOrderId(orderId: string): void

Set the order ID if not provided at construction time.

submitPayment(options?)

submitPayment(options?: {
  sourceToken?: string
  idempotencyKey?: string
  metadata?: Record<string, unknown>
}): Promise<PaymentSession>

Create a payment session with the provider. Valid source states:

  • shipping or failed — always valid
  • info — valid when fulfillment is pickup or none

Returns a PaymentSession with an optional redirectUrl for 3DS.

confirmPayment(sessionId?)

confirmPayment(sessionId?: string): Promise<PaymentSession>

Confirm payment after 3DS redirect. Must be in payment state. Transitions to complete or failed.

handleWebhookUpdate(paymentSession)

handleWebhookUpdate(paymentSession: PaymentSession): void

Handle an async webhook update. Works from any non-terminal state. Transitions directly to complete (for captured) or failed (for failed/cancelled).

toSnapshot()

toSnapshot(): CheckoutSnapshot

Get a serializable snapshot of the current session state.

CheckoutSnapshot:

interface CheckoutSnapshot {
  state: CheckoutState
  channel: CheckoutChannel
  fulfillment: CheckoutFulfillment
  expiresAt: string | null
  customerInfo: CheckoutCustomerInfo | null
  shippingAddress: Omit<Address, 'id' | 'isDefault'> | null
  billingAddress: Omit<Address, 'id' | 'isDefault'> | null
  shippingMethodId: string | null
  paymentSession: PaymentSession | null
  amount: number
  currency: string
  orderId: string | null
  error: string | null
}

Events

The session extends EventEmitter and emits these events:

EventPayloadWhen
stateChange{ from: CheckoutState, to: CheckoutState }Any state transition
complete{ paymentSession: PaymentSession }Payment captured
error{ error: Error, state: CheckoutState }Payment failed
expired{}Session TTL exceeded
session.on('stateChange', ({ from, to }) => {
  console.log(`${from}${to}`)
})

State Transitions

type CheckoutState =
  | 'idle'
  | 'info'
  | 'shipping'
  | 'payment'
  | 'confirming'
  | 'complete'
  | 'failed'

With Address (shipping, local_delivery)

FromToMethod
idleinfosetCustomerInfo()
infoshippingsetShippingAddress()
shippingpaymentsubmitPayment()
paymentconfirmingconfirmPayment()
confirmingcompletePayment captured
confirmingfailedPayment declined
failedpaymentsubmitPayment() (retry)

Without Address (pickup, none)

FromToMethod
idleinfosetCustomerInfo()
infopaymentsubmitPayment()
paymentconfirmingconfirmPayment()
confirmingcompletePayment captured
confirmingfailedPayment declined
failedpaymentsubmitPayment() (retry)

Invalid transitions throw Error: Invalid transition: "{from}" → "{to}".

Session Expiry

When expiresIn is set, the session stores an expiresAt timestamp. After expiry:

  • All state-mutating methods throw Error: Checkout session has expired
  • The expired event is emitted
  • The expiresAt field appears in the snapshot as an ISO string
const session = new CheckoutSession({
  paymentProvider: tap,
  amount: 45.00,
  currency: 'SAR',
  channel: 'pos',
  expiresIn: 30 * 60 * 1000, // 30 minutes
})

session.on('expired', () => {
  // Show "link expired" UI
})