Checkout events
Events in the "checkout" namespace — fired on checkout-related state changes and checkout lifecycle, including checkout sessions.
Events in the checkout.* namespace fire on checkout-related state changes and the checkout system
lifecycle.
Events API
For the common event envelope (event, createdAt) and the full event catalog across every
namespace, see Events API.
Event catalog
| Event | Fired when | Payload includes | Status |
|---|---|---|---|
checkout.session.completed | Payment is received and order is marked paid. | session — full CheckoutSession | Live |
checkout.session.expired | Session expires without a completed payment. | session — full CheckoutSession | Planned |
Checkout Session events
Events in the checkout.session.* sub-namespace include a session field containing the full
CheckoutSession at the moment the event fired. This is
identical to the response from GET /v0/checkout/sessions/:sessionId — it embeds the complete order
with items, amounts, customer, and payment status.
Payload schema
| Field | Type | Description |
|---|---|---|
session | CheckoutSession | Full checkout session with nested order. |
checkout.session.completed
Fired when payment is received and the order is marked paid. The session.order includes the final
paid amounts (paymentStatus: "paid", paidAt timestamp) and the complete customer, items, taxes,
and discounts snapshot.
{
"event": "checkout.session.completed",
"createdAt": "2026-04-15T14:30:00.000Z",
"session": {
"id": "cs_live_clx8k2m9abc1234",
"url": "https://pay.usedecal.com/s/clx8k2m9abc1234",
"active": true,
"customerId": "cust_live_abc123def456",
"failedAttempts": 0,
"successUrl": "https://yoursite.com/order/confirmed",
"callbackUrl": "https://yoursite.com/webhooks/decal",
"expiresAt": "2026-04-15T15:30:00.000Z",
"createdAt": "2026-04-15T14:00:00.000Z",
"updatedAt": "2026-04-15T14:30:00.000Z",
"order": {
"id": "ord_live_xyz789",
"provider": "native",
"currency": "USD",
"status": "completed",
"paymentStatus": "paid",
"amounts": {
"subtotal": 1299,
"tax": 104,
"discount": 0,
"tip": 0,
"total": 1403,
"paid": 1403
},
"items": [
{
"id": "itm_1",
"name": "Classic Burger",
"quantity": 1,
"unitPrice": 1299,
"totalPrice": 1299,
"itemType": "product"
}
],
"taxes": [
{
"id": "tax_cuid_abc",
"name": "Sales Tax",
"type": "additive",
"rate": null,
"amount": 104,
"scope": "order"
}
],
"discounts": [],
"customer": {
"id": "cust_live_abc123def456",
"email": "jane@example.com"
},
"paidAt": "2026-04-15T14:30:00.000Z",
"createdAt": "2026-04-15T14:00:00.000Z",
"updatedAt": "2026-04-15T14:30:00.000Z"
}
}
}checkout.session.expired
Fired when a session reaches its expiresAt time without a completed payment. The session.order
reflects the unpaid state at expiry — status: "open" and paymentStatus: "unpaid" (or
"partially_paid" if some payment was received but never completed).
Planned event
This event is not yet fired. Once it ships, the payload shape will match the Payload
schema above with event === 'checkout.session.expired'.