NAV
shell

Introduction

This document describes the API to make mobile top ups and buy mobile packages. This API offers a REST service to:

Environments

For publishing of these services Tpaga provides two environments:

Authentication

cURL Example:

CLIENT_ID="neZi59dZrKaUdblk4LvbB391wuzXlzyc65aaBH8r"
CLIENT_SECRET="Ib5m6r0SqLqolkWM7yQ8aBitVRwypDonVcJ4fYn4gD3qIXIX5b683y3gUio9T8Ukau1QEZYvBnNrjoYWC8V0Z5Oag4XXc7P9ny21LD0D8n40fg3JVHH8mJiJf52sPKwh"
AUTH_STRING=$(echo -n "$CLIENT_ID:$CLIENT_SECRET" | base64 | tr -d '\n')

curl -v --location --request POST 'https://staging.apiv2.tpaga.co/o/token/' \
  --header "Authorization: Basic $AUTH_STRING" \
  --header 'Content-Type: application/x-www-form-urlencoded' \
  --data-urlencode 'grant_type=client_credentials'

A successful response returns a JSON object in the following format:

{
  "access_token": "<JWT token>",
  "token_type": "Bearer",
  "expires_in": 3600,
  "scope":"read write"
}

An example of a valid request sending the Bearer token:

curl -X GET 'https://staging.apiv2.tpaga.co/api/gateway_topup/v1/merchant/balance' \
  --header 'Authorization: Bearer <JWT token>'

Example to revoke an access token:

curl -X POST 'https://staging.apiv2.tpaga.co/o/revoke_token/' \
  --header 'Content-Type: application/x-www-form-urlencoded' \
  --data-urlencode 'token=<JWT token>' \
  --data-urlencode 'client_id=<your-client-id>' \
  --data-urlencode 'client_secret=<your-client-secret>'

This API uses OAuth 2.0 with JWT-based access tokens. Clients must first obtain an access token using the client credentials flow and then include it in subsequent API requests via the Authorization header.

Obtaining an Access Token

Endpoint: /o/token/

HTTP Method: POST

Description: To obtain an access token, send a POST request to the /o/token/ endpoint using HTTP Basic Authentication with your client credentials. Your CLIENT_ID and CLIENT_SECRET must be combined, base64-encoded, and included in the Authorization header.

Request Parameters

Field Description Type Nullable
grant_type The OAuth2 grant type. Must be set to client_credentials. String No

Note: Client credentials are provided via the HTTP Basic Authentication header.

Response Parameters

Field Description Type Nullable
access_token The generated JWT token String No
token_type The type of token, e.g. "Bearer" String No
expires_in The duration (in seconds) for which the token is valid Integer No

HTTP Responses

Code Description
200 The access token was issued successfully.
400 The request is missing required parameters or includes invalid values.
401 Client authentication failed.

Using the Access Token

Include the obtained JWT access token in the Authorization header for subsequent API requests

Token Expiration and Renewal

Access tokens are valid for a limited period (as specified by the expires_in value). We recommend caching your access token and reusing it until it is near expiration. Avoid requesting a new token on every API call. When the token is close to expiring, request a new one to maintain uninterrupted service.

Revoking an Access Token

Endpoint: /o/revoke_token/

HTTP Method: POST

Description: If you need to revoke an access token, send a POST request to the /o/revoke_token/ endpoint.

Request Parameters

Field Description Type Nullable
token The access token to be revoked. String No
client_id The client ID. String No
client_secret The client secret. String No

Response Parameters

The response body is empty if the token revocation is successful.

HTTP Responses

Code Description
200 The access token was revoked successfully. The response body will be empty.
400 The request is missing required parameters or is malformed.
401 Client authentication failed.
404 The provided token was not found.

Environment Considerations

Transaction statuses

Every top up and every mobile package purchase has one of the following statuses. The API always returns them in uppercase.

Status Final status Description
AUTHORIZED Yes The top up or the package purchase was performed successfully.
REJECTED Yes The top up or the package purchase failed. Check the response body for details. You can send a new request with a new idempotency_token and Tpaga will treat it as a new, different attempt.
UNKNOWN No There was a communication issue with the provider, so the result is not known yet.
IN_PROGRESS No The transaction is being processed. For example, you can receive it when you query a transaction after your request timed out.
CREATED No The transaction was registered, but its processing did not finish because of an internal error.

The following diagram shows how the statuses change:

