Webhooks Model
Tonder's two webhook formats, which integration receives each, and how to read them.
Webhooks are automated messages Tonder sends when transaction events occur. Instead of repeatedly polling our API for status changes, webhooks notify you in real time the moment something happens — a payment completing, failing, or requiring additional authentication.
Two formats: Short and Long
Tonder sends two different webhook formats. Which one you receive depends on your integration mode:
- API Direct and Lite SDK 2.0 → Short format
- Hosted Checkout / mobile SDKs / Legacy → Long format
| Characteristic | Short format | Long format |
|---|---|---|
| Root structure | Top-level fields | Everything inside data{} |
| Status field | status: Pending / Success | transaction_status: Pending / Success |
| Event indicator | event_type: payment_Pending | event: created / confirmed |
| Order reference | client_reference | metadata.external_id / order_id |
| SPEI CLABE | Not included | data.clabe |
| Sender info (SPEI Success) | Not included | sender_name, sender_clabe, sender_bank… |
_incoming_request | Not included | metadata._incoming_request (full object) |
| Integration modes | API Direct · Lite SDK 2.0 · Frictionless SPEI | Hosted Checkout · mobile SDKs · Legacy |
Same transaction, two structures
The example below is a SPEI event in both formats:
{
"id": "78eb98ef-65a8-4038-a2a0",
"operation_type": "payment",
"amount": "500",
"currency": "MXN",
"client_reference": "ORD-001",
"status": "Pending",
"provider": "tonder",
"transaction_id": "26292298-de5e-4edc",
"payment_method_type": "SPEI",
"created": "2026-05-21T19:51:18Z",
"metadata": {
"order_id": "ORD-001",
"external_id": "ORD-001",
"transaction_type": "deposit"
},
"event_type": "payment_Pending",
"action": "MODIFY"
}{
"operation_type": "payment",
"action": "payment",
"event": "created",
"type": "deposit",
"data": {
"id": "3195511b-fd2e-4844-bf02",
"transaction_status": "Pending",
"amount": 500.0,
"currency_code": "MXN",
"payment_id": 5117665,
"payment_method_name": "spei",
"clabe": "710969000312511566",
"concept": "SPEI deposit for payment...",
"metadata": {
"external_id": "ORD-001",
"order_id": "ORD-001",
"transaction_type": "deposit"
}
}
}It's the same transaction with two completely different structures. Confirm your format with your Tonder integration manager before building your webhook handler.
Correlation key
Reference field names differ across modes, but metadata.external_id arrives in every
format and event. Use it as your correlation key.
| Mode | Request field (you send) | Webhook field (you read) |
|---|---|---|
| Hosted Checkout | external_id | metadata.external_id |
| SDK (any platform) | orderReference | metadata.external_id or metadata.order_id |
| API Direct | client_reference | client_reference (top-level) + metadata.external_id |
| Hybrid | both, per leg | both formats — dedupe on metadata.external_id |
Universal rule: populate metadata.external_id on every request — it's the only field
guaranteed to arrive in every webhook of every format.
