NAV
Java Demo

1 Integration Guide

1.1 Message Signature

import org.apache.commons.codec.digest.HmacUtils;

/**
 * Calculate signature
 *
 * @param merchantSecretKey The merchant api key, provided by OnlinePay System when opening an account.
 * @param messageData       The data in the request or response.
 * @return The result signature.
 */
public static String calculateSignature(String merchantSecretKey,
                                        Map<String, Object> messageData) {

    // Sort by parameter name, skip the nulls and 'signature', then join by '|'
    String rawSignature = messageData.entrySet().stream()
            .filter(e -> !"signature".equals(e.getKey()))
            .sorted(Comparator.comparing(Map.Entry::getKey))
            .map(Map.Entry::getValue)
            .filter(Objects::nonNull)
            .map(String::valueOf)
            .collect(Collectors.joining("|"));

    // Use HMAC_SHA256 algorithm
    return new HmacUtils(HMAC_SHA_256, merchantSecretKey).hmacHex(rawSignature);
}

During message exchange, to ensure the authenticity and integrity, Request ParametersResponse Payload and Callback Payload all include a message signature.

Here are the steps to calculate the signature:

1.2 Commonly Used Parameters

Parameter Name Description
merchantId Merchant Id. Provided by OnlinePay System.
merchantSecretKey Merchant API Key. Provided by OnlinePay System.
merchantOrderId Merchant Order Id. Generated by merchant system. Should be unique.
amount Order Amount.
currency Order Currency. Support currencies include CNY, THB, MYR, JPY.
nonce A random string. To improve the unpredictability of signature. Suggest to use random UUID, like: b228f8de-0fc1-47a1-8727-c7a07c05484d
createdAt The created time of the order (UTC+8). Format: yyyy-MM-dd HH:mm:ss like: 2019-03-12 00:38:40. Please use the same format/timezone when calculating signature.

2 General API

2.1 Get Available Methods

private static String merchantId = "8101";
private static String merchantUserId = "testUser01";
private static String merchantSecretKey = "NjE5NDA4NWUtYmVlMi00OWQ1";
private static String methodsGatewayUrl = "https://api.fundsguard.net/methods";

public ResponseEntity queryDepositOrder() {
    Map<String, Object> mapData = new HashMap<>();
    mapData.put("merchantId", merchantId);
    mapData.put("merchantUserId", merchantUserId);
    mapData.put("type", "DEPOSIT");
    mapData.put("currency", "CNY");
    mapData.put("nonce", UUID.randomUUID().toString());
    
    // calculate signature
    mapData.put("signature", calculateSignature(merchantSecretKey, mapData));

    // build the query url
    UriComponentsBuilder uriBuilder = UriComponentsBuilder.fromHttpUrl(depositGatewayUrl);
    mapData.entrySet().stream().forEach(e -> uriBuilder.queryParam(e.getKey(), e.getValue()));

    return new RestTemplate().getForEntity(uriBuilder.toUriString(), String.class);
}

When request succeeds, OnlinePay System will return JSON response data in this structure:

[
    {
        "type": "DEPOSIT",
        "method": "BANK_TRANSFER",
        "currency": "CNY",
        "minimumAmount": "10",
        "maximumAmount": "5000"
    },
    {
        "type": "DEPOSIT",
        "method": "ALIPAY",
        "currency": "CNY",
        "minimumAmount": "10",
        "maximumAmount": "5000"
    }
]

Merchant can use this API to retrieve the latest available payment methods and limits.

Request Format

GET https://api.fundsguard.net/methods?merchantId=&merchantUserId=&type=&nonce=&signature=

Parameters List

Name Required? Description
merchantId Yes Merchant id.
merchantUserId No The user id in merchant system.
type Yes Payment Type. DEPOSIT or PAYOUT
currency Yes Currency。CNY, THB or other supported currencies.
nonce Yes Random UUID to improve the unpredictability of signature.
signature Yes The message signature. Check Integration Guide - Message Signature

Response Data

If the request succeeds, OnlinePay System will return all the available deposit/payout methods and limits. Please check the sample JSON response data on the right.

2.2 Query Account Balance

private static String merchantId = "8101";
private static String merchantSecretKey = "NjE5NDA4NWUtYmVlMi00OWQ1";
private static String balanceGatewayUrl = "https://api.fundsguard.net/balance";

public ResponseEntity getAvailableMethods() {
    Map<String, Object> mapData = new HashMap<>();
    mapData.put("merchantId", merchantId);
    mapData.put("currency", "CNY");
    mapData.put("nonce", UUID.randomUUID().toString());
    
    // calculate signature
    mapData.put("signature", calculateSignature(merchantSecretKey, mapData));

    // build query url
    UriComponentsBuilder uriBuilder = UriComponentsBuilder.fromHttpUrl(depositGatewayUrl);
    mapData.entrySet().stream().forEach(e -> uriBuilder.queryParam(e.getKey(), e.getValue()));

    return new RestTemplate().getForEntity(uriBuilder.toUriString(), String.class);
}

When request succeeds, OnlinePay System will return JSON response data in this structure:

{
    "merchantId": 5001,
    "merchantName": "Test Merchant",
    "currency": "CNY",
    "totalBalance": "32205.68",
    "availableBalance": "32205.68",
    "timestamp": "2019-06-14 17:19:14"
}

Merchant can use this API to query the current account balance.

Request Format

GET https://api.fundsguard.net/balance?merchantId=&type=&nonce=&signature=

Parameters List

Name Required? Description
merchantId Yes Merchant id.
currency Yes Currency。CNY, THB or other supported currencies.
nonce Yes Random UUID to improve the unpredictability of signature.
signature Yes The message signature. Check Integration Guide - Message Signature

Response Data