Transaction statuses

Integration guidelines

Follow these guidelines when you buy a top up (POST /topup_account) or a mobile package (POST /package_buy).

The following diagram summarizes how to handle the response of a purchase:

Purchase flow

Timeouts

We suggest a timeout of 30 seconds for purchase requests.

Status queries

Query the status of a purchase with Get top up information or Get purchase information when the purchase request timed out, failed with an error, or returned a status that is not final.

For example, query right after the timeout or the error (minute 0), then at minute 5 and at minute 15. These are waits of 5 and 10 minutes.

Idempotency

The idempotency_token identifies each purchase. Use a value that you never reuse, such as a UUID.

Reversals and cancellations

The API does not offer reversals or cancellations of top ups or mobile package purchases, and there is no channel to request them.

Errors

When a request fails, the response body describes the error.

Validation errors

Example of a validation error (422):

{
    "error_message": "Este campo no puede estar en blanco.",
    "field": "payment_token",
    "value": ""
}

When the response code is 422, the body has these fields:

Field Description Type Always present
error_message Description of the error String Yes
field Name of the field that caused the error. It is non_field_errors when the error is not about a specific field, for example when the request body is not a JSON object String Yes
value Value of that field in your request. It is only included when the field is part of the request body Same type as the value you sent No

If several fields are invalid, the response describes only one of them.

Other errors

Example of a 402 response:

{
    "error_message": "You have no funds. Please top up your account and contact our support team to keep operating. Thank you."
}

Other errors, such as 401, 402 and 403, return a body with only the error_message field.

Example of a 500 response:

{
    "error_message": "Unknown error",
    "error_token": "error-7xk2m9q4w1z8c3v6b0n5h2j4rt"
}

An unexpected error (500) returns error_message with the value Unknown error, and an error_token field.

Top up services

  1. Get available balance
  2. Get top up providers
  3. Make a mobile top up
  4. Get top up information
  5. Get history Top Up
  6. Testing

Get available balance

Endpoint: /merchant/balance

HTTP Method: GET

Description: This service returns the available balance and the maximum loan amount.

Example request:

curl -X GET 'https://staging.apiv2.tpaga.co/api/gateway_topup/v1/merchant/balance' \
  --header 'Authorization: Bearer <JWT token>'

Example response:

{
  "balance": 0,
  "max_loan_amount": 0
}

Request parameters

This endpoint does not need extra parameters to be sent in the request.

Response parameters

Field Description Type Nullable
balance The current balance that the merchant can use to buy top ups and packages Integer no
max_loan_amount The max overdraft amount. Integer no

HTTP responses

Code Description
200 The merchant balance was queried successfully
401 Invalid authorization token was provided
403 You do not have enough permissions to perform this action, please contact the support team
503 Your account is not properly configured, please contact the support team
5XX Internal server error, it's safe to retry the request

Get top up providers

Example Request:

curl -X GET \
 https://staging.apiv2.tpaga.co/api/gateway_topup/v1/service_providers \
 -H 'Authorization: Bearer <JWT token>'

Example Response:

{
    "service_providers": [
        {
            "slug": "movistar",
            "name": "Movistar",
            "icon_url": "https://some-icon-url.com"
        },
        {
            "slug": "claro-movil",
            "name": "Claro Móvil",
            "icon_url": "https://some-icon-url.com"
        },
        {
            "slug": "avantel",
            "name": "Avantel",
            "icon_url": "https://some-icon-url.com"
        },
        {
            "slug": "uff-movil",
            "name": "Uff Móvil",
            "icon_url": "https://some-icon-url.com"
        },
        {
            "slug": "etb",
            "name": "ETB",
            "icon_url": "https://some-icon-url.com"
        },
        {
            "slug": "tigo",
            "name": "Tigo",
            "icon_url": "https://some-icon-url.com"
        }
    ]
}

Endpoint: /service_providers

HTTP Method: GET

Description: This service returns the current available providers.

Request parameters

This endpoint does not need extra parameters to be sent in the request.

Response parameters

Field Description Type Nullable
service_providers List of available providers List No
service_providers -> slug Unique internal identifier for the provider String No
service_providers -> name Human-readable name for the provider String No
service_providers -> icon_url Suggested icon for the provider String Yes

Make a mobile top up

Endpoint: /topup_account

HTTP Method: POST

Description: This service tops up the given phone number.

Example request:

