NAV -image
bash php

Introduction

Introduction

Payment Gateway Specification Document

This documentation aims to provide all the information you need to work with our API.

Supported payment methods

ABA PAY ABA PAY ACLEDA Pay ACLEDA Pay
AliPay AliPay Bakong KHQR Bakong KHQR
BIC Bank BIC Bank Canadia Bank Plc. Canadia Bank Plc.
Chip Mong Bank Chip Mong Bank eMoney eMoney
FTB  Bank FTB Bank Google Pay Google Pay
Google Pay Master Google Pay Master Google Pay Visa Google Pay Visa
HATTHA Bank HATTHA Bank Huione Pay Huione Pay
KESS PAY KESS PAY KHQR KHQR
Phillip Bank Plc Phillip Bank Plc PPCBank PPCBank
Sathapana Sathapana TrueMoney TrueMoney
U-Pay U-Pay UnionPay UnionPay
Vattanac Bank Vattanac Bank Visa/Master Card Visa/Master Card
WeChat Pay WeChat Pay Wing Bank Wing Bank

Authenticating

Authenticate requests to this API's endpoints by sending an Authorization header with the value "Bearer {ACCESS TOKEN}".

All authenticated endpoints are marked with a requires authentication badge in the documentation below.

POST {baseUrl}/oauth/token

                    
curl --location --request POST '{baseUrl}/oauth/token' \
--header 'Content-Type: application/json' \
--data-raw '{
    "grant_type": "password",
    "client_id": "{CLIENT ID}",
    "client_secret": "{CLIENT SECRET}",
    "username": "{USERNAME}",
    "password": "{PASSWORD}"
}'
                    
                
                    
$curl = curl_init();

curl_setopt_array($curl, array(
    CURLOPT_URL => '{baseUrl}/oauth/token',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_ENCODING => '',
    CURLOPT_MAXREDIRS => 10,
    CURLOPT_TIMEOUT => 0,
    CURLOPT_FOLLOWLOCATION => true,
    CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
    CURLOPT_CUSTOMREQUEST => 'POST',
    CURLOPT_POSTFIELDS =>'{
        "grant_type": "password",
        "client_id": "{CLIENT ID}",
        "client_secret": "{CLIENT SECRET}",
        "username": "{USERNAME}",
        "password": "{PASSWORD}"
    }',
    CURLOPT_HTTPHEADER => array(
        'Content-Type: application/json',
         
    )
));

$response = curl_exec($curl);

curl_close($curl);

echo $response;
                    
                
                    

{
    "token_type": "Bearer",
    "expires_in": "1800",
    "access_token": "ACCESS TOKEN",
    "refresh_token": "REFRESH TOKEN"
}
              
                    
                
Field Type Required Description
grant_type String Yes "password" or "refresh_token"
client_id String Yes {CLIENT ID}
client_secret String Yes {CLIENT SECRET}
username String Yes Required when grant_type equal "password" {USERNAME}
password String Yes Required when grant_type equal "password" {PASSWORD}
refresh_token String Yes Required when grant_type equal "refresh_token" {REFRESH TOKEN}
Field Type Nullable Description
token_type String No Bearer
expires_in Integer No access_token default is 1800 seconds
access_token String No ACCESS TOKEN
refresh_token String No REFRESH TOKEN. The refresh_token will expire after access_token expired 15 minutes. Ex: 2700 seconds when access_token expires in 1800.

Merchant API Gateway

Use a single endpoint to access every available service based on its service’s name and dynamical parameters.

Merchant Info

POST {baseUrl}/api/mch/v2/gateway requires authentication

                    
curl --location --request POST '{baseUrl}/api/mch/v2/gateway' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer {ACCESS TOKEN}' \
--data-raw '{
    "service": "webpay.acquire.merchantinfo",
    "sign_type": "MD5",
    "seller_code": "{SELLER CODE}",
    "sign": "{SIGNATURE}"
}'
                    
                
                    
$curl = curl_init();

curl_setopt_array($curl, array(
    CURLOPT_URL => '{baseUrl}/api/mch/v2/gateway',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_ENCODING => '',
    CURLOPT_MAXREDIRS => 10,
    CURLOPT_TIMEOUT => 0,
    CURLOPT_FOLLOWLOCATION => true,
    CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
    CURLOPT_CUSTOMREQUEST => 'POST',
    CURLOPT_POSTFIELDS =>'{
        "service": "webpay.acquire.merchantinfo",
        "sign_type": "MD5",
        "seller_code": "{SELLER CODE}",
        "sign": "{SIGNATURE}"
    }',
    CURLOPT_HTTPHEADER => array(
        'Content-Type: application/json',
        'Authorization: Bearer {ACCESS TOKEN}' 
    )
));

$response = curl_exec($curl);

curl_close($curl);

echo $response;
                    
                
                    
{
    "success": true,
    "data": {
        "id": 6900,
        "phone_number": "010222333",
        "user_id": "CU2501-101139033689723678",
        "email": "xxx@gmail.com",
        "full_name": "xxx Admin",
        "muser_identity": null,
        "created_at": "2025-01-13 09:32:21",
        "wallet": {
            "id": "CW2501-101139033689723679",
            "balance": 0,
            "currency": "USD",
            "account_number": "000024916"
        },
        "multi_wallets": [
            {
                "id": "CW2501-101139033689723679",
                "balance": 0,
                "currency": "USD",
                "account_number": "000024916",
                "funds_type": "DEFAULT"
            },
            {
                "id": "CW2501-101139033689723680",
                "balance": 0,
                "currency": "KHR",
                "account_number": "000024917",
                "funds_type": "MAIN"
            }
        ]
    },
    "sign": "{SIGNATURE}",
    "sign_type": "MD5"
}      
              
                    
                
Field Type Required Description
service String Yes "webpay.acquire.merchantinfo"
sign_type String Yes MD5 or HMAC-SHA256
seller_code String Yes CU2501-101139033689723677
sign String Yes {GENERATED SIGNATURE}
Field Type Nullable Description
...
Included common data of user_info
...
Error Code Status Code Description
400 VALIDATION_ERROR Validation error.
401 UNAUTHENTICATED Unauthenticated.
403 FORBIDDEN Access denied.
404 NOT_FOUND Record not found.
409 DUPLICATED Existing record found.
419 EXPIRED Requesting record was expired.
422 PROCESS_FAILED Sub-process failed.
500 SYSTEM_ERROR Internal server error.
503 FEATURE_UNDER_MAINTENANCE Feature is under maintenance.
504 GATEWAY_TIMEOUT Gateway time-out.

Create User

POST {baseUrl}/api/mch/v2/gateway requires authentication

                    
curl --location --request POST '{baseUrl}/api/mch/v2/gateway' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer {ACCESS TOKEN}' \
--data-raw '{
    "service": "webpay.acquire.adduserundermerchant",
    "seller_code": "{SELLER CODE}",
    "first_name": "xx",
    "last_name": "xx",
    "phone_number": "010222333",
    "email": "xx@gmail.com",
    "muser_identity": "N0102345",
    "sign_type": "MD5",
    "sign": "{SIGNATURE}"
}'
                    
                
                    
$curl = curl_init();

curl_setopt_array($curl, array(
    CURLOPT_URL => '{baseUrl}/api/mch/v2/gateway',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_ENCODING => '',
    CURLOPT_MAXREDIRS => 10,
    CURLOPT_TIMEOUT => 0,
    CURLOPT_FOLLOWLOCATION => true,
    CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
    CURLOPT_CUSTOMREQUEST => 'POST',
    CURLOPT_POSTFIELDS =>'{
        "service": "webpay.acquire.adduserundermerchant",
        "seller_code": "{SELLER CODE}",
        "first_name" : "xx",
        "last_name" : "xx",
        "phone_number":"010222333",
        "email": "xx@gmail.com",
        "muser_identity": "N0102345",
        "sign_type": "MD5",
        "sign": "{SIGNATURE}"
    }',
    CURLOPT_HTTPHEADER => array(
        'Content-Type: application/json',
        'Authorization: Bearer {ACCESS TOKEN}' 
    )
));

$response = curl_exec($curl);

curl_close($curl);

echo $response;
                    
                
                    
{
    "success": true,
    "data": {
        "id": 6900,
        "phone_number": "010222333",
        "user_id": "CU2501-101139033689723678",
        "email": "xxx@gmail.com",
        "full_name": "xxx Admin",
        "muser_identity": null,
        "created_at": "2025-01-13 09:32:21",
        "wallet": {
            "id": "CW2501-101139033689723679",
            "balance": 0,
            "currency": "USD",
            "account_number": "000024916"
        },
        "multi_wallets": [
            {
                "id": "CW2501-101139033689723679",
                "balance": 0,
                "currency": "USD",
                "account_number": "000024916",
                "funds_type": "DEFAULT"
            },
            {
                "id": "CW2501-101139033689723680",
                "balance": 0,
                "currency": "KHR",
                "account_number": "000024917",
                "funds_type": "MAIN"
            }
        ]
    },
    "sign": "{SIGNATURE}",
    "sign_type": "MD5"
}      
              
                    
                
Field Type Required Description
service String Yes "webpay.acquire.adduserundermerchant"
sign_type String Yes MD5 or HMAC-SHA256
seller_code String Yes CU2501-101139033689723677
first_name String Yes xxx
last_name String Yes xxx
phone_number String Yes 010222333
email String Yes test@xxx.com
muser_identity String No No1234
sign String Yes {GENERATED SIGNATURE}
Field Type Nullable Description
...
Included common data of user_info
...
Error Code Status Code Description
400 VALIDATION_ERROR Validation error.
401 UNAUTHENTICATED Unauthenticated.
403 FORBIDDEN Access denied.
404 NOT_FOUND Record not found.
409 DUPLICATED Existing record found.
419 EXPIRED Requesting record was expired.
422 PROCESS_FAILED Sub-process failed.
500 SYSTEM_ERROR Internal server error.
503 FEATURE_UNDER_MAINTENANCE Feature is under maintenance.
504 GATEWAY_TIMEOUT Gateway time-out.

List User Under Merchant

POST {baseUrl}/api/mch/v2/gateway requires authentication

                    
curl --location --request POST '{baseUrl}/api/mch/v2/gateway' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer {ACCESS TOKEN}' \
--data-raw '{
    "service": "webpay.acquire.getUserUnderMerchant",
    "sign_type": "MD5",
    "seller_code": "{SELLER CODE}",
    "page": 1,
    "sign": "{SIGNATURE}"
}'
                    
                
                    
$curl = curl_init();

curl_setopt_array($curl, array(
    CURLOPT_URL => '{baseUrl}/api/mch/v2/gateway',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_ENCODING => '',
    CURLOPT_MAXREDIRS => 10,
    CURLOPT_TIMEOUT => 0,
    CURLOPT_FOLLOWLOCATION => true,
    CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
    CURLOPT_CUSTOMREQUEST => 'POST',
    CURLOPT_POSTFIELDS =>'{
        "service": "webpay.acquire.getUserUnderMerchant",
        "sign_type": "MD5",
        "seller_code": "{SELLER CODE}",
        "page" : 1,
        "sign": "{SIGNATURE}"
    }',
    CURLOPT_HTTPHEADER => array(
        'Content-Type: application/json',
        'Authorization: Bearer {ACCESS TOKEN}' 
    )
));

$response = curl_exec($curl);

curl_close($curl);

echo $response;
                    
                
                    
{
    "success": true,
    "data": {
        "data" : [
            {
            "id": 6900,
            "phone_number": "010222333",
            "user_id": "CU2501-101139033689723678",
            "email": "xxx@gmail.com",
            "full_name": "xxx Admin",
            "muser_identity": null,
            "created_at": "2025-01-13 09:32:21",
            "wallet": {
                "id": "CW2501-101139033689723679",
                "balance": 0,
                "currency": "USD",
                "account_number": "000024916"
            },
            "multi_wallets": [
                {
                    "id": "CW2501-101139033689723679",
                    "balance": 0,
                    "currency": "USD",
                    "account_number": "000024916",
                    "funds_type": "DEFAULT"
                },
                {
                    "id": "CW2501-101139033689723680",
                    "balance": 0,
                    "currency": "KHR",
                    "account_number": "000024917",
                    "funds_type": "MAIN"
                }
            ]
        }
        ],
        "current_page" : 1,
        "last_page": 2
    },
    "sign": "{SIGNATURE}",
    "sign_type": "MD5"
}      
              
                    
                
Field Type Required Description
service String Yes "webpay.acquire.getUserUnderMerchant"
sign_type String Yes MD5 or HMAC-SHA256
seller_code String Yes CU2501-101139033689723677
page integer Yes 1
sign String Yes {GENERATED SIGNATURE}
Field Type Nullable Description
user_info Array Yes user_info
Error Code Status Code Description
400 VALIDATION_ERROR Validation error.
401 UNAUTHENTICATED Unauthenticated.
403 FORBIDDEN Access denied.
404 NOT_FOUND Record not found.
409 DUPLICATED Existing record found.
419 EXPIRED Requesting record was expired.
422 PROCESS_FAILED Sub-process failed.
500 SYSTEM_ERROR Internal server error.
503 FEATURE_UNDER_MAINTENANCE Feature is under maintenance.
504 GATEWAY_TIMEOUT Gateway time-out.

User Info

POST {baseUrl}/api/mch/v2/gateway requires authentication

                    
curl --location --request POST '{baseUrl}/api/mch/v2/gateway' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer {ACCESS TOKEN}' \
--data-raw '{
    "service": "webpay.acquire.userprofile",
    "sign_type": "MD5",
    "seller_code": "{SELLER CODE}",
    "user_id": "xxx",
    "muser_identity": "xxx",
    "sign": "{SIGNATURE}"
}'
                    
                
                    
$curl = curl_init();

curl_setopt_array($curl, array(
    CURLOPT_URL => '{baseUrl}/api/mch/v2/gateway',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_ENCODING => '',
    CURLOPT_MAXREDIRS => 10,
    CURLOPT_TIMEOUT => 0,
    CURLOPT_FOLLOWLOCATION => true,
    CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
    CURLOPT_CUSTOMREQUEST => 'POST',
    CURLOPT_POSTFIELDS =>'{
        "service": "webpay.acquire.userprofile",
        "sign_type": "MD5",
        "seller_code": "{SELLER CODE}",
        "user_id": "xxx",
        "muser_identity":"xxx",
        "sign": "{SIGNATURE}"
    }',
    CURLOPT_HTTPHEADER => array(
        'Content-Type: application/json',
        'Authorization: Bearer {ACCESS TOKEN}' 
    )
));

$response = curl_exec($curl);

curl_close($curl);

echo $response;
                    
                
                    
{
    "success": true,
    "data": {
        "id": 6900,
        "phone_number": "010222333",
        "user_id": "CU2501-101139033689723678",
        "email": "xxx@gmail.com",
        "full_name": "xxx Admin",
        "muser_identity": null,
        "created_at": "2025-01-13 09:32:21",
        "wallet": {
            "id": "CW2501-101139033689723679",
            "balance": 0,
            "currency": "USD",
            "account_number": "000024916"
        },
        "multi_wallets": [
            {
                "id": "CW2501-101139033689723679",
                "balance": 0,
                "currency": "USD",
                "account_number": "000024916",
                "funds_type": "DEFAULT"
            },
            {
                "id": "CW2501-101139033689723680",
                "balance": 0,
                "currency": "KHR",
                "account_number": "000024917",
                "funds_type": "MAIN"
            }
        ]
    },
    "sign": "{SIGNATURE}",
    "sign_type": "MD5"
}      
              
                    
                
Field Type Required Description
service String Yes "webpay.acquire.userprofile"
sign_type String Yes MD5 or HMAC-SHA256
seller_code String Yes CU2501-101139033689723677
user_id String Yes|No Require when muser_identity value null
muser_identity String Yes|No Require when user_id value null
sign String Yes {GENERATED SIGNATURE}
Field Type Nullable Description
...
Included common data of user_info
...
Error Code Status Code Description
400 VALIDATION_ERROR Validation error.
401 UNAUTHENTICATED Unauthenticated.
403 FORBIDDEN Access denied.
404 NOT_FOUND Record not found.
409 DUPLICATED Existing record found.
419 EXPIRED Requesting record was expired.
422 PROCESS_FAILED Sub-process failed.
500 SYSTEM_ERROR Internal server error.
503 FEATURE_UNDER_MAINTENANCE Feature is under maintenance.
504 GATEWAY_TIMEOUT Gateway time-out.

List Transaction

POST {baseUrl}/api/mch/v2/gateway requires authentication

Filter Field
start_date, end_date, order_id, sort : desc|asc

                    
curl --location --request POST '{baseUrl}/api/mch/v2/gateway' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer {ACCESS TOKEN}' \
--data-raw '{
    "service": "webpay.acquire.getTxnLists",
    "sign_type": "MD5",
    "seller_code": "{SELLER CODE}",
    "page": 1,
    "sign": "{SIGNATURE}"
}'
                    
                
                    
$curl = curl_init();

curl_setopt_array($curl, array(
    CURLOPT_URL => '{baseUrl}/api/mch/v2/gateway',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_ENCODING => '',
    CURLOPT_MAXREDIRS => 10,
    CURLOPT_TIMEOUT => 0,
    CURLOPT_FOLLOWLOCATION => true,
    CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
    CURLOPT_CUSTOMREQUEST => 'POST',
    CURLOPT_POSTFIELDS =>'{
        "service": "webpay.acquire.getTxnLists",
        "sign_type": "MD5",
        "seller_code": "{SELLER CODE}",
        "page" : 1,
        "sign": "{SIGNATURE}"
    }',
    CURLOPT_HTTPHEADER => array(
        'Content-Type: application/json',
        'Authorization: Bearer {ACCESS TOKEN}' 
    )
));

$response = curl_exec($curl);

curl_close($curl);

echo $response;
                    
                
                    
{
    "success": true,
    "data": {
        "data" : [
            {
                "transaction_ref": "TR2501-101139033689723727",
                "credited_amount": 9.65,
                "credited_currency": "USD",
                "debited_amount": 10,
                "debited_currency": "USD",
                "fees_amount": 0.35,
                "transaction_type": "in",
                "fees_ccy": "USD",
                "status": "Succeed",
                "created_at": "2025-01-13 09:54:39",
                "debited_user_id": "AU2501-101139033689723700",
                "credited_user_id": "CU2501-101139033689723678",
                "readable_created_at": "1 week ago",
                "order_id" : "123454"
            }
        ],
        "current_page" : 1,
        "last_page": 2
    },
    "sign": "{SIGNATURE}",
    "sign_type": "MD5"
}      
              
                    
                
Field Type Required Description
service String Yes "webpay.acquire.getTxnLists"
sign_type String Yes MD5 or HMAC-SHA256
seller_code String Yes CU2501-101139033689723677
wallet_id String No xxx
user_id String No xxx
page integer Yes 1
sign String Yes {GENERATED SIGNATURE}
Field Type Nullable Description
transaction_info Array Yes transaction_info
Error Code Status Code Description
400 VALIDATION_ERROR Validation error.
401 UNAUTHENTICATED Unauthenticated.
403 FORBIDDEN Access denied.
404 NOT_FOUND Record not found.
409 DUPLICATED Existing record found.
419 EXPIRED Requesting record was expired.
422 PROCESS_FAILED Sub-process failed.
500 SYSTEM_ERROR Internal server error.
503 FEATURE_UNDER_MAINTENANCE Feature is under maintenance.
504 GATEWAY_TIMEOUT Gateway time-out.

Transaction Info

POST {baseUrl}/api/mch/v2/gateway requires authentication

                    
curl --location --request POST '{baseUrl}/api/mch/v2/gateway' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer {ACCESS TOKEN}' \
--data-raw '{
    "service": "webpay.acquire.getTxnDetail",
    "sign_type": "MD5",
    "seller_code": "{SELLER CODE}",
    "transaction_ref": "xxx",
    "sign": "{SIGNATURE}"
}'
                    
                
                    
$curl = curl_init();

curl_setopt_array($curl, array(
    CURLOPT_URL => '{baseUrl}/api/mch/v2/gateway',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_ENCODING => '',
    CURLOPT_MAXREDIRS => 10,
    CURLOPT_TIMEOUT => 0,
    CURLOPT_FOLLOWLOCATION => true,
    CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
    CURLOPT_CUSTOMREQUEST => 'POST',
    CURLOPT_POSTFIELDS =>'{
        "service": "webpay.acquire.getTxnDetail",
        "sign_type": "MD5",
        "seller_code": "{SELLER CODE}",
        "transaction_ref": "xxx",
        "sign": "{SIGNATURE}"
    }',
    CURLOPT_HTTPHEADER => array(
        'Content-Type: application/json',
        'Authorization: Bearer {ACCESS TOKEN}' 
    )
));