If the request succeeds, OnlinePay System will return the account balance. Please check the sample JSON response data on the right.

2.3 Search Existing Orders

private static String merchantId = "8101";
private static String merchantSecretKey = "NjE5NDA4NWUtYmVlMi00OWQ1";
private static String balanceGatewayUrl = "https://api.fundsguard.net/orders";

public ResponseEntity searchOrders() {
    Map<String, Object> mapData = new HashMap<>();
    mapData.put("merchantId", merchantId);
    mapData.put("type", "DEPOSIT");
    mapData.put("nonce", UUID.randomUUID().toString());
    
    // calculate signature
    mapData.put("signature", calculateSignature(merchantSecretKey, mapData));

    // these parameters should not be included in signature calculation
    mapData.put("createdFrom", "2021-02-01 00:00:00");
    mapData.put("createdTo", "2021-02-10 00:00:00");
    mapData.put("page", "0");
    mapData.put("size", "10");


    // Build query url
    UriComponentsBuilder uriBuilder = UriComponentsBuilder.fromHttpUrl(depositGatewayUrl);
    mapData.entrySet().stream().forEach(e -> uriBuilder.queryParam(e.getKey(), e.getValue()));

    return new RestTemplate().getForEntity(uriBuilder.toUriString(), String.class);
    
    // Result will be returned with pagination
}

When request succeeds, OnlinePay System will return JSON response data in this structure:

{
    "merchantId": 5001,
    "nonce": "c6161266-6646-40c9-afd3-df916891aac8",
    "signature": "e966c19e0ac3aaf8aa4270b46019cd21c2debda616521cc6eb1df364a1635fc8",
    "totalElements": 419,
    "results": [
        {
            "id": "P832010",
            "type": "DEPOSIT",
            "merchantId": 5001,
            "merchantOrderId": "1566420066766",
            "merchantUserId": "david_0730",
            "method": "BANK_TRANSFER",
            "amount": "144.00",
            "currency": "CNY",
            "remark": "Test",
            "status": "SUCCESS",
            "createdAt": "2019-08-21 21:41:09",
            "lastModifiedAt": "2019-08-21 21:41:32"
        },
        {
            "id": "P832011",
            "type": "DEPOSIT",
            "merchantId": 5001,
            "merchantOrderId": "1566481656813",
            "merchantUserId": "david_0730",
            "method": "BANK_TRANSFER",
            "amount": "111.00",
            "currency": "CNY",
            "remark": "Test",
            "status": "SUCCESS",
            "createdAt": "2019-08-22 14:47:40",
            "lastModifiedAt": "2019-08-22 14:48:00"
        },
        {
            "id": "P832012",
            "type": "DEPOSIT",
            "merchantId": 5001,
            "merchantOrderId": "1566481722265",
            "merchantUserId": "david_0730",
            "method": "BANK_TRANSFER",
            "amount": "208.00",
            "currency": "CNY",
            "remark": "Test",
            "status": "SUCCESS",
            "createdAt": "2019-08-22 14:48:42",
            "lastModifiedAt": "2019-08-22 14:48:58"
        },
        {
            "id": "P832013",
            "type": "DEPOSIT",
            "merchantId": 5001,
            "merchantOrderId": "1566481761857",
            "merchantUserId": "david_0730",
            "method": "ALIPAY",
            "amount": "552.00",
            "currency": "CNY",
            "remark": "Test",
            "status": "SUCCESS",
            "createdAt": "2019-08-22 14:49:22",
            "lastModifiedAt": "2019-08-22 14:49:54"
        },
        {
            "id": "P832017",
            "type": "DEPOSIT",
            "merchantId": 5001,
            "merchantOrderId": "1566507623156",
            "merchantUserId": "david_0730",
            "method": "ALIPAY",
            "amount": "130.00",
            "currency": "CNY",
            "remark": "Test",
            "status": "SUCCESS",
            "createdAt": "2019-08-22 22:00:23",
            "lastModifiedAt": "2019-08-22 22:00:36"
        },
        {
            "id": "P832018",
            "type": "DEPOSIT",
            "merchantId": 5001,
            "merchantOrderId": "1566507627910",
            "merchantUserId": "david_0730",
            "method": "ALIPAY",
            "amount": "1085.00",
            "currency": "CNY",
            "remark": "Test",
            "status": "SUCCESS",
            "createdAt": "2019-08-22 22:00:30",
            "lastModifiedAt": "2019-08-22 22:00:49"
        },
        {
            "id": "P832019",
            "type": "DEPOSIT",
            "merchantId": 5001,
            "merchantOrderId": "1566507669397",
            "merchantUserId": "david_0730",
            "method": "ALIPAY",
            "amount": "673.00",
            "currency": "CNY",
            "remark": "Test",
            "status": "FAILED",
            "createdAt": "2019-08-22 22:01:09",
            "lastModifiedAt": "2019-08-22 23:01:09"
        },
        {
            "id": "P832020",
            "type": "DEPOSIT",
            "merchantId": 5001,
            "merchantOrderId": "1566507670657",
            "merchantUserId": "david_0730",
            "method": "ALIPAY",
            "amount": "256.00",
            "currency": "CNY",
            "remark": "Test",
            "status": "SUCCESS",
            "createdAt": "2019-08-22 22:01:10",
            "lastModifiedAt": "2019-08-22 22:01:25"
        },
        {
            "id": "P832021",
            "type": "DEPOSIT",
            "merchantId": 5001,
            "merchantOrderId": "DEB345E629B044CA1A2540830FA854D8",
            "merchantUserId": "david_0730",
            "method": "ALIPAY",
            "amount": "841.00",
            "currency": "CNY",
            "remark": "Test",
            "status": "FAILED",
            "createdAt": "2019-08-23 21:15:54",
            "lastModifiedAt": "2019-08-23 22:15:55"
        },
        {
            "id": "P832035",
            "type": "DEPOSIT",
            "merchantId": 5001,
            "merchantOrderId": "1566653881710",
            "merchantUserId": "david_0730",
            "method": "ALIPAY",
            "amount": "5000.00",
            "currency": "CNY",
            "remark": "Test",
            "status": "SUCCESS",
            "createdAt": "2019-08-24 14:38:07",
            "lastModifiedAt": "2019-08-24 14:38:37"
        }
    ]
}