curl -X POST \
 https://staging.apiv2.tpaga.co/api/gateway_topup/v1/topup_account \
 -H 'Authorization: Bearer <JWT token>' \
 -H 'Content-Type: application/json' \
 -d '{
    "idempotency_token": "85ab25a1-6389-4737-b91b-0f7ddbc73e9a",
    "amount": 1000,
    "service_provider": "etb",
    "destination_number": "3110001111",
    "payment_token": "wallet-11233dafd",
    "payment_origin": "My company"
 }'

Example response:

{
    "token": "topup-4n8c2x7q1m5z9v3b6k0j2h8wdr",
    "idempotency_token": "85ab25a1-6389-4737-b91b-0f7ddbc73e9a",
    "destination_number": "3110001111",
    "service_provider": "etb",
    "amount": 1000,
    "payment_token": "wallet-11233dafd",
    "payment_origin": "My company",
    "route": "PUNTORED",
    "external_gateway_auth_code": "526268936",
    "gateway_topup_token": "ppr-9t3k7m1x5c8v2b6n0q4z7j1h5w3d",
    "status": "AUTHORIZED",
    "result_code": 0
}

Request parameters

Field Description Type Required
destination_number Mobile phone number, without country code: 10 or 12 digits. For DirecTV, send the DirecTV account number instead: only digits, up to 12. Tpaga completes it with zeros on the left, when necessary. String yes
service_provider Service provider slug. Use one of the slugs returned by Get top up providers String yes
amount Top up amount in Colombian pesos (COP), as an integer without decimals. It must be a multiple of 100. The minimum and maximum amounts are configured for each client and agreed during onboarding Integer yes
idempotency_token A unique identifier for the transaction. See Idempotency String - max. 128 characters yes
payment_origin Name of the system where the transaction was generated. Send your company's name here String - max. 64 characters yes
payment_token Unique identifier for the transaction in your system String - max. 255 characters yes

If destination_number does not have 10 or 12 digits, the API answers 422 with field: mobile_number. The transaction is registered as REJECTED, so its idempotency_token cannot be used again: send the corrected purchase with a new idempotency_token.

Response parameters

Field Description Type Nullable
token Internal identifier for the transaction String No
idempotency_token Idempotency token received in the request String No
destination_number Mobile phone number received in the request String No
service_provider Service provider slug String No
amount Top up amount Integer No
payment_token payment_token received in the request String No
payment_origin payment_origin received in the request String No
status Status of the transaction. See Transaction statuses for details String No
result_code Internal code representing transaction status Integer Yes

HTTP responses

Code Description
200 The request was processed. Check the status field: only AUTHORIZED means that the top up was performed successfully.
401 Invalid authorization token was provided
402 Your available funds (balance plus credit limit) are already exhausted. Top up your account to keep operating
403 You do not have enough permissions to perform this action, please contact the support team
409 A top up with the same idempotency_token already exists. The body contains that transaction with its current status. See Idempotency
422 Invalid parameters. See Validation errors and Idempotency
500 Unexpected error. Query the top up status with Get top up information. Take into account that sending a top up with a new idempotency_token will be treated as a new, different top up attempt.
502 The result is unknown (UNKNOWN). It is not a final status: do not treat it as declined. After the status query window, wait for the reconciliation process, according to the procedure agreed during your onboarding
503 (with a transaction body) The top up was rejected (REJECTED)
503 (without a transaction body) Your account is not properly configured, please contact the support team

Error Details

When the response code is 422, the body follows the format described in Validation errors. A repeated idempotency_token is not a validation error in top ups: see Idempotency.

Example Errors

Field Description Example Value Example Error Message
service_provider The mobile operator may be disabled or not really exist invalid-operator Objeto con slug=invalid-operator no existe.
destination_number They send the field empty or blank Este campo no puede estar en blanco
mobile_number The number does not have 10 or 12 digits. 09516588 Este valor no coincide con el patrón requerido.
payment_token They send the field empty or blank. Este campo no puede estar en blanco.
payment_origin They send the field empty or blank. Este campo no puede estar en blanco.
amount The amount is below the minimum configured for your account. 600 El monto de la recarga no puede ser menor a 1000.00.
amount The amount exceeds the maximum configured for your account. 110000 El monto de la recarga no puede ser mayor a 100000.00.
amount The transaction amount is not divisible by 100. 6548 Ensure the given value (6548) is divisible by 100.

