Checkout Resolver
Full control over the checkout lifecycle for custom UIs.
TS
const checkout = elements.processCheckout({
cart_id: 'cart_xxxxx',
order_type: 'pickup',
on_status_change: (status, ctx) => {
console.log(status) // 'preparing' | 'processing' | 'awaiting_authorization' | ...
updateUI(status, ctx.display_text)
},
timeout_ms: 180_000,
})
// Abort if user cancels
abortButton.onclick = () => checkout.abort()
const result = await checkout
if (result.success) {
console.log('Order:', result.order?.id)
} else {
console.error(result.error?.code, result.error?.message)
}For most integrations, use elements.processCheckout() or elements.submitCheckout(). The resolver details below are for advanced custom checkout UIs that need granular status tracking and abort control.
Status Flow
| Status | Description |
|---|---|
preparing | Validating cart and checkout data |
recovering | Resuming interrupted checkout from localStorage |
processing | Submitting to payment provider |
awaiting_authorization | Waiting for OTP/PIN or redirect auth |
polling | Polling payment status from provider |
finalizing | Confirming order and Link enrollment |
success | Payment confirmed, order created |
failed | Payment or validation failed |
processCheckout
Returns an AbortablePromise<ProcessCheckoutResult>. Call .abort() to cancel the checkout and send ABORT_CHECKOUT to the payment iframe.
TS
const checkout = elements.processCheckout({
cart_id: 'cart_xxxxx',
order_type: 'delivery',
location_id: 'loc_main',
notes: 'Ring doorbell',
tip_amount: '2.00',
pay_currency: 'USD',
on_status_change: (status, ctx) => {
setStatusText(ctx.display_text || status)
},
timeout_ms: 180_000, // default 180s
})
const result = await checkoutAbort
TS
// User clicks "Cancel"
checkout.abort()
// The promise resolves with:
// { success: false, error: { code: 'CANCELLED', message: '...', recoverable: true } }Example: Status Tracking with Abort
TS
function startCheckout(elements, cartId: string) {
const checkout = elements.processCheckout({
cart_id: cartId,
order_type: 'pickup',
on_status_change: (status, ctx) => {
switch (status) {
case 'preparing':
showSpinner('Preparing checkout...')
break
case 'processing':
showSpinner('Processing payment...')
break
case 'awaiting_authorization':
showSpinner('Waiting for authorization...')
break
case 'polling':
showSpinner('Confirming payment...')
break
case 'finalizing':
showSpinner('Finalizing order...')
break
}
},
})
// Wire up cancel button
document.getElementById('cancel-btn')?.addEventListener('click', () => {
checkout.abort()
})
return checkout
}submitCheckout
Simplified variant -- collects data from mounted Elements and processes checkout in one call.
TS
const result = await elements.submitCheckout({
cart_id: 'cart_xxxxx',
order_type: 'pickup',
})