Session extensions (booking metadata)
Pass arbitrary partner-defined JSON through the entire checkout
lifecycle by setting extensions on the cart payload when you create
a session. Swft treats the contents as opaque and surfaces them
verbatim in every webhook that fires off the session.
import { Swft } from '@swft-checkout/js'
const swft = new Swft({ apiKey: merchant.api_key })
const session = await swft.sessions.create({ cart: { items: [{ id: 'class:reformer-100', name: '60-min Reformer', quantity: 1, price: 2500 }], extensions: { booking: { class_schedule_id: 'cs_8f...', user_id: 'usr_31...', studio_id: 'stu_4d...', reformer_id: null, payment_type: 'single', }, }, },})window.location.href = session.sessionUrlWhere it shows up
Section titled “Where it shows up”extensions ends up in two places:
-
The
order.completed(andorder.failed,cart.abandoned,refund.issued) webhook as a top-levelextensionsfield alongsidedata. Use this to identify the booking on confirmation and create the booking row server-side. -
The pre-confirmation hook request body as
extensions. Use this to look up the class/inventory and decide{ available: true | false }.
If the session creates a Stripe Subscription (memberships), Swft
copies the extensions into stripe.subscription.metadata.swft_extensions
(JSON-stringified) so every renewal/cancellation event also carries
the same booking context.
Schema
Section titled “Schema”There is no schema on Swft’s side — extensions is Record<string, unknown>. Define yours on the partner side; we recommend versioning
your extension keys (booking_v1, booking_v2, …) so you can
evolve the shape without ambiguity in the webhook handler.