Get top up information

Endpoint: /topup_account/

HTTP Method: GET

Description: This service returns a top up transaction.

Example request:

curl --location --request GET 'https://staging.apiv2.tpaga.co/api/gateway_topup/v1/topup_account/85ab25a1-6389-4737-b91b-0f7ddbc73e9a' \
  --header 'Authorization: Bearer <JWT token>' \
  --header 'Content-Type: application/json'

Example response:

{
    "token": "topup-4n8c2x7q1m5z9v3b6k0j2h8wdr",
    "idempotency_token": "85ab25a1-6389-4737-b91b-0f7ddbc73e9a",
    "destination_number": "3110001111",
    "service_provider": "etb",
    "amount": 1000,
    "payment_token": "wallet-11233dafd",
    "payment_origin": "My company",
    "route": "PUNTORED",
    "external_gateway_auth_code": "526268936",
    "gateway_topup_token": "ppr-9t3k7m1x5c8v2b6n0q4z7j1h5w3d",
    "status": "AUTHORIZED",
    "result_code": 0
}

Request parameters

Field Description Type Required
idempotency_token The idempotency_token used to create the transaction in the "Make a mobile top up" service String Yes

Response parameters

Field Description Type Nullable
token Internal identifier for the transaction String No
idempotency_token Idempotency token received in the request String No
destination_number Mobile phone number received in the request String No
service_provider Service provider slug String No
amount Top up amount Integer No
payment_token payment_token received in the request String No
payment_origin payment_origin received in the request String No
route Internal processing route of the transaction String No
external_gateway_auth_code Authorization code of the transaction, when it is available String Yes
gateway_topup_token Internal reference of the request sent to process the top up, when it is available String Yes
status Status of the transaction. See Transaction statuses for details String No
result_code Internal code representing transaction status Integer Yes

HTTP responses

Code Description
200 The top up was queried successfully
401 Invalid authorization token was provided
403 You do not have enough permissions to perform this action, please contact the support team
422 The top up queried by the idempotency_token does not exist.
5XX Internal server error, it's safe to retry the request

Get history Top Up

Endpoint: /topup_account/transactions

HTTP Method: GET

Description: This endpoint returns the history of top ups made by a client of the API. It supports paginated queries and date range filtering.

Example request:

curl --location --request GET 'https://staging.apiv2.tpaga.co/api/gateway_topup/v1/topup_account/transactions?page=1&per_page=50&start_date=2026-10-01&end_date=2026-10-31' \
  --header 'Authorization: Bearer <JWT token>' \
  --header 'Content-Type: application/json'

Example response:

{
    "count": 3,
    "transactions": [
        {
            "idempotency_token": "85ab25a1-6389-4737-b91b-0f7ddbc73e9a",
            "destination_number": "3110001111",
            "payment_origin": "My company",
            "service_provider": "etb",
            "amount": 1000,
            "status": "AUTHORIZED",
            "date_created": "2026-10-29 09:20:29"
        },
        {
            "idempotency_token": "f5bbcc29-bd7e-404f-b732-a99a1eee5dd1",
            "destination_number": "3110005555",
            "payment_origin": "My company",
            "service_provider": "claro-movil",
            "amount": 2000,
            "status": "REJECTED",
            "date_created": "2026-10-29 10:05:12"
        },
        {
            "idempotency_token": "324b2346-c01f-4b41-ab8f-4cc6fe8590de",
            "destination_number": "3110002222",
            "payment_origin": "My company",
            "service_provider": "movistar",
            "amount": 5000,
            "status": "UNKNOWN",
            "date_created": "2026-10-30 14:48:03"
        }
    ]
}

Request parameters

Use page and per_page to paginate the results. Transactions are sorted by creation date, from the oldest to the newest.

Use start_date and end_date to filter by creation date. Both dates are in Colombia time (UTC-5), and both are included: the range goes from 00:00:00 of start_date to the end of end_date. If you send one of them, the other is required. start_date cannot be later than end_date.

Field Description Type Required Default
page Page number. Minimum value: 1 Integer No 1
per_page Number of transactions per page. Minimum value: 1 Integer No 200
start_date First day of the range, in YYYY-MM-DD format, in Colombia time (UTC-5) String No
end_date Last day of the range, in YYYY-MM-DD format, in Colombia time (UTC-5) String No

Response parameters

