@swft-checkout/js
v1.0.0
Published
JavaScript SDK for Swft Checkout — sub-200ms edge checkout for any platform
Maintainers
Readme
@swft-checkout/js
JavaScript/TypeScript SDK for Swft Checkout — sub-200ms edge checkout for any platform.
Installation
npm install @swft-checkout/js
# or
yarn add @swft-checkout/js
# or
pnpm add @swft-checkout/jsQuick start
import { createSession, redirectToCheckout } from '@swft-checkout/js'
const session = await createSession({ merchantApiKey: 'sk_live_...', currency: 'GBP', lineItems, shippingMethods, subtotal: 2999 })
redirectToCheckout(session.sessionUrl)API reference
createSession(options)
Creates a Swft checkout session. Returns a SwftSession.
import { createSession } from '@swft-checkout/js'
const session = await createSession({
merchantApiKey: process.env.SWFT_API_KEY!,
currency: 'GBP',
lineItems: [
{
name: 'Padel Racket Pro',
quantity: 1,
price: 8999, // pence — £89.99
product_id: 'sku_abc',
image: 'https://example.com/racket.jpg',
sku: 'PADEL-PRO-001',
},
],
shippingMethods: [
{ id: 'standard', label: 'Standard Delivery (3-5 days)', cost: 499 },
{ id: 'express', label: 'Express Delivery (next day)', cost: 999 },
{ id: 'free', label: 'Free Delivery (5-7 days)', cost: 0 },
],
subtotal: 8999,
tax: 1500,
discount: 0,
customer: {
email: '[email protected]',
first_name: 'Jamie',
last_name: 'Smith',
},
extensions: {
order_bump_ids: ['bump_helmet'],
},
})
console.log(session.sessionId) // swft_sess_abc123
console.log(session.sessionUrl) // https://checkout.swft.co.uk/swft_sess_abc123
console.log(session.expiresAt) // ISO 8601 timestampOptions
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| merchantApiKey | string | Yes | Your Swft merchant API key from the dashboard |
| currency | string | Yes | ISO 4217 code: 'GBP', 'USD', 'EUR' |
| lineItems | SwftLineItem[] | Yes | Products in the cart |
| shippingMethods | SwftShippingMethod[] | Yes | Available shipping options |
| subtotal | number | Yes | Cart subtotal in minor units (pence/cents) |
| tax | number | No | Tax in minor units (default 0) |
| discount | number | No | Discount in minor units (default 0) |
| customer | SwftCustomer | No | Pre-fill customer details |
| extensions | Record<string, unknown> | No | Swft module data (order bumps, funnels, etc.) |
| apiUrl | string | No | Override API base URL (default https://api.swft.co.uk) |
| cartHash | string | No | Deduplication hash — auto-generated from line items if omitted |
redirectToCheckout(sessionUrl)
Redirects the browser to the Swft hosted checkout. Must be called in a browser context.
import { redirectToCheckout } from '@swft-checkout/js'
redirectToCheckout(session.sessionUrl)Throws SwftError with code 'browser_only' if called server-side.
getCheckoutUrl(sessionId)
Returns the checkout URL for a given session ID without redirecting.
import { getCheckoutUrl } from '@swft-checkout/js'
const url = getCheckoutUrl('swft_sess_abc123')
// https://checkout.swft.co.uk/swft_sess_abc123verifySwftWebhook(rawBody, signature, secret)
Verifies a Swft webhook using the Web Crypto API. Compatible with Node 18+, browsers, Cloudflare Workers, and Deno.
import { verifySwftWebhook } from '@swft-checkout/js'
// In a Cloudflare Worker or Next.js App Router route handler:
const rawBody = await req.text()
const signature = req.headers.get('x-swft-signature') ?? ''
const payload = await verifySwftWebhook(
rawBody,
signature,
process.env.SWFT_WEBHOOK_SECRET!
)
console.log(payload.event) // 'payment_succeeded'
console.log(payload.sessionId) // 'swft_sess_abc123'Throws SwftError with code 'invalid_signature' and status 401 if verification fails.
verifySwftWebhookNode(rawBody, signature, secret)
Node.js-only synchronous variant using the built-in crypto module. Use this on Node < 18 or when you cannot use async/await in your webhook handler.
import { verifySwftWebhookNode } from '@swft-checkout/js'
// In an Express route:
app.post('/webhooks/swft', express.raw({ type: 'application/json' }), (req, res) => {
const payload = verifySwftWebhookNode(
req.body,
req.headers['x-swft-signature'] as string,
process.env.SWFT_WEBHOOK_SECRET!
)
if (payload.event === 'payment_succeeded') {
// fulfil order
}
res.json({ received: true })
})TypeScript types
interface SwftLineItem {
name: string
quantity: number
price: number // minor units (pence/cents)
product_id?: string | number
variant_id?: string | number
image?: string
sku?: string
attributes?: Record<string, string>
}
interface SwftShippingMethod {
id: string
label: string
cost: number // minor units
}
interface SwftCustomer {
email?: string
first_name?: string
last_name?: string
}
interface SwftCreateSessionOptions {
merchantApiKey: string
currency: string
lineItems: SwftLineItem[]
shippingMethods: SwftShippingMethod[]
subtotal: number
tax?: number
discount?: number
customer?: SwftCustomer
extensions?: Record<string, unknown>
apiUrl?: string
cartHash?: string
}
interface SwftSession {
sessionId: string
sessionUrl: string
expiresAt: string
}Webhook payload
All webhook events share this shape:
interface SwftWebhookPayload {
event: 'payment_succeeded' | 'payment_failed' | 'session_expired'
sessionId: string
paymentIntentId?: string
amount?: number // minor units
currency?: string // ISO 4217
customer?: {
email?: string
first_name?: string
last_name?: string
}
shippingAddress?: {
line1: string
line2?: string
city: string
postcode: string
state?: string
country: string
}
lineItems?: SwftLineItem[]
extensions?: Record<string, unknown>
timestamp: string // ISO 8601
}Error handling
All errors thrown by this SDK are instances of SwftError:
import { createSession, SwftError } from '@swft-checkout/js'
try {
const session = await createSession(options)
} catch (err) {
if (err instanceof SwftError) {
console.error(err.message) // human-readable message
console.error(err.code) // machine-readable code e.g. 'session_error'
console.error(err.status) // HTTP status if applicable e.g. 401
}
}Common error codes:
| Code | Description |
|------|-------------|
| session_error | API returned a non-OK response during session creation |
| invalid_signature | Webhook signature verification failed |
| browser_only | redirectToCheckout called outside a browser |
Environment compatibility
| Environment | createSession | verifySwftWebhook | verifySwftWebhookNode |
|-------------|----------------|---------------------|------------------------|
| Node.js 18+ | Yes | Yes (Web Crypto) | Yes |
| Node.js < 18 | Yes | No | Yes |
| Browser | Yes | Yes | No |
| Cloudflare Workers | Yes | Yes | No |
| Deno | Yes | Yes | No |
| Bun | Yes | Yes | Yes |
createSession uses the native fetch API available in all modern environments. For Node < 18, polyfill fetch with node-fetch or undici.