Merchant can use this API to search for order created in a time range. Result will be returned with pagination.

Request Format

GET https://api.fundsguard.net/orders?merchantId=&type=&nonce=&signature=&createdBefore=&createdAfter=

Parameters List

Name Required? Description
merchantId Yes Merchant id.
type Yes Payment Type. DEPOSIT or PAYOUT
currency Yes Payout currency. CNY, THB or other supported currencies.
nonce Yes Random UUID to improve the unpredictability of signature.
signature Yes The message signature. Check Integration Guide - Message Signature
createdFrom Yes Created From (Inclusive). Format:2021-05-01 00:00:00. This parameter is not included in signature calculation.
createdTo Yes Created To (Exclusive). Format:2021-05-02 00:00:00. This parameter is not included in signature calculation.
page No Page Number. Start with 0, default to 0. This parameter is not included in signature calculation.
size No Page Size. Default to 10. This parameter is not included in signature calculation.

Response Data

If the request succeeds, OnlinePay System will return corresponding orders sorted with pagination. In the response, only merchantId and nonce parameters are needed to calculate/verify the signature.

3 Deposit API

3.1 Deposit Flow

3.2 Submit Deposit Order

private static String merchantId = "8101";
private static String merchantSecretKey = "NjE5NDA4NWUtYmVlMi00OWQ1";
private static String depositGatewayUrl = "https://api.fundsguard.net/deposit";

public ResponseEntity submitDepositOrder() {
    MultiValueMap<String, Object> formData = new LinkedMultiValueMap<>();
    formData.add("merchantId", merchantId);
    formData.add("merchantOrderId", String.valueOf(System.currentTimeMillis()));
    formData.add("merchantUserId", "demo.user");
    formData.add("method", "BANK_TRANSFER");
    formData.add("amount", "150");
    formData.add("currency", "CNY");
    formData.add("remark", "订单备注信息");
    formData.add("depositBank", "ICBC");
    formData.add("redirectUrl", "https://merchant.domain.com/redirectUrl");
    formData.add("callbackUrl", "https://merchant.domain.com/callbackUrl");
    formData.add("nonce", UUID.randomUUID().toString());

    // Calculate the message signature
    Map<String, Object> mapData = formData.toSingleValueMap();
    formData.add("signature", calculateSignature(merchantSecretKey, mapData));

    HttpHeaders httpHeaders = new HttpHeaders();
    httpHeaders.add(CONTENT_TYPE, APPLICATION_FORM_URLENCODED_VALUE);
    HttpEntity httpEntity = new HttpEntity(formData, httpHeaders);

    return new RestTemplate().exchange(depositGatewayUrl, POST, httpEntity, String.class);
}

When request succeeds, OnlinePay System will return JSON response data of this structure:

{
   "id": "P832045",
   "type": "DEPOSIT",
   "merchantId": 8101,
   "merchantOrderId": "1557608872316",
   "merchantUserId": "demo.user",
   "method": "BANK_TRANSFER",
   "amount": "150",
   "currency": "CNY",
   "remark": "Test Remark",
   "status": "CREATED",
   "createdAt": "2019-05-12 05:07:55",
   "nonce": "3b5c7f8c-1e6d-40cd-9d0c-f1613631c089",
   "signature": "47e307e815b3e5630ab07621fd5f02fd11faca9784c9e03b4b6bfb64b9786531",
   "paymentUrl": "https://cashier.[domain.name]/deposit/8913a8aa8393c96b1bdc14e2830be4ceac7fe337"
}

This API is used by merchant. If request succeeds, OnlinePay System will create the deposit order and return the order detail in response.

Request Format

POST https://api.fundsguard.net/deposit

Parameter Format

application/x-www-form-urlencoded

Parameters List

Name Required? Description
merchantId Yes Merchant id.
merchantOrderId Yes Merchant order id.
merchantUserId Yes The user id in merchant system.
method Yes Deposit method. Check Appendix - Supported Deposit Methods
amount Yes Deposit amount.
currency Yes Currency。CNY, THB or other supported currencies.
callbackUrl No Callback url for the merchant to receive asynchronous callback notifications. Not required if merchant has configured to use fixed callback url.
redirectUrl No Redirect url to which users will be redirected when payment is finished.
depositBank No Bank code. Required if method is BANK_TRANSFER or LBT_QR.
depositName No Full name of depositor. Required if method is BANK_TRANSFER or LBT_QR.
depositBankAccount No Bank Account. Required if method is LBT_QR.
depositFromAddress No Wallet address to deposit from. Required if method is USDT.
remark No Additional remark information. Will be returned in the response and callback notification.
nonce Yes Random UUID to improve the unpredictability of signature.
signature Yes The message signature. Check Integration Guide - Message Signature

Response

When submitting a deposit order, OnlinePay System will return order detail and payment page url paymentUrl. Please check the sample JSON response data on the right.

3.3 Query Deposit Order

private static String merchantId = "8101";
private static String merchantSecretKey = "NjE5NDA4NWUtYmVlMi00OWQ1";
private static String depositGatewayUrl = "https://api.fundsguard.net/deposit";