Field Description Type Nullable
count Total transactions made by the API Client or within the selected range. Integer No
transactions List of current transactions List No
transactions -> idempotency_token Idempotency token received in the request String No
transactions -> destination_number Mobile phone number received in the request String No
transactions -> service_provider Service provider slug String No
transactions -> amount Top up amount Integer No
transactions -> payment_origin payment_origin received in the request String No
transactions -> status Status of the transaction. See Transaction statuses for details String No
transactions -> date_created Creation date of the transaction, in Colombia time (UTC-5), in YYYY-MM-DD HH:MM:SS format String No

HTTP responses

Code Description
200 The list of transactions was queried successfully
401 Invalid authorization token was provided
403 You do not have enough permissions to perform this action, please contact the support team
422 Invalid parameters sent
5XX Internal server error, it's safe to retry the request

Testing

The API offers test phone numbers to assist you in the development and certification process. Send the following phone numbers in your requests to simulate different scenarios. These numbers only work in the staging environment.

Phone number Description HTTP code
3110001111 The top up was performed successfully (AUTHORIZED) 200
3110002222 The result of the top up is unknown (UNKNOWN). It is not a final status: see Transaction statuses 502
3110004444 A request with the same idempotency_token is still being processed. The body contains the transaction in IN_PROGRESS. See Idempotency 409
3110005555 The provider rejected the top up (REJECTED). You can send a new request with a new idempotency_token 503

Mobile packages services

  1. Get mobile package providers
  2. Get mobile packages
  3. Purchase a mobile package
  4. Get purchase information
  5. Get history purchases
  6. Test data

Get mobile package providers

Endpoint: /mobile_package_service_providers_list

HTTP Method: GET

Description: This service returns the mobile package providers that are currently available for purchases. Only enabled providers are listed.

Example request:

curl -X GET 'https://staging.apiv2.tpaga.co/api/gateway_topup/v1/mobile_package_service_providers_list' \
  --header 'Authorization: Bearer <JWT token>'

Example response:

{
    "service_providers": [
        {
            "name": "TIGO",
            "provider_code": "3",
            "operator_logo_url": "https://storage.googleapis.com/bucket-faas/suppliers/3.webp",
            "enabled": true
        },
        {
            "name": "CLARO PAQUETES",
            "provider_code": "58",
            "operator_logo_url": "https://storage.googleapis.com/bucket-faas/suppliers/58.webp",
            "enabled": true
        },
        {
            "name": "VIRGIN MOBILE PAQUETES",
            "provider_code": "72",
            "operator_logo_url": "https://storage.googleapis.com/bucket-faas/suppliers/72.webp",
            "enabled": true
        },
        {
            "name": "MOVISTAR PAQUETES",
            "provider_code": "30",
            "operator_logo_url": "https://storage.googleapis.com/bucket-faas/suppliers/30.webp",
            "enabled": true
        }
    ]
}

Request parameters

Use page and per_page to paginate the results. The list has no defined order, so when you paginate, a provider can appear on more than one page or be missing. To get the complete list, request it in a single page, with a per_page value of 200.

Field Description Type Required Default
page Page number. Minimum value: 1 Integer No 1
per_page Number of providers per page. Minimum value: 1 Integer No 200

Response parameters

Field Description Type Nullable
service_providers List of available service providers List No
service_providers -> provider_code Unique identifier for the provider on Tpaga's system String No
service_providers -> name Name of provider String No
service_providers -> operator_logo_url URL of the icon to be displayed on the apps String No
service_providers -> enabled Indicates if the service provider is available. Boolean No

HTTP responses

Code Description
200 The service providers were queried successfully
401 Invalid authorization token was provided
403 You do not have enough permissions to perform this action, please contact the support team
422 Invalid parameters sent
5XX Internal server error, it's safe to retry the request

Get mobile packages

Endpoint: /packages

HTTP Method: GET

Description: This endpoint returns the mobile packages currently available for purchase. It can return all the current mobile packages, or only the packages of a specific service provider.

Example request:

curl --location --request GET 'https://staging.apiv2.tpaga.co/api/gateway_topup/v1/packages' \
  --header 'Authorization: Bearer <JWT token>' \
  --header 'Content-Type: application/json'

Example request with specific service provider:

curl --location --request GET 'https://staging.apiv2.tpaga.co/api/gateway_topup/v1/packages?provider_identifier=58' \
  --header 'Authorization: Bearer <JWT token>' \
  --header 'Content-Type: application/json'

