Introduction
This document describes the One Time Payments (OTP) API. This API offers a REST service for:
- Create OTP codes
- Consult OTP codes information
- Expire an OTP code
We also can configure a webhook to notify the API clients when a OTP code status has changed. See the Webhook section for details.
Environments
We have two independent environments for development and production applications.
- Staging:
https://staging.apiv2.tpaga.co/api/otp/v1/
- Production:
https://production.apiv2.tpaga.co/api/otp/v1/
Flow chart
Quick Start Guide
Once you have an active access_token you can start to use our API to create OTP codes.
Here is the detail of each service offered by the API:
Authentication
cURL Example:
CLIENT_ID="qXUC0u5pdw2709ez8v3ok4pKDy2xB5Qp88keqkz1"
CLIENT_SECRET="Lxr5zR1RExoo5bBFInW2fi0dTY1YxymuSVrqkDVslQASpQoxb4YYRd1QttpI4xEfBXNnjJeB2PfPd01wpNanJGalRjiX4F1Z4cWcerASjWCnDDOubUWwUtIdClhH3eZa"
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/otp/v1/otp' \
--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
Create code
Endpoint: /code
HTTP Method: POST
Description: This service allows to create a new OTP code that will be available to be consumed by a merchant.
Example request:
curl -X POST 'https://staging.apiv2.tpaga.co/api/otp/v1/code' \
--header 'Authorization: Bearer <JWT token>' \
--header 'Content-Type: application/json' \
--data-raw '{
"lifetime_minutes": 10,
"amount": 5000,
"user_document_type": "CC",
"user_document_number": "12345678"
}'
Example response:
{
"code": "6759815",
"authorization_code": null,
"order_id": null,
"status": "active",
"amount": "5000.00",
"settled_amount": null,
"expires_at": "2022-10-25T16:25:25.812767Z",
"created_at": "2022-10-25T16:15:25.912957Z",
"user_document_type": "CC",
"user_document_number": "12345678",
"consumer_name": null
}
Request parameters
Field | Description | Type | Required |
---|---|---|---|
amount | Maximum amount for which the code can be used to pay | Integer | yes |
lifetime_minutes | Time in minutes in which the OTP will be considered "active" and will be available to be used | String | yes |
user_document_type | Identification type of the user for which the OTP was created for. Accepted values: CC, CE, NIT, TI, PA and Other | String | no |
user_document_number | Identification number of the user for which the OTP was created for | String | no |
Response parameters
Field | Description | Type | Nullable |
---|---|---|---|
code | OTP code | String | no |
authorization_code | Internal identifier for the transaction related with the OTP code | String | yes |
order_id | Identifier for the transaction related with the OTP code on the Merchant's system that consumed the code | String | yes |
status | Current status of the code. See Code statuses section for details | String | no |
amount | Amount for which the code was created | Decimal | no |
settled_amount | Final amount for which the code was consumed | Decimal | yes |
expires_at | Expiration date of the code in ISO format and UTC timezone | Date | no |
created_at | Date of creation of the code in ISO format and UTC timezone | Date | no |
lifetime_minutes | Total minutes the code will be considered active and ready to be consumed | Integer | no |
user_document_type | Identification type of the user for which the code was created for | String | yes |
user_document_number | Identification number of the user for which the code was created for | String | yes |
consumer_name | Name of the merchant that consumed the code | String | yes |
error_message | Detailed message related to returned error | String | yes |
field | Name of the field that presents errors in the given request body | String | yes |
value | Value received in the field that presents errors | String | yes |
HTTP responses
Code | Description |
---|---|
201 | The OTP code was created successfully |
401 | Invalid authorization token provided |
403 | You do not have enough permissions to perform this action, please contact the support team |
409 | There was an error creating the OTP code, it's safe to try again |
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 |
Test data to create OTP and receive webhook notification
Here are the values that you can send in the user_document_number
field to generate a webhook notification, to have a better description see Webhook .
For the lifetime_minutes
and amount
fields you can send the usual data as it's explain in Create code.
user_document_number | Description | Code status will be set to | HTTP response code |
---|---|---|---|
successful_transaction | The OTP was consumed successfully and a webhook notification is sent. | settled | 201 |
authorized_transaction | Code status will be set to authorized and since it’s not a final status, no webhook notification is sent. This is a transitory status and it will be unusual you get this status in a response when requesting OTP information. |
authorized | 201 |
cancelled_transaction | The OTP code will be cancelled and a webhook notification is sent. | cancelled | 201 |
reverted_transaction | The OTP code will be set as reverted and a webhook notification is sent. |
reverted | 201 |
After receive the webhook notification, you can request Get code information to have extended information about the OTP code.
Get code information
Endpoint: /code/code
HTTP Method: GET
Description: This service allows to consult all the information of an OTP code.
Example request:
curl -X GET 'https://staging.apiv2.tpaga.co/api/otp/v1/code/1234567' \
--header 'Authorization: Bearer <JWT token>'
Example response:
{
"code": "6759815",
"authorization_code": "random-token-123",
"order_id": "order123",
"status": "settled",
"amount": "5000.00",
"settled_amount": "5000.00",
"expires_at": "2022-10-25T16:25:25.812767Z",
"created_at": "2022-10-25T16:15:25.912957Z",
"user_document_type": "CC",
"user_document_number": "12345678",
"consumer_name": "Merchant Test"
}
Request parameters
Field | Description | Type | Required |
---|---|---|---|
code | OTP code to be consulted | String | yes |
Response parameters
Field | Description | Type | Nullable |
---|---|---|---|
code | OTP code | String | no |
authorization_code | Internal identifier for the transaction related with the OTP code | String | yes |
order_id | Identifier for the transaction related with the OTP code on the Merchant's system that consumed the code | String | yes |
status | Current status of the code. See Code statuses section for details | String | no |
amount | Amount for which the code was created | Decimal | no |
settled_amount | Final amount for which the code was consumed | Decimal | yes |
expires_at | Expiration date of the code in ISO format and UTC timezone | Date | no |
created_at | Date of creation of the code in ISO format and UTC timezone | Date | no |
lifetime_minutes | Total minutes the code will be considered active and ready to be consumed | Integer | no |
user_document_type | Identification type of the user for which the code was created for | String | yes |
user_document_number | Identification number of the user for which the code was created for | String | yes |
consumer_name | Name of the merchant that consumed the code | String | yes |
error_message | Detailed message related to returned error | String | yes |
field | Name of the field that presents errors in the given request body | String | yes |
value | Value received in the field that presents errors | String | yes |
HTTP responses
Code | Description |
---|---|
200 | The OTP code was queried successfully |
401 | Invalid authorization token 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 |
Expire code
Endpoint: /code/expire
HTTP Method: POST
Description: This service allows to expire an OTP code before its expiration date is reached in order to prevent users to use it.
Example request:
curl -X POST 'https://staging.apiv2.tpaga.co/api/otp/v1/otp' \
--header 'Authorization: Bearer <JWT token>' \
--header 'Content-Type: application/json' \
--data-raw '{
"code": "1234567"
}'
Example response:
{
"code": "6759815",
"authorization_code": null,
"order_id": null,
"status": "expired",
"amount": "5000.00",
"settled_amount": null,
"expires_at": "2022-10-25T16:25:25.812767Z",
"created_at": "2022-10-25T16:15:25.912957Z",
"user_document_type": "CC",
"user_document_number": "12345678",
"consumer_name": null
}
Request parameters
Field | Description | Type | Required |
---|---|---|---|
code | An active code to be expired | String | yes |
Response parameters
Field | Description | Type | Nullable |
---|---|---|---|
code | OTP code | String | no |
authorization_code | Internal identifier for the transaction related with the OTP code | String | yes |
order_id | Identifier for the transaction related with the OTP code on the Merchant's system that consumed the code | String | yes |
status | Current status of the code. See Code statuses section for details | String | no |
amount | Amount for which the code was created | Decimal | no |
settled_amount | Final amount for which the code was consumed | Decimal | yes |
expires_at | Expiration date of the code in ISO format and UTC timezone | Date | no |
created_at | Date of creation of the code in ISO format and UTC timezone | Date | no |
lifetime_minutes | Total minutes the code will be considered active and ready to be consumed | Integer | no |
user_document_type | Identification type of the user for which the code was created for | String | yes |
user_document_number | Identification number of the user for which the code was created for | String | yes |
consumer_name | Name of the merchant that consumed the code | String | yes |
error_message | Detailed message related to returned error | String | yes |
field | Name of the field that presents errors in the given request body | String | yes |
value | Value received in the field that presents errors | String | yes |
HTTP responses
Code | Description |
---|---|
200 | The OTP code was expired successfully |
401 | Invalid authorization token provided |
403 | You do not have enough permissions to perform this action, please contact the support team |
409 | There was an error expiring the OTP code, it's safe to try again |
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 |
Webhook
This service allows the client API to receive notifications via HTTP requests when an OTP has reached a final status.
This is an example of the request that we will send to the configured API client endpoint:
curl -X POST 'https://clienthost.com/some/defined/endpoint' \
--header 'Content-Type: application/json' \
--data-raw '{
"otp_code": "1234567"
}'
How it works
When an OTP code reaches a final status (settled
, reverted
or cancelled
) an HTTP POST request will be sent to a (previously configured) client endpoint. That request will have the following body:
Field | Description | Type |
---|---|---|
otp_code | Otp code that has reached a final status | String |
When a webhook notification is sent, the API client should use the received otp_code along with the Get code information endpoint to get the complete information related to the code.
Code statuses
- active: The code is ready to be used.
- expired: The code has expired and cannot be used.
- authorized: The merchant has queried the code to check the max amount for which it can be used.
- settled: The code was consumed by a merchant successfully.
- reverted: The transaction related with the code was reverted by the merchant. In this case you should revert the transaction also in your system if you already debited your user's payment method.
- cancelled: The merchant cancelled the transaction after check the max amount for which the code can be used.