INTRODUCTION

FYI: we are still updating it. But you can start integrating.

IMPORTANT NOTES

  • All merchants need to be registered with KESS first, then we’ll provide.
    1. merchant id
    2. merchant secret key
    3. an api username
    4. and password
    5. RSA2 Certificate (a private key and a public key file). If you want to generate your own RSA2 certificate, you need to provide us with a private/public key for decryption
  • All POST/PUT/PATCH APIs are required form sign (sign_type = RSA2 and sign params).
  • All rest api required header.
    1. merchant-id = (Your merchant id provide by KESS)
    2. merchant-secret-key = (Your merchant secret key provided by KESS)
  • By default, KESS will use your private key to decrypt sensitive fields when you call the api. So you need to use the public key to encrypt the fields. You’ll see fields that need to be encrypted in the api). So KESS doesn’t encrypt data for the response.
  • To sign
    1. Prepare post params for sign
      1. Remove empty value params.
      2. Cleaned params and sort params key as ascending
      3. Build url query for the params ( no ? at the beginning and &at the end of the string)
      4. If the param’s value is an array, it must be encoded and put in [ ]
      5. The string will be used to pass to your RSA2 method to sign.
    2. Use your private key for RSA2 (in case KESS use your public key to decrypt)
    3. Set Encryption Mode to ENCRYPTION_PKCS1
    4. Set Signature Mode to SIGNATURE_PKCS1
    5. Set Signature Mode to SIGNATURE_PKCS1
    6. RSA encrypts the string content
    7. Do base64 encode for the encrypted string, then the bas64 string is our sign content.

(We have sample for php, you can check rsa2Sign() method in KESS_RSA.php)

LOGIN AS MERCHANT FIRST TO USE OTHER API

POST : API_BASE_URL/login
  • user_name = (Your merchant api user name provided by KESS)
  • password = (Your merchant api password provided by KESS)

REQUEST:

{
"user_name": "user_name" ,
"password": "password"
}

RESPONSE:

Success:
{
"success": true
"code": 200,
"message": "OK",
"data": {
"token": "iZiI6MTU5NTUTYxM..."
"user": {
"id": 219
"avatar": "default.png",
"fk_soc": 14,
"time_zone": null,
"full_name": "rest api"
"balance": 5206.235,
"wallet_ref": "CW2001-xxxxx",
"wallet_id": 887,
"currency": "USD"
}
}
}

Failed:
{
"success": false
"code": 400,
"message": "Bad Request",
"error: {
"user_name_password: [
"Invalid login user"
]
}
}

PHP SDK sample:

$username = $request->get('user_name');
$password = $request->get('password');
$KESS_SD = new KESS_SDK ([
'sign_type' => 'RSA2',
'merchant_id' => $this::$merchantId,,
'merchant_secret_key' => $this::$merchantKey,
'cert_key' => $this::$certKey
])
$res = $KESS_SDK->doAuth($username, $password);

LIST FEES

POST : API_BASE_URL/do-action

REQUEST:

{
"service": "list_fees"
}

RESPONSE:

Success:
{
"success": true
"code": 200,
"message": "OK",
"data": {
"FEE": {
"ACLBKHPP": {
"fee_payout": {
"amount": 1000
"currency": "KHR"
}
"fee_payin": {
"amount": 1000
"currency": "KHR"
}
"register_cut_amount": {
"amount": 0.25
"currency": "USD"
}
}
"TOKKE_SELLER": {
"fee_transfer": 0
}
"VISA_MASTER": {
"fee_payin": {
"amount_percentage": 2.5
}
}
"EXCHANGE_RATE": {
"USD_KHR": 4000
"KHR_USD": 0.00025
}
}
}
}

GENERATE PREORDER TOKEN

POST : API_BASE_URL/do-action

Parameters:

Field Type Required Description
service String YES generate_pre_order_token
out_trade_no String YES YOUR_UNIQUE_ID
seller_code String YES SELLER_CODE
description String YES description...
amount String YES 1
currency Integer YES USD
redirect_url OPTIONAL if provided, after done visa/master deposit confirmation, it'll redirect to that url instead of showing the html content
commission_rate Integer OPTIONAL 5

