NAV
shell

Introduction

This document describes the API used to receive payments from the Tpaga Wallet, using OTP (One Time Password) payment codes.

Depending on the use case you are trying to implement, you have two different options to process payments using OTP payments: (please check with our team before deciding which option to use. We will help based on your particular case).

  1. Immediate capture-settle. (In one step).
  2. Authorize first then settle. This option is mostly used when you want to authorize a charge first (maybe because you don't know the final amount yet) and then, after you deliver your product/service, you can settle the final amount.

Before calling /authorize or /capture, call POST /info to obtain the OTP amount and related data. /info does not consume the OTP.

1. Immediate capture-settle

Overview of the payment process

The sequence of operations required to receive a payment from a Tpaga Wallet user is as follows:

The sequence of events is shown in the diagram below:

Capture flow

2. Authorize first then settle

It is possible to receive a payment by authorizing it, and then settling it (these two operations together have the same effect as capturing the OTP as explained before). Receiving a payment in this fashion allows you to check earlier in the transaction that a given OTP actually has enough funds to cover the cost of the purchase.

The sequence of operations to receive a payment in this fashion is the following:

The sequence of events is shown in the diagram below:

Authorize then settle flow

Requirements

Environments

We have two independent environments for development and production applications.

Authentication

To use this API you must have an API key, which Tpaga will provide you, both for our staging (sandbox) and production environments.

Once you have it, you can authenticate your requests by adding the Authorization HTTP header, and passing the API key as the value for that header.

Example: if your key is mak-1234512345, send:

Authorization: mak-1234512345

Example request with API key:

curl -X POST 'https://stag.wallet.tpaga.co/api/v1/otp/info' \
  --header 'Authorization: mak-1234512345' \
  --header 'Content-Type: application/json' \
  --data-raw '{
    "payment_code": "1234567",
    "additional_data": {
      "TipoDoc": "CC",
      "Documento": "1019053548"
    }
  }'

Cashout: receiver identification

For cashout (cash withdrawal) OTPs, from August 2026 the person at the kiosk must be the same wallet user who created the OTP. Send TipoDoc and Documento so Tpaga can verify they match the OTP owner.

Required fields in additional_data

You must send inside additional_data:

Field Required Rule
TipoDoc Yes (cashout from August 2026) Document type of the receiver. Accepted values: CC, CE, PA. Must match the OTP owner (case-insensitive).
Documento Yes (cashout from August 2026) Exact document number of the OTP owner. Leading zeros are not normalized (0123123).

Example additional_data:

{
  "TipoDoc": "CC",
  "Documento": "1019053548",
  "Nombres": "ANA",
  "Apellidos": "PEREZ"
}

Where it applies

Endpoint Validates TipoDoc / Documento
POST /info Yes (from August 2026; check Cashout: receiver identification for more details)
POST /authorize Yes (from August 2026; check Cashout: receiver identification for more details)
POST /capture Yes (from August 2026; same rules as authorize)
POST /settle No — requires a prior successful /authorize or /capture with TipoDoc and Documento
  1. User creates cashout OTP in app
  2. Merchant POST /info (+ TipoDoc, Documento)
  3. Merchant POST /authorize (+ TipoDoc, Documento)
  4. Merchant delivers cash
  5. Merchant POST /settle (authorization_code + amount + order_id)

Alternative: POST /capture with TipoDoc and Documento in one call.

Validation errors (cashout from August 2026)

Example HTTP 422:

{
  "error_code": 422,
  "error_message": "Se requiere TipoDoc y Documento en additional_data",
  "field_name": "additional_data",
  "rejected_value": {}
}
Situation HTTP error_message
Missing TipoDoc and/or Documento 422 Se requiere TipoDoc y Documento en additional_data
Document does not match OTP owner 422 La identificación del receptor no coincide con la del titular del código
OTP owner has no identification in wallet 422 No se puede procesar el retiro en este momento. Por favor indique al usuario que se comunique con soporte de Tpaga
Settle without prior authorize/capture with validated ID 403 La liquidación requiere autorización previa con identificación del receptor validada

Example HTTP 403 on /settle:

{
  "error_code": 403,
  "error_message": "La liquidación requiere autorización previa con identificación del receptor validada",
  "additional_data": {
    "authorization_code": "<token>"
  }
}

Services

Get code information (/info)

Endpoint: /info

HTTP Method: POST

Description: Returns information about an OTP without consuming it. Safe to call multiple times. Guarantees existence of the code, not availability of funds. Call this endpoint to obtain the OTP amount before /authorize or /capture.

