Skip to main content

Digital Payment Integration Guidelines - India

Introduction

Unify Core — Digital Payment API v2 is a service that enables merchants to accept digital payments through e-wallets in India — both one-time and recurring payments — including refunds and the full periodic billing cycle.

All endpoints (except Get Token and the callback endpoints) require two things in the header: the Authorization: Bearer {token} and the apikey.

Important notes:

  • Obtain the token via Get Token before calling any other endpoint.
  • The token is scoped to the apikey + channel + service combination; use the same channel & service on subsequent endpoints.
  • Required headers on request endpoints: Authorization: Bearer {token} and apikey.
  • For GET methods, the apikey is still read from the header by the middleware, even though it is commonly included in the query as well.
  • Pay In is used for one-time payments; recurring payments use Payin Recurring.
  • Check Mandate Status before Trigger Charge Recurring, because the customer may unsubscribe after the predebit was sent.
  • Values inside curly braces { } must be replaced with actual values when making the call.
  • The apikey and client secret are confidential — do not share them with unauthorized parties.

Supported Digital Payment

This is the supported Digital Payment can used in India

No. Digital Payment Category Method Code Status
1 UPI E-Wallet EWALLET UPI Available
2 PhonePe E-Wallet EWALLET PHONEPE Available
3 GooglePay E-Wallet EWALLET GOOGLEPAY Available
4 Paytm E-Wallet EWALLET PAYTM Available

Environment

Below are the base URLs for each environment.

Environment Base URL
Sandbox https://stagingapi.airpay.mobi/
Production https://api.airpay.mobi/

Authentication

Before calling the Digital Payment API, merchant must obtain an Auth Token first.

Basic Auth (Get Token only) — the Get Token endpoint uses HTTP Basic Auth, where the username is the client id and the password is the client secret, sent as header Authorization: Basic {basicAuth}.

Bearer Token + apikey (all other endpoints) — the token from Get Token is used on all subsequent request endpoints, together with the apikey header:

Authorization: Bearer {token}
apikey: {apiKey}

The token is scoped to the apikey + channel + service combination. A token obtained for one channel/service is not valid for another combination — make sure the channel & service in the path of subsequent endpoints exactly match the ones used when running Get Token.

Get Token

Obtain a token using client id & client secret. In Postman the token is automatically saved to the token variable via a test script, then used on the subsequent endpoints.

Sample request: https://api.airpay.mobi/api/v2/ext/ID/OVO/PULSA/2611263d-2406-489c-9042-abcsd76f9b/token/

Authorizations:
BasicAuth
path Parameters
country
required
string <= 50 characters

Country code in the path, example: ID

channel
required
string <= 50 characters

Channel code, example: OVO. Must match the one used when obtaining the token.

service
required
string <= 50 characters

Service code, example: PULSA. Must match the one used when obtaining the token.

apiKey
required
string <= 150 characters

Merchant API key

Responses

Request samples

curl --request GET \
  --url {domain}/api/v2/ext/{country}/{channel}/{service}/{apiKey}/token/ \
  --header 'accept: application/json' \
  --user 'YOUR_CLIENT_ID:YOUR_CLIENT_SECRET'

Response samples

Content type
application/json
{
  • "code": "200",
  • "message": "Success",
  • "data": {
    }
}

Recurring Cycle Explained

Once the recurring payment is registered, the following sequence forms one recurring billing cycle:

  • Initiation — Payin Recurring then Notification Initiate Payment (MO): indicates the recurring payment has been initiated by the customer.
  • D-1 — Predebit: the system notifies the customer that their balance will be debited the next day.
  • Before execution — Mandate Status: the mandate status is checked first, because the customer may unsubscribe after the predebit was sent.
  • D — Trigger Charge Recurring: if the mandate is still active, the balance debit is executed.
  • After the charge — Notification Charge (DN): the debit result is notified to the merchant system.

IMPORTANT: Always check the Mandate Status before running Trigger Charge Recurring. A predebit that has been sent does not guarantee the mandate is still active on the debit day.

Service Aggregator API Specs

Payin (Ewallet) - One Time

One-time e-wallet payment. The customer pays a certain amount through an e-wallet for a single transaction, with no follow-up billing.