*NOTE

  • commission_rate in %
  • optional
    • commission_rate
    • redirect_url

REQUEST:

{
"service": "generate_pre_order_token",
"out_trade_no": "YOUR_UNIQUE_ID",
"seller_code": "SELLER_CODE",
"description": "description...",
"amount": 1,
"currency": "USD",
"description": "description...",
"call_back_url": ".....",
"commission_rate": 5
}

RESPONSE:

Success:
{
"success": true
"code": 200,
"message": "OK",
"data": {
"pre_order_token": "xxxx"
"pre_order_url": "xxxx",
}
}

CREATE USER UNDER YOUR COMPANY

POST : API_BASE_URL/do-action

Parameters:

Field Type Required Description
service String YES create_user
phone_number Integer No 070222703
email string No rhity.khin@gmail.com
first_name String YES Rithy
last_name String YES Khin
address String YES Floor 4, S&C Office Space Building, Street 1984A, Sen Sok, Phnom Penh, Kampuchia (Cambodia)
currency string YES USD
birthday date OPTIONAL 1996-12-01
gender Integer OPTIONAL m

*NOTE

  • phone_number or email must be provided

REQUEST:

{
"service": "create_user",
"phone_number": "070222703",
"first_name": "rithy",
"last_name": "kin",
"address": "Floor 4, S&C Office Space Building, Street 1984A, Sen Sok, Phnom Penh, Kampuchia (Cambodia)",
"currency": "USD",
"description": "description...",
"birthday": "1996-12-01",
"gender": "m"
}

RESPONSE:

Success:
{
"success": true
"code": 200,
"message": "OK",
"data": {
"id": 308
"email": null
"avatar": "users/default.png",
"created_at": "2020-08-02 17:20:42"
"updated_at": "2020-08-02 17:20:42"
"phone_number": "017357446",
"gender": "m"
"last_name": "kin",
"full_name": "rithy"
"address": "phnom penh",
"birthday": "1996-12-01"
"currency": "USD"
}
}

RESPONSE:

Failed:
{
"success": false
"code": 400,
"message": "Bad Request",
"error": {
"phone_number": [ "The phone number has already been taken.",
],
"email": [ "The email has already been taken."
]
}
}

UPDATE USER UNDER YOUR COMPANY

POST : API_BASE_URL/do-action

Parameters:

Field Type Required Description
service String YES update_user
phone_number Integer YES 070222703
first_name String YES Rithy
last_name String YES kin
address String YES Floor 4, S&C Office Space Building, Street 1984A, Sen Sok, Phnom Penh, Kampuchia (Cambodia)
currency string YES USD
birthday OPTIONAL 1996-12-01
gender Integer OPTIONAL m

REQUEST:

{
"service": "update_user",
"phone_number": "070222703",
"first_name": "rithy",
"last_name": "kin",
"address": "Floor 4, S&C Office Space Building, Street 1984A, Sen Sok, Phnom Penh, Kampuchia (Cambodia)",
"currency": "USD",
"description": "description...",
"birthday": "1996-12-01",
"gender": "m"
}

RESPONSE:

Success:
{
"success": true
"code": 200,
"message": "OK",
"data": {
"id": 308
"email": null
"avatar": "users/default.png",
"created_at": "2020-08-02 17:20:42"
"updated_at": "2020-08-02 17:20:42"
"phone_number": "017357446",
"gender": "m"
"last_name": "kin",
"full_name": "rithy"
"address": "phnom penh",
"birthday": "1996-12-01"
"currency": "USD"
}
}

RESPONSE:

Failed:
{
"success": false
"code": 400,
"message": "Bad Request",
"error": {
"phone_number": [ "The phone number has already been taken.",
],
"email": [ "The email has already been taken."
]
}
}

PHP SDK sample:

$username = $request->get('user_name');
$password = $request->get('password');
$KESS_SD = new KESS_SDK ([
'sign_type' => 'RSA2',
'merchant_id' => $this::$merchantId,,
'merchant_secret_key' => $this::$merchantKey,
'cert_key' => $this::$certKey
])
$res = $KESS_SDK->doAction($request->all());;