$response = curl_exec($curl);

curl_close($curl);

echo $response;
                    
                
                    
{
    "success": true,
    "data": {
        "transaction_ref": "TR2501-101139033689723727",
        "credited_amount": 9.65,
        "credited_currency": "USD",
        "debited_amount": 10,
        "debited_currency": "USD",
        "fees_amount": 0.35,
        "transaction_type": "in",
        "fees_ccy": "USD",
        "status": "Succeed",
        "created_at": "2025-01-13 09:54:39",
        "debited_user_id": "AU2501-101139033689723700",
        "credited_user_id": "CU2501-101139033689723678",
        "readable_created_at": "2 weeks ago"
    },
    "sign": "{SIGNATURE}",
    "sign_type": "MD5"
}      
              
                    
                
Field Type Required Description
service String Yes "webpay.acquire.getTxnDetail"
sign_type String Yes MD5 or HMAC-SHA256
seller_code String Yes CU2501-101139033689723677
transaction_ref String Yes TR2402-100719685279940668
sign String Yes {GENERATED SIGNATURE}
Field Type Nullable Description
...
Included common data of transaction_info
...
Error Code Status Code Description
400 VALIDATION_ERROR Validation error.
401 UNAUTHENTICATED Unauthenticated.
403 FORBIDDEN Access denied.
404 NOT_FOUND Record not found.
409 DUPLICATED Existing record found.
419 EXPIRED Requesting record was expired.
422 PROCESS_FAILED Sub-process failed.
500 SYSTEM_ERROR Internal server error.
503 FEATURE_UNDER_MAINTENANCE Feature is under maintenance.
504 GATEWAY_TIMEOUT Gateway time-out.

Money Transfer

POST {baseUrl}/api/mch/v2/gateway requires authentication

                    
curl --location --request POST '{baseUrl}/api/mch/v2/gateway' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer {ACCESS TOKEN}' \
--data-raw '{
    "service": "webpay.acquire.moneytransfer",
    "seller_code": "{SELLER CODE}",
    "amount": 10,
    "currency": "USD",
    "from_wallet_id": "CW2501-101139033689723679",
    "to_wallet_id": "AW2501-101139033689723906",
    "comment": "User comment",
    "sign_type": "MD5",
    "sign": "{SIGNATURE}"
}'
                    
                
                    
$curl = curl_init();

curl_setopt_array($curl, array(
    CURLOPT_URL => '{baseUrl}/api/mch/v2/gateway',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_ENCODING => '',
    CURLOPT_MAXREDIRS => 10,
    CURLOPT_TIMEOUT => 0,
    CURLOPT_FOLLOWLOCATION => true,
    CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
    CURLOPT_CUSTOMREQUEST => 'POST',
    CURLOPT_POSTFIELDS =>'{
        "service": "webpay.acquire.moneytransfer",
        "seller_code": "{SELLER CODE}",
        "amount" : 10,
        "currency" : "USD",
        "from_wallet_id":"CW2501-101139033689723679",
        "to_wallet_id": "AW2501-101139033689723906",
        "comment": "User comment",
        "sign_type": "MD5",
        "sign": "{SIGNATURE}"
    }',
    CURLOPT_HTTPHEADER => array(
        'Content-Type: application/json',
        'Authorization: Bearer {ACCESS TOKEN}' 
    )
));

$response = curl_exec($curl);

curl_close($curl);

echo $response;
                    
                
                    
{
    "success": true,
    "data": {
        "transaction_ref": "TR2501-101200989918337879",
        "amount": 25,
        "currency": "USD",
        "comment": "",
        "created_at": "2025-01-29 10:17:46"
    },
    "sign": "{SIGNATURE}",
    "sign_type": "MD5"
}      
              
                    
                
Field Type Required Description
service String Yes "webpay.acquire.moneytransfer"
sign_type String Yes MD5 or HMAC-SHA256
seller_code String Yes CU2501-101139033689723677
amount Double Yes 10
currency String Yes USD
from_wallet_id String Yes CW2501-101139033689723679
to_wallet_id String Yes AW2501-101139033689723906
comment String No No1234
sign String Yes {GENERATED SIGNATURE}
Field Type Nullable Description
transaction_ref String Yes TR2501-101200989918337879
amount Doble Yes 10
currency String Yes USD
comment String No User comment
created_at Datetime Yes 2025-01-23 00:00:00
Error Code Status Code Description
400 VALIDATION_ERROR Validation error.
401 UNAUTHENTICATED Unauthenticated.
403 FORBIDDEN Access denied.
404 NOT_FOUND Record not found.
409 DUPLICATED Existing record found.
419 EXPIRED Requesting record was expired.
422 PROCESS_FAILED Sub-process failed.
500 SYSTEM_ERROR Internal server error.
503 FEATURE_UNDER_MAINTENANCE Feature is under maintenance.
504 GATEWAY_TIMEOUT Gateway time-out.

Bakong API Gateway

Use a single endpoint to access every available service based on its service’s name and dynamical parameters.

List Bakong Members

POST {baseUrl}/api/mch/v2/gateway requires authentication

                    
curl --location --request POST '{baseUrl}/api/mch/v2/gateway' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer {ACCESS TOKEN}' \
--data-raw '{
    "service": "webpay.acquire.getbakongmembers",
    "sign_type": "MD5",
    "sign": "{SIGNATURE}"
}'
                    
                
                    
$curl = curl_init();

curl_setopt_array($curl, array(
    CURLOPT_URL => '{baseUrl}/api/mch/v2/gateway',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_ENCODING => '',
    CURLOPT_MAXREDIRS => 10,
    CURLOPT_TIMEOUT => 0,
    CURLOPT_FOLLOWLOCATION => true,
    CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
    CURLOPT_CUSTOMREQUEST => 'POST',
    CURLOPT_POSTFIELDS =>'{
        "service": "webpay.acquire.getbakongmembers",
        "sign_type": "MD5",
        "sign": "{SIGNATURE}"
    }',
    CURLOPT_HTTPHEADER => array(
        'Content-Type: application/json',
        'Authorization: Bearer {ACCESS TOKEN}' 
    )
));

$response = curl_exec($curl);

curl_close($curl);

echo $response;
                    
                
                    
{
    "success": true,
    "data": [
        {
            "name": "xxx",
            "bic": "xx",
            "logo": "xx",
        }
    ],
    "sign": "{SIGNATURE}",
    "sign_type": "MD5"
}      
              
                    
                
Field Type Required Description
service String Yes "webpay.acquire.getbakongmembers"
sign_type String Yes MD5 or HMAC-SHA256
sign String Yes {GENERATED SIGNATURE}
Field Type Nullable Description
[Array] Array Yes List of Bakong Members.bakong_info
Error Code Status Code Description
400 VALIDATION_ERROR Validation error.
401 UNAUTHENTICATED Unauthenticated.
403 FORBIDDEN Access denied.
404 NOT_FOUND Record not found.
409 DUPLICATED Existing record found.
419 EXPIRED Requesting record was expired.
422 PROCESS_FAILED Sub-process failed.
500 SYSTEM_ERROR Internal server error.
503 FEATURE_UNDER_MAINTENANCE Feature is under maintenance.
504 GATEWAY_TIMEOUT Gateway time-out.

Withdraw By Bank Account

Withdraw from merchant wallet to Bank Account.

API specification

POST {baseUrl}/api/mch/v2/gateway requires authentication

                    
curl --location --request POST '{baseUrl}/api/mch/v2/gateway' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer {ACCESS TOKEN}' \
--data-raw '{
    "service": "webpay.acquire.withdrawByBankNumber",
    "sign": "79e69e298da1c85cf09366c35e366917",
    "sign_type": "MD5",
    "seller_code": "{SELLER CODE}",
    "bank_account": "123456789",
    "out_trade_no": "WD-00000TEST0002",
    "total_amount": 10,
    "currency": "USD",
    "expires_in": 300,
    "customer": "{ENCRYPTED CUSTOMER DATA}",
    "notify_url": "https:\/\/sample.com\/notifyme",
    "bic": "ACLBKHPPXXX"
}'
                    
                
                    
$curl = curl_init();

curl_setopt_array($curl, array(
    CURLOPT_URL => '{baseUrl}/api/mch/v2/gateway',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_ENCODING => '',
    CURLOPT_MAXREDIRS => 10,
    CURLOPT_TIMEOUT => 0,
    CURLOPT_FOLLOWLOCATION => true,
    CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
    CURLOPT_CUSTOMREQUEST => 'POST',
    CURLOPT_POSTFIELDS =>'{
        "service": "webpay.acquire.withdrawByBankNumber",
        "sign": "79e69e298da1c85cf09366c35e366917",
        "sign_type": "MD5",
        "seller_code": "{SELLER CODE}",
        "bank_account": "123456789",
        "out_trade_no": "WD-00000TEST0002",
        "total_amount": 10,
        "currency": "USD",
        "expires_in": 300,
        "customer": "{ENCRYPTED CUSTOMER DATA}",
        "notify_url" : "https://sample.com/notifyme",
        "bic": "ACLBKHPPXXX"
    }',
    CURLOPT_HTTPHEADER => array(
        'Content-Type: application/json',
        'Authorization: Bearer {ACCESS TOKEN}' 
    )
));

$response = curl_exec($curl);

curl_close($curl);

echo $response;
                    
                
                    
{
    "success": true,
    "data": {
        "token": "UHlHRHk2Nzg462df82a70a8bc",
        "out_trade_no": "WD-00000TEST0002",
        "transaction_id": null,
        "body": "Fund transfer",
        "total_amount": -10,
        "currency": "USD",
        "status": "WAITING",
        "paid_at": null,
        "settled_at": null,
        "settlement_date": null,
        "expired_at": "2022-07-26T06:04:03.000000Z",
        "created_at": "2022-07-26T05:59:03.000000Z",
        "detail": [],
        "seller": {
            "code": "{SELLER CODE}",
            "display_name": "Merchant Name"
        },
        "payment_detail": {
            "id": 8949,
            "payer_id": 793,
            "method_id": 12,
            "tokenize_id": 944,
            "method_desc": "Transfer to customer bank (From Merchant wallet)",
            "holder_name": "airport.taxi",
            "card_info": null,
            "bank_info": null,
            "created_at": "2022-07-26T05:59:03.000000Z",
            "payment_method_bic": "ABAAKHPP",
            "payment_method": {
                "id": 12,
                "title": "ABA PAY",
                "swift_code": "ABAAKHPP"
            }
        }
    },
    "sign": "{SIGNATURE}",
    "sign_type": "MD5"
}      
              
                    
                
Field Type Required Description
service String Yes "webpay.acquire.withdrawByBankNumber"
sign_type String Yes MD5 or HMAC-SHA256
sign String Yes {GENERATED SIGNATURE}
seller_code String Yes {SELLER CODE}
bic String Yes ACLBKHPPXXX for Acleda Bank
...
Include common data of a transaction
...
bank_account String(64) Yes Bank account number. Ex: 123456789
customer String Yes Use to identify the owner. {ENCRYPTED CUSTOMER DATA}. See customer
wallet_id String No Default Main Wallet wallet_id. Ex: 123456789
Field Type Nullable Description
...
Included common data of order_info
...
Error Code Status Code Description
400 VALIDATION_ERROR Validation error.
401 UNAUTHENTICATED Unauthenticated.
403 FORBIDDEN Access denied.
404 NOT_FOUND Record not found.
409 DUPLICATED Existing record found.
419 EXPIRED Requesting record was expired.
422 PROCESS_FAILED Sub-process failed.
500 SYSTEM_ERROR Internal server error.
503 FEATURE_UNDER_MAINTENANCE Feature is under maintenance.
504 GATEWAY_TIMEOUT Gateway time-out.

Generate KHQR

POST {baseUrl}/api/mch/v2/gateway requires authentication

                    
curl --location --request POST '{baseUrl}/api/mch/v2/gateway' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer {ACCESS TOKEN}' \
--data-raw '{
    "service": "webpay.acquire.generateKhqr",
    "sign_type": "MD5",
    "wallet_id": "xx",
    "user_id": "xx",
    "amount": 0,
    "sign": "{SIGNATURE}"
}'
                    
                
                    
$curl = curl_init();

curl_setopt_array($curl, array(
    CURLOPT_URL => '{baseUrl}/api/mch/v2/gateway',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_ENCODING => '',
    CURLOPT_MAXREDIRS => 10,
    CURLOPT_TIMEOUT => 0,
    CURLOPT_FOLLOWLOCATION => true,
    CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
    CURLOPT_CUSTOMREQUEST => 'POST',
    CURLOPT_POSTFIELDS =>'{
        "service": "webpay.acquire.generateKhqr",
        "sign_type": "MD5",
        "wallet_id": "xx",
        "user_id": "xx",
        "amount": 0,
        "sign": "{SIGNATURE}"
    }',
    CURLOPT_HTTPHEADER => array(
        'Content-Type: application/json',
        'Authorization: Bearer {ACCESS TOKEN}' 
    )
));

$response = curl_exec($curl);

curl_close($curl);

echo $response;
                    
                
                    
{
    "success": true,
    "data": {
        "qr_string": "00020101021129490009khqr@kess01090000249240219Kess Innovation Plc5204599953038405802KH5910Bunna Roth6010Phnom Penh62130209015703635991700131738910956926630400AA",
        "md5": "bf6ce95e56672e6991d3bd42af8f481a"
    },
    "sign": "{SIGNATURE}",
    "sign_type": "MD5"
}      
              
                    
                
Field Type Required Description
service String Yes "webpay.acquire.generateKhqr"
sign_type String Yes MD5 or HMAC-SHA256
wallet_id String Yes xxx
user_id String Yes xxx
amount Double Yes if amount = 0 user need input amount
sign String Yes {GENERATED SIGNATURE}
Field Type Nullable Description
qr_string String Yes qr
md5 String Yes Hash
Error Code Status Code Description
400 VALIDATION_ERROR Validation error.
401 UNAUTHENTICATED Unauthenticated.
403 FORBIDDEN Access denied.
404 NOT_FOUND Record not found.
409 DUPLICATED Existing record found.
419 EXPIRED Requesting record was expired.
422 PROCESS_FAILED Sub-process failed.
500 SYSTEM_ERROR Internal server error.
503 FEATURE_UNDER_MAINTENANCE Feature is under maintenance.
504 GATEWAY_TIMEOUT Gateway time-out.

Decode KHQR

POST {baseUrl}/api/mch/v2/gateway requires authentication

                    
curl --location --request POST '{baseUrl}/api/mch/v2/gateway' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer {ACCESS TOKEN}' \
--data-raw '{
    "service": "webpay.acquire.decodeKhqr",
    "sign_type": "MD5",
    "qrcode": "xx",
    "sign": "{SIGNATURE}"
}'
                    
                
                    
$curl = curl_init();

curl_setopt_array($curl, array(
    CURLOPT_URL => '{baseUrl}/api/mch/v2/gateway',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_ENCODING => '',
    CURLOPT_MAXREDIRS => 10,
    CURLOPT_TIMEOUT => 0,
    CURLOPT_FOLLOWLOCATION => true,
    CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
    CURLOPT_CUSTOMREQUEST => 'POST',
    CURLOPT_POSTFIELDS =>'{
        "service": "webpay.acquire.decodeKhqr",
        "sign_type": "MD5",
        "qrcode": "xx",
        "sign": "{SIGNATURE}"
    }',
    CURLOPT_HTTPHEADER => array(
        'Content-Type: application/json',
        'Authorization: Bearer {ACCESS TOKEN}' 
    )
));

$response = curl_exec($curl);

curl_close($curl);

echo $response;
                    
                
                    
{
    "success": true,
    "data": {
        "merchantType": "29",
        "bakongAccountID": "khqr@kess",
        "accountInformation": "000024924",
        "merchantID": null,
        "acquiringBank": "xx Innovation Plc",
        "billNumber": null,
        "mobileNumber": "015xxx",
        "storeLabel": null,
        "terminalLabel": null,
        "purposeOfTransaction": null,
        "languagePreference": null,
        "merchantNameAlternateLanguage": null,
        "merchantCityAlternateLanguage": null,
        "payloadFormatIndicator": "01",
        "pointofInitiationMethod": "12",
        "unionPayMerchant": null,
        "merchantCategoryCode": "5999",
        "transactionCurrency": "usd",
        "transactionAmount": "10",
        "countryCode": "KH",
        "merchantName": "xx Roth",
        "merchantCity": "Phnom Penh",
        "timestamp": "00131736836325291",
        "crc": "A581"
    },
    "sign": "{SIGNATURE}",
    "sign_type": "MD5"
}      
              
                    
                
Field Type Required Description
service String Yes "webpay.acquire.decodeKhqr"
sign_type String Yes MD5 or HMAC-SHA256
qrcode String Yes xxx
sign String Yes {GENERATED SIGNATURE}
Field Type Nullable Description
...
Included common data of khqr_info
...
Error Code Status Code Description
400 VALIDATION_ERROR Validation error.
401 UNAUTHENTICATED Unauthenticated.
403 FORBIDDEN Access denied.
404 NOT_FOUND Record not found.
409 DUPLICATED Existing record found.
419 EXPIRED Requesting record was expired.
422 PROCESS_FAILED Sub-process failed.
500 SYSTEM_ERROR Internal server error.
503 FEATURE_UNDER_MAINTENANCE Feature is under maintenance.
504 GATEWAY_TIMEOUT Gateway time-out.

Scan KHQR

POST {baseUrl}/api/mch/v2/gateway requires authentication

                    
curl --location --request POST '{baseUrl}/api/mch/v2/gateway' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer {ACCESS TOKEN}' \
--data-raw '{
    "service": "webpay.acquire.payKhqr",
    "sign_type": "MD5",
    "remark": "xx",
    "qrcode": "xx",
    "currency": "USD",
    "seller_code": "CU2501-101139033689723677",
    "out_trade_no": "TR-1234567890",
    "amount": "2",
    "sign": "{SIGNATURE}"
}'
                    
                
                    
$curl = curl_init();

curl_setopt_array($curl, array(
    CURLOPT_URL => '{baseUrl}/api/mch/v2/gateway',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_ENCODING => '',
    CURLOPT_MAXREDIRS => 10,
    CURLOPT_TIMEOUT => 0,
    CURLOPT_FOLLOWLOCATION => true,
    CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
    CURLOPT_CUSTOMREQUEST => 'POST',
    CURLOPT_POSTFIELDS =>'{
        "service": "webpay.acquire.payKhqr",
        "sign_type": "MD5",
        "remark": "xx",
        "qrcode": "xx",
        "currency": "USD",
        "seller_code": "CU2501-101139033689723677",
        "out_trade_no" : "TR-1234567890",
        "amount": "2",
        "sign": "{SIGNATURE}"
    }',
    CURLOPT_HTTPHEADER => array(
        'Content-Type: application/json',
        'Authorization: Bearer {ACCESS TOKEN}' 
    )
));

$response = curl_exec($curl);

curl_close($curl);

echo $response;
                    
                
                    
{
    "success": true,
    "data": {
        "transaction_ref": "TR2502-101237442664727769",
        "receiver_info": {
            "receiver_name": "Roth",
            "receiver_bank": "xxx Innovation Plc",
            "receiver_bakong_id": "khqr@kess",
            "receiver_acc_info": "000024924"
        },
        "status": "SUCCEEDED",
        "currency": "USD",
        "amount": "2"
    },
    "sign": "{SIGNATURE}",
    "sign_type": "MD5"
}      
              
                    
                
Field Type Required Description
service String Yes "webpay.acquire.payKhqr"
sign_type String Yes MD5 or HMAC-SHA256
amount String Yes xxx
currency String Yes USD
remark String No xxx
qrcode String Yes xxx
out_trade_no String Yes Alphanumeric or with dash ex: 1234567890, TR-1234567890
wallet_id String No Default Main Wallet
seller_code String Yes CU2501-101139033689723677
sign String Yes {GENERATED SIGNATURE}
Field Type Nullable Description
transaction_ref String Yes TR2502-101237442664727769
receiver_info Object Yes receiver_info
status String Yes SUCCEEDED
REFUNDED
CREATED
FAILED
BLOCKED
CANCEL
FAILED ON VERIFY TRX
currency String Yes USD
amount String Yes 2
Error Code Status Code Description
400 VALIDATION_ERROR Validation error.
401 UNAUTHENTICATED Unauthenticated.
403 FORBIDDEN Access denied.
404 NOT_FOUND Record not found.
409 DUPLICATED Existing record found.
419 EXPIRED Requesting record was expired.
422 PROCESS_FAILED Sub-process failed.
500 SYSTEM_ERROR Internal server error.
503 FEATURE_UNDER_MAINTENANCE Feature is under maintenance.
504 GATEWAY_TIMEOUT Gateway time-out.