public ResponseEntity queryDepositOrder() {
    Map<String, Object> mapData = new HashMap<>();
    mapData.put("merchantId", merchantId);
    mapData.put("merchantOrderId", "1557608872316");
    mapData.put("nonce", UUID.randomUUID().toString());
    
    // calculate message signature
    mapData.put("signature", calculateSignature(merchantSecretKey, mapData));

    // build the query url
    UriComponentsBuilder uriBuilder = UriComponentsBuilder.fromHttpUrl(depositGatewayUrl);
    mapData.entrySet().stream().forEach(e -> uriBuilder.queryParam(e.getKey(), e.getValue()));

    return new RestTemplate().getForEntity(uriBuilder.toUriString(), String.class);
}

When request succeeds, OnlinePay System will return JSON response data in this structure:

{
  "id": "P832045",
  "type": "DEPOSIT",
  "merchantId": 8101,
  "merchantOrderId": "1557608872316",
  "merchantUserId": "demo.user",
  "method": "BANK_TRANSFER",
  "amount": "150",
  "currency": "CNY",
  "remark": "Test Remark",
  "status": "PENDING",
  "createdAt": "2019-05-12 05:07:55",
  "nonce": "e8bf2c7e-b20a-4213-8fd8-1225951d28d7",
  "signature": "93587fb7825e37f55c364fa561d72090d5c89f17c5d0e69918477a8bb56a642d"
}

This API is requested by merchant.

Request Format

GET https://api.fundsguard.net/deposit?merchantId=&merchantOrderId=&nonce=&signature=

Parameters List

Name Required? Description
merchantId Yes Merchant id.
merchantOrderId Yes Merchant order id.
nonce Yes Random UUID to improve the unpredictability of signature.
signature Yes The message signature. Check Integration Guide - Message Signature

Response Data

If the request succeeds, OnlinePay System will return the order detail. Please check the sample JSON response data on the right.

4 Payout API

4.1 Payout Flow

4.2 Submit Payout Order

private static String merchantId = "8101";
private static String merchantSecretKey = "NjE5NDA4NWUtYmVlMi00OWQ1";
private static String payoutGatewayUrl = "https://api.fundsguard.net/payout";

public ResponseEntity submitPayoutOrder() {
    MultiValueMap<String, Object> formData = new LinkedMultiValueMap<>();
    formData.add("merchantId", merchantId);
    formData.add("merchantOrderId", String.valueOf(System.currentTimeMillis()));
    formData.add("merchantUserId", "demo.user");
    formData.add("method", "BANK_TRANSFER");
    formData.add("amount", "150");
    formData.add("currency", "CNY");
    formData.add("remark", "Test Remark");
    formData.add("bankCode", "ICBC");
    formData.add("bankAccountName", "孙悟空");
    formData.add("bankAccountNumber", "1234567890123456");
    formData.add("callbackUrl", "https://merchant.domain.com/callbackUrl");
    formData.add("nonce", UUID.randomUUID().toString());

    // calculates message signature
    Map<String, Object> mapData = formData.toSingleValueMap();
    formData.add("signature", calculateSignature(merchantSecretKey, mapData));

    HttpHeaders httpHeaders = new HttpHeaders();
    httpHeaders.add(CONTENT_TYPE, APPLICATION_FORM_URLENCODED_VALUE);
    HttpEntity httpEntity = new HttpEntity(formData, httpHeaders);

    return new RestTemplate().exchange(payoutGatewayUrl, POST, httpEntity, String.class);
}

When request succeeds, OnlinePay System will return JSON response data of this structure:

{
  "id": "P832046",
  "type": "PAYOUT",
  "merchantId": 8101,
  "merchantOrderId": "1557623282534",
  "merchantUserId": "demo.user",
  "method": "BANK_TRANSFER",
  "amount": "150",
  "currency": "CNY",
  "remark": "Test Remark",
  "status": "CREATED",
  "createdAt": "2019-05-12 09:08:06",
  "nonce": "b0059feb-cf05-4a54-9311-11c265dae895",
  "signature": "7ed31c2664d5f3ed869f356b5bab90e2d838c836575dc78dbe310d3a9409bea4"
}

This API is used by merchant. If request succeeds, OnlinePay System will create the payout order and return the order detail in response.

Request Format

POST https://api.fundsguard.net/payout

Parameter Format

application/x-www-form-urlencoded

Parameters List

Name Required? Description
merchantId Yes Merchant id.
merchantOrderId Yes Merchant order id.
merchantUserId Yes The user id in merchant system.
method Yes Payout method. Supports BANK_TRANSFER and USDT.
amount Yes Payout amount.
currency Yes Payout currency. CNY, THB or other supported currencies.
callbackUrl No Callback url for the merchant to receive asynchronous callback notifications. Not required if merchant has configured to use fixed callback url.
alipayAccountName No The alipay account name of the beneficiary. Required for ALIPAY.
bankCode No The bank code of beneficiary account. Required for BANK_TRANSFER. I.E: ICBC. Check Appendix - Supported Bank List
bankAccountNumber No The number of beneficiary account. Required for BANK_TRANSFER. I.E: 6217003250022956518
bankAccountCode No The IFSC code of beneficiary account. Required for BANK_TRANSFER in INR currency. I.E: IOBA0003123
bankAccountName No The beneficiary name. Required for BANK_TRANSFER. I.E: 张三丰
bankProvince No The province of beneficiary account. I.E: 湖南
bankCity No The city of beneficiary account. I.E: 长沙
bankBranch No The branch of beneficiary account. I.E: 明主路支行
usdtAddress No The wallet address. Required for USDT.
remark No Additional remark information. Will be returned in the response and callback notification.
nonce Yes Random UUID to improve the unpredictability of signature.
signature Yes The message signature. Check Integration Guide - Message Signature

Response

When payout order is submitted, OnlinePay System will return order detail. Please check the sample JSON response data on the right.