Result: an e-wallet payment transaction is created. The final status is delivered via the Ewallet Callback (POST {domain}/api/v2/ext/ewallet/callback, sent by PayU).

Authorizations:
(ApiKeyAuthbearerAuth)
path Parameters
country
required
string <= 50 characters

Country code in the path, example: ID

channel
required
string <= 50 characters

Channel code, example: OVO. Must match the one used when obtaining the token.

service
required
string <= 50 characters

Service code, example: PULSA. Must match the one used when obtaining the token.

query Parameters
msisdn
required
string <= 50 characters

Customer phone number, example: 628123456789

amount
required
string <= 50 characters

Payment / debit / refund amount

order_number
required
string <= 100 characters

Merchant order number, example: ORD-20260627-001

trxid
required
string <= 150 characters

Merchant/related transaction ID, example: TRX20260627001

currency
required
string <= 10 characters

Currency, example: IDR

cycle
string <= 50 characters

Billing cycle, example: daily / ADHOC

header Parameters
apikey
required
string <= 50 characters

Merchant API key (still required in the header, even for GET requests)

Authorization
required
string
Example: Bearer YOUR_TOKEN

Bearer access token obtained from the Get Token endpoint

Responses

Response samples

Content type
application/json
{
  • "code": 200,
  • "message": "success",
  • "data": {}
}

Payin (Ewallet) - One Time (POST)

POST alternative for the one-time e-wallet payment request, using a JSON body.

Authorizations:
(ApiKeyAuthbearerAuth)
path Parameters
country
required
string <= 50 characters

Country code in the path, example: ID

channel
required
string <= 50 characters

Channel code, example: OVO. Must match the one used when obtaining the token.

service
required
string <= 50 characters

Service code, example: PULSA. Must match the one used when obtaining the token.

header Parameters
apikey
required
string <= 50 characters

Merchant API key (still required in the header, even for GET requests)

Authorization
required
string
Example: Bearer YOUR_TOKEN

Bearer access token obtained from the Get Token endpoint

Request Body schema: application/json
name
string <= 50 characters

User name

email
string <= 50 characters

User email

msisdn
required
string <= 50 characters

Customer phone number

amount
required
number

Payment amount

description
string <= 100 characters

Payment description

currency
required
string <= 10 characters

Currency

return_url
string

The return url after success payment

payment_method
string <= 50 characters

Payment method

order_number
required
string <= 50 characters

Merchant order number

trxid
required
string <= 50 characters

Merchant transaction ID

Responses

Request samples

Content type
application/json
{
  • "name": "John Doe",
  • "email": "john@example.com",
  • "msisdn": "628123456789",
  • "amount": 50000,
  • "description": "Payment for service",
  • "currency": "IDR",
  • "payment_method": "ewallet",
  • "order_number": "ORD-20260627-001",
  • "trxid": "TRX20260627001"
}

Response samples

Content type
application/json
{
  • "code": 200,
  • "message": "success",
  • "data": {}
}

Payin Recurring

Recurring payment request. The customer gives consent (a mandate) allowing their balance to be debited periodically according to an agreed cycle.

Result: the recurring payment mandate/schedule is created. The status is delivered via the Payin Recurring Callback (POST {domain}/api/v2/ext/payin-recurring/callback).

Authorizations:
(ApiKeyAuthbearerAuth)
path Parameters
country
required
string <= 50 characters

Country code in the path, example: ID

channel
required
string <= 50 characters

Channel code, example: OVO. Must match the one used when obtaining the token.

service
required
string <= 50 characters

Service code, example: PULSA. Must match the one used when obtaining the token.

query Parameters
amount
required
string <= 50 characters

Payment / debit / refund amount

msisdn
required
string <= 50 characters

Customer phone number, example: 628123456789

order_number
required
string <= 100 characters

Merchant order number, example: ORD-20260627-001

currency
string <= 10 characters

Currency, example: INR / IDR

cycle
string <= 50 characters

Billing cycle, example: daily / ADHOC

header Parameters
apikey
required
string <= 50 characters

Merchant API key (still required in the header, even for GET requests)

Authorization
required
string
Example: Bearer YOUR_TOKEN

Bearer access token obtained from the Get Token endpoint

Responses

Response samples

Content type
application/json
{
  • "code": 200,
  • "message": "success"
}

Payin Recurring (POST)

