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

payment-method-958453405-1 ABA Pay payment-method-958453405-2 Acleda Bank
payment-method-958453405-3 KESS Pay payment-method-958453405-4 Sathapana Bank
payment-method-958453405-5 Wing Bank payment-method-958453405-6 TrueMoney
payment-method-958453405-7 U-Pay payment-method-958453405-8 Visa/Master Card
payment-method-958453405-9 eMoney payment-method-958453405-10 KHQR Code
payment-method-958453405-11 WeChat Pay payment-method-958453405-12 Alipay

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 will expire after {expires_in ex: 1800} seconds. Even requested new authenticating, this access_token still available.
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.

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 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": [
        {
            "id": 1,
            "name": "xxx",
            "branch_code": "xx",
            "bic": "xx",
            "crypto_key_id": null,
            "owner_address_fk_country": null,
            "owner_address_city": "PP",
            "owner_address_region": "PP",
            "owner_address_postalcode": "12100",
            "owner_address_line1": "Bakong bank members",
            "owner_address_line2": null,
            "status": 1,
            "logo": "https://clientdev.kesspay.io/banks/December2022/g8diT9AEdH603rj9GVfA.png",
            "position": null,
            "payin_rate": 0,
            "payout_rate": 0,
            "is_display_on_app": 0
        }
    ],
    "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.
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 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": 9,
            "title": "Visa/Master Card",
            "img_url": "https://devwebpayment.kesspay.io/storage/payment-methods/January2021/PYH0yz4Spxk0He64zmdE.png",
            "bic": "VISA_MASTER",
            "storelink": {
                "ios": null,
                "android": null
            }
        },
        {
            "id": 11,
            "title": "KESS PAY",
            "img_url": "https://devwebpayment.kesspay.io/storage/payment-methods/June2022/sUGkSOt9bwpLUP80Rdst.png",
            "bic": "KESSKH",
            "storelink": {
                "ios": "itms-apps://apple.com/app/1518521952",
                "android": "https://play.google.com/store/apps/details?id=io.kessinnovation.kesschat"
            }
        },
        {
            "id": 12,
            "title": "ABA PAY",
            "img_url": "https://devwebpayment.kesspay.io/storage/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 Bank",
            "img_url": "https://devwebpayment.kesspay.io/storage/payment-methods/January2021/hByq9E5xKTA9n6En12V2.png",
            "bic": "ACLBKHPP",
            "storelink": {
                "ios": "itms-apps://apple.com/app/1196285236",
                "android": "http://play.google.com/store/apps/details?id=com.domain.acledabankqr&hl=en"
            }
        },
        {
            "id": 14,
            "title": "Sathapana",
            "img_url": "https://devwebpayment.kesspay.io/storage/payment-methods/January2021/upXnfv34dpBz9UMNeVGm.png",
            "bic": "SBPLKHPP",
            "storelink": {
                "ios": "itms-apps://apple.com/app/1499664210",
                "android": "https://play.google.com/store/apps/details?id=kh.com.sathapana.consumer"
            }
        },
        {
            "id": 15,
            "title": "WeChat Pay",
            "img_url": "https://devwebpayment.kesspay.io/storage/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": 16,
            "title": "AliPay",
            "img_url": "https://devwebpayment.kesspay.io/storage/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": 17,
            "title": "eMoney",
            "img_url": "https://devwebpayment.kesspay.io/storage/payment-methods/June2021/oLIH0G2nZcd5liB5usUs.png",
            "bic": "EMONEY",
            "storelink": {
                "ios": null,
                "android": null
            }
        },
        {
            "id": 18,
            "title": "Wing Bank",
            "img_url": "https://devwebpayment.kesspay.io/storage/payment-methods/July2022/Q44YlfkgxgXoCwJixuX5.png",
            "bic": "WING",
            "storelink": {
                "ios": "itms-apps://apple.com/app/1113286385",
                "android": "https://play.google.com/store/apps/details?id=com.wingmoney.wingpay"
            }
        },
        {
            "id": 19,
            "title": "TrueMoney",
            "img_url": "https://devwebpayment.kesspay.io/storage/payment-methods/June2022/MBBLsHM6EJeZ3ZejFvkO.png",
            "bic": "TRUEMONEY",
            "storelink": {
                "ios": "itms-apps://apple.com/app/663885752",
                "android": "https://play.google.com/store/apps/details?id=kh.com.truemoney.truemoneymobile"
            }
        }
    ],
    "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
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:
WECHAT, ALIPAY, VISA_MASTER, ABAAKHPP, ACLBKHPP, SBPLKHPP, KESSKH, WING, EMONEY, TRUEMONEY, KHQR
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.

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}"
}'
                    
                
                    
$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}"
    }',
    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 Yes {ENCRYPTED CARD INFORMATION}. See card
setting Object No See setting
customer String No {ENCRYPTED CUSTOMER DATA}. See customer
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": [],
        "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"
        }
    },
    "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 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.refund",
    "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.refund",
        "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": {
        "token": "12314666447313d6a2e93676",
        "out_trade_no": "uiJ9GmgznaZNbXadQG57gMnTo",
        "transaction_id": "111612f019b6836bf1255554",
        "body": "Iphone 14 Pro",
        "total_amount": 0.1,
        "currency": "USD",
        "version": 3,
        "status": "REFUNDED",
        "paid_at": "2022-09-21T08:10:23.000000Z",
        "settled_at": null,
        "settlement_date": "2022-09-28T00:00:00.000000Z",
        "expired_at": "2022-09-21T11:07:20.000000Z",
        "created_at": "2022-09-21T08:07:22.000000Z",
        "detail": [],
        "seller": {
            "code": "{SELLER CODE}",
            "display_name": "Merchant Name"
        },
        "payment_detail": {
            "id": 10698,
            "payer_id": 973,
            "method_id": 16,
            "tokenize_id": null,
            "method_desc": "VISA_MASTER,ALIPAY OR WECHAT",
            "holder_name": null,
            "card_info": null,
            "bank_info": null,
            "created_at": "2022-09-21T08:10:23.000000Z",
            "payment_method_bic": "VISA_MASTER,Wing,ACLEDA,ALIPAY OR WECHAT"
        },
        "error_logs": []
    },
    "sign": "{SIGNATURE}",
    "sign_type": "MD5"
}      
              
                    
                
Field Type Required Description
service String Yes "webpay.acquire.refund"
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
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.

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 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 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
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 Array 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.
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
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}

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"
}

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": "51","acquirerMessage": "Not sufficient funds"}

Notify Url

Params

Field Description
body xxx
out_trade_no xxxx
transaction_id xxxx
status SUCCESS
token ac161e07159156847565115
total_amount 1
currency USD
payment_detail
{"id":8072,"payer_id":255,"method_id":11,"tokenize_id":null,"method_desc":"KESSKH","holder_name":"Test","card_info":null,"bank_info":null,"created_at":"2022-07-07T09:33:45.000000Z","payment_method_bic":"KESSKH"}
card_info (Default null) Need to request to enable visa token for get Card Info
{"card_token":"162847514461108f080312a","swift_code":"VISA_MASTER","card_hashed":"4ccf428eb78130eae273080085cd0add","holder_name":"Test","account_name":"Visa/Master","account_number":"******** **** 0040"}

Visa Token

Url

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