Example response:

{
    "packages": [
        {
            "name": "200 MINUTOS A TODO OPERADOR",
            "description": "200 MNTS O 20DIAS",
            "amount": 9900,
            "validity": "20 DÍAS",
            "package_code": "024",
            "sku": "50015",
            "category_code": "9",
            "category_description": "HABLAR",
            "provider_code": "58"
        },
        {
            "name": "18 MINUTOS A VENEZUELA - $5.000",
            "description": "18MIN_A_VNZLA-30D",
            "amount": 5000,
            "validity": "30 DÍAS",
            "package_code": "353",
            "sku": "50050",
            "category_code": "9",
            "category_description": "HABLAR",
            "provider_code": "58"
        },
        {
            "name": "1.5 GB DE NAVEGACION + MUNUTOS Y MENSAJES ILIMI. + REDES SOCIALES (WHATSAPP FACEBOOK TWITTER) + 7 DIAS POR $7.500",
            "description": "1.5GB_MIN ILIMT+7D",
            "amount": 7500,
            "validity": "7 DIAS",
            "package_code": "767",
            "sku": "50130",
            "category_code": "7",
            "category_description": "TODO INCLUIDO",
            "provider_code": "58"
        },
        {
            "name": "TODO INCLUIDO CON MINUTOS ILIMITADOS CHAT DE WHATSAPP FACEBOOK Y TWITTER  12GB POR 30 DIAS",
            "description": "12GB/ILIMITADO_30D",
            "amount": 41000,
            "validity": "30 DIAS",
            "package_code": "939",
            "sku": "50148",
            "category_code": "7",
            "category_description": "TODO INCLUIDO",
            "provider_code": "58"
        }
    ]
}

Request parameters

Use provider_identifier to get only the packages of one service provider.

Use page and per_page to paginate the results. Packages are sorted by category, but packages of the same category have no defined order, so when you paginate, a package can appear on more than one page or be missing. To get the complete list, request it in a single page, with a per_page value of 200.

Field Description Type Required Default
provider_identifier Service provider identifier. Should be taken from service_providers -> provider_code of the Get mobile package providers service String No
page Page number. Minimum value: 1 Integer No 1
per_page Number of packages per page. Minimum value: 1 Integer No 200

Response parameters

Field Description Type Nullable
packages List of current packages List No
packages -> name Full package description String No
packages -> description Short package description String No
packages -> amount Package value Integer No
packages -> validity The period of validity of the package - E.g, "30 DÍAS" String No
packages -> package_code Unique identifier for the package on Tpaga's system String No
packages -> sku A unique identification number String Yes
packages -> category_code Identifier of the category from the package String No
packages -> category_description Category description of package String No
packages -> provider_code Unique identifier for the provider on Tpaga's system String No

HTTP responses

Code Description
200 The list of packages was queried successfully
401 Invalid authorization token was provided
403 You do not have enough permissions to perform this action, please contact the support team
422 You did not provide valid data for this operation, please check parameters
5XX Internal server error, it's safe to retry the request

Purchase a mobile package

Endpoint: /package_buy

HTTP Method: POST

Description: This service allows the client to buy a mobile package.

Example request:

curl --location --request POST 'https://staging.apiv2.tpaga.co/api/gateway_topup/v1/package_buy' \
 --header 'Authorization: Bearer <JWT token>' \
 --header 'Content-Type: application/json' \
 --data-raw '{
     "destination_number": "3110001111",
     "provider_code": "58",
     "amount": 7500,
     "idempotency_token": "8aefa051-1383-4d23-bb5c-55d5584746ab",
     "payment_token": "wallet-11233dafd",
     "package_code": "767"
 }'

Example response:

{
    "idempotency_token": "8aefa051-1383-4d23-bb5c-55d5584746ab",
    "destination_number": "3110001111",
    "amount": 7500,
    "payment_token": "wallet-11233dafd",
    "package_code": "767",
    "provider_code": "58",
    "route": "PUNTORED",
    "external_gateway_auth_code": "526268936",
    "status": "AUTHORIZED",
    "result_code": 0
}

Request parameters