POST alternative for the recurring payment request, using a JSON body.

Authorizations:
(ApiKeyAuthbearerAuth)
path Parameters
country
required
string <= 50 characters

Country code in the path, example: ID

channel
required
string <= 50 characters

Channel code, example: OVO. Must match the one used when obtaining the token.

service
required
string <= 50 characters

Service code, example: PULSA. Must match the one used when obtaining the token.

header Parameters
apikey
required
string <= 50 characters

Merchant API key (still required in the header, even for GET requests)

Authorization
required
string
Example: Bearer YOUR_TOKEN

Bearer access token obtained from the Get Token endpoint

Request Body schema: application/json
amount
required
number

Recurring payment amount

msisdn
required
string

Customer phone number

email
string

User email

order_number
required
string

Merchant order number

country
string

Country code

currency
string

Currency, example: INR / IDR

return_url
string

The return url after success payment

payment_method
string
channel_code
string
callback_url
string
interval
string
cycle
string

Billing cycle, example: ADHOC

payment_start_date
string <date>
payment_end_date
string <date>
is_no_expired
string

Responses

Request samples

Content type
application/json
{
  • "amount": 5,
  • "msisdn": "919979092377",
  • "email": "user@example.com",
  • "order_number": "1233213222613",
  • "country": "IN",
  • "currency": "INR",
  • "payment_method": "UPI",
  • "channel_code": "googlepay",
  • "callback_url": "https://.../response-payu",
  • "interval": "1",
  • "cycle": "ADHOC",
  • "payment_start_date": "2026-07-02",
  • "payment_end_date": "2026-07-15",
  • "is_no_expired": "false"
}

Response samples

Content type
application/json
{
  • "code": 200,
  • "message": "success"
}

Refund

Refund request. The return of funds from a previously successful transaction, either partially or in full.

Result: the refund request is forwarded to the payment gateway. The final status is delivered via the Refund Callback (POST {domain}/api/v2/ext/refund/callback), example status: REFUND_SUCCESS.

Authorizations:
(ApiKeyAuthbearerAuth)
path Parameters
country
required
string <= 50 characters

Country code in the path, example: ID

channel
required
string <= 50 characters

Channel code, example: OVO. Must match the one used when obtaining the token.

service
required
string <= 50 characters

Service code, example: PULSA. Must match the one used when obtaining the token.

query Parameters
txnid
required
string <= 150 characters

ID of the transaction to be refunded

refund_id
required
string <= 100 characters

Merchant refund ID, example: RFD-20260627-001

amount
required
string <= 50 characters

Payment / debit / refund amount

header Parameters
apikey
required
string <= 50 characters

Merchant API key (still required in the header, even for GET requests)

Authorization
required
string
Example: Bearer YOUR_TOKEN

Bearer access token obtained from the Get Token endpoint

Responses

Response samples

Content type
application/json
{
  • "code": 200,
  • "message": "success"
}

Refund (POST)

POST alternative for the refund request, using a JSON body.

Authorizations:
(ApiKeyAuthbearerAuth)
path Parameters
country
required
string <= 50 characters

Country code in the path, example: ID

channel
required
string <= 50 characters

Channel code, example: OVO. Must match the one used when obtaining the token.

service
required
string <= 50 characters

Service code, example: PULSA. Must match the one used when obtaining the token.

header Parameters
apikey
required
string <= 50 characters

Merchant API key (still required in the header, even for GET requests)

Authorization
required
string
Example: Bearer YOUR_TOKEN

Bearer access token obtained from the Get Token endpoint

Request Body schema: application/json
auth_payu_id
required
string

Authorization ID from the payment gateway (PayU)

refund_id
required
string

Merchant refund ID, example: RFD-20260627-001

amount
required
number

Amount to be refunded

transaction_id
required
string

ID of the transaction to be refunded

Responses

Request samples

Content type
application/json
{
  • "auth_payu_id": "29139358992",
  • "refund_id": "REFUND-2024011623-001",
  • "amount": 50,
  • "transaction_id": "trigger_d144b8dd_1783254835"
}

Response samples

Content type
application/json
{
  • "code": 200,
  • "message": "success"
}

Predebit

Pre-debit notification to the customer. Predebit is sent one day before the debit (D-1) to inform the customer that their balance will be debited on a specific date.