Virtual Card API Gateway

Use a single endpoint to access every available service based on its service’s name and dynamical parameters.

Create Virtual Card

POST {baseUrl}/api/mch/v2/gateway requires authentication

                    
curl --location --request POST '{baseUrl}/api/mch/v2/gateway' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer {ACCESS TOKEN}' \
--data-raw '{
    "service": "webpay.acquire.createVirtualCard",
    "seller_code": "{SELLER CODE}",
    "cumulative_limit": 3,
    "daily_max_trans": 0,
    "daily_trans_limit_amount": 1,
    "sign_type": "MD5",
    "currency": "USD",
    "sign": "{SIGNATURE}"
}'
                    
                
                    
$curl = curl_init();

curl_setopt_array($curl, array(
    CURLOPT_URL => '{baseUrl}/api/mch/v2/gateway',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_ENCODING => '',
    CURLOPT_MAXREDIRS => 10,
    CURLOPT_TIMEOUT => 0,
    CURLOPT_FOLLOWLOCATION => true,
    CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
    CURLOPT_CUSTOMREQUEST => 'POST',
    CURLOPT_POSTFIELDS =>'{
        "service": "webpay.acquire.createVirtualCard",
        "seller_code": "{SELLER CODE}",
        "cumulative_limit":3,
        "daily_max_trans" : 0,
        "daily_trans_limit_amount": 1,
        "sign_type": "MD5",
        "currency" : "USD",
        "sign": "{SIGNATURE}"
    }',
    CURLOPT_HTTPHEADER => array(
        'Content-Type: application/json',
        'Authorization: Bearer {ACCESS TOKEN}' 
    )
));

$response = curl_exec($curl);

curl_close($curl);

echo $response;
                    
                
                    
{
    "success": true,
    "data": {
        "purchaseRequestId": "24831209",
        "velocityControl": [{
            "maxTrans": 10,
            "period" : "C",
            "cumulativeLimit": 1,
            "availableBalance": 100
        }],
        "transactionLimitControl": {
            "amount": 100
        },
        "vcnInformation": {
            "pan": "5364588625436475",
            "expiry": "2602",
            "avv": "267"
        }
    },
    "sign": "{SIGNATURE}",
    "sign_type": "MD5"
}      
              
                    
                
Field Type Required Description
service String Yes "webpay.acquire.createVirtualCard"
sign_type String Yes MD5 or HMAC-SHA256
seller_code String Yes CU2501-101139033689723677
cumulative_limit Integer Yes 10
daily_max_trans Integer Yes 0
daily_trans_limit_amount Integer Yes 10
currency String Yes USD
wallet_id String No
sign String Yes {GENERATED SIGNATURE}
Field Type Nullable Description
purchaseRequestId String Yes 24831209
velocity_control_info Array Yes velocity_control_info
...
Included common data of transaction_limit_control_info
...
...
Included common data of vcn_information
...
Error Code Status Code Description
400 VALIDATION_ERROR Validation error.
401 UNAUTHENTICATED Unauthenticated.
403 FORBIDDEN Access denied.
404 NOT_FOUND Record not found.
409 DUPLICATED Existing record found.
419 EXPIRED Requesting record was expired.
422 PROCESS_FAILED Sub-process failed.
500 SYSTEM_ERROR Internal server error.
503 FEATURE_UNDER_MAINTENANCE Feature is under maintenance.
504 GATEWAY_TIMEOUT Gateway time-out.

List Virtual Card

POST {baseUrl}/api/mch/v2/gateway requires authentication

                    
curl --location --request POST '{baseUrl}/api/mch/v2/gateway' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer {ACCESS TOKEN}' \
--data-raw '{
    "service": "webpay.acquire.getVirtualCards",
    "seller_code": "{SELLER CODE}",
    "sign": "{SIGNATURE}"
}'
                    
                
                    
$curl = curl_init();

curl_setopt_array($curl, array(
    CURLOPT_URL => '{baseUrl}/api/mch/v2/gateway',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_ENCODING => '',
    CURLOPT_MAXREDIRS => 10,
    CURLOPT_TIMEOUT => 0,
    CURLOPT_FOLLOWLOCATION => true,
    CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
    CURLOPT_CUSTOMREQUEST => 'POST',
    CURLOPT_POSTFIELDS =>'{
        "service": "webpay.acquire.getVirtualCards",
        "seller_code": "{SELLER CODE}",
        "sign": "{SIGNATURE}"
    }',
    CURLOPT_HTTPHEADER => array(
        'Content-Type: application/json',
        'Authorization: Bearer {ACCESS TOKEN}' 
    )
));

$response = curl_exec($curl);

curl_close($curl);

echo $response;
                    
                
                    
{
    "success": true,
    "data": [
        {
            "purchase_req_id": "24808839",
            "pan": "5364588647578601",
            "expiry": "2602",
            "avv": "272",
            "currency": "USD",
            "status": 1
        },
        {
            "purchase_req_id": "24831209",
            "pan": "5364588625436475",
            "expiry": "2602",
            "avv": "267",
            "currency": "USD",
            "status": 1
        }
    ],
    "sign": "{SIGNATURE}",
    "sign_type": "MD5"
}      
              
                    
                
Field Type Required Description
service String Yes "webpay.acquire.getVirtualCards"
sign_type String Yes MD5 or HMAC-SHA256
seller_code String Yes CU2501-101139033689723677
user_id String No
sign String Yes {GENERATED SIGNATURE}
Field Type Nullable Description
purchase_req_id String Yes 24831209
pan String Yes 5364588647578601
expiry String Yes 2603
avv String Yes 263
currency String Yes USD
status Integer Yes 1
Error Code Status Code Description
400 VALIDATION_ERROR Validation error.
401 UNAUTHENTICATED Unauthenticated.
403 FORBIDDEN Access denied.
404 NOT_FOUND Record not found.
409 DUPLICATED Existing record found.
419 EXPIRED Requesting record was expired.
422 PROCESS_FAILED Sub-process failed.
500 SYSTEM_ERROR Internal server error.
503 FEATURE_UNDER_MAINTENANCE Feature is under maintenance.
504 GATEWAY_TIMEOUT Gateway time-out.

Get Virtual Card Balance

POST {baseUrl}/api/mch/v2/gateway requires authentication

                    
curl --location --request POST '{baseUrl}/api/mch/v2/gateway' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer {ACCESS TOKEN}' \
--data-raw '{
    "service": "webpay.acquire.getVirtualCardBalance",
    "seller_code": "{SELLER CODE}",
    "purchase_req_id": "24831209",
    "sign": "{SIGNATURE}"
}'
                    
                
                    
$curl = curl_init();

curl_setopt_array($curl, array(
    CURLOPT_URL => '{baseUrl}/api/mch/v2/gateway',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_ENCODING => '',
    CURLOPT_MAXREDIRS => 10,
    CURLOPT_TIMEOUT => 0,
    CURLOPT_FOLLOWLOCATION => true,
    CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
    CURLOPT_CUSTOMREQUEST => 'POST',
    CURLOPT_POSTFIELDS =>'{
        "service": "webpay.acquire.getVirtualCardBalance",
        "seller_code": "{SELLER CODE}",
        "purchase_req_id" : "24831209",
        "sign": "{SIGNATURE}"
    }',
    CURLOPT_HTTPHEADER => array(
        'Content-Type: application/json',
        'Authorization: Bearer {ACCESS TOKEN}' 
    )
));

$response = curl_exec($curl);

curl_close($curl);

echo $response;
                    
                
                    
{
    "success": true,
    "data": {
        "purchaseRequestId": "24808839",
        "availableBalance": 1
    },
    "sign": "{SIGNATURE}",
    "sign_type": "MD5"
}      
              
                    
                
Field Type Required Description
service String Yes "webpay.acquire.getVirtualCardBalance"
sign_type String Yes MD5 or HMAC-SHA256
seller_code String Yes CU2501-101139033689723677
purchase_req_id String Yes 100
sign String Yes {GENERATED SIGNATURE}
Field Type Nullable Description
purchaseRequestId String Yes 24831209
availableBalance Integer Yes 1
Error Code Status Code Description
400 VALIDATION_ERROR Validation error.
401 UNAUTHENTICATED Unauthenticated.
403 FORBIDDEN Access denied.
404 NOT_FOUND Record not found.
409 DUPLICATED Existing record found.
419 EXPIRED Requesting record was expired.
422 PROCESS_FAILED Sub-process failed.
500 SYSTEM_ERROR Internal server error.
503 FEATURE_UNDER_MAINTENANCE Feature is under maintenance.
504 GATEWAY_TIMEOUT Gateway time-out.

Get Virtual Card Detail

POST {baseUrl}/api/mch/v2/gateway requires authentication

                    
curl --location --request POST '{baseUrl}/api/mch/v2/gateway' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer {ACCESS TOKEN}' \
--data-raw '{
    "service": "webpay.acquire.getVirtualCardDetail",
    "seller_code": "{SELLER CODE}",
    "purchase_req_id": "24831209",
    "sign": "{SIGNATURE}"
}'
                    
                
                    
$curl = curl_init();

curl_setopt_array($curl, array(
    CURLOPT_URL => '{baseUrl}/api/mch/v2/gateway',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_ENCODING => '',
    CURLOPT_MAXREDIRS => 10,
    CURLOPT_TIMEOUT => 0,
    CURLOPT_FOLLOWLOCATION => true,
    CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
    CURLOPT_CUSTOMREQUEST => 'POST',
    CURLOPT_POSTFIELDS =>'{
        "service": "webpay.acquire.getVirtualCardDetail",
        "seller_code": "{SELLER CODE}",
        "purchase_req_id" : "24831209",
        "sign": "{SIGNATURE}"
    }',
    CURLOPT_HTTPHEADER => array(
        'Content-Type: application/json',
        'Authorization: Bearer {ACCESS TOKEN}' 
    )
));

$response = curl_exec($curl);

curl_close($curl);

echo $response;
                    
                
                    
{
    "success": true,
    "data": {
        "purchaseRequestId": "24831209",
        "velocityControl": [{
            "maxTrans": 10,
            "period" : "C",
            "availableBalance": 1,
            "cumulativeLimit": 100
        }],
        "transactionLimitControl": {
            "amount": 100
        },
        "vcnInformation": {
            "pan": "5364588625436475",
            "expiry": "2602",
            "avv": "267"
        }
    },
    "sign": "{SIGNATURE}",
    "sign_type": "MD5"
}      
              
                    
                
Field Type Required Description
service String Yes "webpay.acquire.getVirtualCardDetail"
sign_type String Yes MD5 or HMAC-SHA256
seller_code String Yes CU2501-101139033689723677
purchase_req_id String Yes 100
sign String Yes {GENERATED SIGNATURE}
Field Type Nullable Description
purchaseRequestId String Yes 24831209
velocity_control_info Array Yes velocity_control_info
...
Included common data of transaction_limit_control_info
...
...
Included common data of vcn_information
...
Error Code Status Code Description
400 VALIDATION_ERROR Validation error.
401 UNAUTHENTICATED Unauthenticated.
403 FORBIDDEN Access denied.
404 NOT_FOUND Record not found.
409 DUPLICATED Existing record found.
419 EXPIRED Requesting record was expired.
422 PROCESS_FAILED Sub-process failed.
500 SYSTEM_ERROR Internal server error.
503 FEATURE_UNDER_MAINTENANCE Feature is under maintenance.
504 GATEWAY_TIMEOUT Gateway time-out.

List Virtual Card Report

POST {baseUrl}/api/mch/v2/gateway requires authentication

                    
curl --location --request POST '{baseUrl}/api/mch/v2/gateway' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer {ACCESS TOKEN}' \
--data-raw '{
    "service": "webpay.acquire.getVirtualCardReport",
    "seller_code": "{SELLER CODE}",
    "purchase_req_id": "24831209",
    "from": 0,
    "take": 10,
    "sign": "{SIGNATURE}"
}'
                    
                
                    
$curl = curl_init();

curl_setopt_array($curl, array(
    CURLOPT_URL => '{baseUrl}/api/mch/v2/gateway',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_ENCODING => '',
    CURLOPT_MAXREDIRS => 10,
    CURLOPT_TIMEOUT => 0,
    CURLOPT_FOLLOWLOCATION => true,
    CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
    CURLOPT_CUSTOMREQUEST => 'POST',
    CURLOPT_POSTFIELDS =>'{
        "service": "webpay.acquire.getVirtualCardReport",
        "seller_code": "{SELLER CODE}",
        "purchase_req_id" : "24831209",
        "from" : 0,
        "take" : 10,
        "sign": "{SIGNATURE}"
    }',
    CURLOPT_HTTPHEADER => array(
        'Content-Type: application/json',
        'Authorization: Bearer {ACCESS TOKEN}' 
    )
));

$response = curl_exec($curl);

curl_close($curl);

echo $response;
                    
                
                    
{
    "success": true,
    "data": {
        "reportStatus": "Completed",
        "from": 0,
        "take": 100,
        "hasMore": false,
        "tranInfos": [
            {
                "id": 92,
                "credit_fund_amount": 1,
                "credit_fund_currency": "USD",
                "debit_fund_amount": 0,
                "debit_fund_currency": "USD",
                "type": "topup",
                "is_success": 1,
                "is_settled": 0,
                "trans_date": "2025-04-03 07:11:06",
                "sub_type": null,
                "merchant_name": null,
                "issuer_response": null
            }
        ]
    },
    "sign": "{SIGNATURE}",
    "sign_type": "MD5"
}      
              
                    
                
Field Type Required Description
service String Yes "webpay.acquire.getVirtualCardReport"
sign_type String Yes MD5 or HMAC-SHA256
seller_code String Yes CU2501-101139033689723677
purchase_req_id String Yes 100
from Integer Yes 0
take Integer Yes 100
sign String Yes {GENERATED SIGNATURE}
Field Type Nullable Description
reportStatus String Yes Completed
from Integer Yes 0
take Integer Yes 100
hasMore Boolean Yes false
tranInfos Array yes transaction_virtual_card
Error Code Status Code Description
400 VALIDATION_ERROR Validation error.
401 UNAUTHENTICATED Unauthenticated.
403 FORBIDDEN Access denied.
404 NOT_FOUND Record not found.
409 DUPLICATED Existing record found.
419 EXPIRED Requesting record was expired.
422 PROCESS_FAILED Sub-process failed.
500 SYSTEM_ERROR Internal server error.
503 FEATURE_UNDER_MAINTENANCE Feature is under maintenance.
504 GATEWAY_TIMEOUT Gateway time-out.

TopUp Balance

POST {baseUrl}/api/mch/v2/gateway requires authentication

                    
curl --location --request POST '{baseUrl}/api/mch/v2/gateway' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer {ACCESS TOKEN}' \
--data-raw '{
    "service": "webpay.acquire.cardTopUpBalance",
    "seller_code": "{SELLER CODE}",
    "topup_amount": 3,
    "sign_type": "MD5",
    "purchase_req_id": "xxxx",
    "sign": "{SIGNATURE}"
}'
                    
                
                    
$curl = curl_init();

curl_setopt_array($curl, array(
    CURLOPT_URL => '{baseUrl}/api/mch/v2/gateway',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_ENCODING => '',
    CURLOPT_MAXREDIRS => 10,
    CURLOPT_TIMEOUT => 0,
    CURLOPT_FOLLOWLOCATION => true,
    CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
    CURLOPT_CUSTOMREQUEST => 'POST',
    CURLOPT_POSTFIELDS =>'{
        "service": "webpay.acquire.cardTopUpBalance",
        "seller_code": "{SELLER CODE}",
        "topup_amount":3,
        "sign_type": "MD5",
        "purchase_req_id" : "xxxx",
        "sign": "{SIGNATURE}"
    }',
    CURLOPT_HTTPHEADER => array(
        'Content-Type: application/json',
        'Authorization: Bearer {ACCESS TOKEN}' 
    )
));

$response = curl_exec($curl);

curl_close($curl);

echo $response;
                    
                
                    
{
    "success": true,
    "data": {
        "purchaseRequestId": "24824411",
        "availableBalance": 19
    },
    "sign": "{SIGNATURE}",
    "sign_type": "MD5"
}      
              
                    
                
Field Type Required Description
service String Yes "webpay.acquire.cardTopUpBalance"
sign_type String Yes MD5 or HMAC-SHA256
seller_code String Yes CU2501-101139033689723677
topup_amount Integer Yes 10
purchase_req_id String Yes xxxx
sign String Yes {GENERATED SIGNATURE}
Field Type Nullable Description
purchaseRequestId String Yes 24831209
availableBalance Integer Yes 10
Error Code Status Code Description
400 VALIDATION_ERROR Validation error.
401 UNAUTHENTICATED Unauthenticated.
403 FORBIDDEN Access denied.
404 NOT_FOUND Record not found.
409 DUPLICATED Existing record found.
419 EXPIRED Requesting record was expired.
422 PROCESS_FAILED Sub-process failed.
500 SYSTEM_ERROR Internal server error.
503 FEATURE_UNDER_MAINTENANCE Feature is under maintenance.
504 GATEWAY_TIMEOUT Gateway time-out.

Change Velocity Limit

POST {baseUrl}/api/mch/v2/gateway requires authentication

                    
curl --location --request POST '{baseUrl}/api/mch/v2/gateway' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer {ACCESS TOKEN}' \
--data-raw '{
    "service": "webpay.acquire.changeVelocityLimit",
    "seller_code": "{SELLER CODE}",
    "max_trans": 3,
    "cumulative_limit": 3,
    "sign_type": "MD5",
    "period": "C",
    "purchase_req_id": "xxxx",
    "sign": "{SIGNATURE}"
}'
                    
                
                    
$curl = curl_init();

curl_setopt_array($curl, array(
    CURLOPT_URL => '{baseUrl}/api/mch/v2/gateway',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_ENCODING => '',
    CURLOPT_MAXREDIRS => 10,
    CURLOPT_TIMEOUT => 0,
    CURLOPT_FOLLOWLOCATION => true,
    CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
    CURLOPT_CUSTOMREQUEST => 'POST',
    CURLOPT_POSTFIELDS =>'{
        "service": "webpay.acquire.changeVelocityLimit",
        "seller_code": "{SELLER CODE}",
        "max_trans":3,
        "cumulative_limit":3,
        "sign_type": "MD5",
        "period" : "C",
        "purchase_req_id" : "xxxx",
        "sign": "{SIGNATURE}"
    }',
    CURLOPT_HTTPHEADER => array(
        'Content-Type: application/json',
        'Authorization: Bearer {ACCESS TOKEN}' 
    )
));

$response = curl_exec($curl);

curl_close($curl);

echo $response;
                    
                
                    
{
    "success": true,
    "data": {
        "purchaseRequestId": "24824411",
        "velocityControl": [{
            "maxTrans": 10,
            "availableBalance": 19,
            "period": "C",
            "cumulativeLimit" : 104
        }],
        "transactionLimitControl": {
            "amount": 18
        }
    },
    "sign": "{SIGNATURE}",
    "sign_type": "MD5"
}      
              
                    
                
Field Type Required Description
service String Yes "webpay.acquire.changeVelocityLimit"
sign_type String Yes MD5 or HMAC-SHA256
seller_code String Yes CU2501-101139033689723677
max_trans Integer Yes 10
cumulative_limit Integer Yes 10
purchase_req_id String Yes xxxx
period String Yes C
sign String Yes {GENERATED SIGNATURE}
Field Type Nullable Description
purchaseRequestId String Yes 24831209
velocity_control_info Array Yes velocity_control_info
...
Included common data of transaction_limit_control_info
...
Error Code Status Code Description
400 VALIDATION_ERROR Validation error.
401 UNAUTHENTICATED Unauthenticated.
403 FORBIDDEN Access denied.
404 NOT_FOUND Record not found.
409 DUPLICATED Existing record found.
419 EXPIRED Requesting record was expired.
422 PROCESS_FAILED Sub-process failed.
500 SYSTEM_ERROR Internal server error.
503 FEATURE_UNDER_MAINTENANCE Feature is under maintenance.
504 GATEWAY_TIMEOUT Gateway time-out.

Freeze Card

