Events

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

EventFired whenPayload includesStatus
checkout.session.completedPayment is received and order is marked paid.session — full CheckoutSessionLive
checkout.session.expiredSession expires without a completed payment.session — full CheckoutSessionPlanned

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

FieldTypeDescription
sessionCheckoutSessionFull 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'.