Result: the pre-debit notification is sent to the customer. Confirmation is delivered via the Predebit Callback (POST {domain}/api/v2/ext/predebit/callback).

Authorizations:
(ApiKeyAuthbearerAuth)
path Parameters
country
required
string <= 50 characters

Country code in the path, example: ID

channel
required
string <= 50 characters

Channel code, example: OVO. Must match the one used when obtaining the token.

service
required
string <= 50 characters

Service code, example: PULSA. Must match the one used when obtaining the token.

query Parameters
auth_payu_id
required
string <= 100 characters

Authorization ID from the payment gateway (PayU)

request_id
required
string <= 150 characters

Unique request ID (UUID) / charge request ID

amount
required
string <= 50 characters

Payment / debit / refund amount

debit_date
required
string <date> <= 20 characters

Debit date, format YYYY-MM-DD

invoice_display_number
required
string <= 100 characters

Invoice number displayed to the customer

header Parameters
apikey
required
string <= 50 characters

Merchant API key (still required in the header, even for GET requests)

Authorization
required
string
Example: Bearer YOUR_TOKEN

Bearer access token obtained from the Get Token endpoint

Responses

Response samples

Content type
application/json
{
  • "code": 200,
  • "message": "success"
}

Mandate Status

Check the mandate status before executing the debit. Between the predebit (D-1) and the debit (D), the customer may unsubscribe. Therefore the mandate status must be checked before the charge is triggered.

Result: returns the customer mandate status (active / inactive), which determines whether the debit may proceed.

Authorizations:
(ApiKeyAuthbearerAuth)
path Parameters
country
required
string <= 50 characters

Country code in the path, example: ID

channel
required
string <= 50 characters

Channel code, example: OVO. Must match the one used when obtaining the token.

service
required
string <= 50 characters

Service code, example: PULSA. Must match the one used when obtaining the token.

query Parameters
auth_payu_id
required
string <= 100 characters

Authorization ID from the payment gateway (PayU)

request_id
required
string <= 150 characters

Unique request ID (UUID) / charge request ID

header Parameters
apikey
required
string <= 50 characters

Merchant API key (still required in the header, even for GET requests)

Authorization
required
string
Example: Bearer YOUR_TOKEN

Bearer access token obtained from the Get Token endpoint

Responses

Response samples

Content type
application/json
{
  • "code": 200,
  • "message": "success",
  • "data": {
    }
}

Trigger Charge Recurring

Execute the customer balance debit (recurring). The execution of the customer balance debit for the current billing cycle.

Result: the customer balance is debited by the specified amount. The final result is delivered via the Trigger Charge Recurring Callback (POST {domain}/api/v2/ext/trigger-charge-recurring/callback).

Authorizations:
(ApiKeyAuthbearerAuth)
path Parameters
country
required
string <= 50 characters

Country code in the path, example: ID

channel
required
string <= 50 characters

Channel code, example: OVO. Must match the one used when obtaining the token.

service
required
string <= 50 characters

Service code, example: PULSA. Must match the one used when obtaining the token.

query Parameters
auth_payu_id
required
string <= 100 characters

Authorization ID from the payment gateway (PayU)

request_id
required
string <= 150 characters

Unique request ID (UUID) / charge request ID

amount
required
string <= 50 characters

Payment / debit / refund amount

phone
required
string <= 50 characters

Customer phone number

header Parameters
apikey
required
string <= 50 characters

Merchant API key (still required in the header, even for GET requests)

Authorization
required
string
Example: Bearer YOUR_TOKEN

Bearer access token obtained from the Get Token endpoint

Responses

Response samples

Content type
application/json
{
  • "code": 200,
  • "message": "success"
}

Trigger Charge Recurring (POST)

POST alternative for the trigger charge recurring request, using a JSON body.

Authorizations:
(ApiKeyAuthbearerAuth)
path Parameters
country
required
string <= 50 characters

Country code in the path, example: ID

channel
required
string <= 50 characters

Channel code, example: OVO. Must match the one used when obtaining the token.

service
required
string <= 50 characters

Service code, example: PULSA. Must match the one used when obtaining the token.

header Parameters
apikey
required
string <= 50 characters

Merchant API key (still required in the header, even for GET requests)