POST {baseUrl}/api/mch/v2/gateway requires authentication

                    
curl --location --request POST '{baseUrl}/api/mch/v2/gateway' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer {ACCESS TOKEN}' \
--data-raw '{
    "service": "webpay.acquire.freezeCard",
    "seller_code": "{SELLER CODE}",
    "sign_type": "MD5",
    "purchase_req_id": "xxxx",
    "sign": "{SIGNATURE}"
}'
                    
                
                    
$curl = curl_init();

curl_setopt_array($curl, array(
    CURLOPT_URL => '{baseUrl}/api/mch/v2/gateway',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_ENCODING => '',
    CURLOPT_MAXREDIRS => 10,
    CURLOPT_TIMEOUT => 0,
    CURLOPT_FOLLOWLOCATION => true,
    CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
    CURLOPT_CUSTOMREQUEST => 'POST',
    CURLOPT_POSTFIELDS =>'{
        "service": "webpay.acquire.freezeCard",
        "seller_code": "{SELLER CODE}",
        "sign_type": "MD5",
        "purchase_req_id" : "xxxx",
        "sign": "{SIGNATURE}"
    }',
    CURLOPT_HTTPHEADER => array(
        'Content-Type: application/json',
        'Authorization: Bearer {ACCESS TOKEN}' 
    )
));

$response = curl_exec($curl);

curl_close($curl);

echo $response;
                    
                
                    
{
    "success": true,
    "data": {
        "purchaseRequestId": "24824411"
    },
    "sign": "{SIGNATURE}",
    "sign_type": "MD5"
}      
              
                    
                
Field Type Required Description
service String Yes "webpay.acquire.freezeCard"
sign_type String Yes MD5 or HMAC-SHA256
seller_code String Yes CU2501-101139033689723677
purchase_req_id String Yes xxxx
sign String Yes {GENERATED SIGNATURE}
Field Type Nullable Description
purchaseRequestId String Yes 24831209
Error Code Status Code Description
400 VALIDATION_ERROR Validation error.
401 UNAUTHENTICATED Unauthenticated.
403 FORBIDDEN Access denied.
404 NOT_FOUND Record not found.
409 DUPLICATED Existing record found.
419 EXPIRED Requesting record was expired.
422 PROCESS_FAILED Sub-process failed.
500 SYSTEM_ERROR Internal server error.
503 FEATURE_UNDER_MAINTENANCE Feature is under maintenance.
504 GATEWAY_TIMEOUT Gateway time-out.

Unfreeze Card

POST {baseUrl}/api/mch/v2/gateway requires authentication

                    
curl --location --request POST '{baseUrl}/api/mch/v2/gateway' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer {ACCESS TOKEN}' \
--data-raw '{
    "service": "webpay.acquire.unfreezeCard",
    "seller_code": "{SELLER CODE}",
    "sign_type": "MD5",
    "purchase_req_id": "xxxx",
    "sign": "{SIGNATURE}"
}'
                    
                
                    
$curl = curl_init();

curl_setopt_array($curl, array(
    CURLOPT_URL => '{baseUrl}/api/mch/v2/gateway',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_ENCODING => '',
    CURLOPT_MAXREDIRS => 10,
    CURLOPT_TIMEOUT => 0,
    CURLOPT_FOLLOWLOCATION => true,
    CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
    CURLOPT_CUSTOMREQUEST => 'POST',
    CURLOPT_POSTFIELDS =>'{
        "service": "webpay.acquire.unfreezeCard",
        "seller_code": "{SELLER CODE}",
        "sign_type": "MD5",
        "purchase_req_id" : "xxxx",
        "sign": "{SIGNATURE}"
    }',
    CURLOPT_HTTPHEADER => array(
        'Content-Type: application/json',
        'Authorization: Bearer {ACCESS TOKEN}' 
    )
));

$response = curl_exec($curl);

curl_close($curl);

echo $response;
                    
                
                    
{
    "success": true,
    "data": {
        "purchaseRequestId": "24824411"
    },
    "sign": "{SIGNATURE}",
    "sign_type": "MD5"
}      
              
                    
                
Field Type Required Description
service String Yes "webpay.acquire.unfreezeCard"
sign_type String Yes MD5 or HMAC-SHA256
seller_code String Yes CU2501-101139033689723677
purchase_req_id String Yes xxxx
sign String Yes {GENERATED SIGNATURE}
Field Type Nullable Description
purchaseRequestId String Yes 24831209
Error Code Status Code Description
400 VALIDATION_ERROR Validation error.
401 UNAUTHENTICATED Unauthenticated.
403 FORBIDDEN Access denied.
404 NOT_FOUND Record not found.
409 DUPLICATED Existing record found.
419 EXPIRED Requesting record was expired.
422 PROCESS_FAILED Sub-process failed.
500 SYSTEM_ERROR Internal server error.
503 FEATURE_UNDER_MAINTENANCE Feature is under maintenance.
504 GATEWAY_TIMEOUT Gateway time-out.

Tap To Phone API Gateway

Use a single endpoint to access every available service based on its service’s name and dynamical parameters.

Create Order

POST {baseUrl}/api/mch/v2/gateway requires authentication

                    
curl --location --request POST '{baseUrl}/api/mch/v2/gateway' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer {ACCESS TOKEN}' \
--data-raw '{
    "service": "webpay.acquire.kioskCreateOrder",
    "sign_type": "MD5",
    "sign": "{SIGNATURE}",
    "seller_code": "{SELLER CODE}",
    "out_trade_no": "TEST-1234567891",
    "body": "iPhone 13 pro Case",
    "total_amount": 10,
    "currency": "USD",
    "notify_url": "https:\/\/sample.com\/notifyme"
}'
                    
                
                    
$curl = curl_init();

curl_setopt_array($curl, array(
    CURLOPT_URL => '{baseUrl}/api/mch/v2/gateway',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_ENCODING => '',
    CURLOPT_MAXREDIRS => 10,
    CURLOPT_TIMEOUT => 0,
    CURLOPT_FOLLOWLOCATION => true,
    CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
    CURLOPT_CUSTOMREQUEST => 'POST',
    CURLOPT_POSTFIELDS =>'{
        "service": "webpay.acquire.kioskCreateOrder",
        "sign_type": "MD5",
        "sign": "{SIGNATURE}",
        "seller_code": "{SELLER CODE}",
        "out_trade_no": "TEST-1234567891",
        "body": "iPhone 13 pro Case",
        "total_amount": 10,
        "currency": "USD",
        "notify_url": "https://sample.com/notifyme"
    }',
    CURLOPT_HTTPHEADER => array(
        'Content-Type: application/json',
        'Authorization: Bearer {ACCESS TOKEN}' 
    )
));

$response = curl_exec($curl);

curl_close($curl);

echo $response;
                    
                
                    
{
    "success": true,
    "data": {
        "amount": 5,
        "fee": 0,
        "total_amount": 5,
        "order_ref": "000000000936",
        "pre_order_id": "5d7481203376937f82d55942",
        "order_info": {
            "token": "5d7481203376937f82d55942",
            "out_trade_no": "1gbwzExpeN2tsfvruHlfiBCCk",
            "transaction_id": null,
            "body": "test",
            "total_amount": 5,
            "currency": "USD",
            "notify_url": null,
            "version": "4",
            "meta": {
                "customer_fees": {
                    "WECHAT": {
                        "fee": 0,
                        "currency": "USD"
                    },
                    "ALIPAY": {
                        "fee": 0,
                        "currency": "USD"
                    }
                },
                "additional": [],
                "iframe_static_card": null,
                "merchant_info": []
            },
            "status": "WAITING",
            "paid_at": null,
            "settled_at": null,
            "settlement_date": null,
            "expired_at": "2025-02-05T11:02:04.000000Z",
            "created_at": "2025-02-03T09:02:05.000000Z",
            "detail": [],
            "seller": {
                "code": "CU2206-27710032233644359",
                "display_name": "LM",
                "motp_mch_id": "111702",
                "m_id": null
            },
            "tip": null,
            "bank_ref": null,
            "bank_info": [],
            "refund_histories": [],
            "payment_detail": null,
            "error_logs": [],
            "card_info": {
                "BIN": null,
                "scheme": null,
                "card_token": null,
                "swift_code": null,
                "card_hashed": null,
                "holder_name": null,
                "account_logo": null,
                "account_name": null,
                "account_number": null
            },
            "wechat_alipay_info": {
                "openid": null,
                "service": null,
                "currency": null,
                "total_amount": null,
                "total_amount_cny": null
            }
        }
    },
    "sign": "{SIGNATURE}",
    "sign_type": "MD5"
}      
              
                    
                
Field Type Required Description
service String Yes "webpay.acquire.kioskCreateOrder"
sign_type String Yes MD5 or HMAC-SHA256
sign String Yes {GENERATED SIGNATURE}
...
Include common data of a transaction
...
Field Type Nullable Description
amount Double Yes 10
fee Double Yes0.1
total_amount Double Yes 10.1
order_ref String Yes 10799
pre_order_id String Yes 5d7481203376937f82d55942
order_info Object Yes See order_info
Error Code Status Code Description
400 VALIDATION_ERROR Validation error.
401 UNAUTHENTICATED Unauthenticated.
403 FORBIDDEN Access denied.
404 NOT_FOUND Record not found.
409 DUPLICATED Existing record found.
419 EXPIRED Requesting record was expired.
422 PROCESS_FAILED Sub-process failed.
500 SYSTEM_ERROR Internal server error.
503 FEATURE_UNDER_MAINTENANCE Feature is under maintenance.
504 GATEWAY_TIMEOUT Gateway time-out.

Confirm Order

POST {baseUrl}/api/mch/v2/gateway requires authentication

                    
curl --location --request POST '{baseUrl}/api/mch/v2/gateway' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer {ACCESS TOKEN}' \
--data-raw '{
    "service": "webpay.acquire.confirmKioskOrder",
    "sign_type": "MD5",
    "sign": "{SIGNATURE}",
    "pre_order_id": "5d7481203376937f82d55942"
}'
                    
                
                    
$curl = curl_init();

curl_setopt_array($curl, array(
    CURLOPT_URL => '{baseUrl}/api/mch/v2/gateway',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_ENCODING => '',
    CURLOPT_MAXREDIRS => 10,
    CURLOPT_TIMEOUT => 0,
    CURLOPT_FOLLOWLOCATION => true,
    CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
    CURLOPT_CUSTOMREQUEST => 'POST',
    CURLOPT_POSTFIELDS =>'{
        "service": "webpay.acquire.confirmKioskOrder",
        "sign_type": "MD5",
        "sign": "{SIGNATURE}",
        "pre_order_id": "5d7481203376937f82d55942"
    }',
    CURLOPT_HTTPHEADER => array(
        'Content-Type: application/json',
        'Authorization: Bearer {ACCESS TOKEN}' 
    )
));

$response = curl_exec($curl);

curl_close($curl);

echo $response;
                    
                
                    
{
    "success": true,
    "data": {
            "token": "5d7481203376937f82d55942",
            "out_trade_no": "1gbwzExpeN2tsfvruHlfiBCCk",
            "transaction_id": null,
            "body": "test",
            "total_amount": 5,
            "currency": "USD",
            "notify_url": null,
            "version": "4",
            "meta": {
                "customer_fees": {
                    "WECHAT": {
                        "fee": 0,
                        "currency": "USD"
                    },
                    "ALIPAY": {
                        "fee": 0,
                        "currency": "USD"
                    }
                },
                "additional": [],
                "iframe_static_card": null,
                "merchant_info": []
            },
            "status": "WAITING",
            "paid_at": null,
            "settled_at": null,
            "settlement_date": null,
            "expired_at": "2025-02-05T11:02:04.000000Z",
            "created_at": "2025-02-03T09:02:05.000000Z",
            "detail": [],
            "seller": {
                "code": "CU2206-27710032233644359",
                "display_name": "LM",
                "motp_mch_id": "111702",
                "m_id": null
            },
            "tip": null,
            "bank_ref": null,
            "bank_info": [],
            "refund_histories": [],
            "payment_detail": null,
            "error_logs": [],
            "card_info": {
                "BIN": null,
                "scheme": null,
                "card_token": null,
                "swift_code": null,
                "card_hashed": null,
                "holder_name": null,
                "account_logo": null,
                "account_name": null,
                "account_number": null
            },
            "wechat_alipay_info": {
                "openid": null,
                "service": null,
                "currency": null,
                "total_amount": null,
                "total_amount_cny": null
            }
        },
    "sign": "{SIGNATURE}",
    "sign_type": "MD5"
}      
              
                    
                
Field Type Required Description
service String Yes "webpay.acquire.confirmKioskOrder"
sign_type String Yes MD5 or HMAC-SHA256
sign String Yes {GENERATED SIGNATURE}
pre_order_id String Yes 5d7481203376937f82d55942
Field Type Nullable Description
order_info Object Yes See order_info
Error Code Status Code Description
400 VALIDATION_ERROR Validation error.
401 UNAUTHENTICATED Unauthenticated.
403 FORBIDDEN Access denied.
404 NOT_FOUND Record not found.
409 DUPLICATED Existing record found.
419 EXPIRED Requesting record was expired.
422 PROCESS_FAILED Sub-process failed.
500 SYSTEM_ERROR Internal server error.
503 FEATURE_UNDER_MAINTENANCE Feature is under maintenance.
504 GATEWAY_TIMEOUT Gateway time-out.

SDK Document

Document

Mobile Top Up API Gateway

Use a single endpoint to access every available service based on its service’s name and dynamical parameters.

List Mobile Top Up

POST {baseUrl}/api/mch/v2/gateway requires authentication

                    
curl --location --request POST '{baseUrl}/api/mch/v2/gateway' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer {ACCESS TOKEN}' \
--data-raw '{
    "service": "webpay.acquire.listMobileTopUp",
    "sign_type": "MD5",
    "seller_code": "{SELLER CODE}",
    "sign": "{SIGNATURE}"
}'
                    
                
                    
$curl = curl_init();

curl_setopt_array($curl, array(
    CURLOPT_URL => '{baseUrl}/api/mch/v2/gateway',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_ENCODING => '',
    CURLOPT_MAXREDIRS => 10,
    CURLOPT_TIMEOUT => 0,
    CURLOPT_FOLLOWLOCATION => true,
    CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
    CURLOPT_CUSTOMREQUEST => 'POST',
    CURLOPT_POSTFIELDS =>'{
        "service": "webpay.acquire.listMobileTopUp",
        "sign_type": "MD5",
        "seller_code": "{SELLER CODE}",
        "sign": "{SIGNATURE}"
    }',
    CURLOPT_HTTPHEADER => array(
        'Content-Type: application/json',
        'Authorization: Bearer {ACCESS TOKEN}' 
    )
));

$response = curl_exec($curl);

curl_close($curl);

echo $response;
                    
                
                    
{
    "success": true,
    "data": [
        {
            "provider_name": "Smart Axiata",
            "service_name": "smart",
            "logo": "telecoms/February2025/Q0MdFNxvtPQa4D48lood.webp",
            "prefix": "010,015,016,069,070,081,086,087,093,096,098",
            "active": 1,
            "is_under_maintenance": 0,
            "maintenance_description": null,
            "pinless": 1,
            "pinbase": 0
        },
        {
            "provider_name": "Viettel",
            "service_name": "metfone",
            "logo": "telecoms/February2025/PbGVyeBEAvNj4an9y51b.png",
            "prefix": "023,031,060,066,067,068,071,088,090,097",
            "active": 1,
            "is_under_maintenance": 0,
            "maintenance_description": null,
            "pinless": 1,
            "pinbase": 0
        }
    ],
    "sign": "{SIGNATURE}",
    "sign_type": "MD5"
}      
              
                    
                
Field Type Required Description
service String Yes "webpay.acquire.listMobileTopUp"
sign_type String Yes MD5 or HMAC-SHA256
seller_code String Yes CU2501-101139033689723677
sign String Yes {GENERATED SIGNATURE}
Field Type Nullable Description
provider_name String Yes Smart
service_name String Yes smart
logo String Yes xxx.png
prefix String Yes 010,015
active Boolean Yes 1
is_under_maintenance Boolean Yes 0
maintenance_description String Yes xxx
pinless boolean Yes 0
pinbase boolean Yes 0
Error Code Status Code Description
400 VALIDATION_ERROR Validation error.
401 UNAUTHENTICATED Unauthenticated.
403 FORBIDDEN Access denied.
404 NOT_FOUND Record not found.
409 DUPLICATED Existing record found.
419 EXPIRED Requesting record was expired.
422 PROCESS_FAILED Sub-process failed.
500 SYSTEM_ERROR Internal server error.
503 FEATURE_UNDER_MAINTENANCE Feature is under maintenance.
504 GATEWAY_TIMEOUT Gateway time-out.

Mobile Top Up

POST {baseUrl}/api/mch/v2/gateway requires authentication

                    
curl --location --request POST '{baseUrl}/api/mch/v2/gateway' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer {ACCESS TOKEN}' \
--data-raw 'null'
                    
                
                    
$curl = curl_init();

curl_setopt_array($curl, array(
    CURLOPT_URL => '{baseUrl}/api/mch/v2/gateway',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_ENCODING => '',
    CURLOPT_MAXREDIRS => 10,
    CURLOPT_TIMEOUT => 0,
    CURLOPT_FOLLOWLOCATION => true,
    CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
    CURLOPT_CUSTOMREQUEST => 'POST',
    CURLOPT_POSTFIELDS =>'{
        "service": "webpay.acquire.mobileTopUp",
        "sign_type": "MD5",
        "seller_code": "{SELLER CODE}",
        "provider" : "smart",
        "amount" : 1,
        "phone_number" : "010xxxxxx"
        "sign": "{SIGNATURE}"
    }',
    CURLOPT_HTTPHEADER => array(
        'Content-Type: application/json',
        'Authorization: Bearer {ACCESS TOKEN}' 
    )
));

$response = curl_exec($curl);

curl_close($curl);

echo $response;
                    
                
                    
{
    "success": true,
    "data": {
        "is_ok": true,
        "instance_id": "7a052f574199493523b55d90",
        "correlation_id": "101237442664742519"
    },
    "sign": "{SIGNATURE}",
    "sign_type": "MD5"
}      
              
                    
                
Field Type Required Description
service String Yes "webpay.acquire.mobileTopUp"
sign_type String Yes MD5 or HMAC-SHA256
seller_code String Yes CU2501-101139033689723677
provider String Yes smart
topup_method String No default pinless
amount double Yes 1.50
phone_number String Yes 010xxxxxx
sign String Yes {GENERATED SIGNATURE}
Field Type Nullable Description
instance_id String Yes 7a052f574199493523b55d90
is_ok Boolean Yes 1
correlation_id String Yes 101237442664742519
Error Code Status Code Description
400 VALIDATION_ERROR Validation error.
401 UNAUTHENTICATED Unauthenticated.
403 FORBIDDEN Access denied.
404 NOT_FOUND Record not found.
409 DUPLICATED Existing record found.
419 EXPIRED Requesting record was expired.
422 PROCESS_FAILED Sub-process failed.
500 SYSTEM_ERROR Internal server error.
503 FEATURE_UNDER_MAINTENANCE Feature is under maintenance.
504 GATEWAY_TIMEOUT Gateway time-out.

API Gateway

Use a single endpoint to access every available service based on its service’s name and dynamical parameters. We have provided two common services “initiate transaction” and “query” for our merchants to interact with our customers over a web application (WebPay) to process the payment with dynamic amounts and currency.

List payment methods

Pull available payment methods under merchant account.

POST {baseUrl}/api/mch/v2/gateway requires authentication

                    
curl --location --request POST '{baseUrl}/api/mch/v2/gateway' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer {ACCESS TOKEN}' \
--data-raw '{
    "service": "webpay.acquire.getpaymentmethods",
    "sign_type": "MD5",
    "sign": "{SIGNATURE}"
}'
                    
                
                    
$curl = curl_init();

curl_setopt_array($curl, array(
    CURLOPT_URL => '{baseUrl}/api/mch/v2/gateway',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_ENCODING => '',
    CURLOPT_MAXREDIRS => 10,
    CURLOPT_TIMEOUT => 0,
    CURLOPT_FOLLOWLOCATION => true,
    CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
    CURLOPT_CUSTOMREQUEST => 'POST',
    CURLOPT_POSTFIELDS =>'{
        "service": "webpay.acquire.getpaymentmethods",
        "sign_type": "MD5",
        "sign": "{SIGNATURE}"
    }',
    CURLOPT_HTTPHEADER => array(
        'Content-Type: application/json',
        'Authorization: Bearer {ACCESS TOKEN}' 
    )
));

$response = curl_exec($curl);