Field Description Type Required
idempotency_token A unique identifier for the transaction. See Idempotency String - max. 128 characters Yes
amount Package amount in Colombian pesos (COP), as an integer without decimals. Send the amount of the package, as returned by Get mobile packages. The minimum and maximum amounts are configured for each client and agreed during onboarding Integer Yes
provider_code Service provider identifier. Should be taken from service_providers -> provider_code of the Get mobile package providers service String Yes
destination_number Mobile phone number to apply the package String Yes
payment_token Identifier for the payment in your system String - max. 255 characters Yes
package_code Package identifier. Should be taken from packages -> package_code of the Get mobile packages service String Yes

If destination_number is not a valid mobile number, the API answers 422 with field: mobile_number. The transaction is registered as REJECTED, so its idempotency_token cannot be used again: send the corrected purchase with a new idempotency_token.

Response parameters

Field Description Type Nullable
idempotency_token Idempotency token received in the request to purchase the package String No
destination_number Mobile number received in the request to purchase the package String No
amount Amount received in the request to purchase the package Integer No
payment_token Payment token received in the request to purchase the package String No
package_code Package code received in the request to purchase the package String No
provider_code Service Provider received in the request to purchase the package String No
status Status of the transaction. See Transaction statuses for details String No
result_code Internal code representing transaction status Integer Yes

HTTP responses

Code Description
200 The request was processed. Check the status field: only AUTHORIZED means that the package was purchased successfully.
401 Invalid authorization token was provided
402 Your available funds (balance plus credit limit) are already exhausted. Top up your account to keep operating
403 You do not have enough permissions to perform this action, please contact the support team
409 A purchase with the same idempotency_token is being processed or was already answered. Query its status with Get purchase information
422 Invalid parameters, including an idempotency_token that already exists. See Validation errors and Idempotency
500 Unexpected error. Query the purchase status with Get purchase information. Take into account that sending a purchase with a new idempotency_token will be treated as a new, different purchase attempt.
502 The result is unknown (UNKNOWN). It is not a final status: do not treat it as declined. After the status query window, wait for the reconciliation process, according to the procedure agreed during your onboarding
503 (with a transaction body) The purchase was rejected (REJECTED)
503 (without a transaction body) Your account is not properly configured, please contact the support team

Error Details

When the response code is 422, the body follows the format described in Validation errors.

Example Errors

Field Description Example Value Example Error Message
idempotency_token A package request is being sent with an idempotency that already exists wb-n001dbfqc60t Ya existe un/a mobile package transaction con este/a idempotency token.
provider_code The mobile operator does not match the package being sent 58 El service_provider se debe corresponder con el mobile_package.
provider_code The mobile operator may be disabled 58 El operador móvil del paquete no está habilitado.
provider_code The mobile operator not really exist 58 Objeto con provider_code=58 no existe
provider_code The package is disabled 58 El paquete móvil no está habilitado.
package_code The package not exist 767 Objeto con package_code=767 no existe
destination_number They send the field empty or blank Este campo no puede estar en blanco
mobile_number The number does not have 10 characters long. 301486565 Este valor no coincide con el patrón requerido.
payment_token They send the field empty or blank. Este campo no puede estar en blanco.
amount The amount is below the minimum configured for your account. 600 El monto del paquete no puede ser menor a 1000.00.
amount The amount exceeds the maximum configured for your account. 110000 El monto del paquete no puede ser mayor a 100000.00.

Get purchase information

Endpoint: /package_buy/

HTTP Method: GET

Description: This service returns a mobile package purchase transaction.

Example request:

curl --location --request GET 'https://staging.apiv2.tpaga.co/api/gateway_topup/v1/package_buy/8aefa051-1383-4d23-bb5c-55d5584746ab' \
  --header 'Authorization: Bearer <JWT token>' \
  --header 'Content-Type: application/json'

Example response:

{
    "idempotency_token": "8aefa051-1383-4d23-bb5c-55d5584746ab",
    "destination_number": "3110001111",
    "amount": 7500,
    "payment_token": "wallet-11233dafd",
    "package_code": "767",
    "provider_code": "58",
    "route": "PUNTORED",
    "external_gateway_auth_code": "526268936",
    "status": "AUTHORIZED",
    "result_code": 0
}

Request parameters

Field Description Type Required
idempotency_token The idempotency_token used to create the transaction in the "Purchase a mobile package" service String Yes

Response parameters