4.3 Query Payout Order

private static String merchantId = "8101";
private static String merchantSecretKey = "NjE5NDA4NWUtYmVlMi00OWQ1";
private static String payoutGatewayUrl = "https://api.fundsguard.net/payout";

public ResponseEntity queryPayoutOrder() {
    Map<String, Object> mapData = new HashMap<>();
    mapData.put("merchantId", merchantId);
    mapData.put("merchantOrderId", "1557623282534");
    mapData.put("nonce", UUID.randomUUID().toString());

    // calculates message signature
    mapData.put("signature", calculateSignature(merchantSecretKey, mapData));

    // builds query url
    UriComponentsBuilder uriBuilder = UriComponentsBuilder.fromHttpUrl(payoutGatewayUrl);
    mapData.entrySet().stream().forEach(e -> uriBuilder.queryParam(e.getKey(), e.getValue()));

    return new RestTemplate().getForEntity(uriBuilder.toUriString(), String.class);
}

When request succeeds, OnlinePay System will return JSON response data in this structure:

{
  "id": "P832046",
  "type": "PAYOUT",
  "merchantId": 8101,
  "merchantOrderId": "1557623282534",
  "merchantUserId": "demo.user",
  "method": "BANK_TRANSFER",
  "amount": "150",
  "remark": "Test Remark",
  "status": "PENDING",
  "createdAt": "2019-05-12 09:08:06",
  "nonce": "b69c4957-1b55-47df-87fb-f91fed9b0625",
  "signature": "f3f285718cf797b1796bea76a97046da8b31ad7e2fe554f0c851c71093c8a8d4"
}

This API is requested by merchant.

Request Format

GET https://api.fundsguard.net/payout?merchantId=&merchantOrderId=&nonce=&signature=

Parameters List

Name Required? Description
merchantId Yes Merchant id.
merchantOrderId Yes Merchant order id.
nonce Yes Random UUID to improve the unpredictability of signature.
signature Yes The message signature. Check Integration Guide - Message Signature

Response Data

If the request succeeds, OnlinePay System will return the order detail. Please check the sample JSON response data on the right.

5 Settlement API

5.1 Settlement Flow

5.2 Submit Settlement Request

private static String merchantId = "8101";
private static String merchantSecretKey = "NjE5NDA4NWUtYmVlMi00OWQ1";
private static String settlementGatewayUrl = "https://api.fundsguard.net/settlement";

public ResponseEntity submitSettlementRequest() {
    MultiValueMap<String, Object> formData = new LinkedMultiValueMap<>();
    formData.add("merchantId", merchantId);
    formData.add("merchantOrderId", String.valueOf(System.currentTimeMillis()));
    formData.add("merchantUserId", "demo.user");
    formData.add("method", "BANK_TRANSFER");
    formData.add("amount", "150");
    formData.add("currency", "CNY");
    formData.add("remark", "Test Remark");
    formData.add("bankCode", "ICBC");
    formData.add("bankAccountName", "孙悟空");
    formData.add("bankAccountNumber", "1234567890123456");
    formData.add("callbackUrl", "https://merchant.domain.com/callbackUrl");
    formData.add("nonce", UUID.randomUUID().toString());

    // calculates message signature
    Map<String, Object> mapData = formData.toSingleValueMap();
    formData.add("signature", calculateSignature(merchantSecretKey, mapData));

    HttpHeaders httpHeaders = new HttpHeaders();
    httpHeaders.add(CONTENT_TYPE, APPLICATION_FORM_URLENCODED_VALUE);
    HttpEntity httpEntity = new HttpEntity(formData, httpHeaders);

    return new RestTemplate().exchange(payoutGatewayUrl, POST, httpEntity, String.class);
}

When request succeeds, OnlinePay System will return JSON response data of this structure:

{
  "id": "P832046",
  "type": "PAYOUT",
  "merchantId": 8101,
  "merchantOrderId": "1557623282534",
  "merchantUserId": "demo.user",
  "method": "BANK_TRANSFER",
  "amount": "150",
  "currency": "CNY",
  "remark": "Test Remark",
  "status": "CREATED",
  "createdAt": "2019-05-12 09:08:06",
  "nonce": "b0059feb-cf05-4a54-9311-11c265dae895",
  "signature": "7ed31c2664d5f3ed869f356b5bab90e2d838c836575dc78dbe310d3a9409bea4"
}

This API is used by merchants. If request succeeds, OnlinePay System will create the settlement request and return the order detail in response.

Request Format

POST https://api.fundsguard.net/settlement

Parameter Format

application/x-www-form-urlencoded

Parameters List

Name Required? Description
merchantId Yes Merchant id.
merchantOrderId Yes The request id of the settlement.
merchantUserId Yes The user who requests the settlement
method Yes Payout method. Only supports BANK_TRANSFER for now.
amount Yes Payout amount.
currency Yes Payout currency. CNY, THB or other supported currencies.
callbackUrl No Callback url for the merchant to receive asynchronous callback notifications. Not required if merchant has configured to use fixed callback url.
bankCode Yes The bank code of beneficiary account. I.E: ICBC. Check Appendix - Supported Bank List
bankAccountNumber Yes The number of beneficiary account. I.E: 6217003250022956518
bankAccountName Yes The beneficiary name. I.E: 张三丰
bankProvince No The province of beneficiary account. I.E: 湖南
bankCity No The city of beneficiary account. I.E: 长沙
bankBranch No The branch of beneficiary account. I.E: 明主路支行
remark No Additional remark information. Will be returned in the response and callback notification.
nonce Yes Random UUID to improve the unpredictability of signature.
signature Yes The message signature. Check Integration Guide - Message Signature

Response

When submitting a settlement request, OnlinePay System will return request detail. Please check the sample JSON response data on the right.

