Direct API (S2S)

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
FieldTypeDescription
operation_typestringMust be "payment" to process a payment.
amountdecimalAmount using a dot as the decimal separator (e.g. 100.00).
currencystringCurrency: "MXN", "USD" or "CLP". Mexico and Chile use the same flow; only this value changes.
customerobjectCustomer info, with at least name and email.
payment_methodobjectMethod config, with type and method-specific parameters.
client_referencestringYour 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:

StatusDescription
PendingThe transaction is being processed (common for asynchronous payments).
ProcessingBeing processed by the provider.
AuthorizedAuthorized, pending capture or settlement.
SuccessCompleted successfully.
DeclinedDeclined by the provider or issuing bank.
CancelledCancelled before completion.
FailedFailed to process.
ExpiredThe 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}/.

Next steps

Was this page helpful?

On this page