curl_close($curl);

echo $response;
                    
                
                    
{
    "success": true,
    "data": [
    {
        "id": 12,
        "title": "ABA PAY",
        "img_url": "https:\/\/kess-web-cdn-dev.sgp1.digitaloceanspaces.com\/WEBPAY\/logos\/payment-methods\/January2021\/zNSxh2tYwT9KaNnoQb67.png",
        "bic": "ABAAKHPP",
        "storelink": {
            "ios": "itms-apps:\/\/apple.com\/app\/968860649",
            "android": "https:\/\/play.google.com\/store\/apps\/details?id=com.paygo24.ibank&hl=en&gl=US"
        }
    },
    {
        "id": 13,
        "title": "ACLEDA Pay",
        "img_url": "https:\/\/kess-web-cdn-dev.sgp1.digitaloceanspaces.com\/WEBPAY\/logos\/payment-methods\/January2021\/hByq9E5xKTA9n6En12V2.png",
        "bic": "ACLBKHPP",
        "storelink": {
            "ios": null,
            "android": "http:\/\/play.google.com\/store\/apps\/details?id=com.domain.acledabankqr&hl=en"
        }
    },
    {
        "id": 16,
        "title": "AliPay",
        "img_url": "https:\/\/kess-web-cdn-dev.sgp1.digitaloceanspaces.com\/WEBPAY\/logos\/payment-methods\/January2021\/Q9ERYHkIObsx9b4AHdJ4.jpg",
        "bic": "ALIPAY",
        "storelink": {
            "ios": "itms-apps:\/\/apple.com\/app\/333206289",
            "android": "https:\/\/play.google.com\/store\/apps\/details?id=com.eg.android.AlipayGphone"
        }
    },
    {
        "id": 21,
        "title": "Bakong KHQR",
        "img_url": "https:\/\/kess-web-cdn-dev.sgp1.digitaloceanspaces.com\/WEBPAY\/logos\/payment-methods\/June2022\/AI6o4p5koHpwdKkmFtLU.png",
        "bic": "KHQR",
        "storelink": {
            "ios": null,
            "android": null
        }
    },
    {
        "id": 26,
        "title": "BIC Bank",
        "img_url": "https:\/\/kess-web-cdn-dev.sgp1.digitaloceanspaces.com\/WEBPAY\/logos\/payment-methods\/August2023\/WcZMqhXBF76Im5cv8Tv5.png",
        "bic": "BIOBKHPP",
        "storelink": {
            "ios": null,
            "android": null
        }
    },
    {
        "id": 27,
        "title": "Canadia Bank Plc.",
        "img_url": "https:\/\/kess-web-cdn-dev.sgp1.digitaloceanspaces.com\/WEBPAY\/logos\/payment-methods\/September2023\/ZeSnimPKvM1RmphltTmZ.jpg",
        "bic": "CADIKHPP",
        "storelink": {
            "ios": null,
            "android": null
        }
    },
    {
        "id": 29,
        "title": "Chip Mong Bank",
        "img_url": "https:\/\/kess-web-cdn-dev.sgp1.digitaloceanspaces.com\/WEBPAY\/logos\/payment-methods\/May2024\/XBrHaUjpqYcCSR4Re1Ob.jpg",
        "bic": "CHNOKHPP",
        "storelink": {
            "ios": "https:\/\/apps.apple.com\/kh\/app\/chip-mong-bank\/id1453457373",
            "android": "market:\/\/details?id=com.chipmongbank.mobileappproduction&hl=en"
        }
    },
    {
        "id": 17,
        "title": "eMoney",
        "img_url": "https:\/\/kess-web-cdn-dev.sgp1.digitaloceanspaces.com\/WEBPAY\/logos\/payment-methods\/June2021\/oLIH0G2nZcd5liB5usUs.png",
        "bic": "EMONEY",
        "storelink": {
            "ios": null,
            "android": null
        }
    },
    {
        "id": 30,
        "title": "FTB  Bank",
        "img_url": "https:\/\/kess-web-cdn-dev.sgp1.digitaloceanspaces.com\/WEBPAY\/logos\/payment-methods\/September2024\/Utcp75YBeb2Q1c3QSdKQ.jpg",
        "bic": "FTCCKHPP",
        "storelink": {
            "ios": null,
            "android": null
        }
    },
    {
        "id": 31,
        "title": "Google Pay",
        "img_url": "https:\/\/kess-web-cdn-dev.sgp1.digitaloceanspaces.com\/WEBPAY\/logos\/payment-methods\/March2025\/ocwXSKtGBABEnLpcYgJ0.png",
        "bic": "GOOGLEPAY",
        "storelink": {
            "ios": null,
            "android": null
        }
    },
    {
        "id": 156,
        "title": "Google Pay Master",
        "img_url": "https:\/\/kess-web-cdn-dev.sgp1.digitaloceanspaces.com\/WEBPAY\/logos\/payment-methods\/March2025\/snI1BK0MVTgNOzFion8J.jpg",
        "bic": "GOOGLEPAYMASTER",
        "storelink": {
            "ios": null,
            "android": null
        }
    },
    {
        "id": 155,
        "title": "Google Pay Visa",
        "img_url": "https:\/\/kess-web-cdn-dev.sgp1.digitaloceanspaces.com\/WEBPAY\/logos\/payment-methods\/March2025\/yXo9pFdvg7TiPO2ZMFGh.jpg",
        "bic": "GOOGLEPAYVISA",
        "storelink": {
            "ios": null,
            "android": null
        }
    },
    {
        "id": 28,
        "title": "HATTHA Bank",
        "img_url": "https:\/\/kess-web-cdn-dev.sgp1.digitaloceanspaces.com\/WEBPAY\/logos\/payment-methods\/February2025\/A0qsvnEa37hUs4w3IaOH.png",
        "bic": "HATHKHPP",
        "storelink": {
            "ios": "https:\/\/apps.apple.com\/us\/app\/hattha-mobile\/id1493188010",
            "android": "market:\/\/details?id=com.kh.hkl.mobilebanking"
        }
    },
    {
        "id": 36,
        "title": "Huione Pay",
        "img_url": "https:\/\/kess-web-cdn-dev.sgp1.digitaloceanspaces.com\/WEBPAY\/logos\/payment-methods\/February2025\/sUMs5jiGvHbgHRun4klz.png",
        "bic": "HUIONEPAY",
        "storelink": {
            "ios": null,
            "android": null
        }
    },
    {
        "id": 11,
        "title": "KESS PAY",
        "img_url": "https:\/\/kess-web-cdn-dev.sgp1.digitaloceanspaces.com\/WEBPAY\/logos\/payment-methods\/June2022\/sUGkSOt9bwpLUP80Rdst.png",
        "bic": "KESSKH",
        "storelink": {
            "ios": "itms-apps:\/\/apple.com\/app\/1518521952",
            "android": null
        }
    },
    {
        "id": 24,
        "title": "KHQR",
        "img_url": "https:\/\/kess-web-cdn-dev.sgp1.digitaloceanspaces.com\/WEBPAY\/logos\/payment-methods\/November2022\/93CwJR4tzQNbwLeIUzsD.jpg",
        "bic": "KESSKHQR",
        "storelink": {
            "ios": null,
            "android": null
        }
    },
    {
        "id": 37,
        "title": "Phillip Bank Plc",
        "img_url": "https:\/\/kess-web-cdn-dev.sgp1.digitaloceanspaces.com\/WEBPAY\/logos\/payment-methods\/February2025\/5vcvXcDIQ7wwzmLBJkuw.jpg",
        "bic": "HDSBKHPP",
        "storelink": {
            "ios": null,
            "android": null
        }
    },
    {
        "id": 25,
        "title": "PPCBank",
        "img_url": "https:\/\/kess-web-cdn-dev.sgp1.digitaloceanspaces.com\/WEBPAY\/logos\/payment-methods\/August2023\/rIMxZ5jHbeoAveCFrfIp.jpg",
        "bic": "PPCBKHPP",
        "storelink": {
            "ios": "https:\/\/apps.apple.com\/kh\/app\/ppcbank-mobile-banking\/id1499620876",
            "android": "market:\/\/details?id=kh.com.ppcbank.mbanking2p"
        }
    },
    {
        "id": 14,
        "title": "Sathapana",
        "img_url": "https:\/\/kess-web-cdn-dev.sgp1.digitaloceanspaces.com\/WEBPAY\/logos\/payment-methods\/January2021\/upXnfv34dpBz9UMNeVGm.png",
        "bic": "SBPLKHPP",
        "storelink": {
            "ios": "https:\/\/apps.apple.com\/kh\/app\/sathapana-mobile\/id1358225801",
            "android": "https:\/\/play.google.com\/store\/apps\/details?id=kh.com.sathapana.consumer"
        }
    },
    {
        "id": 19,
        "title": "TrueMoney",
        "img_url": "https:\/\/kess-web-cdn-dev.sgp1.digitaloceanspaces.com\/WEBPAY\/logos\/payment-methods\/June2022\/MBBLsHM6EJeZ3ZejFvkO.png",
        "bic": "TRUEMONEY",
        "storelink": {
            "ios": "https:\/\/apps.apple.com\/kh\/app\/truemoney-cambodia\/id1162466939",
            "android": "https:\/\/play.google.com\/store\/apps\/details?id=th.co.truemoney.wallet&hl=en&gl=US"
        }
    },
    {
        "id": 22,
        "title": "U-Pay",
        "img_url": "https:\/\/kess-web-cdn-dev.sgp1.digitaloceanspaces.com\/WEBPAY\/logos\/payment-methods\/July2022\/vi9RbgdfzifyqsG5TrCF.jpeg",
        "bic": "UPAY",
        "storelink": {
            "ios": null,
            "android": null
        }
    },
    {
        "id": 32,
        "title": "UnionPay",
        "img_url": "https:\/\/kess-web-cdn-dev.sgp1.digitaloceanspaces.com\/WEBPAY\/logos\/payment-methods\/February2025\/tqrrQ2NJDfkRg7eFvuC9.png",
        "bic": "UNIONPAY",
        "storelink": {
            "ios": null,
            "android": null
        }
    },
    {
        "id": 20,
        "title": "Vattanac Bank",
        "img_url": "https:\/\/kess-web-cdn-dev.sgp1.digitaloceanspaces.com\/WEBPAY\/logos\/payment-methods\/August2023\/aHW2liozM453Zqr2xPCz.png",
        "bic": "VBLCKHPP",
        "storelink": {
            "ios": "itms-apps:\/\/apple.com\/app\/1494415503",
            "android": "https:\/\/play.google.com\/store\/apps\/details?id=com.vattanacbank.mobile"
        }
    },
    {
        "id": 9,
        "title": "Visa\/Master Card",
        "img_url": "https:\/\/kess-web-cdn-dev.sgp1.digitaloceanspaces.com\/WEBPAY\/logos\/payment-methods\/July2024\/RHgYIV6UYZGSRIKtqbUP.png",
        "bic": "VISA_MASTER",
        "storelink": {
            "ios": null,
            "android": null
        }
    },
    {
        "id": 15,
        "title": "WeChat Pay",
        "img_url": "https:\/\/kess-web-cdn-dev.sgp1.digitaloceanspaces.com\/WEBPAY\/logos\/payment-methods\/January2021\/ZjWHPwMknOrbjPPi6Rtp.png",
        "bic": "WECHAT",
        "storelink": {
            "ios": "itms-apps:\/\/apple.com\/app\/414478124",
            "android": "https:\/\/play.google.com\/store\/apps\/details?id=com.tencent.mm"
        }
    },
    {
        "id": 18,
        "title": "Wing Bank",
        "img_url": "https:\/\/kess-web-cdn-dev.sgp1.digitaloceanspaces.com\/WEBPAY\/logos\/payment-methods\/July2022\/Q44YlfkgxgXoCwJixuX5.png",
        "bic": "WING",
        "storelink": {
            "ios": null,
            "android": null
        }
    }
],
    "sign": "{SIGNATURE}",
    "sign_type": "MD5"
}      
              
                    
                
Field Type Required Description
service String Yes "webpay.acquire.getpaymentmethods"
sign_type String Yes MD5 or HMAC-SHA256
sign String Yes {GENERATED SIGNATURE}
Field Type Nullable Description
[Array] Array Yes List of available payment methods. See payment_method
Error Code Status Code Description
400 VALIDATION_ERROR Validation error.
401 UNAUTHENTICATED Unauthenticated.
403 FORBIDDEN Access denied.
404 NOT_FOUND Record not found.
409 DUPLICATED Existing record found.
419 EXPIRED Requesting record was expired.
422 PROCESS_FAILED Sub-process failed.
500 SYSTEM_ERROR Internal server error.
503 FEATURE_UNDER_MAINTENANCE Feature is under maintenance.
504 GATEWAY_TIMEOUT Gateway time-out.

Generate Payment Link

Send or open payment link to procceed payment.

POST {baseUrl}/api/mch/v2/gateway requires authentication

                    
curl --location --request POST '{baseUrl}/api/mch/v2/gateway' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer {ACCESS TOKEN}' \
--data-raw '{
    "service": "webpay.acquire.createorder",
    "sign_type": "MD5",
    "sign": "{SIGNATURE}",
    "seller_code": "{SELLER CODE}",
    "out_trade_no": "TEST-1234567891",
    "body": "iPhone 13 pro Case",
    "total_amount": 10,
    "currency": "USD",
    "notify_url": "https:\/\/sample.com\/notifyme",
    "login_type": "ANONYMOUS"
}'
                    
                
                    
$curl = curl_init();

curl_setopt_array($curl, array(
    CURLOPT_URL => '{baseUrl}/api/mch/v2/gateway',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_ENCODING => '',
    CURLOPT_MAXREDIRS => 10,
    CURLOPT_TIMEOUT => 0,
    CURLOPT_FOLLOWLOCATION => true,
    CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
    CURLOPT_CUSTOMREQUEST => 'POST',
    CURLOPT_POSTFIELDS =>'{
        "service": "webpay.acquire.createorder",
        "sign_type": "MD5",
        "sign": "{SIGNATURE}",
        "seller_code": "{SELLER CODE}",
        "out_trade_no": "TEST-1234567891",
        "body": "iPhone 13 pro Case",
        "total_amount": 10,
        "currency": "USD",
        "notify_url": "https://sample.com/notifyme",
        "login_type": "ANONYMOUS"
    }',
    CURLOPT_HTTPHEADER => array(
        'Content-Type: application/json',
        'Authorization: Bearer {ACCESS TOKEN}' 
    )
));

$response = curl_exec($curl);

curl_close($curl);

echo $response;
                    
                
                    
{
    "success": true,
    "data": {
        "token": "111612f019b6836bf1255554",
        "out_trade_no": "TEST-1234567891",
        "transaction_id": null,
        "body": "iPhone 13 pro Case",
        "total_amount": 10,
        "currency": "USD",
        "status": "WAITING",
        "paid_at": null,
        "settled_at": null,
        "settlement_date": null,
        "expired_at": "2022-07-18T10:44:53.000000Z",
        "created_at": "2022-07-18T07:44:54.000000Z",
        "detail": [],
        "seller": {
            "code": "{SELLER CODE}",
            "display_name": "ABCD"
        },
        "payment_detail": null,
        "queue_number": "0001",
        "payment_link": "{baseUrl}/pay/{token}"
    },
    "sign": "{SIGNATURE}",
    "sign_type": "MD5"
}      
              
                    
                
Field Type Required Description
service String Yes "webpay.acquire.createOrder"
sign_type String Yes MD5 or HMAC-SHA256
sign String Yes {GENERATED SIGNATURE}
...
Include common data of a transaction
...
login_type String No Use to define the type of user session. Ex: ANONYMOUS, GENERAL, or FACEBOOK
setting Object No See setting
customer String No {ENCRYPTED CUSTOMER DATA}. See customer
descriptor String No xxx
Field Type Nullable Description
payment_link URL No {baseUrl}/pay/{token}
...
Included common data of order_info
...
Error Code Status Code Description
400 VALIDATION_ERROR Validation error.
401 UNAUTHENTICATED Unauthenticated.
403 FORBIDDEN Access denied.
404 NOT_FOUND Record not found.
409 DUPLICATED Existing record found.
419 EXPIRED Requesting record was expired.
422 PROCESS_FAILED Sub-process failed.
500 SYSTEM_ERROR Internal server error.
503 FEATURE_UNDER_MAINTENANCE Feature is under maintenance.
504 GATEWAY_TIMEOUT Gateway time-out.

Native Pay

Generate dynamic QR code or deeplink.

POST {baseUrl}/api/mch/v2/gateway requires authentication

                    
curl --location --request POST '{baseUrl}/api/mch/v2/gateway' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer {ACCESS TOKEN}' \
--data-raw '{
    "service": "webpay.acquire.nativePay",
    "sign_type": "MD5",
    "sign": "{SIGNATURE}",
    "seller_code": "{SELLER CODE}",
    "out_trade_no": "TEST-1234567891",
    "body": "iPhone 13 pro Case",
    "total_amount": 10,
    "currency": "USD",
    "notify_url": "https:\/\/sample.com\/notifyme",
    "service_code": "KESSKH"
}'
                    
                
                    
$curl = curl_init();

curl_setopt_array($curl, array(
    CURLOPT_URL => '{baseUrl}/api/mch/v2/gateway',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_ENCODING => '',
    CURLOPT_MAXREDIRS => 10,
    CURLOPT_TIMEOUT => 0,
    CURLOPT_FOLLOWLOCATION => true,
    CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
    CURLOPT_CUSTOMREQUEST => 'POST',
    CURLOPT_POSTFIELDS =>'{
        "service": "webpay.acquire.nativePay",
        "sign_type": "MD5",
        "sign": "{SIGNATURE}",
        "seller_code": "{SELLER CODE}",
        "out_trade_no": "TEST-1234567891",
        "body": "iPhone 13 pro Case",
        "total_amount": 10,
        "currency": "USD",
        "notify_url": "https://sample.com/notifyme",
        "service_code": "KESSKH"
    }',
    CURLOPT_HTTPHEADER => array(
        'Content-Type: application/json',
        'Authorization: Bearer {ACCESS TOKEN}' 
    )
));

$response = curl_exec($curl);

curl_close($curl);

echo $response;
                    
                
                    
{
    "success": true,
    "data": {
        "qrcode": "00020101021230100006KESSKH5204000053038405402105802KH5919KESS INNOVATION PLC6010Phnom Penh6236012444816b39953515cd6262b1870304test630448F7",
        "deeplink": null,
        "expires_in": 10799,
        "brand_logo": "https://devwebpayment.kesspay.io/storage/payment-methods/June2022/sUGkSOt9bwpLUP80Rdst.png",
        "app_name": "KESSCHAT",
        "service_code": "KESSKH",
        "order_info": {
            "token": "44816b39953515cd6262b187",
            "out_trade_no": "TEST-1234567892",
            "transaction_id": null,
            "body": "iPhone 13 pro Case",
            "total_amount": 10,
            "currency": "USD",
            "status": "WAITING",
            "paid_at": null,
            "settled_at": null,
            "settlement_date": null,
            "expired_at": "2022-07-19T09:18:55.000000Z",
            "created_at": "2022-07-19T06:18:56.000000Z",
            "detail": [],
            "seller": {
                "code": "{SELLER CODE}",
                "display_name": "Merchant Name"
            },
            "payment_detail": null,
            "error_logs": []
        }
    },
    "sign": "{SIGNATURE}",
    "sign_type": "MD5"
}      
              
                    
                
