NAV
shell

Introduction

This document describes the Bill Payments API. This API offers a REST service for:

Environments

We have two independent environments for development and production applications.

Quick Start Guide

Once you have an active api-key you can start to use our API to query and pay bills for your customers.

Here is the detail of each service offered by the API:

  1. Authentication

  2. Get available balance

  3. Get available agreements

  4. Query a bill to pay

  5. Pay bill

  6. Get bill payment status

Authentication

cURL Example:

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

curl -v --location 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_bill_payment/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

Get available balance

Endpoint: /merchant/balance

HTTP Method: GET

Description: This service allows to query the available balance and the max loan to continue paying bills.

Example request:

curl -X GET 'https://staging.apiv2.tpaga.co/api/gateway_bill_payment/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 pay bills Integer no
max_loan_amount The max overdraft amount. Integer no
error_message Detailed message related to returned error String yes

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
5XX Internal sever error, it's safe to retry the request

Get available agreements

Endpoint: /utility_providers

HTTP Method: GET

Description: This service returns the current available agreements that can be used to query and pay bills. Includes pagination in case the number of agreements is greater than 500.

Example request:

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

Example response:

{
  "service_providers": [
    {
      "id": "movistar_fijo",
      "name": "Movistar - Fijo",
      "style": {
        "title": "Movistar",
        "icon_url": "https://s3.amazonaws.com/tpaga-wallet-resources/android/promotions/bill_payment_promotion/movistar_fijo_icono.png",
        "description": "",
        "placeholder": "Número de Celular"
      },
      "ean13_biller_code": "7701055000054",
      "is_scannable": true,
      "cost_is_editable": false,
      "is_queriable": true
    },
    {
      "id": "etb",
      "name": "ETB",
      "style": {
        "title": "ETB",
        "icon_url": "https://s3.amazonaws.com/tpaga-wallet-resources/android/promotions/bill_payment_promotion/etb_icono.png",
        "description": "",
        "placeholder": "Referencia de Pago"
      },
      "ean13_biller_code": "7707181500017",
      "is_scannable": true,
      "cost_is_editable": false,
      "is_queriable": true
    },
    {
      "id": "codensa",
      "name": "Codensa",
      "style": {
        "title": "Codensa",
        "icon_url": "https://s3.amazonaws.com/tpaga-wallet-resources/android/promotions/bill_payment_promotion/codensa_icono.png",
        "description": "",
        "placeholder": "Número de Cuenta"
      },
      "ean13_biller_code": "7707209914253",
      "is_scannable": false,
      "cost_is_editable": false,
      "is_queriable": true
    },
    {
      "id": "claro_movil",
      "name": "Claro",
      "style": {
        "title": "Claro",
        "icon_url": "https://s3.amazonaws.com/tpaga-wallet-resources/android/promotions/bill_payment_promotion/claro_icono.png",
        "description": "",
        "placeholder": "Referencia de Pago"
      },
      "ean13_biller_code": "7707175320010",
      "is_scannable": true,
      "cost_is_editable": false,
      "is_queriable": true
    }
  ],
  "categories": [
    {
      "id": "mobile",
      "style": {
        "title": "Celular",
        "icon_url": "https://tpaga-wallet-resources.s3.amazonaws.com/android/promotions/inscribed_bills/mobile.png",
        "description": "Recarga en línea: minutos y datos"
      },
      "service_providers": [
        "claro_movil"
      ]
    },
    {
      "id": "phone",
      "style": {
        "title": "Teléfono",
        "icon_url": "https://tpaga-wallet-resources.s3.amazonaws.com/android/promotions/inscribed_bills/phone.png",
        "description": "Paga tu teléfono fijo"
      },
      "service_providers": [
        "movistar_fijo",
      ]
    },
    {
      "id": "internet",
      "style": {
        "title": "Internet",
        "icon_url": "https://tpaga-wallet-resources.s3.amazonaws.com/android/promotions/inscribed_bills/internet.png",
        "description": "Paga Internet"
      },
      "service_providers": [
        "etb"
      ]
    },
    {
      "id": "power",
      "style": {
        "title": "Luz",
        "icon_url": "https://tpaga-wallet-resources.s3.amazonaws.com/android/promotions/inscribed_bills/power.png",
        "description": "Paga la luz"
      },
      "service_providers": [
        "codensa"
      ]
    },
  ]
}