PAYMENTS

PAY BY TOKEN:

Transfer balance from wallet to wallet.

POST : API_BASE_URL/do-action

Parameters:

Field Type Required Description
service String YES update_user
pre_order_token String YES TOKEN

REQUEST:

{
"service": "update_user",
"pre_order_token": "TOKEN",
}

RESPONSE:

Success:
{
"success": true
"code": 200,
"message": "OK",
"data": {
"reference": "TR2007-98816440081055755"
}
}

TRANSFER

Transfer balance from wallet to wallet.

POST : API_BASE_URL/do-action

Parameters:

Field Type Required Description
service String YES transfer
from_user_id String YES from_user_id
to_user_id String YES to_user_id
amount String YES 10
currency String YES USD
fees_amount double No 0.05
fees_currency string No USD

*NOTE

  • if fee_amount sent, fee_currency is required too

*Params Request

  • from_user_id : Id of user that debit balance.
  • to_user_id : Id of user that credit balance.
  • amount : Amount to transfer.
  • currency : Currency.

REQUEST:

{
"service": "update_user",
"from_user_id": "from_user_id",
"to_user_id": "to_user_id",
"amount": 10,
"currency": "USD"
}

RESPONSE:

Success:
{
"success": true
"code": 200,
"message": "OK",
"data": {
"reference": "TR2007-98816440081055755"
}
}

LIST ALL SUPPORT BANKS

  • This api allow you to see available banks and select which bank you need to pay with.
  • You can customize list by use params: per_page, page
POST : API_BASE_URL/do-action

Parameters:

Field Type Required Description
service String YES transfer

REQUEST:

{
"service": "list_banks",
}

RESPONSE:

Success:
{
"success": true
"code": 200,
"message": "OK",
"data": {
"current_page": 1
"data": [
{
"id": 4
"name": "ACLEDA BANK Plc"
"region": "Cambodia"
"city": "Phnom Penh"
"logo": "banks/December2019/sdOYbmk0b5WHTJolGkMW.png"
},
{
"id": 5
"name": "ADVANCED BANK OF ASIA LIMITED"
"region": "Cambodia"
"city": "Phnom Penh"
"logo": "banks/December2019/sdOYbmk0b5WHTJolGkMW.png"
}
]
"from": 1
"last_page": 1
"per_page": 20
"to": 2
"total": 2
}
}

TOKENIZE

  • To make deposit or withdraw you need to have Bank, Cards(local card) or Visa/master

LOCAL CARD

POST : API_BASE_URL/do-action

Parameters:

Field Type Required Description
service String YES tokenize_local_card
user_id Integer YES CARD_OWNER_USER_ID
holder_name String YES Your user holder name
bank_id String YES 4
bank_code String YES bank_code

*Params Request

  • service : tokenize_local_card.
  • user_id : Id of user who owns card.
  • holder_name : Card holder’s name (Encryption required).
  • bank_id : Id of bank you have selected which bank is properly.
  • bank_code : Card number (Encryption required)

*Params Response

  • token : Please keep this token to use when you want to make deposit/withdraw.

REQUEST:

{
"service": "tokenize_local_card",
"user_id": "CARD_OWNER_USER_ID",
"holder_name": "Your user holder name",
"bank_id": 4,
"bank_code": "bank_code",
}

RESPONSE:

Success:
{
"success": true
"code": 200,
"message": "OK",
"data": {
"token": "51407657715075dd297be51a45013492"
}
}

BANK ACCOUNT

POST : API_BASE_URL/do-action

Parameters:

Field Type Required Description
service String YES tokenize_bank_account
user_id Integer YES CARD_OWNER_USER_ID
holder_name String YES Your user holder name
bank_id BigInteger YES 4
bank_number String YES <00010221412688/td>

*Params Request

  • service : tokenize_bank_account.
  • user_id : Id of user who owner bank account.
  • bank_id : Id of bank you have selected which bank is properly.
  • bank_number : Bank account number (Encryption required)