Authorization
required
string
Example: Bearer YOUR_TOKEN

Bearer access token obtained from the Get Token endpoint

Request Body schema: application/json
auth_payu_id
required
string

Authorization ID from the payment gateway

request_id
required
string

Charge request ID, example: trigger_LINKIT12398761

amount
required
string

Amount debited, example: 5.00

phone
required
string

Customer phone number

email
string
currency
string
description
string
callback_url
string
country
string

Responses

Request samples

Content type
application/json
{
  • "auth_payu_id": "28657904858",
  • "request_id": "trigger_LINKIT12398761",
  • "amount": "5.00",
  • "phone": "081292795541",
  • "email": "user@example.com",
  • "currency": "INR",
  • "description": "Weekly subscription",
  • "country": "{country}"
}

Response samples

Content type
application/json
{
  • "code": 200,
  • "message": "success"
}

Callback

Callback endpoints receive notifications from the payment gateway (PayU). Callbacks do not require a Bearer Token.

Callbacks from PayU (ewallet, refund, trigger charge) are flat and do not include apikey/channel/service in the body. If trx_id is empty, the system falls back to looking up the transaction via reference_id / txn_id.

Notification Charge (DN)

Charge result notification (delivery notification). Informs the merchant system of the debit/charge result.

Authorizations:
ApiKeyAuth
query Parameters
apikey
required
string <= 150 characters

Merchant API key

country
required
string <= 50 characters

Country code

channel
required
string <= 50 characters

Channel code

service
required
string <= 50 characters

Service code

trxid
required
string <= 150 characters

Merchant/related transaction ID, example: TRX20260627001

status_code
required
string <= 50 characters

Status code, example: success

status_desc
required
string <= 150 characters

Status description, example: charge notification received

Responses

Response samples

Content type
application/json
{
  • "code": 200,
  • "message": "success"
}

Notification Charge (DN) (POST)

POST variant of the charge result notification (delivery notification).

Authorizations:
ApiKeyAuth
query Parameters
apikey
required
string <= 150 characters

Merchant API key

country
required
string <= 50 characters

Country code

channel
required
string <= 50 characters

Channel code

service
required
string <= 50 characters

Service code

trxid
required
string <= 150 characters

Merchant/related transaction ID, example: TRX20260627001

status_code
required
string <= 50 characters

Status code, example: success

status_desc
required
string <= 150 characters

Status description, example: charge notification received

Responses

Response samples

Content type
application/json
{
  • "code": 200,
  • "message": "success"
}

Ewallet Callback

Sent by PayU with the final status of a one-time e-wallet payment. Flat body, does not include apikey/channel/service.

Authorizations:
ApiKeyAuth
Request Body schema: application/json
property name*
additional property
any

Responses

Request samples

Content type
application/json
{ }

Response samples

Content type
application/json
{
  • "code": 200,
  • "message": "success"
}

Refund Callback

Sent by PayU with the final status of a refund request (example status: REFUND_SUCCESS). Flat body, does not include apikey/channel/service.

Authorizations:
ApiKeyAuth
Request Body schema: application/json
property name*
additional property
any

Responses

Request samples

Content type
application/json
{ }

Response samples

Content type
application/json
{
  • "code": 200,
  • "message": "success"
}

Predebit Callback

Confirmation callback for the predebit (D-1) notification.

Authorizations:
ApiKeyAuth
Request Body schema: application/json
property name*
additional property
any

Responses

Request samples

Content type
application/json
{ }

Response samples

Content type
application/json
{
  • "code": 200,
  • "message": "success"
}

Payin Recurring Callback

Delivers the status of the recurring payment mandate/schedule registration (Notification Initiate Payment / MO).

Authorizations:
ApiKeyAuth
Request Body schema: application/json
property name*
additional property
any

Responses

Request samples

Content type
application/json
{ }

Response samples

Content type
application/json
{
  • "code": 200,
  • "message": "success"
}

Trigger Charge Callback

Sent by PayU with the final result of the recurring balance debit. Flat body, does not include apikey/channel/service.

Authorizations:
ApiKeyAuth
Request Body schema: application/json
property name*
additional property
any

Responses

Request samples

Content type
application/json
{ }

Response samples

Content type
application/json
{
  • "code": 200,
  • "message": "success"
}