Digital Payment Integration Guidelines - Indonesia
This document specifies the protocols operated between Airpay PLATFORM and the content provider or merchant system.
This document is intended for merchants who want to integrate Indonesian Digital Payment payments through a Single API provided by Airpay, using payment gateway. This integration allows you to accept payments from multiple Indonesian digital wallets using a standardized and efficient process.
This integration is a solution that simplifies the process of integrating multiple Digital Payment into a single unified API. With this approach, merchants or partners only need to integrate with one standardized endpoint, without having to deal with technical differences of each individual Digital Payment provider.
This is the supported Digital Payment can used in Indonesia
| No. | Digital Payment | Category | Method | Code | Status |
|---|---|---|---|---|---|
| 1 | DANA | E-Wallet | EWALLET | DANA | Available |
| 2 | OVO | E-Wallet | EWALLET | OVO | Proccess |
| 3 | ShopeePay | E-Wallet | EWALLET | SHOPEEPAY | Available |
| 4 | LinkAja | E-Wallet | EWALLET,DEBIT | LINKAJA | Available |
| 5 | QR | QR | QR | QRIS | Available |
| 6 | MANDIRI | Virtual Account | VA | MANDIRI | Available |
| 7 | BRI | Virtual Account | VA | BRI | Available |
| 8 | BNI | Virtual Account | VA | BNI | Available |
| 9 | INA | Virtual Account | VA | INA | Available |
| 10 | BCA | Virtual Account | VA | BCA | Available |
| 11 | DANAMON | Virtual Account | VA | DANAMON | Available |
| 12 | CIMB NIAGA | Virtual Account | VA | CIMB | Available |
| 13 | PANIN | Virtual Account | VA | PANIN | Available |
| 14 | SINARMAS | Virtual Account | VA | SINARMAS | Available |
| 15 | PERMATA | Virtual Account | VA | PERMATA | Proccess |
| 16 | Maybank | Virtual Account | VA | MAYBANK | Proccess |
| 17 | INDOMARET PAYMENT POINT | Virtual Account | VA | INDOMARET | Available |
Below are the base URLs for each environment.
| Environment | Base URL |
|---|---|
| Sandbox | https://stagingapi.airpay.mobi |
| Production | https://api.airpay.mobi |
Before requesting an Auth Token or calling any Digital Payment API, a merchant must first complete onboarding and register the service on the Airpay dashboard. The client_id and client_secret used in the Authentication step below are only issued once this process is done.
client_id and client_secret for that service via email. These are the credentials used to obtain the Auth Token described in the next section.Calling the API before onboarding is approved, before the service is registered, or before the registered service itself is approved will result in an authentication error, since no client_id/client_secret will exist yet for that merchant/service combination.
The client_id and client_secret below are only issued after onboarding is approved and the service you registered is approved and active. See the Onboarding & Service Registration section above if you haven't done this yet.
Before calling the Digital Payment API, merchant must obtain an Auth Token first.
The client_id and client_secret are provided by Airpay via email during merchant onboarding. Use these credentials to request an access_token from the Token endpoint below, then use that token as a Bearer token in the Authorization header when calling the Digital Payment API.
Exchange client_id and client_secret (provided by Airpay via email) for a token, sent via HTTP Basic Auth. Use the returned token as a Bearer token in the Authorization header when calling the Digital Payment API.
Sample request:
https://site.com/api/v2/ext/ID/DANA/games/2611263d-2406-489c-9042-abcsd76f9b/token/
PATH PARAMETERS:
| Name | TYPE | Required | Description | Example Value |
|---|---|---|---|---|
country |
string ≤50 | Required |
Country Code | ID |
channel |
string ≤50 | Required |
Payment Channel | OVO |
service |
string ≤50 | Required |
Service Type | games |
apiKey |
string ≤50 | Required |
Merchant API Key | YOUR_API_KEY |
HEADERS (BASIC AUTH):
| Name | TYPE | Required | Description | Example Value |
|---|---|---|---|---|
username |
string | Required |
Client ID | YOUR_CLIENT_ID |
password |
string | Required |
Client Secret | YOUR_CLIENT_SECRET |
Error Response List:
| Error Code | Error Message |
|---|---|
| 401 | Invalid client_id or client_secret |
| country required | string <= 50 characters Country Name |
| channel required | string <= 50 characters Channel type Ex. (DANA, OVO) |
| service_ewallet required | string <= 50 characters Service name |
| apiKey required | string <= 150 characters Your API key |
curl --request GET \ --url {domain}/api/v2/ext/{country}/{channel}/{service}/{apiKey}/token/ \ --header 'accept: application/json' \ --user 'YOUR_CLIENT_ID:YOUR_CLIENT_SECRET'
{- "code": "200",
- "message": "Success",
- "data": {
- "token": "fcf33833-a4d1-4fb1-a55e-b2023031ed99"
}
}This API will using to merchant who want to integration to Digital Payment in Indonesia using payment gateway
Merchant must obtain an Auth Token first (see Get Auth Token) before calling this API, and pass it via the Authorization: Bearer <token> header.
Sample request:
https://xxx.xxxxxx.xxxx/api/v2/ext/ID/DANA/games/ewallet/request
Sample header:
apikey: 2611263d-2406-489c-9042-abcsd76f9b
authorization: Bearer YOUR_TOKEN
Error Response List:
| Error Code | Error Message |
|---|---|
| 400 | Bad request |
| 500 | Internal system error |
| 900 | Invalid signature |
| 901 | Invalid token |
| 902 | Token expired |
| 903 | Invalid channel |
| 904 | Invalid telco |
| 905 | Invalid service id |
| 906 | Invalid msisdn |
| 907 | Invalid OTP |
| 9071 | Invalid OTP key, not found or expired |
| 9072 | Invalid OTP value or not found |
| 908 | Channel not active |
| 909 | Telco not active |
| 910 | Service id not active |
| 911 | Duplicate trxid |
| 912 | Invalid Source or source may not register to this service |
| country required | string <= 50 characters Country Name |
| channel required | string <= 50 characters Channel type Ex. (DANA, OVO) |
| service_ewallet required | string <= 50 characters Service name |
| apikey required | string <= 50 characters Api Key |
| authorization required | string Example: Bearer YOUR_TOKEN Bearer access token obtained from the Token endpoint (see Authentication section) |
| name required | string <= 50 characters User name |
| email required | string <= 50 characters User email |
| msisdn required | string <= 50 characters User msisdn |
| amount required | string <= 50 characters Service amount |
| description required | string <= 50 characters Description text |
| currency required | string <= 50 characters Currency type (Ex: IDR, USD etc) |
| payment_method required | string <= 50 characters Payment method (Ex: QR, INVOICE - uppercase only). The description can be read in chapter 2 |
| card_number required | string <= 50 characters Card number |
| card_name required | string <= 50 characters Card name |
| cvc required | string <= 50 characters CVC number |
| expired_date required | string <= 50 characters Expired date |
| order_number required | string <= 50 characters Order number |
| address1 | string <= 50 characters User address 1 |
| address2 | string <= 50 characters User address 2 |
| postcode | string <= 50 characters Post Code |
| trxid | string <= 50 characters Transaction ID |
| clickid required | string <= 50 characters Click ID |
| pubid required | string <= 50 characters Publisher ID |
| return_url required | string <= 50 characters The return url after success payment |
{- "name": "John Doe",
- "email": "john.doe@example.com",
- "msisdn": "628123456789",
- "amount": "10000",
- "description": "Payment for service",
- "currency": "IDR",
- "payment_method": "QR",
- "card_number": "1234567890123456",
- "card_name": "John Doe",
- "cvc": "123",
- "expired_date": "12/25",
- "order_number": "ORD123456789",
- "address1": "Jl. Sudirman No. 1",
- "address2": "Jakarta Pusat",
- "postcode": "10110",
- "trxid": "TRX123456789",
- "clickid": "CLICK123456",
- "pubid": "PUB123456",
}{- "code": 200,
- "message": "success",
- "data": {
- "trxid": "LINKIT25061750660948",
- "trx_date": "2025-06-23 06:42:27 UTC",
- "data_return": "https://Digital Payment.redirection"
}
}Postback URL: Reply URL at CP Server (If Applicable) for Receiving postback
Example. 1 ) http://partner.com/callback
Note: Each merchant must provide only one postback URL. The furnished URLs should be intended for production purposes.
Whenever a transaction's payment status changes (e.g. a payment completes or fails), Airpay will notify the merchant by sending an HTTP POST request with a JSON body to the postback URL registered by the merchant (see Merchant Integration Requirements above).
The merchant's endpoint is expected to respond with OK once the callback has been received successfully.
This is not an Airpay endpoint — it is the URL the merchant hosts and registers as their postback URL (see Merchant Integration Requirements above). Airpay calls it to notify the merchant of a payment status change.
status_desc values:
| Value | Description |
|---|---|
| PENDING | Payment has not been completed yet |
| PAID | Payment completed successfully |
| FAILED | Payment failed |
| EXPIRED | Payment expired before it was completed |
| CANCELED | Payment was canceled |
| apikey required | string Merchant API key |
| country required | string Country code |
| channel required | string Channel type Ex. (DANA, OVO) |
| service required | string Service name |
| trxid required | string Transaction ID from LINKIT360 |
| trx_date required | string Transaction date, format YYYY-MM-DD HH:MM:SS TZ |
| status_code required | string HTTP-style status code of the callback itself |
| status_desc required | string Payment status — see the values listed above |
{- "apikey": "2611263d-2406-489c-9042-abcsd76f9b",
- "country": "ID",
- "channel": "DANA",
- "service": "games",
- "trxid": "LINKIT25061750660948",
- "trx_date": "2025-06-23 06:42:27 UTC",
- "status_code": "200",
- "status_desc": "PAID"
}