*Params Response

  • token : Please keep this token to use when you want to make deposit/withdraw
  • bank_number : last 4 number of bank number.
  • need_verify: If true and qr_image is not empty please open qr_image to scan to active bank account.

REQUEST:

{
"service": "tokenize_bank_account",
"user_id": "CARD_OWNER_USER_ID",
"holder_name": "Your user holder name",
"bank_id": 4,
"bank_number": "00010221412688"
}

RESPONSE:

Success:
{
"success": true
"code": 200,
"message": "OK",
"data": {
"token": "51407657715075dd297be51a45013492"
"bank_number": "1234"
"qr_image": "”https://payway-staging.ababank.com/assets/abaqr/abaqr-1599443412.png"
"need_verify": true
}
}

VISA/MASTER

POST : API_BASE_URL/do-action

Parameters:

Field Type Required Description
service String YES tokenize_visa_master
user_id Integer YES CARD_OWNER_USER_ID
sourceOfFunds string YES
type String YES
number Integer YES 4162210200041730
securityCode String YES 123
expiry array YES Object of array
month date YES 4162210200041730
year date YES 2020
holder_name string YES Your user holder name

*Params Request

  • service : tokenize_visa_master.
  • user_id : Id of user who owner bank account.
  • holder_name : Card holder’s name (Encryption required).
  • bank_id : Id of bank you have selected which bank is properly.
  • bank_number : Bank account number (Encryption required)

*Params Response

  • token : Please keep this token to use when you want to make deposit/withdraw.

REQUEST:

{
"service": "tokenize_visa_master",
"user_id": "CARD_OWNER_USER_ID",
"sourceOfFunds": {
"card": {
"number": "4162210200041730"
"securityCode": "1234"
"expiry": {
"month": "02"
"year": "2020"
}
}
}
"holder_name": "Your user holder name",
}

RESPONSE:

Success:
{
"success": true
"code": 200,
"message": "OK",
"data": {
"token": "51407657715075dd297be51a45013492"
}
}

DEPOSIT

  • To make deposit or withdraw you need to have Bank, Cards(local card) or Visa/master

DEPOSIT LOCAL CARD

POST : API_BASE_URL/do-action

Parameters:

Field Type Required Description
service String YES deposit_by_local_card
token string YES TOKEN
pre_order_token string YES PRE_ORDER_TOKEN
amount String YES 5
currency String YES USD

*Params Request

  • service : deposit_by_local_card.
  • token : Get token after you add card successfully.
  • pre_order_token: if you use pre order, pre_order_token is required
  • amount : Amount to deposit
  • currency : Currency

*Params Response

  • reference : Transaction reference.
  • token : Please keep this token to confirm payment.
  • need_verify_trx : If true need to confirm payment by OTP, Soft token.
  • html_confirm_payment : If you see has html here please run this html to confirm payment (Visa/Master).

REQUEST:

{
"service": "deposit_by_local_card",
"token": "TOKEN",
"pre_order_token": "PRE_ORDER_TOKEN",
"amount": "Your user holder name",
"currency": "USD"
}

RESPONSE:

Success:
{
"success": true
"code": 200,
"message": "OK",
"data": {
"reference": "TR2007-98816440081055770"
"token": "51407657715075dd297be51a45013492"
"token_type": "1"
"need_verify_trx": "true"
"html_confirm_payment": " html…."
}
}

DEPOSIT BANK ACCOUNT

POST : API_BASE_URL/do-action

Parameters:

Field Type Required Description
service String YES deposit_by_bank_account
user_id Integer YES CARD_OWNER_USER_ID
token String YES "TOKEN"
pre_order_token String YES "PRE_ORDER_TOKEN"
amount String YES 1
currency String YES USD

*Params Request

  • user_id : Id of user who owner credit wallet.
  • token : Get token after you add bank account successfully
  • pre_order_token: if you use pre order, pre_order_token is required.
  • amount : Amount to deposit.
  • currency : Currency

*Params response

  • reference : Transaction reference.
  • token : Please keep this token to confirm payment.
  • pre_order_token: if you use pre order, pre_order_token is required.
  • need_verify_trx : If true need to confirm payment by OTP, Soft token.
  • token_type : 1 is OTP else Soft token

