Non-Card Payments (APMs)
Charge with SPEI, OXXO Pay, MercadoPago and cash vouchers from the same endpoint.
This guide shows how to create payments using alternative payment methods (APMs) through the unified
/process/ endpoint. You process local options like SPEI bank transfers and OXXO Pay cash payments
with a single, consistent call.
The core request
All payments are created with a POST to /process/. The body contains the fields common to all
methods, plus a payment_method object with method-specific fields.
POST https://stage.tonder.io/api/v1/process/ # Sandbox
POST https://app.tonder.io/api/v1/process/ # Production| Field | Type | Description |
|---|---|---|
operation_type | string | Must be "payment" to process a payment. |
amount | decimal | Amount using a dot as the decimal separator (e.g. 100.00). |
currency | string | Currency: "MXN", "USD" or "CLP". Mexico and Chile use the same flow; only this value changes. |
customer | object | Customer info, with at least name and email. |
payment_method | object | Method config, with type and method-specific parameters. |
client_reference | string | Your unique transaction identifier for reconciliation. |
Depending on the method, additional fields may be required inside payment_method. See each
method's details in Payment methods.
Examples by method
{
"operation_type": "payment",
"amount": 500.00,
"currency": "MXN",
"customer": { "name": "Carlos Eduardo López", "email": "carlos.lopez@empresa.mx" },
"payment_method": { "type": "SPEI" },
"client_reference": "ORD-001"
}A successful SPEI response has status Pending and includes payment instructions for the customer:
{
"id": "550e8400-e29b-41d4-a716-446655440001",
"operation_type": "payment",
"status": "Pending",
"amount": 500.00,
"currency": "MXN",
"client_reference": "ORD-001",
"payment_id": 12346,
"transaction_id": "txn_spei456",
"provider": "spei_provider",
"created_at": "2024-07-26T10:35:00Z",
"status_code": 201,
"payment_instructions": {
"clabe": "646180157000000004",
"reference": "7812345678",
"expires_at": "2024-07-27T10:35:00Z",
"bank_name": "STP"
}
}{
"operation_type": "payment",
"amount": 250.00,
"currency": "MXN",
"customer": { "name": "María Isabel Fernández", "email": "maria.fernandez@email.com" },
"payment_method": { "type": "oxxopay" },
"client_reference": "ORD-001"
}A successful OXXO Pay response has status Pending and includes a URL with the payment instructions
and reference for the customer:
{
"id": "887e3ff0-4f28-456d-bf33-857de2cdf788",
"operation_type": "payment",
"status": "Pending",
"amount": 34.0,
"currency": "MXN",
"client_reference": "ORD-001",
"provider": "tonder",
"created_at": "2026-02-17T21:32:28.887557Z",
"status_code": 201,
"next_action": {
"redirect_to_url": {
"url": "https://stage-payflow.tonder.io/oxxo-pay?token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}
},
"verify_transaction_status_url": "/transactions/887e3ff0-4f28-456d-bf33-857de2cdf788/"
}Response statuses
The status field can have one of these values:
| Status | Description |
|---|---|
Pending | The transaction is being processed (common for asynchronous payments). |
Processing | Being processed by the provider. |
Authorized | Authorized, pending capture or settlement. |
Success | Completed successfully. |
Declined | Declined by the provider or issuing bank. |
Cancelled | Cancelled before completion. |
Failed | Failed to process. |
Expired | The reference expired unpaid. |
Always validate id (the unique identifier — store it) and status (the current state). Never rely
on the HTTP status code alone.
Asynchronous flow
SPEI and OXXO are asynchronous: the initial status is always pending because they require a
customer action (completing the transfer or paying at a store).
POST /process/ with the chosen method → 201 Pending + payment_instructions.
Show the customer the CLABE/reference (SPEI) or the voucher (OXXO).
Completes the bank transfer or pays cash at the store.
Receive the webhook (status: success) or poll
GET /api/v1/transactions/{id}/.