Field Description Type Nullable
idempotency_token Idempotency token received in the request to purchase the package String No
destination_number Mobile number received in the request to purchase the package String No
amount Amount received in the request to purchase the package Integer No
payment_token Payment token received in the request to purchase the package String No
package_code Package code received in the request to purchase the package String No
provider_code Service Provider received in the request to purchase the package String No
status Status of the transaction. See Transaction statuses for details String No
result_code Internal code representing transaction status Integer Yes

HTTP responses

Code Description
200 The purchase was queried successfully, whatever its status. Check status in the body
401 Invalid authorization token was provided
403 You do not have enough permissions to perform this action, please contact the support team
422 The purchase queried by the idempotency_token does not exist
5XX Internal server error, it's safe to retry the request

Get history purchases

Endpoint: /package_buy/transactions

HTTP Method: GET

Description: This endpoint returns the purchase history of packages made by a client of the API. It supports paginated queries and date range filtering.

Example request:

curl --location --request GET 'https://staging.apiv2.tpaga.co/api/gateway_topup/v1/package_buy/transactions?page=1&per_page=50&start_date=2026-10-01&end_date=2026-10-31' \
  --header 'Authorization: Bearer <JWT token>' \
  --header 'Content-Type: application/json'

Example response:

{
    "count": 3,
    "transactions": [
        {
            "idempotency_token": "8aefa051-1383-4d23-bb5c-55d5584746ab",
            "destination_number": "3110001111",
            "amount": 7500,
            "package_code": "767",
            "provider_code": "58",
            "status": "AUTHORIZED",
            "created_at": "2026-10-29 11:20:02"
        },
        {
            "idempotency_token": "bc2cee0c-b1f2-4033-b02f-cc07fa4d8c00",
            "destination_number": "3110000000",
            "amount": 9900,
            "package_code": "024",
            "provider_code": "58",
            "status": "REJECTED",
            "created_at": "2026-10-29 16:42:37"
        },
        {
            "idempotency_token": "0084ee14-27b8-452c-a886-8f4ceb57270d",
            "destination_number": "3110006666",
            "amount": 5000,
            "package_code": "353",
            "provider_code": "58",
            "status": "UNKNOWN",
            "created_at": "2026-10-30 08:15:44"
        }
    ]
}

Request parameters

Use page and per_page to paginate the results. Transactions are sorted by creation date, from the oldest to the newest.

Use start_date and end_date to filter by creation date. Both dates are in Colombia time (UTC-5), and both are included: the range goes from 00:00:00 of start_date to the end of end_date. If you send one of them, the other is required. start_date cannot be later than end_date.

Field Description Type Required Default
page Page number. Minimum value: 1 Integer No 1
per_page Number of transactions per page. Minimum value: 1 Integer No 200
start_date First day of the range, in YYYY-MM-DD format, in Colombia time (UTC-5) String No
end_date Last day of the range, in YYYY-MM-DD format, in Colombia time (UTC-5) String No

Response parameters

Field Description Type Nullable
count Total transactions made by the API Client or within the selected range. Integer No
transactions List of current transactions List No
transactions -> idempotency_token Idempotency token received in the request to purchase the package String No
transactions -> destination_number Mobile number received in the request to purchase the package String No
transactions -> amount Amount received in the request to purchase the package Integer No
transactions -> package_code Package code received in the request to purchase the package String No
transactions -> provider_code Service Provider received in the request to purchase the package String No
transactions -> status Status of the transaction. See Transaction statuses for details String No
transactions -> created_at Creation date of the transaction, in Colombia time (UTC-5), in YYYY-MM-DD HH:MM:SS format String No

HTTP responses

Code Description
200 The list of transactions was queried successfully
401 Invalid authorization token was provided
403 You do not have enough permissions to perform this action, please contact the support team
422 Invalid parameters sent
5XX Internal server error, it's safe to retry the request

Test data

Because third-party providers sometimes have problems with test environments, the API offers test phone numbers to assist in the development and certification process. These numbers only work in the staging environment.

Destination Number Description HTTP code
3110001111 The mobile package was purchased successfully (AUTHORIZED) 200
3110006666 The result of the purchase is unknown (UNKNOWN). It is not a final status: see Transaction statuses 502
3110000000 The provider rejected the purchase (REJECTED). You can send a new request with a new idempotency_token 503

Changelog

This changelog starts at version 1.1.0. Changes made before that version are not listed.

1.1.0 — 2026-11-06

All the changes in this version are backward compatible. The API itself did not change: this version updates the documentation to describe the current behavior of the API.

Added

Clarified

Fixed

Removed