For cashout from August 2026, send TipoDoc and Documento to validate the receiver (check Cashout: receiver identification for more details). Failure returns 422.

Example request:

curl -X POST 'https://stag.wallet.tpaga.co/api/v1/otp/info' \
  --header 'Authorization: <merchant_api_key>' \
  --header 'Content-Type: application/json' \
  --data-raw '{
    "payment_code": "1234567",
    "additional_data": {
      "TipoDoc": "CC",
      "Documento": "1019053548"
    }
  }'

Request parameters

Field Type Required Description
payment_code String Yes OTP shown by the wallet user
additional_data Object Conditional For cashout from August 2026: must include TipoDoc and Documento (check Cashout: receiver identification for more details)

HTTP responses

Code Description
200 Code information returned
401 Missing or invalid API key
404 Code not found or expired
422 Validation error (including receiver identification for cashout from August 2026)
503 Temporary failure; safe to retry

Authorize (/authorize)

Endpoint: /authorize

HTTP Method: POST

Description: Reserves the OTP amount for the merchant. Completes the purchase later with /settle.

For cashout from August 2026, additional_data must include matching TipoDoc and Documento (check Cashout: receiver identification for more details). On failure returns 422 and does not authorize.

Example request:

curl -X POST 'https://stag.wallet.tpaga.co/api/v1/otp/authorize' \
  --header 'Authorization: <merchant_api_key>' \
  --header 'Content-Type: application/json' \
  --data-raw '{
    "payment_code": "1234567",
    "purchase_amount": 50000,
    "purchase_order_id": "ORDER-123456789",
    "additional_data": {
      "TipoDoc": "CC",
      "Documento": "1019053548"
    }
  }'

HTTP responses

Code Description
200 Authorized; returns authorization_code
401 Missing or invalid API key
402 Insufficient funds
404 Code not found, expired, or already used
422 Validation error (including TipoDoc/Documento)
502 / 503 Upstream or temporary failure

Settle (/settle)

Endpoint: /settle

HTTP Method: POST

Description: Finalizes a previously authorized OTP. Amount must be ≤ authorized amount.

For cashout from August 2026, /settle does not ask again for TipoDoc / Documento. It requires a prior successful /authorize (or /capture) with those fields. Otherwise returns 403 (check Cashout: receiver identification for more details).

Example request:

curl -X POST 'https://stag.wallet.tpaga.co/api/v1/otp/settle' \
  --header 'Authorization: <merchant_api_key>' \
  --header 'Content-Type: application/json' \
  --data-raw '{
    "authorization_code": "<token_from_authorize>",
    "purchase_amount": 50000,
    "purchase_order_id": "ORDER-123456789"
  }'

HTTP responses

Code Description
200 Settled
401 Missing or invalid API key
403 Cashout from August 2026: missing prior validated receiver identification
404 Authorization code not found or expired
422 Validation error
503 Temporary failure; safe to retry

Capture (/capture)

Endpoint: /capture

HTTP Method: POST

Description: Authorize + settle in a single request.

For cashout from August 2026, same TipoDoc / Documento rules as /authorize (check Cashout: receiver identification for more details).

Example request:

curl -X POST 'https://stag.wallet.tpaga.co/api/v1/otp/capture' \
  --header 'Authorization: <merchant_api_key>' \
  --header 'Content-Type: application/json' \
  --data-raw '{
    "payment_code": "1234567",
    "purchase_amount": 50000,
    "purchase_order_id": "ORDER-123456789",
    "additional_data": {
      "TipoDoc": "CC",
      "Documento": "1019053548"
    }
  }'

HTTP responses

Same family as /authorize (including 422 for receiver identification failures).

Cancel (/cancel)

Endpoint: /cancel

HTTP Method: POST

Description: Voids a payment and returns funds to the wallet user when applicable. Allowed within 24 hours of creation.

Revert (/revert)

Endpoint: /revert

HTTP Method: POST

Description: Same effect as cancel, but identified by purchase_order_id when you do not have the authorization_code.

About OTP codes

Errors

Error Code Meaning
400 Bad Request -- Your request is invalid.
401 Unauthorized -- Your API key is wrong.
402 Payment Required -- Insufficient funds.
403 Forbidden -- Not allowed (e.g. settle without validated receiver ID on migrated cashout).
404 Not Found -- The specified resource could not be found.
409 Conflict -- The OTP was already authorized/canceled/settled.
422 Unprocessable Entity -- Validation error (including TipoDoc/Documento on migrated cashout).
502 Bad Gateway -- Upstream payment system failure.
503 Service Unavailable -- Temporary failure; safe to retry.
500 Internal Server Error -- We had a problem with our server. Try again later.