6 Callback API

6.1 Send Callback Notification

Sample code of Merchant API which receives/processes OnlinePay System callback notifications:

private static String merchantId = "8101";
private static String merchantSecretKey = "NjE5NDA4NWUtYmVlMi00OWQ1";

@SneakyThrows
@PostMapping(name = "/demo/callback", consumes = APPLICATION_JSON_VALUE)
public ResponseEntity koingDemoCallbackEndpoint(@RequestBody String requestData) {
    Map<String, Object> mapData = objectMapper.readValue(requestJsonData, Map.class);

    // Verify callback signature
    String expectedSignature = calculateSignature(merchantSecretKey, mapData);
    if (!expectedSignature.equals(mapData.get("signature"))) {
        // singature not match, or other reason, return error
        return ResponseEntity.badRequest().build();
    }

    // merchant business related code, check callback data (orderId, status, amount, etc)
    // and then update user data, wallet balance, etc.

    // returns 200 if everything is fine
    return ResponseEntity.ok().build();
}

OnlinePay System will send JSON data in the callback in this structure:

{
  "id": "P832045",
  "type": "DEPOSIT",
  "merchantId": 8101,
  "merchantOrderId": "1557608872316",
  "merchantUserId": "demo.user",
  "method": "BANK_TRANSFER",
  "amount": "150",
  "currency": "CNY",
  "remark": "Test Remark",
  "status": "FAILED",
  // "failureReason": "Failed due to timeout", // Optional parameter, check detaisl in Parameters List section below.
  // "overrideStatus": "yes", // Optional parameter, check detaisl in Parameters List section below.
  "createdAt": "2019-05-12 05:07:55",
  "nonce": "59bf85fc-f90f-43e0-a38a-b2952cfb1e9e",
  "signature": "3eb593a9b4349db248359c5efa5c138f6c941002533d6609f9709409fbdd0933"
}

Callback API is called by OnlinePay System to notify merchant the status changes of orders.

The callback url is either specified dynamically when merchant submitting the deposit/payout order; or configured as fixed (by OnlinePay System customer support).

After merchant receives and processes the callback notification, merchant should return HTTP status code 200. Otherwise, OnlinePay System will keep retrying to send the notifications. The maximum retry attempt is 8. The time intervals between each retry attempts are: 0s, 3s, 9s, 27s, 1m21s, 4m3s, 12m9s, 36m27s.

Request Format

POST [callbackUrl]

Parameter Format

application/json

Parameters List

Name Required? Description
id Yes Sequence id in OnlinePay System system.
type Yes Order type. DEPOSIT orPAYOUT
merchantId Yes Merchant id.
merchantOrderId Yes Merchant order id.
merchantUserId Yes The user id in merchant system.
remark No Additional remark information.
method Yes Order payment method.
amount Yes Order amount.
currency Yes Payout currency. CNY, THB or other supported currencies.
status Yes Order status. SUCCESS or FAILED
failureReason No Only returned when status is FAILED. Possible failure reasons include, but are not limited to:”Failed due to timeout”, “Failed to submit to upstream”, “Failed to process in the upstream”.
overrideStatus No Only returned when deposit status is changing from FAILED to SUCCESS or payout status is changing from SUCCESS to FAILED. When receive this parameter, it should be include in signature calculation.
createdAt Yes created time. Format: yyyy-MM-dd HH:mm:ss
nonce Yes Random UUID to improve the unpredictability of signature.
signature Yes The message signature. Check Integration Guide - Message Signature

7 Appendix

7.1 CNY Payment Methods and Supported Banks

7.1.1 CNY Payment Methods

Code Payment Type Payment Method Description
BANK_TRANSFER Deposit Bank Transfer Bank Transfer
ALIPAY Deposit AliPay AliPay
ALIPAY_S AliPay (Small Amount) AliPay (Small Amount)
ALIPAY_M AliPay (Medium Amount) AliPay (Medium Amount)
WECHAT Deposit WeChat Pay WeChat Pay
BANK_TRANSFER Payout Bank Transfer Bank Transfer
ALIPAY Payout AliPay AliPay

7.1.2 CNY Supported Banks

Code Bank Name Deposit Payout
BC0001 中国银行 Yes Yes
BC0002 中国农业银行 Yes Yes
BC0003 中国建设银行 Yes Yes
BC0004 中国工商银行 Yes Yes
BC0005 中国邮政储蓄银行 Yes Yes
BC0006 中国交通银行 Yes Yes
BC0007 招商银行 Yes Yes
BC0008 中国民生银行 Yes Yes
BC0009 中信银行 Yes Yes
BC0010 平安银行 Yes Yes
BC0011 华夏银行 Yes Yes
BC0012 广发银行 Yes Yes
BC0013 浦发银行 Yes Yes
BC0014 光大银行 Yes Yes
BC0015 兴业银行 Yes Yes
BC0020 北京银行 Yes Yes
BC0021 广州银行 Yes Yes

7.2 MYR Payment Methods and Supported Banks

7.2.1 MYR Payment Methods

Code Payment Type Payment Method Description
ONLINE_DEBIT Deposit Online Debit FPX
E_WALLET Deposit eWallet eWallet
QR Deposit QR DuitNow
BANK_TRANSFER Deposit Bank Transfer Bank Transfer
BANK_TRANSFER Payout Bank Transfer Bank Transfer

7.2.2 MYR Supported Banks