Field Type Required Description
service String Yes "webpay.acquire.nativePay"
sign_type String Yes MD5 or HMAC-SHA256
sign String Yes {GENERATED SIGNATURE}
...
Include common data of a transaction
...
only_deeplink Boolean No Generate deeplink only. Ex: 1 or 0
is_ios_device Boolean No When only_deeplink is true merchant have to pass this parameter to prove the mobile device\'s OS (IOS or Android). Ex: 1 or 0
service_code String Yes Use one of following:
ABAAKHPP, ACLBKHPP, ALIPAY, KHQR, BIOBKHPP, CADIKHPP, CHNOKHPP, EMONEY, FTCCKHPP, GOOGLEPAY, GOOGLEPAYMASTER, GOOGLEPAYVISA, HATHKHPP, HUIONEPAY, KESSKH, KESSKHQR, HDSBKHPP, PPCBKHPP, SBPLKHPP, TRUEMONEY, UPAY, UNIONPAY, VBLCKHPP, VISA_MASTER, WECHAT, WING
descriptor String No xxx
Field Type Nullable Description
qrcode String Yes Null when qrcode_link is present or deeplink only mode. Ex: {QR code string}
qrcode_link URL Yes Null when qrcode is present or deeplink only mode. Ex: {Link to open QR code}
deeplink String Yes Always present when is it only_deeplink equal 1 (true){Deeplink}
expires_in Integer No In seconds. Ex: 10799
for_ios Boolean Yes To identify the deeplink suit with mobile device OS (IOS or Android)
brand_logo URL Yes Payment method logo
app_name String No Mobile app name. Ex: KESSCHAT
service_code String No Ex: KESSKH
order_info Object No See order_info
Error Code Status Code Description
400 VALIDATION_ERROR Validation error.
401 UNAUTHENTICATED Unauthenticated.
403 FORBIDDEN Access denied.
404 NOT_FOUND Record not found.
409 DUPLICATED Existing record found.
419 EXPIRED Requesting record was expired.
422 PROCESS_FAILED Sub-process failed.
500 SYSTEM_ERROR Internal server error.
503 FEATURE_UNDER_MAINTENANCE Feature is under maintenance.
504 GATEWAY_TIMEOUT Gateway time-out.

Quick Pay

    
curl --location --request POST 'https://devwebpayment.kesspay.io/api/mch/v2/gateway' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer {ACCESS TOKEN}' \
--data-raw '{
    "service": "webpay.acquire.quickpay",
    "sign_type": "MD5",
    "sign": "{SIGNATURE}",
    "seller_code": "{SELLER CODE}",
    "out_trade_no": "TEST-1234567891",
    "body": "iPhone 13 pro Case",
    "total_amount": 10,
    "currency": "USD",
    "notify_url": "https://sample.com/notifyme",
    "service_code": "KESSKH"
}'
    
    
$curl = curl_init();

curl_setopt_array($curl, array(
    CURLOPT_URL => 'https://devwebpayment.kesspay.io/api/mch/v2/gateway',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_ENCODING => '',
    CURLOPT_MAXREDIRS => 10,
    CURLOPT_TIMEOUT => 0,
    CURLOPT_FOLLOWLOCATION => true,
    CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
    CURLOPT_CUSTOMREQUEST => 'POST',
    CURLOPT_POSTFIELDS =>'{
        "service": "webpay.acquire.quickpay",
        "sign_type": "MD5",
        "sign": "{SIGNATURE}",
        "seller_code": "{SELLER CODE}",
        "out_trade_no": "TEST-1234567891",
        "auth_code" : 123453,
        "body": "iPhone 13 pro Case",
        "total_amount": 10,
        "currency": "USD",
        "notify_url": "https://sample.com/notifyme",
        "service_code": "WECHAT"
    }',
    CURLOPT_HTTPHEADER => array(
        'Content-Type: application/json',
        'Authorization: Bearer {ACCESS TOKEN}'
    ),
));

$response = curl_exec($curl);

curl_close($curl);
echo $response;
    

POST {baseUrl}/api/mch/v2/gateway requires authentication

                    
curl --location --request POST '{baseUrl}/api/mch/v2/gateway' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer {ACCESS TOKEN}' \
--data-raw '{
    "service": "webpay.acquire.quickpay",
    "sign_type": "MD5",
    "sign": "{SIGNATURE}",
    "seller_code": "{SELLER CODE}",
    "out_trade_no": "TEST-1234567891",
    "body": "iPhone 13 pro Case",
    "total_amount": 10,
    "currency": "USD",
    "notify_url": "https:\/\/sample.com\/notifyme",
    "login_type": "ANONYMOUS",
    "service_code": "WECHAT",
    "auth_code": 1234567
}'
                    
                
                    
$curl = curl_init();

curl_setopt_array($curl, array(
    CURLOPT_URL => '{baseUrl}/api/mch/v2/gateway',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_ENCODING => '',
    CURLOPT_MAXREDIRS => 10,
    CURLOPT_TIMEOUT => 0,
    CURLOPT_FOLLOWLOCATION => true,
    CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
    CURLOPT_CUSTOMREQUEST => 'POST',
    CURLOPT_POSTFIELDS =>'{
        "service": "webpay.acquire.quickpay",
        "sign_type": "MD5",
        "sign": "{SIGNATURE}",
        "seller_code": "{SELLER CODE}",
        "out_trade_no": "TEST-1234567891",
        "body": "iPhone 13 pro Case",
        "total_amount": 10,
        "currency": "USD",
        "notify_url": "https://sample.com/notifyme",
        "login_type": "ANONYMOUS",
        "service_code" : "WECHAT",
        "auth_code": 1234567
    }',
    CURLOPT_HTTPHEADER => array(
        'Content-Type: application/json',
        'Authorization: Bearer {ACCESS TOKEN}' 
    )
));

$response = curl_exec($curl);

curl_close($curl);

echo $response;
                    
                
                    
{
    "success": true,
    "data": {
        "token": "111612f019b6836bf1255554",
        "out_trade_no": "TEST-1234567891",
        "transaction_id": null,
        "body": "iPhone 13 pro Case",
        "total_amount": 10,
        "currency": "USD",
        "status": "WAITING",
        "paid_at": null,
        "settled_at": null,
        "settlement_date": null,
        "expired_at": "2022-07-18T10:44:53.000000Z",
        "created_at": "2022-07-18T07:44:54.000000Z",
        "detail": [],
        "seller": {
            "code": "{SELLER CODE}",
            "display_name": "Merchant Name"
        },
        "payment_detail": null,
        "queue_number": "0001",
        "card_info" : {
            "BIN": null,
            "scheme": null,
            "card_token": null,
            "swift_code": null,
            "card_hashed": null,
            "holder_name": null,
            "account_logo": null,
            "account_name": null,
            "account_number": null
        },
        "wechat_alipay_info" : {
            "openid": "2088632596656451",
            "service": "Alipay or Wechat",
            "currency": "USD",
            "total_amount": "0.01",
            "total_amount_cny": "0.07"
        },
        "refund_histories" : [
            {
                "amount": 1,
                "currency": "USD",
                "status": "PARTIAL_REFUNDED",
                "reason": "Vgph5a74fsoQr1fgrSinpe9bh",
                "transaction_id": "TR-123",
                "rejected_reason": null,
                "out_trade_no" : "TR-345",
                "merchant_reference" : "xxx"
            }    
        ]
    },
    "sign": "{SIGNATURE}",
    "sign_type": "MD5"
}      
              
                    
                
Field Type Required Description
service String Yes "webpay.acquire.quickpay"
sign_type String Yes MD5 or HMAC-SHA256
sign String Yes {GENERATED SIGNATURE}
seller_code String(32) Yes "CU12-34567890" provided from KESS
out_trade_no String(32) Yes Alphanumeric or with dash ex: 1234567890, TR-1234567890, or TR1234567890
auth_code Numeric Yes 12345
body String(255) Yes Describe your transaction
total_amount Double Yes 10.50 for 10.50USD
currency Char(3) Yes USD or KHR
notify_url String(255) No Notify to merchant server. Ex: https://sample.com/notifyme
service_code String Yes Use one of following:
WECHAT, ALIPAY
Field Type Nullable Description
...
Included common data of order_info
...
Error Code Status Code Description
400 VALIDATION_ERROR Validation error.
401 UNAUTHENTICATED Unauthenticated.
403 FORBIDDEN Access denied.
404 NOT_FOUND Record not found.
409 DUPLICATED Existing record found.
419 EXPIRED Requesting record was expired.
422 PROCESS_FAILED Sub-process failed.
500 SYSTEM_ERROR Internal server error.
503 FEATURE_UNDER_MAINTENANCE Feature is under maintenance.
504 GATEWAY_TIMEOUT Gateway time-out.

Direct Pay

Initiate Credit/Debit card transaction directly from merchant server.

Sequence diagram

direct-pay

API specification

POST {baseUrl}/api/mch/v2/gateway requires authentication

                    
curl --location --request POST '{baseUrl}/api/mch/v2/gateway' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer {ACCESS TOKEN}' \
--data-raw '{
    "service": "webpay.acquire.directPay",
    "sign_type": "MD5",
    "sign": "{SIGNATURE}",
    "seller_code": "{SELLER CODE}",
    "out_trade_no": "TEST-1234567891",
    "body": "iPhone 13 pro Case",
    "total_amount": 10,
    "currency": "USD",
    "notify_url": "https:\/\/sample.com\/notifyme",
    "redirect_url": "https:\/\/sample.com\/redirectme",
    "card": "{ENCRYPTED CARD INFORMATION}",
    "ip_address": "127.0.0.1"
}'
                    
                
                    
$curl = curl_init();

curl_setopt_array($curl, array(
    CURLOPT_URL => '{baseUrl}/api/mch/v2/gateway',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_ENCODING => '',
    CURLOPT_MAXREDIRS => 10,
    CURLOPT_TIMEOUT => 0,
    CURLOPT_FOLLOWLOCATION => true,
    CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
    CURLOPT_CUSTOMREQUEST => 'POST',
    CURLOPT_POSTFIELDS =>'{
        "service": "webpay.acquire.directPay",
        "sign_type": "MD5",
        "sign": "{SIGNATURE}",
        "seller_code": "{SELLER CODE}",
        "out_trade_no": "TEST-1234567891",
        "body": "iPhone 13 pro Case",
        "total_amount": 10,
        "currency": "USD",
        "notify_url": "https://sample.com/notifyme",
        "redirect_url": "https://sample.com/redirectme",
        "card": "{ENCRYPTED CARD INFORMATION}",
        "ip_address" : "127.0.0.1"
    }',
    CURLOPT_HTTPHEADER => array(
        'Content-Type: application/json',
        'Authorization: Bearer {ACCESS TOKEN}' 
    )
));

$response = curl_exec($curl);

curl_close($curl);

echo $response;
                    
                
                    
{
    "success": true,
    "data": {
        "required_3ds": true,
        "pre_card_input": true,
        "html_confirm_payment": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\"><html><head><title>Process Secure Payment</title><meta http-equiv=\"content-type\" content=\"text/html;charset=UTF-8\"><meta name=\"description\" content=\"Process Secure Payment\"><meta name=\"robots\" content=\"noindex\"><style type=\"text/css\">body {font-family:\"Trebuchet MS\",sans-serif; background-color: #FFFFFF; }#msg {border:5px solid #666; background-color:#fff; margin:20px; padding:25px; max-width:40em; -webkit-border-radius: 10px; -khtml-border-radius: 10px; -moz-border-radius: 10px; border-radius: 10px;}#submitButton { text-align: center ; }#footnote {font-size:0.8em;}</style></head><body onload=\"return window.document.echoForm.submit()\"><form name=\"echoForm\" method=\"POST\" action=\"https://mtf.gateway.mastercard.com/acs/MastercardACS/a1ea9661-2440-4f41-82f2-8f5cf81bb808\" accept-charset=\"UTF-8\"><input type=\"hidden\" name=\"PaReq\" value=\"eAFVUdtugkAUfDfxHwjpa9kLomiOa6yXSEzRVG36SmArpLLogre/71mvLU/M7J7ZOTPQO+Ub6yB1mRWqazOH2pZUcZFkat21V8vxq2/3RL0Gy1RLOVzIeK+lgHdZltFaWlmCMxQ/5lOP03bTFjDvf8idgJumQEmHA7lDHNVxGqlKQBTv3oJQeKzJuQvkBiGXOhgKxl2KeksgVwwqyqWYjhaLIAxnn/1lMAuBXEiIi72q9Fkw1gRyB7DXG5FW1bZDyPF4dH7QcqZUcYgqXNWJixyIuQLk6Wi+N95KXPCUJWKQkBEPdPo9jGnpHc5fGfcn2zFpTxtdIOYGJFElBaec0xZrW4x2qN9xcZcLD1FujInVYmi9MOpQikteKdial/pXYAIE8pcBTFljDWfhN/DogUCetoWSqImJPv6BPH0PJibXuMIEvUbL9bCZpqkHCzIJXw6MSoZxcY9eZQwAYkbJrTzM5FIwMv+Kr9d+AQfRs6A=\"><input type=\"hidden\" name=\"TermUrl\" value=\"https://clientdev.kesspay.io/api/3DSecureId/3dsT710032233656121?secureKey=FBDSHJF345FBDNVFD@G5499\"><input type=\"hidden\" name=\"MD\" value=\"\"><noscript><div id=\"msg\"><div id=\"submitButton\"><input type=\"submit\" value=\"Click here to continue\" class=\"button\"></div></div></noscript></form></body></html>\n",
        "order_info": {
            "token": "746173280aeb862720557599",
            "out_trade_no": "1234567893",
            "transaction_id": null,
            "body": "iPhone 13 pro Case",
            "total_amount": 10,
            "currency": "USD",
            "meta": null,
            "status": "WAITING",
            "paid_at": null,
            "settled_at": null,
            "settlement_date": null,
            "expired_at": "2022-07-19T13:08:27.000000Z",
            "created_at": "2022-07-19T10:08:28.000000Z",
            "detail": [],
            "seller": {
                "code": "{SELLER CODE}",
                "display_name": "Merchant Name"
            },
            "payment_detail": null
        }
    },
    "sign": "{SIGNATURE}",
    "sign_type": "MD5"
}      
              
                    
                
Field Type Required Description
service String Yes "webpay.acquire.directPay"
sign_type String Yes MD5 or HMAC-SHA256
sign String Yes {GENERATED SIGNATURE}
...
Include common data of a transaction
...
card String No Required when service_code = VISA_MASTER
{ENCRYPTED CARD INFORMATION}. See card
setting Object No See setting
customer String No {ENCRYPTED CUSTOMER DATA}. See customer
ip_addess String No Required when service_code = VISA_MASTER client ip
service_code String No default VISA_MASTER
Use one of following: VISA_MASTER,GOOGLEPAY,UNIONPAY
descriptor String No xxx
Field Type Nullable Description
required_3ds Boolean No Required merchant to integrate 3DS when it is "true".
pre_card_input Boolean No Card information must be inputted when it is "true", "false" meant user will input card information after the transaction initiated.
html_confirm_payment String Yes Open this HTML in merchant platform when it is not empty. Use it to comfirm 3ds or open card input form when the pre_card_input was "false"
order_info Object No See order_info
Error Code Status Code Description
400 VALIDATION_ERROR Validation error.
401 UNAUTHENTICATED Unauthenticated.
403 FORBIDDEN Access denied.
404 NOT_FOUND Record not found.
409 DUPLICATED Existing record found.
419 EXPIRED Requesting record was expired.
422 PROCESS_FAILED Sub-process failed.
500 SYSTEM_ERROR Internal server error.
503 FEATURE_UNDER_MAINTENANCE Feature is under maintenance.
504 GATEWAY_TIMEOUT Gateway time-out.

Close Order

Update transaction status to CLOSED.

POST {baseUrl}/api/mch/v2/gateway requires authentication

                    
curl --location --request POST '{baseUrl}/api/mch/v2/gateway' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer {ACCESS TOKEN}' \
--data-raw '{
    "service": "webpay.acquire.closeorder",
    "sign_type": "HMAC-SHA256",
    "sign": "4d9ec129143a8f1953b51b1e09f5e632d68f253d4c9458887f0494921922bfb5",
    "out_trade_no": "TEST-1234567891"
}'
                    
                
                    
$curl = curl_init();

curl_setopt_array($curl, array(
    CURLOPT_URL => '{baseUrl}/api/mch/v2/gateway',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_ENCODING => '',
    CURLOPT_MAXREDIRS => 10,
    CURLOPT_TIMEOUT => 0,
    CURLOPT_FOLLOWLOCATION => true,
    CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
    CURLOPT_CUSTOMREQUEST => 'POST',
    CURLOPT_POSTFIELDS =>'{
        "service": "webpay.acquire.closeorder",
        "sign_type": "HMAC-SHA256",
        "sign": "4d9ec129143a8f1953b51b1e09f5e632d68f253d4c9458887f0494921922bfb5",
        "out_trade_no": "TEST-1234567891"
    }',
    CURLOPT_HTTPHEADER => array(
        'Content-Type: application/json',
        'Authorization: Bearer {ACCESS TOKEN}' 
    )
));

$response = curl_exec($curl);

curl_close($curl);

echo $response;
                    
                
                    
{
    "success": true,
    "data": {
        "token": "111612f019b6836bf1255554",
        "out_trade_no": "TEST-1234567891",
        "transaction_id": null,
        "body": "Repay",
        "total_amount": 10,
        "currency": "USD",
        "status": "CLOSED",
        "paid_at": null,
        "settled_at": null,
        "settlement_date": null,
        "expired_at": "2022-07-18T10:44:53.000000Z",
        "created_at": "2022-07-18T07:44:54.000000Z",
        "detail": [],
        "seller": {
            "code": "{SELLER CODE}",
            "display_name": "Merchant Name"
        },
        "payment_detail": null,
        "error_logs": []
    },
    "sign": "{SIGNATURE}",
    "sign_type": "MD5"
}      
              
                    
                
Field Type Required Description
service String Yes "webpay.acquire.closeorder"
sign_type String Yes MD5 or HMAC-SHA256
sign String Yes {GENERATED SIGNATURE}
out_trade_no String(32) Yes Alphanumeric or with dash ex: 1234567890, TR-1234567890, or TR1234567890
Field Type Nullable Description
...
Included common data of order_info
...
Error Code Status Code Description
400 VALIDATION_ERROR Validation error.
401 UNAUTHENTICATED Unauthenticated.
403 FORBIDDEN Access denied.
404 NOT_FOUND Record not found.
409 DUPLICATED Existing record found.
419 EXPIRED Requesting record was expired.
422 PROCESS_FAILED Sub-process failed.
500 SYSTEM_ERROR Internal server error.
503 FEATURE_UNDER_MAINTENANCE Feature is under maintenance.
504 GATEWAY_TIMEOUT Gateway time-out.

Query Order

Transaction inquiry.

POST {baseUrl}/api/mch/v2/gateway requires authentication

                    
curl --location --request POST '{baseUrl}/api/mch/v2/gateway' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer {ACCESS TOKEN}' \
--data-raw '{
    "service": "webpay.acquire.queryOrder",
    "sign_type": "MD5",
    "sign": "{SIGNATURE}",
    "out_trade_no": "TEST-1234567891"
}'
                    
                
                    
$curl = curl_init();

curl_setopt_array($curl, array(
    CURLOPT_URL => '{baseUrl}/api/mch/v2/gateway',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_ENCODING => '',
    CURLOPT_MAXREDIRS => 10,
    CURLOPT_TIMEOUT => 0,
    CURLOPT_FOLLOWLOCATION => true,
    CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
    CURLOPT_CUSTOMREQUEST => 'POST',
    CURLOPT_POSTFIELDS =>'{
        "service": "webpay.acquire.queryOrder",
        "sign_type": "MD5",
        "sign": "{SIGNATURE}",
        "out_trade_no": "TEST-1234567891"
    }',
    CURLOPT_HTTPHEADER => array(
        'Content-Type: application/json',
        'Authorization: Bearer {ACCESS TOKEN}' 
    )
));

$response = curl_exec($curl);

curl_close($curl);

echo $response;
                    
                
                    
{
    "success": true,
    "data": {
        "token": "111612f019b6836bf1255554",
        "out_trade_no": "TEST-1234567891",
        "transaction_id": null,
        "body": "iPhone 13 pro Case",
        "total_amount": 10,
        "currency": "USD",
        "status": "WAITING",
        "paid_at": null,
        "settled_at": null,
        "settlement_date": null,
        "expired_at": "2022-07-18T10:44:53.000000Z",
        "created_at": "2022-07-18T07:44:54.000000Z",
        "detail": [],
        "error_logs" : [],
        "seller": {
            "code": "{SELLER CODE}",
            "display_name": "Merchant Name"
        },
        "payment_detail": null,
        "queue_number": "0001",
        "card_info" : {
            "BIN": null,
            "scheme": null,
            "card_token": null,
            "swift_code": null,
            "card_hashed": null,
            "holder_name": null,
            "account_logo": null,
            "account_name": null,
            "account_number": null
        },
        "wechat_alipay_info" : {
            "openid": "2088632596656451",
            "service": "Alipay or Wechat",
            "currency": "USD",
            "total_amount": "0.01",
            "total_amount_cny": "0.07"
        },
        "refund_histories" : [
            {
                "amount": 1,
                "currency": "USD",
                "status": "PARTIAL_REFUNDED",
                "reason": "Vgph5a74fsoQr1fgrSinpe9bh",
                "transaction_id": "TR-123",
                "rejected_reason": null,
                "out_trade_no" : "TR-345",
                "merchant_reference" : "xxx"
            }    
        ]
    },
    "sign": "{SIGNATURE}",
    "sign_type": "MD5"
}      
              
                    
                
