Reference
Session and transaction statuses, webhook payloads, and the fields each event returns.
Reference for Hosted Checkout statuses, identifiers, and webhook events.
Statuses: session vs. transaction
A common point of confusion is the difference between the status of a session and that of a
payment transaction. They represent two different things:
- Session status represents the entire checkout experience — think of it as the "cart" or
"order" waiting to be paid. Its lifecycle is simple: it starts as
pendingand can only end ascompleted(paid) orexpired(abandoned). - Transaction status represents a single attempt to pay for that session. A customer might have multiple transactions within one session if their first attempt fails.
| Type | Purpose | Example values |
|---|---|---|
| Session status | The state of the order (is it paid?) | pending, completed, expired |
| Transaction status | The state of a specific payment attempt (did this charge go through?) | Pending, Success, Declined, Expired |
For order fulfillment, base your logic on the transaction status (transaction_status or the
payment.transaction event), not only on the session status. A session.status: "completed"
or "expired" alone is not enough to confirm whether the payment succeeded or was declined.
Note: for some merchants, transaction_status can come back empty ("") to represent a
Declined transaction instead of staying "Pending". If you see this behavior, treat it as
Declined.
Session status
| Status | Description |
|---|---|
| pending | The session has been created but the customer hasn't completed the payment. The URL is active. |
| completed | The customer completed the payment successfully. Final state. |
| expired | The session wasn't completed in time (customer abandoned the page) and can no longer be paid. Final state. |
Transaction status
| Status | Description |
|---|---|
| Pending | The payment was initiated but isn't yet confirmed (e.g. awaiting 3D Secure). |
| Success | The payment was successfully authorized and processed. |
| Declined | The card issuer or processor declined the payment. The customer may retry. |
| Expired | The attempt wasn't completed in time (e.g. failed 3D Secure). |
Key identifiers
| ID | Type | What it is |
|---|---|---|
id (Session ID) | string | Unique identifier for the session. Example: cs_97_41521_d11ba771.... Appears in the checkout URL and when calling Get a Session. |
payment_id (Payment ID) | number | Identifier for a transaction (a payment attempt). Example: 41521. A session may have several if the first card is declined. |
external_id (External ID) | string | Your internal order identifier, e.g. ORD-001. You send it when creating the session and use it to reconcile. Searchable in the Dashboard. |
Your order (external_id) maps 1:1 to a Tonder session, which can have 1:N payment transactions.
Webhook events
All webhook payloads follow this structure:
{
"action": "session.created",
"type": "checkout.hosted",
"data": {
// ... object related to the event
}
}| Field | Type | Description |
|---|---|---|
action | string | The event type (e.g. session.created, session.completed, session.expired). |
type | string | The checkout type, always checkout.hosted for Hosted Checkout. |
data | object | Event-specific data containing session or transaction details. |
The external_id you send when creating the session appears in the Dashboard as Order ID and
in transaction reports as Business Transaction ID, but it is not returned in webhook
payloads. To receive your order reference in a webhook, also include it inside the metadata
object when creating the session; it will be available under data.metadata.
session.created
Sent when a new checkout session is created.
session.completed
Sent when a session is successfully paid and completed. This is the primary event for confirming a successful order.
session.expired
Sent when a pending session expires without a successful payment (e.g. the customer abandoned the checkout).
payment.transaction
Sent when a payment transaction status changes (Pending, Success, Declined). A session may have
multiple payment.transaction events if the user retries. While session.completed tells you the
order is paid, payment.transaction gives you details about each attempt.
