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, Lite SDK 2.0 and Hosted Checkout 2.0 → Short format
  • Mobile SDKs / Legacy (including Hosted Checkout accounts still on the legacy flow) → Long format
CharacteristicShort formatLong format
Root structureTop-level fieldsEverything inside data{}
Status fieldstatus: Pending / Successtransaction_status: Pending / Success
Event indicatorevent_type: payment_Pendingevent: created / confirmed
Order referenceclient_referencemetadata.external_id / order_id
SPEI CLABENot includeddata.clabe
Sender info (SPEI Success)Not includedsender_name, sender_clabe, sender_bank…
_incoming_requestNot includedmetadata._incoming_request (full object)
Integration modesAPI Direct · Lite SDK 2.0 · Frictionless SPEI · Hosted Checkout 2.0Mobile 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.

Withdrawals

Withdrawal webhooks have two formats of their own, and which one you receive depends on how your account is configured. The flat format has the same shape as the Short payment format (status: Pending, event_type: withdrawal_Pending, transfer_method_type instead of payment_method_type). The extended format nests the full withdrawal record under withdrawal{} and carries the status in the internal names (PAID_FULL). Both are documented, with examples, in Withdrawals.

Correlation key

Reference field names differ across modes, but metadata.external_id arrives in every format and event. Use it as your correlation key.

ModeRequest field (you send)Webhook field (you read)
Hosted Checkoutexternal_idmetadata.external_id
SDK (any platform)orderReferencemetadata.external_id or metadata.order_id
API Directclient_referenceclient_reference (top-level) + metadata.external_id
Hybridboth, per legboth formats — correlate 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.

Next steps

Was this page helpful?

On this page