Field Type Required Description
service String Yes "webpay.acquire.queryOrder"
sign_type String Yes MD5 or HMAC-SHA256
sign String Yes {GENERATED SIGNATURE}
out_trade_no String(32) Yes Alphanumeric or with dash ex: 1234567890, TR-1234567890, or TR1234567890
Field Type Nullable Description
...
Included common data of order_info
...
Error Code Status Code Description
400 VALIDATION_ERROR Validation error.
401 UNAUTHENTICATED Unauthenticated.
403 FORBIDDEN Access denied.
404 NOT_FOUND Record not found.
409 DUPLICATED Existing record found.
419 EXPIRED Requesting record was expired.
422 PROCESS_FAILED Sub-process failed.
500 SYSTEM_ERROR Internal server error.
503 FEATURE_UNDER_MAINTENANCE Feature is under maintenance.
504 GATEWAY_TIMEOUT Gateway time-out.

Query Refund

Transaction inquiry.

POST {baseUrl}/api/mch/v2/gateway requires authentication

                    
curl --location --request POST '{baseUrl}/api/mch/v2/gateway' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer {ACCESS TOKEN}' \
--data-raw 'null'
                    
                
                    
$curl = curl_init();

curl_setopt_array($curl, array(
    CURLOPT_URL => '{baseUrl}/api/mch/v2/gateway',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_ENCODING => '',
    CURLOPT_MAXREDIRS => 10,
    CURLOPT_TIMEOUT => 0,
    CURLOPT_FOLLOWLOCATION => true,
    CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
    CURLOPT_CUSTOMREQUEST => 'POST',
    CURLOPT_POSTFIELDS =>'{
        "service": "webpay.acquire.queryRefund",
        "sign_type": "MD5",
        "sign": "{SIGNATURE}",
        "out_trade_no": "TEST-1234567891",
    }',
    CURLOPT_HTTPHEADER => array(
        'Content-Type: application/json',
        'Authorization: Bearer {ACCESS TOKEN}' 
    )
));

$response = curl_exec($curl);

curl_close($curl);

echo $response;
                    
                
                    
{
    "success": true,
    "data": {
        "amount": 1,
        "currency": "USD",
        "status": "PARTIAL_REFUNDED",
        "reason": "Vgph5a74fsoQr1fgrSinpe9bh",
        "transaction_id": "TEST-1234567891",
        "rejected_reason": null,
        "out_trade_no" : "TR-345",
        "merchant_reference" : "xxx"
    },
    "sign": "{SIGNATURE}",
    "sign_type": "MD5"
}      
              
                    
                
Field Type Required Description
service String Yes "webpay.acquire.queryRefund"
sign_type String Yes MD5 or HMAC-SHA256
sign String Yes {GENERATED SIGNATURE}
transaction_id String(32) No Required field when merchant_reference empty, TR-1234567890, or TR1234567890
merchant_reference String(32) No Required field when transaction_id empty, TR-1234567890, or TR1234567890
Field Type Nullable Description
...
Included common data of refund_histories
...
Error Code Status Code Description
400 VALIDATION_ERROR Validation error.
401 UNAUTHENTICATED Unauthenticated.
403 FORBIDDEN Access denied.
404 NOT_FOUND Record not found.
409 DUPLICATED Existing record found.
419 EXPIRED Requesting record was expired.
422 PROCESS_FAILED Sub-process failed.
500 SYSTEM_ERROR Internal server error.
503 FEATURE_UNDER_MAINTENANCE Feature is under maintenance.
504 GATEWAY_TIMEOUT Gateway time-out.

Query Order By Date Range

Transaction inquiry.

POST {baseUrl}/api/mch/v2/gateway requires authentication

                    
curl --location --request POST '{baseUrl}/api/mch/v2/gateway' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer {ACCESS TOKEN}' \
--data-raw '{
    "service": "webpay.acquire.queryorderbydaterange",
    "sign_type": "MD5",
    "sign": "{SIGNATURE}",
    "start_date": "2022-01-15",
    "end_date": "2022-01-16",
    "per_page": 50,
    "page": 1
}'
                    
                
                    
$curl = curl_init();

curl_setopt_array($curl, array(
    CURLOPT_URL => '{baseUrl}/api/mch/v2/gateway',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_ENCODING => '',
    CURLOPT_MAXREDIRS => 10,
    CURLOPT_TIMEOUT => 0,
    CURLOPT_FOLLOWLOCATION => true,
    CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
    CURLOPT_CUSTOMREQUEST => 'POST',
    CURLOPT_POSTFIELDS =>'{
        "service": "webpay.acquire.queryorderbydaterange",
        "sign_type": "MD5",
        "sign": "{SIGNATURE}",
        "start_date": "2022-01-15",
        "end_date": "2022-01-16",
        "per_page" : 50,
        "page" : 1
    }',
    CURLOPT_HTTPHEADER => array(
        'Content-Type: application/json',
        'Authorization: Bearer {ACCESS TOKEN}' 
    )
));

$response = curl_exec($curl);

curl_close($curl);

echo $response;
                    
                
                    
{
    "success": true,
    "data": {
        "items": [
            {
                "token": "111612f019b6836bf1255554",
                "out_trade_no": "TEST-1234567891",
                "transaction_id": null,
                "body": "iPhone 13 pro Case",
                "total_amount": 10,
                "currency": "USD",
                "status": "WAITING",
                "paid_at": null,
                "settled_at": null,
                "settlement_date": null,
                "expired_at": "2022-07-18T10:44:53.000000Z",
                "created_at": "2022-07-18T07:44:54.000000Z",
                "detail": [],
                "seller": {
                    "code": "{SELLER CODE}",
                    "display_name": "Merchant Name"
                },
                "payment_detail": null,
                "queue_number": "0001"
            }
        ],
        "current_page": 1,
        "last_page": 1,
        "total": 1,
        "per_page": 50
    },
    "sign": "{SIGNATURE}",
    "sign_type": "MD5"
}      
              
                    
                
Field Type Required Description
service String Yes "webpay.acquire.queryorderbydaterange"
sign_type String Yes MD5 or HMAC-SHA256
sign String Yes {GENERATED SIGNATURE}
start_date date Yes 2022-01-15
end_date date Yes End date must be after or equal start date 2022-01-15
per_page Integer Yes Must be between 1 and 1000
page Integer Yes Must be start from number one
Field Type Nullable Description
...
Included common data of order_info
...
Error Code Status Code Description
400 VALIDATION_ERROR Validation error.
401 UNAUTHENTICATED Unauthenticated.
403 FORBIDDEN Access denied.
404 NOT_FOUND Record not found.
409 DUPLICATED Existing record found.
419 EXPIRED Requesting record was expired.
422 PROCESS_FAILED Sub-process failed.
500 SYSTEM_ERROR Internal server error.
503 FEATURE_UNDER_MAINTENANCE Feature is under maintenance.
504 GATEWAY_TIMEOUT Gateway time-out.

Refund

Available for VISA_MASTER ,Wing Bank, ACLEDA Bank, WeChat and Alipay only.
For refund, Visa Card,Wing Bank,ACLEDA Bank processing time is up to 15 days.

POST {baseUrl}/api/mch/v2/gateway requires authentication

                    
curl --location --request POST '{baseUrl}/api/mch/v2/gateway' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer {ACCESS TOKEN}' \
--data-raw '{
    "service": "webpay.acquire.v2Refund",
    "sign_type": "MD5",
    "sign": "{SIGNATURE}",
    "out_trade_no": "TEST-1234567891",
    "reason": "test"
}'
                    
                
                    
$curl = curl_init();

curl_setopt_array($curl, array(
    CURLOPT_URL => '{baseUrl}/api/mch/v2/gateway',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_ENCODING => '',
    CURLOPT_MAXREDIRS => 10,
    CURLOPT_TIMEOUT => 0,
    CURLOPT_FOLLOWLOCATION => true,
    CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
    CURLOPT_CUSTOMREQUEST => 'POST',
    CURLOPT_POSTFIELDS =>'{
        "service": "webpay.acquire.v2Refund",
        "sign_type": "MD5",
        "sign": "{SIGNATURE}",
        "out_trade_no": "TEST-1234567891",
        "reason" : "test"
    }',
    CURLOPT_HTTPHEADER => array(
        'Content-Type: application/json',
        'Authorization: Bearer {ACCESS TOKEN}' 
    )
));

$response = curl_exec($curl);

curl_close($curl);

echo $response;
                    
                
                    
{
    "success": true,
    "data": {
        "amount": 1,
        "currency": "USD",
        "status": "PARTIAL_REFUNDED",
        "reason": "Vgph5a74fsoQr1fgrSinpe9bh",
        "transaction_id": "TR-1234",
        "rejected_reason": null,
        "out_trade_no" : "TR-345",
        "merchant_reference" : "xxx"
    },
    "sign": "{SIGNATURE}",
    "sign_type": "MD5"
}      
              
                    
                
Field Type Required Description
service String Yes "webpay.acquire.v2Refund"
sign_type String Yes MD5 or HMAC-SHA256
sign String Yes {GENERATED SIGNATURE}
out_trade_no String Yes TEST-1234567891
partial_refund_amount numeric No 10
partial_refund_amount_ccy String No USD
reason String Yes TEST
callback_url String No https://sample.com/notifyme
merchant_reference String No TEST
Field Type Nullable Description
...
Included common data of refund_histories
...
Error Code Status Code Description
400 VALIDATION_ERROR Validation error.
401 UNAUTHENTICATED Unauthenticated.
403 FORBIDDEN Access denied.
404 NOT_FOUND Record not found.
409 DUPLICATED Existing record found.
419 EXPIRED Requesting record was expired.
422 PROCESS_FAILED Sub-process failed.
500 SYSTEM_ERROR Internal server error.
503 FEATURE_UNDER_MAINTENANCE Feature is under maintenance.
504 GATEWAY_TIMEOUT Gateway time-out.

Tokenize

Tokenize Card

    
curl --location --request POST 'https://devwebpayment.kesspay.io/api/mch/v2/gateway' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer {ACCESS TOKEN}' \
--data-raw '{
    "service": "webpay.acquire.saveCard",
    "sign_type": "MD5",
    "sign": "{SIGNATURE}",
    "seller_code": "{SELLER CODE}",
    "notify_url": "https://sample.com/notifyme"
}'
    
    
$curl = curl_init();

curl_setopt_array($curl, array(
    CURLOPT_URL => 'https://devwebpayment.kesspay.io/api/mch/v2/gateway',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_ENCODING => '',
    CURLOPT_MAXREDIRS => 10,
    CURLOPT_TIMEOUT => 0,
    CURLOPT_FOLLOWLOCATION => true,
    CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
    CURLOPT_CUSTOMREQUEST => 'POST',
    CURLOPT_POSTFIELDS =>'{
        "service": "webpay.acquire.saveCard",
        "sign_type": "MD5",
        "sign": "{SIGNATURE}",
        "seller_code": "{SELLER CODE}",
        "notify_url": "https://sample.com/notifyme"
    }',
    CURLOPT_HTTPHEADER => array(
        'Content-Type: application/json',
        'Authorization: Bearer {ACCESS TOKEN}'
    ),
));

$response = curl_exec($curl);

curl_close($curl);
echo $response;
    

POST {baseUrl}/api/mch/v2/gateway requires authentication

                    
curl --location --request POST '{baseUrl}/api/mch/v2/gateway' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer {ACCESS TOKEN}' \
--data-raw '{
    "service": "webpay.acquire.saveCard",
    "sign_type": "MD5",
    "sign": "{SIGNATURE}",
    "seller_code": "{SELLER CODE}",
    "notify_url": "https:\/\/sample.com\/notifyme"
}'
                    
                
                    
$curl = curl_init();

curl_setopt_array($curl, array(
    CURLOPT_URL => '{baseUrl}/api/mch/v2/gateway',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_ENCODING => '',
    CURLOPT_MAXREDIRS => 10,
    CURLOPT_TIMEOUT => 0,
    CURLOPT_FOLLOWLOCATION => true,
    CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
    CURLOPT_CUSTOMREQUEST => 'POST',
    CURLOPT_POSTFIELDS =>'{
        "service": "webpay.acquire.saveCard",
        "sign_type": "MD5",
        "sign": "{SIGNATURE}",
        "seller_code": "{SELLER CODE}",
        "notify_url": "https://sample.com/notifyme"
    }',
    CURLOPT_HTTPHEADER => array(
        'Content-Type: application/json',
        'Authorization: Bearer {ACCESS TOKEN}' 
    )
));

$response = curl_exec($curl);

curl_close($curl);

echo $response;
                    
                
                    
{
    "success": true,
    "data":  {
        "link": "https://devwebpayment.kesspay.io/spa/inti-card?token=9109e714384c001482515129"
    },
    "sign": "{SIGNATURE}",
    "sign_type": "MD5"
}      
              
                    
                
Field Type Required Description
service String Yes "webpay.acquire.saveCard"
sign_type String Yes MD5 or HMAC-SHA256
sign String Yes {GENERATED SIGNATURE}
seller_code String(32) Yes "CU12-34567890" provided from KESS
notify_url String(255) Yes Notify to merchant server. Ex: https://sample.com/notifyme
redirect_url String(255) No Redirect to merchant server. Ex: https://sample.com/redirectme
Field Type Nullable Description
link URL No {baseUrl}/spa/inti-card?token={token}
Error Code Status Code Description
400 VALIDATION_ERROR Validation error.
401 UNAUTHENTICATED Unauthenticated.
403 FORBIDDEN Access denied.
404 NOT_FOUND Record not found.
409 DUPLICATED Existing record found.
419 EXPIRED Requesting record was expired.
422 PROCESS_FAILED Sub-process failed.
500 SYSTEM_ERROR Internal server error.
503 FEATURE_UNDER_MAINTENANCE Feature is under maintenance.
504 GATEWAY_TIMEOUT Gateway time-out.

Subscription

POST {baseUrl}/api/mch/v2/gateway requires authentication

                    
curl --location --request POST '{baseUrl}/api/mch/v2/gateway' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer {ACCESS TOKEN}' \
--data-raw '{
    "service": "webpay.acquire.subscription",
    "sign_type": "MD5",
    "sign": "{SIGNATURE}",
    "pre_order_token": "TEST-1234567891",
    "seller_code": "test",
    "holder_name": "test",
    "card": "{ENCRYPTED CARD INFORMATION}",
    "interval": "monthly"
}'
                    
                
                    
$curl = curl_init();

curl_setopt_array($curl, array(
    CURLOPT_URL => '{baseUrl}/api/mch/v2/gateway',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_ENCODING => '',
    CURLOPT_MAXREDIRS => 10,
    CURLOPT_TIMEOUT => 0,
    CURLOPT_FOLLOWLOCATION => true,
    CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
    CURLOPT_CUSTOMREQUEST => 'POST',
    CURLOPT_POSTFIELDS =>'{
        "service": "webpay.acquire.subscription",
        "sign_type": "MD5",
        "sign": "{SIGNATURE}",
        "pre_order_token": "TEST-1234567891",
        "seller_code" : "test",
        "holder_name" : "test",
        "card" : "{ENCRYPTED CARD INFORMATION}",
        "interval" : "monthly"
    }',
    CURLOPT_HTTPHEADER => array(
        'Content-Type: application/json',
        'Authorization: Bearer {ACCESS TOKEN}' 
    )
));

$response = curl_exec($curl);

curl_close($curl);

echo $response;
                    
                
                    
{
    "success": true,
    "data": {
        "code": "SUB2502-101238649986744586",
        "status": "created",
        "html_confirm_payment": "<div id=\"redirectTo3ds1AcsSimple\"></div>"
    },
    "sign": "{SIGNATURE}",
    "sign_type": "MD5"
}      
              
                    
                
Field Type Required Description
service String Yes "webpay.acquire.subscription"
sign_type String Yes MD5 or HMAC-SHA256
sign String Yes {GENERATED SIGNATURE}
pre_order_token String Yes TEST-1234567891
seller_code String Yes TEST-1234567891
holder_name String Yes xxx
card String Yes {ENCRYPTED CARD INFORMATION}. See card
interval String Yes monthly
Field Type Nullable Description
code String Yes TEST-1234567891
status String Yes created
html_confirm_payment String Yes xxx
Error Code Status Code Description
400 VALIDATION_ERROR Validation error.
401 UNAUTHENTICATED Unauthenticated.
403 FORBIDDEN Access denied.
404 NOT_FOUND Record not found.
409 DUPLICATED Existing record found.
419 EXPIRED Requesting record was expired.
422 PROCESS_FAILED Sub-process failed.
500 SYSTEM_ERROR Internal server error.
503 FEATURE_UNDER_MAINTENANCE Feature is under maintenance.
504 GATEWAY_TIMEOUT Gateway time-out.

Withdraw (Cash-out)

To withdraw (cash-out) please follow these guidelines:

Verify Bank Account

Verify bank account number and pull bank number holder name (use to display to sender).

POST {baseUrl}/api/mch/v2/gateway requires authentication

                    
curl --location --request POST '{baseUrl}/api/mch/v2/gateway' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer {ACCESS TOKEN}' \
--data-raw '{
    "service": "webpay.acquire.verifybankaccount",
    "sign": "00afabe1d95f8f671becc626b4785c39",
    "sign_type": "MD5",
    "seller_code": "{SELLER CODE}",
    "bank_account_number": "123456789",
    "bic": "ABAAKHPP"
}'
                    
                
                    
$curl = curl_init();

curl_setopt_array($curl, array(
    CURLOPT_URL => '{baseUrl}/api/mch/v2/gateway',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_ENCODING => '',
    CURLOPT_MAXREDIRS => 10,
    CURLOPT_TIMEOUT => 0,
    CURLOPT_FOLLOWLOCATION => true,
    CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
    CURLOPT_CUSTOMREQUEST => 'POST',
    CURLOPT_POSTFIELDS =>'{
        "service": "webpay.acquire.verifybankaccount",
        "sign": "00afabe1d95f8f671becc626b4785c39",
        "sign_type": "MD5",
        "seller_code": "{SELLER CODE}",
        "bank_account_number": "123456789",
        "bic": "ABAAKHPP"
    }',
    CURLOPT_HTTPHEADER => array(
        'Content-Type: application/json',
        'Authorization: Bearer {ACCESS TOKEN}' 
    )
));

$response = curl_exec($curl);

curl_close($curl);

echo $response;
                    
                
                    
{
    "success": true,
    "data": {
        "owner_name": "TESTING-ABA-KESS",
        "currency": "USD",
        "account_number": "123456789"
    },
    "sign": "{SIGNATURE}",
    "sign_type": "MD5"
}      
              
                    
                
Field Type Required Description
service String Yes "webpay.acquire.verifybankaccount"
sign_type String Yes MD5 or HMAC-SHA256
sign String Yes {GENERATED SIGNATURE}
bank_account_number Numeric Yes Ex: 000123456, 012345678, 123456789012345
seller_code String Yes {SELLER CODE}
bic String Yes ACLBKHPP for Acleda Bank, WING for Wing Bank. and ABAAKHPP for ABA Bank. Ex: ACLBKHPP
Field Type Nullable Description
owner_name String No Bank account holder name. Please use this name to display to sender!. Ex: TESTING-ABA-KESS
currency Char(3) No USD or KHR
account_number Numeric No Ex: 123456789
Error Code Status Code Description
400 VALIDATION_ERROR Validation error.
401 UNAUTHENTICATED Unauthenticated.
403 FORBIDDEN Access denied.
404 NOT_FOUND Record not found.
409 DUPLICATED Existing record found.
419 EXPIRED Requesting record was expired.
422 PROCESS_FAILED Sub-process failed.
500 SYSTEM_ERROR Internal server error.
503 FEATURE_UNDER_MAINTENANCE Feature is under maintenance.
504 GATEWAY_TIMEOUT Gateway time-out.

Tokenize Bank Account

Store bank account numbers with customer information in the KESS system for future usage.

POST {baseUrl}/api/mch/v2/gateway requires authentication

                    
curl --location --request POST '{baseUrl}/api/mch/v2/gateway' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer {ACCESS TOKEN}' \
--data-raw '{
    "service": "webpay.acquire.tokenizebankaccount",
    "sign": "79e69e298da1c85cf09366c35e366917",
    "sign_type": "MD5",
    "bank_account_number": "123456789",
    "bic": "ABAAKHPP",
    "seller_code": "{SELLER CODE}",
    "customer": "{ENCRYPTED CUSTOMER DATA}"
}'
                    
                
                    