Request parameters

If the request parameters aren't sent, it returns the first 500 available agreements.

Field Description Type Required
page Page number that it's gonna be shown. Starts at 1. Default to 1 Integer No
per_page Number of items per page. Maximun number is 500. Default to 500 Integer No

Response parameters

Field Description Type Nullable
service_providers List of available agreements List No
service_providers -> id Unique identifier for the agreement on Tpaga's system String No
service_providers -> name Human readable name for the agreement String No
service_providers -> style Suggested icon, title, description, and placeholder for the agreement Json No
service_providers -> style -> title Title for the agreement String No
service_providers -> style -> icon_url URL of the icon for the agreement String No
service_providers -> style -> description Description for the agreement String Yes
service_providers -> style -> placeholder Placeholder text for the agreement. Indicates the value to be captured (e.g., invoice number or account reference) to query the bill. This field is optional and may not always be present. String Yes
service_providers -> ean13_biller_code Optional EAN-13 code of the biller. If not provided, value will be null. String Yes
service_providers -> is_scannable Indicates whether the provider supports barcode scanning to identify the bill or agreement. A True value means the provider allows this functionality. Boolean No
service_providers -> cost_is_editable Indicates whether the payment amount is editable by the user if a value is returned during the query process Boolean No
service_providers -> is_queriable Indicates whether the provider supports querying bills before payment. A True value means the provider allows querying for bill details in advance. Boolean No
categories Grouping of agreements suggested by Tpaga List No
categories -> id Unique identifier for the agreement on Tpaga's system String No
categories -> style Suggested icon, title, and description for the category Json No
categories -> style -> title Title for the category String No
categories -> style -> icon_url URL of the icon for the category String No
categories -> style -> description Description for the category String Yes
categories -> service_providers Unique identifiers of the agreements in the category (list of service_providers -> id). An agreement can belong to more than one category, as some agreements allow paying bills from different categories (e.g., EPM can handle payments for gas and electricity). List No

HTTP responses

Code Description
200 The available agreements 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
5XX Internal sever error, it's safe to retry the request

Query a bill to pay

Endpoint: /utility_providers/<service_provider_id>/bills/<bill_reference>

HTTP Method: GET

Description: This service returns the value for which the bill can be paid.

Example request:

curl -X GET 'https://staging.apiv2.tpaga.co/api/gateway_bill_payment/v1/utility_providers/etb/bills/111100005555/' \
  --header 'Authorization: Bearer <JWT token>'

Example response:

{
  "utility_provider": "etb",
  "short_bill_reference": "111100005555",
  "amount": "12300.00",
  "payable_until": "2022-08-09"
}

Example error response:

{
  "error_message": "Bill has expired",
  "billcheck_error_code": "expired_bill"
}

Request Parameters

Field Description Type Required Max Length Min Length
service_provider_id Agreement identifier. Should be taken from service_providers -> id of the "available agreements" service String Yes 64 1
bill_reference Number printed on the bill used to identify it String Yes 20 1

Response Parameters

Field Description Type Nullable Max Length Min Length
utility_provider Service provider ID received in the request String No 64 1
short_bill_reference Bill reference received in the request String No 20 1
amount Amount for which the bill is available to be paid String No - -
payable_until DEPRECATED - This field will be removed and should not be used None Yes - -
error_message Detailed message related to returned error, check Error Details section String Yes 255 1
billcheck_error_code Internal code to identify an error, check Error Details section String Yes 64 1
field Name of the field that presents errors in the given request body String Yes 64 1

HTTP responses