REQUEST:

{
"service": "deposit_by_bank_account",
"user_id": "CARD_OWNER_USER_ID",
"token": "TOKEN",
"pre_order_token": "PRE_ORDER_TOKEN",
"amount": 1,
"currency": "USD"
}

RESPONSE:

{
"success": true
"code": 200,
"message": "OK",
"data": {
"reference": "TR2007-98816440081055770"
"token": "51407657715075dd297be51a45013492"
"token_type": "1"
"need_verify_trx": "true"
}
}

DEPOSIT VISA / MASTER

POST : API_BASE_URL/do-action

Parameters:

Field Type Required Description
service String YES deposit_by_visa_master
security_code Integer YES SECRUITY_CODE
token String YES TOKEN
pre_order_token String YES PRE_ORDER_TOKEN
amount String YES 1
currency String YES USD

*Params Request:

  • user_id : Id of user who owner credit wallet.
  • token : Get token after you add card successfully.
  • security_code : cvv code on card (Encryption required).
  • amount : Amount to deposit.
  • currency : Currency.
  • pre_order_token: if you use pre order, pre_order_token is required.

Params response:

  • reference : Transaction reference
  • token : Please keep this token to confirm payment
  • need_verify_trx : If true need to confirm payment by OTP, Soft token
  • token_type : 1 is OTP else Soft token
  • html_confirm_payment : If you see has html here please run this html to confirm payment (Visa/Master) please check example below

html_confirm_payment:

  • Web
    1. To implement on web page please add redirect_url on Generate Preorder Token. So when confirm success we will redirect to that url with response

      Example:

      https://callbackurl.test?result = base64. So you can get from query string result and decode base64 to see response json

      {
      "success": true
      "code": 200,
      "message": "OK",
      "data": {
      "transaction_ref": "TR-634378438475"
      }
      }
  • Android / IOS
    1. If on Generate Preorder Token has no redirect_url you will got response as html after submit confirm on html_confirm_payment ( you will got blank screen because html input is hidden )

      Example:

      < body >
      < form action="" method="post">
      < input type="hidden" class="result" name="result" id="result" value = "'.$value.'" />
      < /form>
      < /body >

REQUEST:

{
"service": "deposit_by_visa_master",
"security_code": "SECRUITY_CODE",
"token": "TOKEN",
"amount": 1,
"currency": "USD"
}

RESPONSE:

{
"success": true
"code": 200,
"message": "OK",
"data": {
"reference": "TR2007-98816440081055770"
"token": "51407657715075dd297be51a45013492"
"token_type": "1"
"need_verify_trx": "true"
"html_confirm_payment": "< html…."
}
}

CONFIRM PAYMENT

POST : API_BASE_URL/do-action

Parameters:

Field Type Required Description
service String YES confirm_payments
user_id Integer YES SECRUITY_CODE
token String YES TOKEN
password password YES PASSWORD

REQUEST:

{
"service": "confirm_payments",
"user_id": "ID",
"token": "TOKEN",
"password": "PASSWORD"
}

RESPONSE:

{
"success": true
"code": 200,
"message": "OK",
"data": {
[]
}
}

BLOCK MONEY

POST : API_BASE_URL/do-action

Parameters:

Field Type Required Description
service String YES block_money
user_token string YES token
amount String YES 123
currency password YES USD
reference String YES Desc..

REQUEST:

{
"service": "block_money",
"user_token": "token",
"amount": "123",
"currency": "USD"
"reference": "Desc..."
}

RESPONSE:

{
"success": true
"code": 200,
"message": "OK",
"data": {
"transaction_ref": "TR2007-98816440081055770",
}
}

CANCEL BLOCKED MONEY

POST : API_BASE_URL/do-action

Parameters:

Field Type Required Description
service String YES cancel_block_money
transaction_ref string YES TR2007-98816440081055770

*Params Request

  • transaction_ref : ref response from blocked transaction

REQUEST:

{
"service": "cancel_block_money",
"transaction_ref": "TR2007-98816440081055770",
}

RESPONSE:

{
"success": true
"code": 200,
"message": "OK",
"data": {
[]
}
}