Skip to main content
Checkout wraps every element you would otherwise mount separately into a single lifecycle. This page walks through what happens between overflow.checkout(...) and onSubmit.

Lifecycle

  1. Create. overflow.checkout(options) returns a handle. No network calls yet.
  2. Mount. checkout.mount('#host') renders a loading skeleton, then fetches your merchant payment settings from the Overflow API.
  3. Ready. Once configuration loads, Checkout renders the configured sections and fires onReady.
  4. Interact. As the shopper types or selects fields, onChange fires with the aggregated { value, complete, errors }.
  5. Submit. The submit button inside Checkout (or your programmatic checkout.submit() call) validates every section, tokenizes the selected payment method, and fires onSubmit with the payload.
  6. Authorize. Forward the payload to your server, which calls the Overflow API to authorize the charge with your secret key.

Section order

Sections render in this default order:
  1. Contact
  2. Shipping address
  3. Billing address
  4. Payment methods
  5. Custom elements
Reorder with options.order. Unlisted sections fall through in default order after the ones you listed:
Entries for sections you did not configure are no-ops at render time; they do not force a section to appear.

Payment method order

Payment methods render in the order you pass:
Methods that fail a runtime check (a wallet on http://, a wallet that reports unavailable, a missing configuration) are hidden without shifting siblings. If a method becomes available later in the session, it slots back into its original position. defaultPaymentMethod, when set, overrides the initial selection. If the default is unavailable at runtime, the first available method wins.

Contact block

Contact is opt-in. Omit contact (or pass {}) to render Checkout with no contact fields.
Any key you include with an object value is enabled. Order inside the contact block is email → fullName → companyName → phone; override with contact.order.

Addresses

Set billingAddress and/or shippingAddress to enable those sections. Each accepts every option the standalone element accepts.

Custom elements

Custom elements slot in via customElements. Each entry is one mounted child managed by Checkout.
The default position of the custom block is after Payment methods. Reorder via order: ['contact', 'customElements', 'paymentMethods'].

Submit flow

Calling checkout.submit() (or the internal submit button firing) does the following in one pass:
  1. Flush any pending debounced validation on every mounted child.
  2. Collect per-section errors, tagged by source.
  3. If there are errors, fire onError with the aggregated fieldErrors and stop.
  4. Otherwise, tokenize the selected payment method.
  5. Fire onSubmit with { value } where value carries the method, the tokenized payment payload, and every configured section (contact, addresses, custom elements).
Wallets follow a slightly different path: the wallet button opens its own sheet, and the tokenized payload arrives on onSubmit from the sheet directly. Contact and address data collected inside the wallet sheet are folded into value alongside the payment payload.

Update in place

You can change Checkout options after mount:
The SDK diffs the new options and re-renders only the affected sections. Shopper input in unaffected fields is preserved.

Programmatic access to custom elements

Reach into a configured custom slot with checkout.getCustomElement(name):
Returns null if the slot is not configured. Built-in sub-elements (email, card, etc.) are not exposed this way; their values are already on the aggregated envelope.

Next steps

Best practices

Recommendations for real integrations.

Sections

Per-section configuration.
Last modified on July 17, 2026