Code Bank Name Deposit Payout
BM0001 Public Bank Yes Yes
BM0002 Bank Rakyat Yes Yes
BM0003 Alliance Bank Yes Yes
BM0004 Maybank2U Yes Yes
BM0005 Bank Islam Yes Yes
BM0006 Bank Muamalat Yes Yes
BM0007 Affin Bank Yes Yes
BM0008 RHB Bank Yes Yes
BM0009 OCBC Bank Yes Yes
BM0010 Standard Chartered Yes Yes
BM0011 Hong Leong Bank Yes Yes
BM0012 UOB Bank Yes Yes
BM0013 CIMB Clicks Yes Yes
BM0014 AmBank Yes Yes
BM0015 HSBC Bank Yes Yes
BM0016 Bank of China Yes Yes
BM0017 Bank Simpanan Nasional Yes Yes

7.3 THB Payment Methods and Supported Banks

7.3.1 THB Payment Methods

Code Payment Type Payment Method Description
QR Deposit QR PromptPay
LBT_QR Deposit Bank Transfer with QR Bank Transfer with QR
BANK_TRANSFER Deposit Bank Transfer Bank Transfer
BANK_TRANSFER Payout Bank Transfer Bank Transfer

7.3.2 THB Supported Banks

Code Bank Name Deposit Payout
BT0001 Bangkok Bank Yes Yes
BT0002 Kasikorn Bank Yes Yes
BT0003 Krung Thai Bank Yes Yes
BT0004 TMBThanachart Bank Yes Yes
BT0005 Siam Commercial Bank Yes Yes
BT0006 Citibank Yes Yes
BT0007 Standard Chartered Yes Yes
BT0008 CIMB Thai Yes Yes
BT0009 UOB Yes Yes
BT0010 Bank of Ayudhya Yes Yes
BT0011 Mega International Yes Yes
BT0012 Bank of America Yes Yes
BT0013 Government Savings Bank Yes Yes
BT0014 HSBC Yes Yes
BT0015 Deutsche Bank Yes Yes
BT0016 Government Housing Bank Yes Yes
BT0017 BAAC Yes Yes
BT0018 Mizuho Bank Yes Yes
BT0019 BNP Paribas Yes Yes
BT0020 Bank of China Yes Yes
BT0021 Thanachart Bank Yes Yes
BT0022 Islamic Bank of Thailand Yes Yes
BT0023 TISCO Bank Yes Yes
BT0024 Kiatnakin Phatra Bank Yes Yes
BT0025 ICBC (Thai) Yes Yes
BT0026 Thai Credit Bank Yes Yes
BT0027 Land and Houses Bank Yes Yes

7.4 IDR Payment Methods and Supported Banks

7.4.1 IDR Payment Methods

Code Payment Type Payment Method Description
QR Deposit QRIS QRIS
BANK_TRANSFER Deposit Bank Transfer with VA Bank Transfer with VA
BANK_TRANSFER Payout Bank Transfer Bank Transfer

7.4.2 IDR Supported Banks