Code Description
200 The bill was queried successfully.
401 Invalid authorization token.
402 Insufficient funds. Please top up your account and contact support.
403 Insufficient permissions. Contact support.
412 No bill payment providers are enabled for this bill. Contact support.
422 Invalid data provided (details in response body).
5XX Internal server error. Safe to retry.

Error Details

Errors are communicated through error_message and optional fields such as billcheck_error_code and field. Below are common error scenarios:

error_message billcheck_error_code field
Bill has expired expired_bill
There is no bill that matches the given bill_payment_provider and bill_reference bill_does_not_exist
This bill number has already been paid already_paid_bill
Tpaga is having issues with the bill payment service bill_cannot_be_paid
Please try again later try_again_later
Asegúrese de que este campo no tenga más de 20 caracteres. invalid_field_length short_bill_reference
Insufficient funds. Please top up your account and contact support to continue operating.
There is no bill_payment_provider enabled

Test data to query bills

Here are some values that you can send in the bill_reference field to generate many API responses.

For the service_provider_id field you can use any of the returned by the "available agreements" service

bill_reference Description HTTP response code
111100005555 Bill is available to be paid 200
000000 Bill is available to be paid and the amount is not fixed 200
dummy412 There is no bill payment providers enabled for this bill 412
dummy422-does-not-exist Generates the bill_does_not_exist error code 422
dummy422-expired-bill Generates the expired_bill error code 422
dummy422-already-paid-bill Generates the already_paid_bill error code 422
dummy422-try-again Generates the `dummy422- error code 422
dummy422-cannot-be-paid Generates the bill_cannot_be_paid error code 422

Pay bill

Endpoint: /pay_bill

HTTP Method: POST

Description: This service allows the client to pay previously queried bills.

Example request:

curl -X POST 'https://staging.apiv2.tpaga.co/api/gateway_bill_payment/v1/pay_bill' \
  --header 'Authorization: Bearer <JWT token>' \
  --header 'Content-Type: application/json' \
  --data-raw '{
      "idempotency_token": "some-random-and-unique-token-12f12",
      "amount": 12300,
      "utility_provider": "etb",
      "short_bill_reference": "111100005555",
      "payment_token": "external_unique_token_12dd3",
      "payment_origin": "Test API client 1"
  }'

Example response:

{
  "token": "bpm-h1q2kyqdoshji95bm14fxfie3f7j",
  "idempotency_token": "some-random-and-unique-token-12f12",
  "short_bill_reference": "111100005555",
  "utility_provider": "etb",
  "amount": 12300,
  "payment_token": "external_unique_token_12dd3",
  "payment_origin": "Test API client 1",
  "route": "MOVILRED",
  "external_gateway_auth_code": null,
  "gateway_bill_payment_token": null,
  "status": "AUTHORIZED",
  "result_code": null,
  "bank_transaction_id": "dummy_bank_tx_id",
  "payment_provider_data": {}
}

Request parameters

Field Description Type Min Length Max Length Required
idempotency_token A unique identifier for the transaction. Use this token to retry transactions safely String 1 128 Yes
amount Amount for which the bill will be paid. This value must be the same received when querying the bill Integer 1 19 Yes
utility_provider Agreement identifier. Should be taken from service_providers -> id of the "available agreements" service String 1 64 Yes
short_bill_reference Number printed on the bill used to identify it. String 1 20 Yes
payment_origin Identifier for the external system where the payment for this bill was performed. E.g., "API_WALLET" String 1 64 Yes
payment_token Identifier for the payment in the external system. E.g., an API wallet promotion purchase token. String 1 255 Yes

Response parameters

Field Description Type Min Length Max Length Nullable
token A unique internal identifier for the transaction. This token is primarily used for future processes, such as verifying the status of a specific bill payment if an issue occurs. String 1 32 No
idempotency_token The idempotency token received in the request. This value is sent by the client to ensure that repeated requests do not result in duplicate transactions. It is echoed in the response to maintain traceability. String 1 128 No
short_bill_reference Bill reference received in the request String 1 20 No
utility_provider Utility provider received in the request String 1 64 No
amount Amount received in the request Integer - - No
payment_token Payment token received in the request String 1 255 No
payment_origin Payment origin received in the request String 1 64 No
route Payment provider used to pay the bill String 1 20 No
external_gateway_auth_code Authorization code for the bill payment issued by the payment provider String 1 128 Yes
gateway_bill_payment_token Internal transaction identifier String 1 128 Yes
status Status of the transaction. See Transaction statuses for details String 1 40 No
result_code Internal code representing transaction. See Result Code for details Integer 1 4 Yes
bank_transaction_id Transaction identifier in the Bank's system String 1 24 Yes
payment_provider_data Additional information for the transaction related to the provider used JSON - - Yes
error_message Detailed message related to returned error String 1 500 Yes
field Name of the field that presents errors in the given request body String 1 100 Yes

Result Code

The result_code field in the response provides a numeric representation of the transaction outcome. Each code corresponds to a specific status or error condition, helping identify the reason for success, failure, or special circumstances. Refer to the table below for the possible result codes and their meanings:

Code Description
0 The transaction succeeded.
10 The transaction met the same conditions as a previous one, no changes made.
13 The provided amount is invalid.
15 There was an error with the payment provider.
16 An unknown error occurred with the payment provider.
82 The bill does not exist.
84 The bill has already been paid.
90 The transaction was failed.
8000 The payment value does not match the value for the bill provided by the payment provider.

HTTP responses

Code Description
200 The bill was paid successfully
401 Invalid authorization token was provided
402 You have no funds. Please top up your account and contact our support team to keep operating
403 You do not have enough permissions to perform this action, please contact the support team
409 There is another bill payment transaction with the same idempotency_token, their status will be returned
422 You did not provide valid data for this operation, please check response body for details
503 Bill payment rejected by the provider. Check response body for details
5XX Internal sever error, it's safe to retry the request using de same idempotency_token

Transaction Statuses

Test data to pay bills

Here are some values that you can send in the bill_reference field to generate many API responses.

For the utility_provider field you can use any of the service_provider_id returned by the "available agreements" service.

bill_reference Description Transaction status HTTP response code
111100005555 The bill payment was performed successfully AUTHORIZED 200
000000 The bill payment was performed successfully and the amount can be different from the returned by the "Query Bill" service AUTHORIZED 200
111100001111 The bill payment is being processed in other request, try again later to get a final status IN_PROGRESS 409
111100003333 The bill payment failed. It's safe to retry the transacion with a new idempotency_token REJECTED 503
111100004444 There was an error processing the transactions. Contact Tpaga and do not retry the transaction to avoid duplicated payments UNKNOWN 502

Get bill payment status

Endpoint: /bill_payment_transactions/<idempotency_token>

HTTP Method: GET

Description: This service is useful to get the updated status of a bill payment transaction on IN_PROGRESS or UNKNOWN status.

Example request:

curl -X GET 'https://staging.apiv2.tpaga.co/api/gateway_bill_payment/v1/bill_payment_transactions/some-random-and-unique-token-944' \
  --header 'Authorization: Bearer <JWT token>'

Example response:

{
  "token": "bpm-0cj5j7d1blbygel2x97ez9hagtzw",
  "idempotency_token": "some-random-and-unique-token-944",
  "short_bill_reference": "111100005555",
  "utility_provider": "etb",
  "amount": 1300,
  "payment_token": "external_unique_token_12dd34",
  "payment_origin": "Test API client 1",
  "route": "MOVILRED",
  "external_gateway_auth_code": null,
  "gateway_bill_payment_token": null,
  "status": "AUTHORIZED",
  "result_code": null,
  "bank_transaction_id": "dummy_bank_tx_id",
  "payment_provider_data": {}
}

Request parameters

Field Description Type Required
idempotency_token The idempotency_token to create the transaction in the "Pay bill" service String Yes

Response parameters

The response body is the same to the "Pay Bill" service.

HTTP responses

Code Description
200 The bill payment 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 response body for details
5XX Internal sever error, it's safe to retry the request