$curl = curl_init();

curl_setopt_array($curl, array(
    CURLOPT_URL => '{baseUrl}/api/mch/v2/gateway',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_ENCODING => '',
    CURLOPT_MAXREDIRS => 10,
    CURLOPT_TIMEOUT => 0,
    CURLOPT_FOLLOWLOCATION => true,
    CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
    CURLOPT_CUSTOMREQUEST => 'POST',
    CURLOPT_POSTFIELDS =>'{
        "service": "webpay.acquire.tokenizebankaccount",
        "sign": "79e69e298da1c85cf09366c35e366917",
        "sign_type": "MD5",
        "bank_account_number": "123456789",
        "bic": "ABAAKHPP",
        "seller_code": "{SELLER CODE}",
        "customer": "{ENCRYPTED CUSTOMER DATA}"
    }',
    CURLOPT_HTTPHEADER => array(
        'Content-Type: application/json',
        'Authorization: Bearer {ACCESS TOKEN}' 
    )
));

$response = curl_exec($curl);

curl_close($curl);

echo $response;
                    
                
                    
{
    "success": true,
    "data": {
        "token": "02246c07832b03d22a81551c7e962129c5628301324a0c90a",
        "holder_name": "TESTING-ABA-KESS",
        "account_number": "12****789",
        "bank_bic": "ABAAKHPP",
        "currency": "USD"
    },
    "sign": "{SIGNATURE}",
    "sign_type": "MD5"
}      
              
                    
                
Field Type Required Description
service String Yes "webpay.acquire.tokenizebankaccount"
sign_type String Yes MD5 or HMAC-SHA256
sign String Yes {GENERATED SIGNATURE}
seller_code String Yes {SELLER CODE}
bank_account_number Numeric Yes Ex: 000123456, 012345678, 123456789012345
bic String Yes ACLBKHPP for Acleda Bank, WING for Wing Bank. and ABAAKHPP for ABA Bank. Ex: ACLBKHPP
customer String Yes {ENCRYPTED CUSTOMER DATA}. See customer
Field Type Nullable Description
token String(64) No Alphanumeric. Tokenize identifier. Use this token for withdraw API. Ex: 02246c07832b03d22a81551c7e962129c5628301324a0c90a
holder_name String No Bank account holder name. Please use this name to display to sender!. Ex: TESTING-ABA-KESS
account_number Numeric No Ex: 123456789
bank_bic String No ACLBKHPP for Acleda Bank and ABAAKHPP for ABA Bank. Ex: ACLBKHPP
currency Char(3) No USD or KHR
Error Code Status Code Description
400 VALIDATION_ERROR Validation error.
401 UNAUTHENTICATED Unauthenticated.
403 FORBIDDEN Access denied.
404 NOT_FOUND Record not found.
409 DUPLICATED Existing record found.
419 EXPIRED Requesting record was expired.
422 PROCESS_FAILED Sub-process failed.
500 SYSTEM_ERROR Internal server error.
503 FEATURE_UNDER_MAINTENANCE Feature is under maintenance.
504 GATEWAY_TIMEOUT Gateway time-out.

Withdraw

Withdraw from merchant wallet to bank account (tokenized bank account).

Sequence diagram

withdrawal diagram

API specification

POST {baseUrl}/api/mch/v2/gateway requires authentication

                    
curl --location --request POST '{baseUrl}/api/mch/v2/gateway' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer {ACCESS TOKEN}' \
--data-raw '{
    "service": "webpay.acquire.withdraw",
    "sign": "79e69e298da1c85cf09366c35e366917",
    "sign_type": "MD5",
    "seller_code": "{SELLER CODE}",
    "bank_account_token": "02246c07832d03d22a81551c7e962129c5628301324a0c90d",
    "out_trade_no": "WD-00000TEST0002",
    "total_amount": 10,
    "currency": "USD",
    "expires_in": 300,
    "customer": "{ENCRYPTED CUSTOMER DATA}"
}'
                    
                
                    
$curl = curl_init();

curl_setopt_array($curl, array(
    CURLOPT_URL => '{baseUrl}/api/mch/v2/gateway',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_ENCODING => '',
    CURLOPT_MAXREDIRS => 10,
    CURLOPT_TIMEOUT => 0,
    CURLOPT_FOLLOWLOCATION => true,
    CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
    CURLOPT_CUSTOMREQUEST => 'POST',
    CURLOPT_POSTFIELDS =>'{
        "service": "webpay.acquire.withdraw",
        "sign": "79e69e298da1c85cf09366c35e366917",
        "sign_type": "MD5",
        "seller_code": "{SELLER CODE}",
        "bank_account_token": "02246c07832d03d22a81551c7e962129c5628301324a0c90d",
        "out_trade_no": "WD-00000TEST0002",
        "total_amount": 10,
        "currency": "USD",
        "expires_in": 300,
        "customer": "{ENCRYPTED CUSTOMER DATA}"
    }',
    CURLOPT_HTTPHEADER => array(
        'Content-Type: application/json',
        'Authorization: Bearer {ACCESS TOKEN}' 
    )
));

$response = curl_exec($curl);

curl_close($curl);

echo $response;
                    
                
                    
{
    "success": true,
    "data": {
        "token": "UHlHRHk2Nzg462df82a70a8bc",
        "out_trade_no": "WD-00000TEST0002",
        "transaction_id": null,
        "body": "Fund transfer",
        "total_amount": -10,
        "currency": "USD",
        "status": "WAITING",
        "paid_at": null,
        "settled_at": null,
        "settlement_date": null,
        "expired_at": "2022-07-26T06:04:03.000000Z",
        "created_at": "2022-07-26T05:59:03.000000Z",
        "detail": [],
        "seller": {
            "code": "{SELLER CODE}",
            "display_name": "Merchant Name"
        },
        "payment_detail": {
            "id": 8949,
            "payer_id": 793,
            "method_id": 12,
            "tokenize_id": 944,
            "method_desc": "Transfer to customer bank (From Merchant wallet)",
            "holder_name": "airport.taxi",
            "card_info": null,
            "bank_info": null,
            "created_at": "2022-07-26T05:59:03.000000Z",
            "payment_method_bic": "ABAAKHPP",
            "payment_method": {
                "id": 12,
                "title": "ABA PAY",
                "instruction_text": null,
                "type": "tokenize_bank_account",
                "img": "payment-methods/January2021/zNSxh2tYwT9KaNnoQb67.png",
                "app_name": "ABA Mobile",
                "app_logo": null,
                "brand_logo": "payment-methods/August2021/DIoFm9KEvnrnNf6w5Cm4.png",
                "swift_code": "ABAAKHPP",
                "payment_type": "offline",
                "sort_level": "1",
                "emv_enabled": 0,
                "native_pay_enabled": 1,
                "ios_deeplink": "itms-apps://apple.com/app/968860649",
                "android_deeplink": "https://play.google.com/store/apps/details?id=com.paygo24.ibank&hl=en&gl=US",
                "activated": 1,
                "created_at": null,
                "updated_at": "2022-07-01T08:20:05.000000Z",
                "deleted_at": null
            }
        },
        "receiver_name": "Sok Dara",
        "is_required_otp": true,
        "verify_otp_url": "{URL}"
    },
    "sign": "{SIGNATURE}",
    "sign_type": "MD5"
}      
              
                    
                
Field Type Required Description
service String Yes "webpay.acquire.withdraw"
sign_type String Yes MD5 or HMAC-SHA256
sign String Yes {GENERATED SIGNATURE}
seller_code String Yes {SELLER CODE}
...
Include common data of a transaction
...
bank_account_token String(64) Yes Tokenize bank account token. Ex: 02246c07832b03d22a81551c7e962129c5628301324a0c90a
customer String Yes Use to identify the owner. {ENCRYPTED CUSTOMER DATA}. See customer
Field Type Nullable Description
...
Included common data of order_info
...
receiver_name String No Bank account holder name. Ex: Sok Dara
is_required_otp Boolean No When it is true merchant platform have to open verify_otp_url to confirm the withdrawal. When false the withdrawal is completed.
verify_otp_url URL Yes Null when is_required_otp equal false. Ex: https://...
Error Code Status Code Description
400 VALIDATION_ERROR Validation error.
401 UNAUTHENTICATED Unauthenticated.
403 FORBIDDEN Access denied.
404 NOT_FOUND Record not found.
409 DUPLICATED Existing record found.
419 EXPIRED Requesting record was expired.
422 PROCESS_FAILED Sub-process failed.
500 SYSTEM_ERROR Internal server error.
503 FEATURE_UNDER_MAINTENANCE Feature is under maintenance.
504 GATEWAY_TIMEOUT Gateway time-out.

Signature

Signature algorithm

Sample ...

    
function makeSign(array $param, $key)
{
    $signType = $param['sign_type'];

    $string = toUrlParams($param);
    $string = $string . "&key=".$key;

    if ($signType == "MD5")
        $string = md5($string);
    else if ($signType == "HMAC-SHA256")
        $string = hash_hmac("sha256", $string, $key);

    return $string;
}

function toUrlParams(array $values)
{

    $values = array_filter($values, function ($var) {
        return !is_null($var);
    });

    ksort($values);

    $buff = "";

    foreach ($values as $k => $v)
    {
        if($k != "sign" && $v !== "" && !is_array($v) && !is_object($v)){
            $buff .= $k . "=" . $v . "&";
        }
    }

    $buff = trim($buff, "&");

    return $buff;
}

// Request parameters
$params = json_decode('
{
    "service": "webpay.acquire.directPay",
    "sign_type": "MD5",
    "sign": "{SIGNATURE}",
    "seller_code": "{SELLER CODE}",
    "out_trade_no": "TEST-1234567891",
    "body": "iPhone 13 pro Case",
    "total_amount": 10,
    "currency": "USD",
    "notify_url": "https://sample.com/notifyme",
    "redirect_url": "https://sample.com/redirectme",
    "card": "{ENCRYPTED CARD INFORMATION}"
}
', true);

echo makeSign($params, '{API SECRET KEY}');
    

Objects

Common objects that used in the API Gateway.

setting

Field Type Required Description
template String No "company", "company-01", ...
enabled_payment_methods Array No ["VISA_MASTER", ...]
payment_type String No "offline" for display QR code only even in mobile or "online" is flexible
background_color String No Payment page background color. Ex: #FFFFFF
display_fee_amount Double No Custom display fee amount

customer

    
$rawText = json_encode([
    "phone_number" => "012345678"
    "email" => "sample@sample.com",
    "first_name" => "Sok",
    "last_name" => "Dara"
]);

$publicKey = '-----BEGIN PUBLIC KEY-----
...
-----END PUBLIC KEY-----
';

openssl_public_encrypt($rawText, $encrypted, $publicKey);

$encrypted_hex = bin2hex($encrypted);

echo $encrypted_hex;
    
Field Type Required Description
phone_number Numeric Yes Customer's phone number. Ex: 012345678
email String Yes Customer's email. Ex: sample@sample.com
first_name String Yes Sok
last_name String Yes Dara
address String(1000) No Current customer's address. Ex: #12, str 2330, ...
city String(500) No City. Ex: London
postcode String(50) No Ex: E1 6AN or 12000

transaction

Field Type Required Description
seller_code String(32) Yes "CU12-34567890" provided from KESS
out_trade_no String(32) Yes Alphanumeric or with dash ex: 1234567890, TR-1234567890, or TR1234567890
body String(255) Yes Describe your transaction
schema_url String(255) No xxx
total_amount Double Yes 10.50 for 10.50USD
currency Char(3) Yes USD or KHR
notify_url String(255) No Notify to merchant server. Ex: https://sample.com/notifyme
redirect_url String(255) No Redirect to merchant web page. Ex: https://sample.com/redirectme
expires_in Integer No Set your transaction expiry after {expires_in} seconds. Default is 1800 (30 minute).

order_info

Field Type Nullable Description
token String(25) No Unique transaction token. Ex: 111612f019b683
out_trade_no String(32) No 1234567890
transaction_id String(32) Yes 1234567890
body String(255) No Describe your transaction
total_amount Double No 10.50 for 10.50USD
currency Char(3) No USD or KHR
meta Object Yes See meta
status String No "WAITING": new created order and it is waiting for payment.
"SUCCESS": transaction is paid.
"CLOSED": transaction is closed, failed, or expired.
"REFUNDED": The transaction is refunded back to the payer.
"PENDING_REFUNDED": In case payment is not KHQR and Cards. On some banks may not support realtime that need to manual refund. But most of banks are support realtime.
"PARTIAL_REFUNDED": The transaction has partial refund.
"PENDING_PARTIAL_REFUND": In case payment is not KHQR and Cards. On some banks may not support realtime that need to manual refund. But most of banks are support realtime.
"REJECT_REFUNDED": The transaction has reject refunded.
paid_at Datetime Yes Ex: 2022-07-18T10:44:53.000000Z
settled_at Datetime Yes Ex: 2022-07-18T10:44:53.000000Z
settlement_date Datetime Yes Ex: 2022-07-18T10:44:53.000000Z
expired_at Datetime No Ex: 2022-07-18T10:44:53.000000Z
created_at Datetime No Ex: 2022-07-18T07:44:54.000000Z
payment_detail Object Yes See payment_detail
bank_info Object Yes See bank_info
refund_histories Array Object Yes See refund_histories
queue_number String Yes Today (GMT) transaction count. Ex: 0001 when it's first transaction of current day.
payment_link URL No {baseUrl}/pay/{token}
error_logs Array No See error_logs_info

payment_detail

Field Type Required Description
method_desc String No Payment description. Ex: Transfer to customer bank (From Merchant wallet)
holder_name String No Holder name
card_info Object No Card information.
bank_info Object No Bank account information.
created_at Timestamp Yes Ex: 2022-07-26T05:59:03.000000Z
payment_method_bic String Yes bank identifier code. Ex: ABAAKHPP
payment_method Object Yes See payment_method

card

    
$rawText = json_encode([
    "number" => "5473500160001018",
    "securityCode" => "123",
    "expiry" => [
        "month" => "12",
        "year"  => "35"
    ]
]);

$publicKey = '-----BEGIN PUBLIC KEY-----
...
-----END PUBLIC KEY-----
';

openssl_public_encrypt($rawText, $encrypted, $publicKey);

$encrypted_hex = bin2hex($encrypted);

echo $encrypted_hex;
    
Field Type Required Description
number Numeric Yes Card number. Ex: 5473500160001018
securityCode Char(4) Yes CVV code on the back of credit/debit card. Ex: 123
expiry Object Yes Card expiry. Ex:
{
"month": "12",
"year": "35"
}

payment_method

Field Type Required Description
id Integer Yes Unique ID
title String Yes Payment method title.
img_url URL Yes Payment method logo URL.
bic String Yes Bank identify code. Ex: KESSKH for KESSCHAT App, VISA_MASTER, or ABAAKHPP for ABA Pay
storelink Object Yes Ex:
{
"ios": "itms-apps://apple.com/app/1518521952",
"android": "https://play.google.com/store/apps/details?id=io.kessinnovation.kesschat"
}

bank_info

Field Type Nullable Description
senderBank String Yes ABA
senderPartcode String Yes xx
account_name String Yes ABA
account_number String Yes xxx

card_info

Field Type Nullable Description
BIN String Yes 526666
scheme String Yes xx
card_token String Yes Use this token to pay visa-token
account_name String Yes xxx
account_number String Yes xxx

user_info

Field Type Nullable Description
id integer Yes 526666
phone_number String Yes 010111222
user_id String Yes CU2501-101139033689723678
email String Yes xxx@test.com
full_name String Yes xxx
muser_identity String No N1234
wallet Object Yes wallet-info
multi_wallets Array Yes wallet-info

wallet_info

Field Type Nullable Description
id String Yes 526666
balance integer Yes xx
currency String Yes USD OR KHR
account_number String Yes xxx

refund_histories

Field Type Nullable Description
amount Double No 10.50 for 10.50USD
currency Char(3) No USD or KHR
status String No "REFUNDED": The transaction is refunded back to the payer.
"PENDING_REFUNDED": In case payment is not KHQR and Cards. On some banks may not support realtime that need to manual refund. But most of banks are support realtime.
"PARTIAL_REFUNDED": The transaction has partial refund.
"PENDING_PARTIAL_REFUND": In case payment is not KHQR and Cards. On some banks may not support realtime that need to manual refund. But most of banks are support realtime.
"REJECT_REFUNDED": The transaction has reject refunded.
reason String No xxx
transaction_id String No xxx
rejected_reason String Yes xxx
out_trade_no String Yes xxx
merchant_reference String Yes xxx

transaction_info

Field Type Nullable Description
transaction_ref String Yes 526666
credited_amount integer Yes xx
credited_currency String Yes USD
debited_amount integer Yes xxx
debited_currency String Yes USD
fees_amount Double Yes USD
fees_ccy String Yes USD
order_id String Yes 12343
transaction_type String Yes in
out
status String Yes Created
Succeed
Failed
created_at Datetime Yes xx
debited_user_id String Yes xx
credited_user_id String Yes xx
readable_created_at String Yes xx

velocity_control_info

Field Type Nullable Description
maxTrans Integer Yes 1
availableBalance Integer Yes 100
period String Yes C
cumulativeLimit Integer Yes 104

transaction_limit_control_info

Field Type Nullable Description
amount Integer Yes 1

vcn_information

Field Type Nullable Description
pan String Yes 12345676543
expiry String Yes 2602
avv String Yes 266

transaction_virtual_card

Field Type Nullable Description
credit_fund_amount Double Yes 1
credit_fund_currency String Yes USD
debit_fund_amount Double Yes 1
debit_fund_currency String Yes USD
type String Yes topup
is_success Boolean Yes 1
is_settled Boolean Yes 0
trans_date Datetime Yes 2025-04-03 07:11:06
sub_type String No
merchant_name String No
issuer_response String No

bakong_info

Field Type Nullable Description
name String Yes xx
bic String Yes xx
logo String Yes xx

khqr_info

Field Type Nullable Description
merchantType String Yes xx
bakongAccountID String Yes xx
accountInformation String Yes xx
merchantID String No
acquiringBank String Yes xx
billNumber String No
mobileNumber String Yes xxx
storeLabel String No
terminalLabel String No
purposeOfTransaction String No
languagePreference String No
merchantNameAlternateLanguage String No
merchantCityAlternateLanguage String No
payloadFormatIndicator String Yes 01
pointofInitiationMethod String Yes 01
unionPayMerchant String No
merchantCategoryCode String Yes 5999
transactionCurrency String Yes usd
transactionAmount String Yes 10
countryCode String Yes KH
merchantName String Yes xx
merchantCity String Yes xx
timestamp String Yes 00131736836325291
crc String Yes A581

receiver_info

Field Type Nullable Description
receiver_name String Yes ABA
receiver_bank String Yes xx
receiver_bakong_id String Yes khqr@kess
receiver_acc_info String Yes 000024924

error_logs_info

Field Type Nullable Description
code String Yes CREDIT_CARD_ERROR
message String Yes xx
created_at DateTime Yes 2025-03-21T02:29:13.000000Z

Redirect Url

Success

Field Nullable Description
success No 1
out_trade_no No TR1234567890
message No Payment Successful!
token No TR1234567890

Failure Only VISA MASTER

Field Nullable Description
success No 0
token No TR1234567890
out_trade_no No TR1234567890
message No xxx
pay_response Yes
{"gatewayCode": "INSUFFICIENT_FUNDS","acquirerMessage": "Transaction declined due to insufficient funds"}

Note

{
    "NEED_CONTACT": "Please contact us for detail",
    "NO_OTP": "Payer cancelled or not confirm 3DS",
    "DECLINED": "Payment was declined by issuer or payer authentication was not able to be successfully completed.",
    "BLOCKED": "Transaction blocked due to Risk or 3D Secure blocking rules",
    "CARD_NOT_SUPPORT_3DS": "Transaction blocked due to Risk or 3D Secure blocking rules",
    "INSUFFICIENT_FUNDS": "Transaction declined due to insufficient funds",
    "UNSPECIFIED_FAILURE": "Transaction could not be processed",
    "SUCCESS": "Transaction is successfully",
    "WAITING_FINAL_STATUS": "Transaction was created and waiting final status. Please try again later",
    "NO_MATCH": "Incorrect card security code"
}

Notify Url

Params

Order info
Sample Params

Notify Save Card

Params

Card info
Sample Params

Notify Refund

Params

Refund info
Sample Params

Visa Token

Url

{BaseUrl}/ccpay/{order_info.token}?card_token={card_info.card_token}