Code Bank Name Deposit Payout
BI0001 Bank Rakyat Indonesia No Yes
BI0002 Bank Mandiri (Persero) Tbk No Yes
BI0003 Bank Negara Indonesia No Yes
BI0004 Bank Danamon Indonesia Tbk No Yes
BI0005 PT Bank Permata Tbk No Yes
BI0006 PT Bank Permata Tbk Syariah No Yes
BI0007 Bank Central Asia Tbk No Yes
BI0008 PT Bank Internasional Indonesia Tbk No Yes
BI0009 PT Bank Panin Tbk No Yes
BI0010 PT Bank CIMB Niaga Tbk No Yes
BI0011 PT Bank UOB Buana Tbk No Yes
BI0012 PT Bank OCBC NISP Tbk No Yes
BI0013 Citibank N.A. No Yes
BI0014 Bank of America NA No Yes
BI0015 PT Bank Windu Kentjana International Tbk No Yes
BI0016 PT Bank Artha Graha Internasional Tbk No Yes
BI0017 Bank of Tokyo-Mitsubishi UFJ, Ltd. No Yes
BI0018 DBS Bank Ltd. No Yes
BI0019 Bank Resona Perdania No Yes
BI0020 Bank Mizuho Indonesia No Yes
BI0021 Standard Chartered Bank No Yes
BI0022 PT Bank Capital Indonesia Tbk No Yes
BI0023 Bank BNP Paribas Indonesia No Yes
BI0024 PT ANZ Panin Bank No Yes
BI0025 Bank of China Limited No Yes
BI0026 PT Bank Bumi Arta Tbk No Yes
BI0027 HSBC Bank (Indonesia) No Yes
BI0028 Bank ANTAR DAERAH No Yes
BI0029 PT Bank Rabobank International Indonesia No Yes
BI0030 PT Bank JTrust Indonesia No Yes
BI0031 PT Bank Mayapada Internasional Tbk No Yes
BI0032 Bank Jawa Barat dan Banten Tbk No Yes
BI0033 Bank DKI No Yes
BI0034 Bank Pembangunan Daerah Istimewa Yogyakarta No Yes
BI0035 Bank Jateng No Yes
BI0036 Bank Jatim No Yes
BI0037 Bank Jambi No Yes
BI0038 Bank Jambi Syariah No Yes
BI0039 Bank Aceh No Yes
BI0040 Bank Aceh Syariah No Yes
BI0041 Bank Sumut No Yes
BI0042 Bank Nagari No Yes
BI0043 Bank Riau No Yes
BI0044 Bank Riau Syariah No Yes
BI0045 Bank Sumsel Babel No Yes
BI0046 Bank Sumsel Babel Syariah No Yes
BI0047 Bank Lampung No Yes
BI0048 Bank Kalsel No Yes
BI0049 Bank Kalbar No Yes
BI0050 Bank Pembangunan Daerah Kalimantan Timur No Yes
BI0051 Bank Pembangunan Daerah Kalimantan Tengah No Yes
BI0052 Bank Sulawesi Selatan dan Sulawesi Barat No Yes
BI0053 Bank Sulut No Yes
BI0054 Bank Nusa Tenggara Barat No Yes
BI0055 Bank Nusa Tenggara Barat Syariah No Yes
BI0056 Bank Pembangunan Daerah Bali No Yes
BI0057 Bank Nusa Tenggara Timur No Yes
BI0058 Bank Maluku No Yes
BI0059 Bank Pembangunan Daerah Papua No Yes
BI0060 Bank Bengkulu No Yes
BI0061 Bank Sulawesi Tengah No Yes
BI0062 Bank Sultra No Yes
BI0063 Bank Banten No Yes
BI0064 Bank Nusantara Parahyangan No Yes
BI0065 Bank of India Indonesia No Yes
BI0066 Bank Muamalat Indonesia No Yes
BI0067 Bank Mestika No Yes
BI0068 Shinhan Bank No Yes
BI0069 PT Bank Sinarmas Tbk No Yes
BI0070 PT Bank Maspion Indonesia Tbk No Yes
BI0071 Bank Ganesha No Yes
BI0072 Industrial and Commercial Bank of China (ICBC) No Yes
BI0073 PT Bank QNB Kesawan Tbk No Yes
BI0074 Bank Tabungan Negara No Yes
BI0075 Bank Woori Saudara 1906 Tbk No Yes
BI0076 PT Bank Tabungan Pensiunan Nasional Tbk No Yes
BI0077 PT Bank Victoria Syariah No Yes
BI0078 Bank Jabar Banten Syariah No Yes
BI0079 Bank Mega Tbk No Yes
BI0080 Bank Bukopin No Yes
BI0081 Bank Syariah Indonesia No Yes
BI0082 Bank Jasa Jakarta No Yes
BI0083 KEB Hana Bank No Yes
BI0084 PT Bank MNC Internasional Tbk No Yes
BI0085 Bank Yudha Bhakti No Yes
BI0086 Bank Rakyat Indonesia (Agroniaga) No Yes
BI0087 Bank SBI Indonesia (Indomonex) No Yes
BI0088 Bank Royal No Yes
BI0089 Bank Nationalnobu No Yes
BI0090 Bank Mega Syariah No Yes
BI0091 Bank Ina Perdana No Yes
BI0092 Bank Panin Syariah No Yes
BI0093 Bank Prima Master No Yes
BI0094 Bank Syariah Bukopin No Yes
BI0095 Bank Sahabat Sampoerna No Yes
BI0096 Bank Dinar Indonesia No Yes
BI0097 Bank Amar Indonesia No Yes
BI0098 Bank Seabank Indonesia No Yes
BI0099 Bank Central Asia Syariah No Yes
BI0100 PT Bank Artos Indonesia No Yes
BI0101 Bank Tabungan Pensiunan Nasional Syariah No Yes
BI0102 Bank Multiarta Sentosa No Yes
BI0103 PT Bank Mayora Indah Tbk No Yes
BI0104 PT Bank Index Selindo No Yes
BI0105 Central Nasional Bank No Yes
BI0106 PT Bank Mantap Sejahtera No Yes
BI0107 PT Bank Victoria International No Yes
BI0108 PT Bank Harda Internasional Tbk No Yes
BI0109 Bank Pembangunan Daerah Kepulauan Selayar No Yes
BI0110 PT Bank IFI No Yes
BI0111 Bank Aladin Syariah No Yes
BI0112 China Trust Commercial Bank, Indonesia Branch No Yes
BI0113 Commonwealth Bank of Australia No Yes

7.5 VND Payment Methods and Supported Banks

7.5.1 VND Payment Methods

Code Payment Type Payment Method Description
QR Deposit QR QR
E_WALLET Deposit MOMO MOMO
BANK_TRANSFER Deposit Bank Transfer Bank Transfer
BANK_TRANSFER Payout Bank Transfer Bank Transfer

7.5.2 VND Supported Banks

Code Bank Name Deposit Payout
BV0011 Military Bank No Yes
BV0012 Nam A Bank No Yes
BV0013 National Citizen Bank No Yes
BV0015 Orient Commercial Joint Stock Bank No Yes
BV0016 Prosperity and Growth Bank No Yes
BV0017 Public Vietnam Commercial Bank No Yes
BV0018 Sacombank No Yes
BV0020 Saigon Bank No Yes
BV0022 SeABank No Yes
BV0024 Tien Phong Bank No Yes
BV0026 VietABank No Yes
BV0027 Vietcombank No Yes
BV0028 Vietinbank No Yes
BV0029 Vietnam Export Import Bank No Yes
BV0030 Vietnam International Bank No Yes
BV0031 Vietnam Prosperity Bank No Yes
BV0032 BaoViet Bank No Yes
BV0036 Kien Long Bank No Yes
BV0037 LienVietPostBank No Yes
BV0039 Shinhan Bank No Yes
BV0046 WOORI BANK No Yes
BV0054 Cake Digital Bank by VPBank No Yes
BV0070 Cooperative Bank of Vietnam No Yes

7.6 INR Payment Methods and Supported Banks

7.6.1 INR Payment Methods

Code Payment Type Payment Method Description
QR Deposit UPI QR Scan UPI QR Scan
BANK_TRANSFER Payout IMPS Bank Transfer IMPS Bank Transfer

7.6.2 INR Supported Banks

Code Bank Name Deposit Payout
BD0001 State Bank of India No Yes
BD0002 HDFC Bank No Yes
BD0003 ICICI Bank No Yes
BD0004 Bank of Baroda No Yes
BD0005 Punjab National Bank No Yes
BD0006 Canara Bank No Yes
BD0007 Union Bank of India No Yes
BD0008 Axis Bank No Yes
BD0009 Indian Bank No Yes
BD0010 Indian Overseas Bank No Yes