NAV
java php

Ⅰ、TopPay API Reference

Welcome to the TopPay API documentation page, which is aimed at technical personnel with development capabilities. Java language can directly refer to the Java code example on the right. If you have any questions, able to pass Telegram Messenger 👨‍💻 Cindy contact us for a consultation.

Ⅱ、Introduction

RequestMode

HTTP POST

ContentType

application/json

Sign

The shaded area on the right is the signature tool class

import com.google.gson.JsonObject;
import org.apache.commons.codec.binary.Base64;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
import org.apache.tomcat.util.http.fileupload.IOUtils;

import javax.crypto.Cipher;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * <p>
 *  TopPay RSA signatureToolClass
 * </p>
 *
 * @author TopPay
 */
public class TopPayRequestUtil {

  /**
   * VERIFY SIGNATURE
   * @param params
   * @return
   */
  public static boolean verifySign(JsonObject params, String publickey) throws InvalidKeySpecException, NoSuchAlgorithmException {
    String platSign = params.remove("platSign").getAsString(); // sign
    List<String> paramNameList = new ArrayList<>(params.keySet());
    Collections.sort(paramNameList);

    StringBuilder stringBuilder = new StringBuilder();
    for (String name : paramNameList) {
      stringBuilder.append(params.get(name).getAsString());
    }
    System.out.println("keys:" + stringBuilder);

    String decryptSign  = publicDecrypt(platSign, getPublicKey(publickey));
    System.out.println("decryptSign:" + decryptSign);

    return stringBuilder.toString().equals(decryptSign);
  }

  /**
   * PRIVATE KEY ENCRYPTION
   * @param data
   * @param privateKey
   * @return
   */

  public static String privateEncrypt(String data, RSAPrivateKey privateKey){
    try{
      Cipher cipher = Cipher.getInstance("RSA");
      cipher.init(Cipher.ENCRYPT_MODE, privateKey);
      return Base64.encodeBase64String(rsaSplitCodec(cipher, Cipher.ENCRYPT_MODE, data.getBytes("UTF-8"), privateKey.getModulus().bitLength()));
    }catch(Exception e){
      throw new RuntimeException("ENCRYPTED STRING[" + data + "]Encountered an exception", e);
    }
  }

  /**
   * PUBLIC KEY DECRYPTION
   * @param data
   * @param publicKey
   * @return
   */

  public static String publicDecrypt(String data, RSAPublicKey publicKey){
    try{
      Cipher cipher = Cipher.getInstance("RSA");
      cipher.init(Cipher.DECRYPT_MODE, publicKey);
      return new String(rsaSplitCodec(cipher, Cipher.DECRYPT_MODE, Base64.decodeBase64(data), publicKey.getModulus().bitLength()), "UTF-8");
    }catch(Exception e){
      throw new RuntimeException("When attempting to encrypt the string [" + data + "], an exception occurred.", e);
    }
  }

  /**
   * GET PRIVATE KEY
   * @param privateKey KEY STRING (BASE 64 ENCODED)
   */
  public static RSAPrivateKey getPrivateKey(String privateKey) throws NoSuchAlgorithmException, InvalidKeySpecException {
    //Obtain the private key object through the Key command encoded by PKCS 8
    KeyFactory keyFactory = KeyFactory.getInstance("RSA");
    PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(Base64.decodeBase64(privateKey));
    RSAPrivateKey key = (RSAPrivateKey) keyFactory.generatePrivate(pkcs8KeySpec);
    return key;
  }

  /**
   * GET PUBLIC KEY
   * @param publicKey KEY STRING (BASE 64 ENCODED)
   */
  public static RSAPublicKey getPublicKey(String publicKey) throws NoSuchAlgorithmException, InvalidKeySpecException {
    //Obtain the public key object through the Key command encoded by X509
    KeyFactory keyFactory = KeyFactory.getInstance("RSA");
    X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(Base64.decodeBase64(publicKey));
    RSAPublicKey key = (RSAPublicKey) keyFactory.generatePublic(x509KeySpec);
    return key;
  }

  private static byte[] rsaSplitCodec(Cipher cipher, int opmode, byte[] datas, int keySize){
    int maxBlock = 0;
    if(opmode == Cipher.DECRYPT_MODE){
      maxBlock = keySize / 8;
    }else{
      maxBlock = keySize / 8 - 11;
    }
    ByteArrayOutputStream out = new ByteArrayOutputStream();
    int offSet = 0;
    byte[] buff;
    int i = 0;
    try{
      while(datas.length > offSet){
        if(datas.length-offSet > maxBlock){
          buff = cipher.doFinal(datas, offSet, maxBlock);
        }else{
          buff = cipher.doFinal(datas, offSet, datas.length-offSet);
        }
        out.write(buff, 0, buff.length);
        i++;
        offSet = i * maxBlock;
      }
    }catch(Exception e){
      throw new RuntimeException("An exception occurred while encrypting or decrypting data with a threshold of [" + maxBlock + "].", e);
    }
    byte[] resultDatas = out.toByteArray();
    IOUtils.closeQuietly(out);
    return resultDatas;
  }

  public static String doPost(String url,String json) throws IOException {
    HttpClient client = new DefaultHttpClient();
    HttpPost post = new HttpPost(url);
    StringEntity s = new StringEntity(json);
    s.setContentEncoding("UTF-8");
    s.setContentType("application/json");//SENDING JSON DATA NEEDS TO SET CONTENT TYPE
    post.setEntity(s);
    HttpResponse res = client.execute(post);
    if(res.getStatusLine().getStatusCode() == HttpStatus.SC_OK){
      return EntityUtils.toString(res.getEntity());// RETURN JSON FORMAT

    }
    return null;
  }
}

How to Sign:

RSA BASED SIGNATURE VERIFICATION METHOD
After sorting the keys of all non-empty parameters according to ASCII, take the parameter value (excluding Key) and splicing
Use the RAS algorithm to calculate the string and calculate the signature string.

Parameter example

Param Type
merchantCode S820211021094748000001
orderNum T1642592278863
payMoney 150.60
notifyUrl your notify ur
dateTime 2022-01-01 10:55:00
expiryPeriod 1440

How to get data for sign

Example
First sort according to ASCII according to the parameter Key, and encrypt the string after sorting.
StrA = 2022-01-01 10:55:[email protected] notify
urlT1642593166888150.60082122965511Test Pay

How to calculate signature

Use the key pair you configured in the backend of the Top Pay merchant, and use your private key to encrypt and calculate RSA (Str A) to get the final signature string
sign = IMLn23c4orM+7pZhHoRmbjrol4X33jeAqFxbZuQ+pnznBIGhb6Ail3qQPmKwcuhNCt536nmldpbWI72
k1lDxd0zZ95ZHElcNzwTFHFKtd8063uy6rFaxaW6DQ47t4U/95dpGfHAZe0GiIFAQ6xQquaoLINyQa4QqL+cpB
JFEg1dyW6GYLFSdJnx7ycQvFYllmOpGZmdPLny62GvrCWvkiIARUsmc9fpkpTx5UQEDTgmhwdCKBkhHVsx2AiQ
bYDxZ5WBuU1GZeiJjPuzSxvzWP6VoQBsfpwTI5kdJs6aQCekGO2/YScD+tGgrm2J89Pc/axPcb1xZzsi5SxpWh
feabQ\u003d\u003d

Ⅲ、Configure merchant public key information

1.Bind google verification code

Log in to the merchant background->PERSONAL CENTER->Security information, use Google Authenticator to scan the QR code on the page to bind your account

2.Rsa key pair generation address

POST http://pay.hehebo.com:15082/index-rsa.jsp

3.Configure public key

Click Payment Configuration->API Configuration, fill in your public key information and save. The configuration is complete

4.Merchant platform url

https://tl-merchant.toppayment.com/

Ⅳ、Pay Api

1.Code example

The code example is for reference only. For specific parameter descriptions, please refer to Request Parameter Description


import com.google.gson.Gson;
import com.google.gson.JsonObject;
import java.io.IOException;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import java.util.Map;
import java.util.TreeMap;

public class TopPayDemo {
  // test account
  private static final String MCH_CODE = "S820211021094748000001";  //merchant code
  private static final String PLAT_PUBLIC_KEY = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC2JoMfFqLsSJjAiCahEnlP3aRj8yCT+WHzR+VvPBTw9S1i7iYWb+MY09CG/HYuHF4+IxshXDJygmndxKf/esuwPybS8mAd//yubHpmZsmBqg1FffT8VH1APa6ZRWASUp4U01ZrbCCp35QA8FuWrJGMJxGx4xk7KUtV2yujxC8noQIDAQAB";  // platform public key
  private static final String MCH_PRIVATE_KEY = "MIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBAJU8gKFKD0luIYx7X8+JRdCIE0UDBctS6LjXxWLEv/EO7jDBTid6zYP1KmNgpd2DAWWtBFBSQ+gcNwVZZSBHJiSDqVvvJVs2FEbeBvfdv4X93+IYRAXksBasSW5Tpdshbo82pVL4V7wuKCuFLk9UxBHbpQjWAbfyF66RmwIbZD71AgMBAAECgYBjPe7UU2nDDSfmQg0++CyjNjqKRC5QPfxhH6w1uF1kMueXKJWOj42n2RutJpJmsj31nY8m0u4xpsG4HvCu/GGSFhhKZCHLvzp41oY2ubYj9nuFNU//81LycQjulWo2y0UUBY0k2piEt+SwPaiUNbT6nMxNMjlnjRe2okp/3rw+KQJBANG3YlZWoVbCEqzy64bJJLxiPsCA5ErGB0NzRGitq44xkhqGtR8ZZQyVz40pruNa58d73O2xyJSy5+fmZGn4E+sCQQC2LBnguj0CSCKub0mPDcunTTz9V79VXBBZdlB1/YGmRUx2s4sQrJNZS7rL4EqBQ3maIRnG+s+AXCSTfsYrV6CfAkEAxugnVfpelhoGepEAgNuggyivmgfl/2Gpm/jk5l/qOjib+ZrQiQmeBPzGWX4yiSM8eMDrP2sC8r5pJFMp5DRONwJBAJ4n4XuSFJ9jgwCPy3vvzSv9SYLk6E6yM9uHdUlKgoGYzk6Lh6M9QFuY/J49plFdBDiEnj16yCU3WeXXfTJpzB8CQQDMNMR/rIOTE9xGybS3mlQbt22AUnO6XhupWcckEKW4nPGxATwYBQzCY3i/9FTGN0vA+9ZPC2cwHtNxI2kXf3Vp";  // merchant private key
  private static final String payUrl = "https://tl-openapi.toppay.asia/gateway/prepaidOrder";
  private static final String cashUrl = "https://tl-openapi.toppay.asia/gateway/cash";
  private static final String payNotify = "your notify url";
  private static final String cashNotify = "your notify url";

  public static void main(String[] args) throws Exception {
    pay();
  }
  private static void pay() throws Exception {
    Map<String, String> requestParams = new TreeMap<>();
    requestParams.put("merchantCode", MCH_CODE);
    requestParams.put("orderType", "0"); // orderType(0-BAHT transaction)
    requestParams.put("method", "BankTransfer"); //  When using online banking, pass in the corresponding bank abbreviation, and pass in qr Pay when using a QR code, or not
    requestParams.put("transAccNo", "1234567890"); // When using online banking, the card number paid by the user must be transmitted, and the real card number must be passed, otherwise the transaction will fail
    requestParams.put("orderNum", "T1642592278863"); // merchant order number
    requestParams.put("payMoney", "150.12");  // order amount
    requestParams.put("notifyUrl", payNotify);// callback address
    requestParams.put("dateTime", "20220101235959");// timestamp format yyyyMMddHHmmss

    StringBuilder stringBuilder = new StringBuilder();
    for (String key : requestParams.keySet()) {
      stringBuilder.append(requestParams.get(key));  // stitching parameters
    }

    String keyStr = stringBuilder.toString();  // get the string to be encrypted
    System.out.println("keyStr:" + keyStr);
    String signedStr = TopPayRequestUtil.privateEncrypt(keyStr, TopPayRequestUtil.getPrivateKey(MCH_PRIVATE_KEY));  // private key encryption
    requestParams.put("sign", signedStr);

    String postJson = new Gson().toJson(requestParams);
    System.out.println("Post Json Params:" + postJson);

    String responseJson = TopPayRequestUtil.doPost(payUrl, postJson);  //  post request
    System.out.println("Response Msg:" + responseJson);
  }
}


<?php
    // platform public key, from Secret key config
    $platPublicKey = 'MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiaKBgQCcEUIvQ/5L+SWbHOeR8VFeZvLbUk7V7OeEAQlQwIVLSZMTef3KtsOKKAsUYPf/aAcKRzZZXECODsPQiDPcdZvM/rFkgrFWkR7lPjTj5SiPxGaiK2Z2sne7A8aDF7fV/D7lfmEwNdZ7FWKVEB84/81BHnlGUwb5HpRTISG+boSO6wIDAQAB';
    // mchchant private key
    $mchPrivateKey = 'MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAMigm7rtWnTeNagwFzGTH+Uw1ypbiy7VhIoFJbgSYSSHdCaXWdT/l2+2fQlEYgAETVZ/IXB29MCnrf3O0dwRFXiipIbsm5zyqSLiS6cKXe8zN1/PlQWUbEt5wyWm0GADB/4bV6eu6gA7sGXmjQqrzfKZkcie3aK7+7ry1NFxTI51AgMBAAECgYEAklqXQAVlt1tiSQ7L3J425jp6u6uMHN4lkYmvuleuBbfKQ1yla3wIPLYjAF+iHeEFidOz0Rb19JRdmIkHDkJoJg2W27LvO6RdUwzgRnsuA3OuNz97w08B3aXXbPmB91nTFjKSlUsbh3IQWP71noxW+iKn844EW5hC5Gvn4L3quAECQQDrz1r0VKIbBSBB2aLuz1XyD/TBT2aRhvOKf0XtTRiQhNjtJxoQmvNbbhvUwj8an7HyCuihAbdbrC2ymFFyOSDZAkEA2c4Yudi48C6COrroi1cWgPlEFeGJXP/V1k5loZ1n2vstYAGPhAB4wUnFBLDvMqaBzWJt7MRkiazT8KnBQCDY/QJAMXpNlEyZwt+deBOpO0BnwSWV7mWxmMFfImU4D+WITPbC7aexsWBBxaJh1o93XCe715RwYTAR//stj3akSDoyaQJAa4FKuxC51/Nc3Fg9R+modeiTLqmv/3NXvPvdNjRXesLX1rduex0wfVdII9ShfEKrdxDKaT9W0NyzD+r6NAkCkQJBAMAnTgPYf0f7rh417GdoP7R7Nwi8KBKwPHlmfRukibOQlKt9xjqpsKJwglLn8pcnXbYbswXIdqzuBvIGAe3OWNg=';
    // merchent ID from idntask, from User info
    $merchantCode = 'YOUR_MERCHANT_CODE_HERE';
     //Order Type(0-BAHT TRANSACTION)
    $orderType = '0';
    // Merchant system unique order number
    $orderNum = 'TEST1231231231';
    // pay money
    $payMoney = '15.12';
    // url for callback
    $notifyUrl = 'http://example.com/callback';
    // order time
    $dateTime = date("YmdHis",time());
    $params = array(
        'merchantCode' => $merchantCode,
        'orderType' => $orderType,
        'orderNum' => $orderNum,
        'payMoney' => $payMoney,
        'notifyUrl' => $notifyUrl,
        'dateTime' => $dateTime,
    );

    ksort($params);
    $params_str = '';
    foreach ($params as $key => $val) {
        $params_str = $params_str . $val;
    }


    $sign = pivate_key_encrypt($params_str, $mchPrivateKey);

    $params['sign'] = $sign;

    $params_string = json_encode($params);
    $url = 'https://tl-openapi.toppay.asia/gateway/prepaidOrder';
    $ch = curl_init();

    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
    curl_setopt($ch, CURLOPT_POSTFIELDS, $params_string);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_HTTPHEADER, array(
        'Content-Type: application/json',
        'Content-Length: ' . strlen($params_string))
    );
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);

    //execute post
    $request = curl_exec($ch);
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);

    if($httpCode == 200)
    {
        $result = json_decode($request, true);
        echo "platRespCode :". $result['platRespCode'] . "\n";
        echo "platRespMessage :". $result['platRespMessage'] . "\n";
        echo "platOrderNum :". $result['platOrderNum'] . "\n";
        echo "orderNum :". $result['orderNum'] . "\n";
        echo "payMoney :". $result['payMoney'] . "\n";
        echo "payFee :". $result['payFee'] . "\n";
        echo "platSign :". $result['platSign'] . "\n";

        $decryptStr = public_key_decrypt($result['platSign'], $platPublicKey);
        echo "decryptStr :". $decryptStr . "\n";
    }
    else {
        echo $httpCode;
    }

    function pivate_key_encrypt($data, $pivate_key)
    {
        $pivate_key = '-----BEGIN PRIVATE KEY-----'."\n".$pivate_key."\n".'-----END PRIVATE KEY-----';
        $pi_key = openssl_pkey_get_private($pivate_key);
        $crypto = '';
        foreach (str_split($data, 117) as $chunk) {
            openssl_private_encrypt($chunk, $encryptData, $pi_key);
            $crypto .= $encryptData;
        }

        return base64_encode($crypto);
    }

    function public_key_decrypt($data, $public_key)
    {
        $public_key = '-----BEGIN PUBLIC KEY-----'."\n".$public_key."\n".'-----END PUBLIC KEY-----';
        $data = base64_decode($data);
        $pu_key =  openssl_pkey_get_public($public_key);
        $crypto = '';
        foreach (str_split($data, 128) as $chunk) {
            openssl_public_decrypt($chunk, $decryptData, $pu_key);
            $crypto .= $decryptData;
        }

        return $crypto;
    }

2.Request address

We provide two modes of collection and order placement.

Cashier mode(Mode 1, you can use our cashier page): POST https://tl-openapi.toppay.asia/gateway/prepaidOrder

API mode(Mode 2 directly requests the API to obtain the returned information, and you can choose according to your own needs): POST https://tl-openapi.toppay.asia/gateway/payment

Note: Do not fill in Chinese in all the parameters! ! !

3.Request param

Cashier mode(Mode 1):

Param Type Required Describe Example
merchantCode string(32) Y merchant ID,Get it in merchant background S820211021094748000001
orderType string(10) Y order type 0-Fiat currency transaction
orderNum string(32) Y merchant order number 10000001
transAccNo string(16) N The user's payment card number (real) is valid when using online bank transfer 1234567890
payMoney string(10) Y payment amount(only two decimal) 20.54
notifyUrl string(100) Y asynchronous notification address of successful order payment (used to receive notification after successful order transaction) https://host:port/notifyUrl
dateTime string(32) Y timestamp format:yyyyMMddHHmmss 20190101235959
method string(32) N pay type
1.If you need to specify a payment method, you can choose one of the payment methods in the example on the right;
2.If you do not specify a payment method, you do not need to pass this parameter (only in cashier mode), all supported payment methods are displayed by default.
BankTransfer (online bank transfer)
qrPay(qr code scanning)
sign string(255) Y sign fnbSOvY83pr8hXg+FdNNYi2ubQUGNv/qGYc4TjRl+XxO2jo92dyjKHFU9/4hNECilMooOcH

Api mode((Mode 2):

Param Type Required Describe Example
merchantCode string(32) Y merchant ID,Get it in merchant background S820211021094748000001
orderType string(10) Y order type 0-Fiat currency transaction
orderNum string(32) Y merchant order number 10000001
payMoney string(10) Y payment amount(only two decimal) 20.54
notifyUrl string(100) Y asynchronous notification address of successful order payment (used to receive notification after successful order transaction) https://host:port/notifyUrl
dateTime string(32) Y timestamp format:yyyyMMddHHmmss 20190101235959
method string(32) Y pay type BankTransfer(online bank transfer)
qrPay(qr code scanning)
transAccNo string(16) N User payment card number (true) must be passed when using online banking transfer 1234567890
sign string(255) Y sign fnbSOvY83pr8hXg+FdNNYi2ubQUGNv/qGYc4TjRl+XxO2jo92dyjKHFU9/4hNECilMooOcH

4.Request example

Mode 1,(method and transAccNo can not be passed, the page to be redirected is different)


{
    "merchantCode": "S820211021094748000001",
    "orderType": "0",
    "orderNum": "T1642593166888",
    "transAccNo": "1234567890", 
    "payMoney": "150.12",
    "method": "BankTransfer",
    "notifyUrl": "your notify url",
    "dateTime": "2022-01-01 10:55:00",
    "sign": "fnbSOvY83pr8hXg+FdNNYi2ubQUGNv/qGYc4TjRl+Xxd1yc9fpkpTx5UQEDTgmhwdCKBkhHVsx2AiQbYDxZ5WBuU1GZeiJ"
}

Mode 2,(method must pass,When using qr Pay, you can not pass the transAccNo, and you must pass the transAccNo when using online banking transfer)

{
    "merchantCode": "S820211021094748000001",
    "orderType": "0",
    "orderNum": "T1642593166888",
    "transAccNo": "1234567890", 
    "payMoney": "150.12",
    "method": "BankTransfer",
    "notifyUrl": "your notify url",
    "dateTime": "2022-01-01 10:55:00",
    "sign": "fnbSOvY83pr8hXg+FdNNYi2ubQUGNv/qGYc4TjRl+Xxd1yc9fpkpTx5UQEDTgmhwdCKBkhHVsx2AiQbYDxZ5WBuU1GZeiJ"
}

5.Response param

Param Type Required Describe Example
platRespCode String Y whether the business is successful FAIL/SUCCESS
platRespMessage String Y interface response information prompt Request Transaction Success
platOrderNum String Y platform order number PI1453242857400963072
payMoney string Y payment amount 150.32
orderNum String Y merchant order number 23645782
url String N cash register link Cashier mode(mode 1),Returned when 'platRespCode' is SUCCESS
payData String N response parameters Api mode(mode 2),Returned when 'platRespCode' is SUCCESS

6.Response example

Cashier mode


{
    "platOrderNum": "PRE1483771634191044608",
    "payMoney": "150.32",
    "orderNum": "T1642593166888",
    "platRespCode": "SUCCESS",
    "platRespMessage": "Request Transaction Success",
    "url": "https://tl-openapi.toppay.asia/gateway/order/PRE1483771634191044608"
}

Api mode(When using qrPay, payData returns the QR code serial number; when using online banking transfer, it returns the receiving card number)


{
    "payData": "123456789",
    "platOrderNum": "PRE1483771634191044608",
    "payMoney": "150.32",
    "orderNum": "T1642593166888",
    "platRespCode": "SUCCESS",
    "method": "BankTransfer",
    "bankName": "KBANK",
    "platRespMessage": "Request Transaction Success"
}

Example of a failure response message

{
    "platRespCode": "FAIL",
    "platRespMessage": "Error message"
}

7.Pay api callback notify

When verifying the signature, use the Platform Public Key provided in Merchant Background-Receipt and Payment Configuration-API Configuration to decrypt! ! !

When verifying the signature, verify the signature according to the actual callback parameters, do not use fixed parameters

After accepting the asynchronous notification, you need to respond with SUCCESS string, without quotation marks, not in Json format.

Otherwise, TopPay will continue to initiate 5 notifications.


import com.google.gson.JsonObject;

public class TopPayNotify {
    // test account
    private static final String MCH_CODE = "S820211021094748000001";  // merchant number
    private static final String PLAT_PUBLIC_KEY = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC2JoMfFqLsSJjAiCahEnlP3aRj8yCT+WHzR+VvPBTw9S1i7iYWb+MY09CG/HYuHF4+IxshXDJygmndxKf/esuwPybS8mAd//yubHpmZsmBqg1FffT8VH1APa6ZRWASUp4U01ZrbCCp35QA8FuWrJGMJxGx4xk7KUtV2yujxC8noQIDAQAB";  // platform public key
    public static void main(String[] args) throws Exception {
        JsonObject notifyBody = new jsonObject();
        boolean verifyResult = TopPayRequestUtil.verifySign(notifyBody,PLAT_PUBLIC_KEY);
        if (verifyResult) {
            // ... signature verification passed,do something
        } else {
            // ... signature verification error
        }
    }
}

<?php

$res = json_decode(file_get_contents('php://input'), true);
$platSign = $res['platSign'];
unset($res['platSign']);
$public_key = 'MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDFJ/AmUV4Z8udG8aOBUt/kEwc/DbxF5Gtfw6Y00NHQ4Pz2X2x9IxjUZxn2dnFxmrmhqKNlfwXOqyejhBzi0pSHyGoI4XP9IEfZGO6YkSb9DCY1ZxX8fDl2G+tPCbWYTVO4JutFmzTWgk1Uhhu6L9dlOMUHvZf3/6czA/a9C7azXwIDAQAB';
$decryptSign = public_key_decrypt($platSign, $public_key);

$params = $res;
ksort($params);
$params_str = '';
foreach ($params as $key => $val) {
    $params_str = $params_str . $val;
}

if($params_str == $decryptSign) {
    if($res['code'] == '00') {
        echo 'success';
    }
    else {
        echo 'fail';
    }
}
else {
    echo 'fail';
}

function public_key_decrypt($data, $public_key)
{
    $public_key = '-----BEGIN PUBLIC KEY-----'."\n".$public_key."\n".'-----END PUBLIC KEY-----';
    $data = base64_decode($data);
    $pu_key =  openssl_pkey_get_public($public_key);
    $crypto = '';
    foreach (str_split($data, 128) as $chunk) {
        openssl_public_decrypt($chunk, $decryptData, $pu_key);
        $crypto .= $decryptData;
    }

    return $crypto;
}
Param Remark Example
code response code 00
msg response message SUCCESS
method pay type Online bank transfer: the abbreviation of the bank when placing an order
QR code scanning: qrPay
status pay result INIT_ORDER:order initialization
NO_PAY:unpaid
SUCCESS:payment successful
PAY_CANCEL:revoke
PAY_ERROR:payment failed
platOrderNum platform order number BK_1563278763273
orderNum merchant order number T1231511321515
payMoney payment amount 100000
payFee merchant fee 500
transAccNo User payment card number 123456
It will only be returned if the method is online banking transfer
platSign platform signature ja6R8eukQY9jc8zrhtf34654ungj7u8sdgdfjfs

8.Pay api callback notify example

{
    "code": "00",
    "msg": "SUCCESS",
    "status": "SUCCESS",
    "method": "BankTransfer",
    "platOrderNum": "PRE1483771634191044608",
    "orderNum": "T1642593166888",
    "payMoney": "150",
    "payFee": "16",
    "transAccNo": "*****1236",
    "platSign": "ja6R8eukQY9jc8zrhtf34654ungj7u8sdgdfjfs"
}

Ⅴ、Cash api

1.Code example

The code example is for reference only, please refer to request parameter description for specific parameter description

import com.google.gson.Gson;
import com.google.gson.JsonObject;
import java.util.Map;
import java.util.TreeMap;
public class TopPayDemo {
  private static final String MCH_CODE = "S820211021094748000001";  // merchant code
  private static final String PLAT_PUBLIC_KEY = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC2JoMfFqLsSJjAiCahEnlP3aRj8yCT+WHzR+VvPBTw9S1i7iYWb+MY09CG/HYuHF4+IxshXDJygmndxKf/esuwPybS8mAd//yubHpmZsmBqg1FffT8VH1APa6ZRWASUp4U01ZrbCCp35QA8FuWrJGMJxGx4xk7KUtV2yujxC8noQIDAQAB";  // platform public key
  private static final String MCH_PRIVATE_KEY = "MIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBAJU8gKFKD0luIYx7X8+JRdCIE0UDBctS6LjXxWLEv/EO7jDBTid6zYP1KmNgpd2DAWWtBFBSQ+gcNwVZZSBHJiSDqVvvJVs2FEbeBvfdv4X93+IYRAXksBasSW5Tpdshbo82pVL4V7wuKCuFLk9UxBHbpQjWAbfyF66RmwIbZD71AgMBAAECgYBjPe7UU2nDDSfmQg0++CyjNjqKRC5QPfxhH6w1uF1kMueXKJWOj42n2RutJpJmsj31nY8m0u4xpsG4HvCu/GGSFhhKZCHLvzp41oY2ubYj9nuFNU//81LycQjulWo2y0UUBY0k2piEt+SwPaiUNbT6nMxNMjlnjRe2okp/3rw+KQJBANG3YlZWoVbCEqzy64bJJLxiPsCA5ErGB0NzRGitq44xkhqGtR8ZZQyVz40pruNa58d73O2xyJSy5+fmZGn4E+sCQQC2LBnguj0CSCKub0mPDcunTTz9V79VXBBZdlB1/YGmRUx2s4sQrJNZS7rL4EqBQ3maIRnG+s+AXCSTfsYrV6CfAkEAxugnVfpelhoGepEAgNuggyivmgfl/2Gpm/jk5l/qOjib+ZrQiQmeBPzGWX4yiSM8eMDrP2sC8r5pJFMp5DRONwJBAJ4n4XuSFJ9jgwCPy3vvzSv9SYLk6E6yM9uHdUlKgoGYzk6Lh6M9QFuY/J49plFdBDiEnj16yCU3WeXXfTJpzB8CQQDMNMR/rIOTE9xGybS3mlQbt22AUnO6XhupWcckEKW4nPGxATwYBQzCY3i/9FTGN0vA+9ZPC2cwHtNxI2kXf3Vp";  // merchant private key
  private static final String cashUrl = "https://tl-openapi.toppay.asia/gateway/cash";
  private static final String cashNotify = "http://host:port/notify";

  public static void main(String[] args) throws Exception {
    cash();
  }
  private static void cash() throws Exception {
    Map<String, String> requestParams = new TreeMap<>();
    requestParams.put("merchantCode", MCH_CODE);
    requestParams.put("orderNum", "186888188666"); // Merchant order number
    requestParams.put("method", "Disbursement"); // Payment method (disbursement by default)
    requestParams.put("orderType", "0"); // Order Type(0-baht transaction)
    requestParams.put("money", "125.12"); // Order amount, supports two decimal places
    requestParams.put("feeType", "0");  //  fee type
    requestParams.put("dateTime", "20200101235959");// timestamp format yyyyMMddHHmmss
    requestParams.put("number", "2021071209403321313122");     // Customer bank card number
    requestParams.put("bankCode", "001");       // Bank code: refer to Appendix I pay
    //Name The original text participates in the signature, but Unicode encoding is required when calling the API
    requestParams.put("name", "จางซาน");  // customer name
    requestParams.put("mobile", "082122965511"); // customer phone,Can not pass
    requestParams.put("email", "[email protected]"); // customer mail,Can not pass
    //The original text of description participates in the signature, but Unicode encoding is required when calling the API
    requestParams.put("description", "คำอธิบาย");    // description
    requestParams.put("notifyUrl", cashNotify);  // callback address
    StringBuilder stringBuilder = new StringBuilder();
    for (String key : requestParams.keySet()) {
      stringBuilder.append(requestParams.get(key));  // stitching parameters
    }

    String keyStr = stringBuilder.toString();  // get the string to be encrypted
    System.out.println("keyStr:" + keyStr);
    String signedStr = TopPayRequestUtil.privateEncrypt(keyStr, TopPayRequestUtil.getPrivateKey(MCH_PRIVATE_KEY));  // private key encryption
    requestParams.put("sign", signedStr);


    //After the signature is completed, encode the name and description UnicodeUtil sample code reference Item 9 of this section Thai Unicode
    requestParams.put("name", UnicodeUtil.toUnicode("จางซาน", true));  // customer name
    requestParams.put("description", UnicodeUtil.toUnicode("คำอธิบาย", true));    // description

    String postJson = new Gson().toJson(requestParams);
    System.out.println("Post Json Params:" + postJson);

    String responseJson = TopPayRequestUtil.doPost(cashUrl, postJson);  // send post json request
    System.out.println("Response Msg:" + responseJson);

    boolean pass = TopPayRequestUtil.verifySign(new Gson().fromJson(responseJson, JsonObject.class), PLAT_PUBLIC_KEY);  // signature verification
    if (pass) {
      // ... signature verification passed,execute normal business logic
    } else {
      // ... signature verification error
    }
  }
}


<?php
    // platform public key, from Secret key config
    $platPublicKey = 'MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiaKBgQCcEUIvQ/5L+SWbHOeR8VFeZvLbUk7V7OeEAQlQwIVLSZMTef3KtsOKKAsUYPf/aAcKRzZZXECODsPQiDPcdZvM/rFkgrFWkR7lPjTj5SiPxGaiK2Z2sne7A8aDF7fV/D7lfmEwNdZ7FWKVEB84/81BHnlGUwb5HpRTISG+boSO6wIDAQAB';
    // mchchant private key
    $mchPrivateKey = 'MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAMigm7rtWnTeNagwFzGTH+Uw1ypbiy7VhIoFJbgSYSSHdCaXWdT/l2+2fQlEYgAETVZ/IXB29MCnrf3O0dwRFXiipIbsm5zyqSLiS6cKXe8zN1/PlQWUbEt5wyWm0GADB/4bV6eu6gA7sGXmjQqrzfKZkcie3aK7+7ry1NFxTI51AgMBAAECgYEAklqXQAVlt1tiSQ7L3J425jp6u6uMHN4lkYmvuleuBbfKQ1yla3wIPLYjAF+iHeEFidOz0Rb19JRdmIkHDkJoJg2W27LvO6RdUwzgRnsuA3OuNz97w08B3aXXbPmB91nTFjKSlUsbh3IQWP71noxW+iKn844EW5hC5Gvn4L3quAECQQDrz1r0VKIbBSBB2aLuz1XyD/TBT2aRhvOKf0XtTRiQhNjtJxoQmvNbbhvUwj8an7HyCuihAbdbrC2ymFFyOSDZAkEA2c4Yudi48C6COrroi1cWgPlEFeGJXP/V1k5loZ1n2vstYAGPhAB4wUnFBLDvMqaBzWJt7MRkiazT8KnBQCDY/QJAMXpNlEyZwt+deBOpO0BnwSWV7mWxmMFfImU4D+WITPbC7aexsWBBxaJh1o93XCe715RwYTAR//stj3akSDoyaQJAa4FKuxC51/Nc3Fg9R+modeiTLqmv/3NXvPvdNjRXesLX1rduex0wfVdII9ShfEKrdxDKaT9W0NyzD+r6NAkCkQJBAMAnTgPYf0f7rh417GdoP7R7Nwi8KBKwPHlmfRukibOQlKt9xjqpsKJwglLn8pcnXbYbswXIdqzuBvIGAe3OWNg=';
    // merchent ID from idntask, from User info
    $merchantCode = 'YOUR_MERCHANT_CODE_HERE';
    // Merchant system unique order number
    $orderNum = 'T'.date("YmdHis",time());
    // Payment method 
    $method = 'Disbursement';
    //order type(0-baht transaction)
    $orderType = '0';
    // withdraw money
    $money = '20000';
    // fee type
    $feeType = '1';
    // timestamp format yyyyMMddHHmmss
    $dateTime = date("YmdHis",time());
    // customer bank card number
    $number = '123456';
    // bank code(for details refer to the bottom of the document)
    $bankCode = '014';
    // Display name on bank confirmation display
    $name = 'จางซาน';
    // Customer's mobile number
    $mobile = '082112345678';
    // Customer's email address
    $email = '[email protected]';
    // The virtual account description
    $description = 'คำอธิบาย';
    // url for callback
    $notifyUrl = 'http://example.com/callback';
    $params = array(
        'merchantCode' => $merchantCode,
        'orderType' => $orderType,
        'method' => $method,
        'orderNum' => $orderNum,
        'money' => $money,
        'feeType' => $feeType,
        'dateTime' => $dateTime,
        'number' => $number,
        'bankCode' => $bankCode,
        'name' => $name,
        'mobile' => $mobile,
        'email' => $email,
        'notifyUrl' => $notifyUrl,
        'description' => $description
    );

    ksort($params);
    $params_str = '';
    foreach ($params as $key => $val) {
        $params_str = $params_str . $val;
    }


    $sign = pivate_key_encrypt($params_str, $mchPrivateKey);

    $params['sign'] = $sign;

    //After the original text participates in the signature, it needs to use unicode encoding. For the encoding method, refer to Item 9 in this section. Thai Unicode
    $params['name'] = unicode_encode($name);
    $params['description'] = unicode_encode($description);

    $params_string = json_encode($params);
    $url = 'https://tl-openapi.toppay.asia/gateway/prepaidOrder';
    $ch = curl_init();

    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
    curl_setopt($ch, CURLOPT_POSTFIELDS, $params_string);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_HTTPHEADER, array(
        'Content-Type: application/json',
        'Content-Length: ' . strlen($params_string))
    );
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);

    //execute post
    $request = curl_exec($ch);
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);

    if($httpCode == 200)
    {
        $result = json_decode($request, true);
        echo "platRespCode :". $result['platRespCode'] . "\n";
        echo "platRespMessage :". $result['platRespMessage'] . "\n";
        echo "platOrderNum :". $result['platOrderNum'] . "\n";
        echo "orderNum :". $result['orderNum'] . "\n";
        echo "status :". $result['status'] . "\n";
        echo "statusMsg :". $result['statusMsg'] . "\n";
        echo "money :". $result['money'] . "\n";
        echo "fee :". $result['fee'] . "\n";
        echo "feeType :". $result['feeType'] . "\n";
        echo "bankCode :". $result['bankCode'] . "\n";
        echo "number :". $result['number'] . "\n";
        echo "name :". $result['name'] . "\n";
        echo "description :". $result['description'] . "\n";
        echo "platSign :". $result['platSign'] . "\n";

        $decryptStr = public_key_decrypt($result['platSign'], $platPublicKey);
        echo "decryptStr :". $decryptStr . "\n";
    }
    else {
        echo $httpCode;
    }

    function pivate_key_encrypt($data, $pivate_key)
    {
        $pivate_key = '-----BEGIN PRIVATE KEY-----'."\n".$pivate_key."\n".'-----END PRIVATE KEY-----';
        $pi_key = openssl_pkey_get_private($pivate_key);
        $crypto = '';
        foreach (str_split($data, 117) as $chunk) {
            openssl_private_encrypt($chunk, $encryptData, $pi_key);
            $crypto .= $encryptData;
        }

        return base64_encode($crypto);
    }

    function public_key_decrypt($data, $public_key)
    {
        $public_key = '-----BEGIN PUBLIC KEY-----'."\n".$public_key."\n".'-----END PUBLIC KEY-----';
        $data = base64_decode($data);
        $pu_key =  openssl_pkey_get_public($public_key);
        $crypto = '';
        foreach (str_split($data, 128) as $chunk) {
            openssl_public_decrypt($chunk, $decryptData, $pu_key);
            $crypto .= $decryptData;
        }

        return $crypto;
    }

2.Request address

POST https://tl-openapi.toppay.asia/gateway/cash

Note: Do not fill in Chinese in all the parameters! ! !

3.Request param

Param Type Required Remark Example
merchantCode string Y merchant ID,Get it in Merchant Platform-Personal Center-Personal Information S820211021094748000001
orderType string(10) Y order type 0-baht transaction
method string(10) Y payment method disbursement is passed by default
orderNum string Y merchant order number 10000001
money string Y payment amount 150.12(supports two decimal places)
feeType String Y fee type 0:deducted from the payment amount,1:extra handling fee
bankCode string Y bank number 014(REFER TO APPENDIX II BANKCODE SECTION)
number string Y customer bank card number 12312431241
name String Y customer name Jack
mobile string N customer phone 1234567890
email string N customer mail [email protected]
notifyUrl string Y callback address https://123123.com
dateTime string Y timestamp format:yyyyMMddHHmmss 20200101235959
description string Y return by request parameter pai
sign string Y sign Yg+ePvTFhiRrARcZKBcRG0l89rqisPIuZQStYqBIwSMPaqvqbc3dFevgS9jt

4.Request example

{
  "merchantCode": "S820211021094748000001",
  "orderType": "0",
  "method": "Disbursement",
  "orderNum": "186888188666",
  "money": "50000",
  "feeType": "1",
  "bankCode": "014",
  "number": "2021071209403321313122",
  "name": "test cash name",
  "mobile": "082122965511",
  "email": "[email protected]",
  "notifyUrl": "your notify url",
  "dateTime": "2021-07-12 09:41:00",
  "description": "test cash",
  "sign": "Yg+ePvTFhiRrARcZKBcRG0l89rqisPIuZQStYqBIwSMPaqwH77qRXI1J+jElOBpa"
}

5.Response param

Param Type Required Remark Example
platRespCode String Y code FAIL:fail\SUCCESS:success
platRespMessage String Y message successful request
platOrderNum String Y platform order number PI1453242857400963072
orderNum String Y merchant order number 23645782
status int Y order status 0-pending
1-processing
2-successful payment
4-payment failed
5-bank payment
statusMsg String Y order status information Apply
money string Y payment amount 150000
fee String Y fee amount 12.25
feeType String Y fee type 0:order deduction,1:extra handling fee
bankCode String N bank number 014(Refer to appendix ii bankcode section)
number String Y customer bank card number 12312431241
name String Y customer name Jack
description String Y return by request parameter pay
platSign String Y sign PI1453242857400963072

6.Response example

{
  "platRespCode": "SUCCESS",
  "platRespMessage": "Request success",
  "platOrderNum": "W0620220119174331000001",
  "orderNum": "186888188666",
  "status": 0,
  "statusMsg": "Apply",
  "money": "50000",
  "fee": "7",
  "feeType": "0",
  "bankCode": "014",
  "number": "2021071209403321313122",
  "name": "test cash name",
  "description": "test cash",
  "platSign": "E5uNF7B9NXyhtlRo2I7/KVHN4Sbz0c3VbwCLpH3vjUpv6Cai+bmJA/Q8dVE2RJRe1+dsbzg=="
}

7.Cash api callback notify

When verifying the signature, use the Platform Public Key provided in Merchant Background-Receipt and Payment Configuration-API Configuration to decrypt! ! !

After accepting the asynchronous notification, you need to respond with SUCCESS string, without quotation marks, not in Json format.

Otherwise, TopPay will continue to initiate 5 notifications.

Param Remark Example
platOrderNum platform order number BK_1563278763273
orderNum merchant order number T1231511321515
money amount 100000
feeType fee type 0:deduction in order, 1:deduction out order
fee fee 500
name name Neo
number bank number 45649849659456
bankCode bank code 014 @see BankCode
status order status 0-Todo
1-Doing
2-Success
4-Failed
5-Bank doing
statusMsg order status message Payout Success
description description description
platSign sign ja6R8eukQY9jc8...

8. Cash api callback notify example

{
  "platOrderNum": "W0620220119174331000001",
  "orderNum": "186888188666",
  "money": "50000",
  "fee": "7",
  "feeType": "0",
  "name": "test cash name",
  "number": "2021071209403321313122",
  "bankCode": "014",
  "status": "2",
  "statusMsg": "SUCCESS",
  "description": "test cash",
  "platSign": "LGEpz2LjbZ6Iyvn+zLc/+t26AaH0aEhHVD62lSCdo6XIkAg86AUncCvmym62wVoE3r2+dHnv27qi/01UQDcqFK8DYioRCcydYSjB4QRVezG3fcZlhWrACmWGacnXkE7p5zChL7pK5h0HuBhbo1zKt4FunQR6QMmcBVfv7YfB3W0"

}

9.Thai unicode

The order is paid in Thai Baht. If name and description are in Thai, they need to be converted to Unicode when placing the order

Please pay attention! When signing parameters, please use the original Thai text to participate in the signature, otherwise the signature verification will fail! ! !


import org.apache.commons.lang3.StringUtils;

/**
 * unicode tools
 * 
 */
public class UnicodeUtil {

  public static void main(String[] args) {
    String str = "ข้อความต้นฉบับ";
    System.out.println("raw string:" + str);
    String unicodeStr = toUnicode(str, true);
    System.out.println("converted unicode string:" + unicodeStr);
    String originalStr = toString(unicodeStr);
    System.out.println("convert back to original string:" + originalStr);
  }

  /**
   * converts a string to a unicode encoded string
   *
   * @param originalText original text to be converted
   * @param isSkipAscii  Whether to skip ASCII characters (only visible characters are skipped)
   * @return converted unicode
   */
  public static String toUnicode(String originalText, boolean isSkipAscii) {
    if (StringUtils.isEmpty(originalText)) {
      return originalText;
    }

    final int len = originalText.length();
    final StringBuilder unicode = new StringBuilder(originalText.length() * 6);
    char c;
    for (int i = 0; i < len; i++) {
      c = originalText.charAt(i);
      if (isSkipAscii && isAsciiPrintable(c)) {
        unicode.append(c);
      } else {
        unicode.append(toUnicodeHex(c));
      }
    }
    return unicode.toString();
  }

  /**
   * unicode convert string
   *
   * @param unicode original text to be converted
   * @return converted string
   */
  public static String toString(String unicode) {
    if (StringUtils.isBlank(unicode)) {
      return unicode;
    }

    final int len = unicode.length();
    StringBuilder sb = new StringBuilder(len);
    int i;
    int pos = 0;
    while ((i = StringUtils.indexOfIgnoreCase(unicode, "\\u", pos)) != -1) {
      sb.append(unicode, pos, i);//write the part before the unicode character
      pos = i;
      if (i + 5 < len) {
        char c;
        try {
          c = (char) Integer.parseInt(unicode.substring(i + 2, i + 6), 16);
          sb.append(c);
          pos = i + 6;//skip entire unicode characters
        } catch (NumberFormatException e) {
          //illegal unicode character skip
          sb.append(unicode, pos, i + 2);//Write "\\u"
          pos = i + 2;
        }
      } else {
        //non unicode character end
        break;
      }
    }

    if (pos < len) {
      sb.append(unicode, pos, len);
    }
    return sb.toString();
  }

  /**
   * Whether it is a visible ASCII character, the visible character is between 32~126
   *
   * @param ch character to be checked
   * @return whether it is a visible ascii character
   */
  public static boolean isAsciiPrintable(char ch) {
    return ch >= 32 && ch < 127;
  }

  /**
   * convert char to unicode
   *
   * @param ch char to be converted
   * @return converted unicode
   */
  public static String toUnicodeHex(char ch) {
    String hex = Integer.toHexString(ch);
    if (hex.length() < 4) {
      hex = "0" + hex;
    }
    return "\\u" + hex;
  }

}
<?php 
  function unicode_encode($str) {
      $unicode = '';
      for ($i = 0; $i < mb_strlen($str); $i++) {
          $char = mb_substr($str, $i, 1);
          $unicode .= '\u' . str_pad(dechex(mb_ord($char)), 4, '0', STR_PAD_LEFT);
      }
      return $unicode;
  }
  $str = 'จ้าเหมยแซ่หลี่';
  $unicode = unicode_encode($str);
  echo $unicode;
?>

Ⅵ、Order query

1.Order query


import com.google.gson.JsonObject;
public class OrderQuery {
  // test account
  private static final String MCH_CODE = "S820211021094748000001";  // merchant code
  private static final String PLAT_PUBLIC_KEY = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC2JoMfFqLsSJjAiCahEnlP3aRj8yCT+WHzR+VvPBTw9S1i7iYWb+MY09CG/HYuHF4+IxshXDJygmndxKf/esuwPybS8mAd//yubHpmZsmBqg1FffT8VH1APa6ZRWASUp4U01ZrbCCp35QA8FuWrJGMJxGx4xk7KUtV2yujxC8noQIDAQAB";  // platform public key
  private static final String MCH_PRIVATE_KEY = "MIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBAJU8gKFKD0luIYx7X8+JRdCIE0UDBctS6LjXxWLEv/EO7jDBTid6zYP1KmNgpd2DAWWtBFBSQ+gcNwVZZSBHJiSDqVvvJVs2FEbeBvfdv4X93+IYRAXksBasSW5Tpdshbo82pVL4V7wuKCuFLk9UxBHbpQjWAbfyF66RmwIbZD71AgMBAAECgYBjPe7UU2nDDSfmQg0++CyjNjqKRC5QPfxhH6w1uF1kMueXKJWOj42n2RutJpJmsj31nY8m0u4xpsG4HvCu/GGSFhhKZCHLvzp41oY2ubYj9nuFNU//81LycQjulWo2y0UUBY0k2piEt+SwPaiUNbT6nMxNMjlnjRe2okp/3rw+KQJBANG3YlZWoVbCEqzy64bJJLxiPsCA5ErGB0NzRGitq44xkhqGtR8ZZQyVz40pruNa58d73O2xyJSy5+fmZGn4E+sCQQC2LBnguj0CSCKub0mPDcunTTz9V79VXBBZdlB1/YGmRUx2s4sQrJNZS7rL4EqBQ3maIRnG+s+AXCSTfsYrV6CfAkEAxugnVfpelhoGepEAgNuggyivmgfl/2Gpm/jk5l/qOjib+ZrQiQmeBPzGWX4yiSM8eMDrP2sC8r5pJFMp5DRONwJBAJ4n4XuSFJ9jgwCPy3vvzSv9SYLk6E6yM9uHdUlKgoGYzk6Lh6M9QFuY/J49plFdBDiEnj16yCU3WeXXfTJpzB8CQQDMNMR/rIOTE9xGybS3mlQbt22AUnO6XhupWcckEKW4nPGxATwYBQzCY3i/9FTGN0vA+9ZPC2cwHtNxI2kXf3Vp";  // merchant private key
  private static final String orderQueryUrl = "https://tl-openapi.toppay.asia/gateway/query";

  public static void main(String[] args) throws Exception {
    // pay
    query();
  }
  private static void query() throws Exception {
    Map<String, String> requestParams = new TreeMap<>();
    requestParams.put("merchantCode", MCH_CODE);
    requestParams.put("queryType", "CASH_QUERY"); // payment channel
    requestParams.put("orderNum", "186888188666"); // merchant order number
    requestParams.put("platOrderNum", "PRE186888188666"); // platform order number
    requestParams.put("dateTime", "20220101105500");// timestamp format yyyyMMddHHmmss

    StringBuilder stringBuilder = new StringBuilder();
    for (String key : requestParams.keySet()) {
      stringBuilder.append(requestParams.get(key));  // stitching parameters
    }

    String keyStr = stringBuilder.toString();  // get the string to be encrypted
    System.out.println("keyStr:" + keyStr);
    String signedStr = TopPayRequestUtil.privateEncrypt(keyStr, TopPayRequestUtil.getPrivateKey(MCH_PRIVATE_KEY));  // private key encryption
    requestParams.put("sign", signedStr);

    String postJson = new Gson().toJson(requestParams);
    System.out.println("Post Json Params:" + postJson);

    String responseJson = TopPayRequestUtil.doPost(orderQueryUrl, postJson);  // send post json request
    System.out.println("Response Msg:" + responseJson);
  }
}

Request address

POST https://tl-openapi.toppay.asia/gateway/query

Note: Both the merchant order number and the platform order number must be passed one of them, or they can be passed at the same time

Request param

param required description example
merchantCode Y merchant code S820190712000002
queryType Y query type pay:ORDER_QUERY.cash:CASH_QUERY
orderNum Y merchant order number T1231511321515
platOrderNum Y platform order number PRE1234567890
dateTime Y timestamp 20191018105510 yyyy-MM-dd HH:mm:ss
sign Y RSA sign ja6R8eukQ...

merchantCode(format reference-sample pay order query response message)

Param Type Required description Example
success BOOLEAN Y response status true/false
code int Y response code 1000 means success, others are failure
message String Y response message return specific response information
data Json Y response parameters The following parameters are all returned in data, or null if failed
msg String Y order status details Request Transaction Success
platOrderNum String Y platform order number PI1453242857400963072
amount String Y payment amount 1500
fee string Y fee amount 5
orderNum String Y merchant order number 23645782
inAddress string N Account address TLRx8JXsDidC7PYVLmeD6Bhk5k5CUjnPV3
sendAddress String N Billing address TLRx8JcxDidC7PYVLmeD6Bhk5k5CUjnPV3
platRespCode String Y request business status FAIL:fail\SUCCESS:succeed
platRespMessage String Y respond to information prompts Request Transaction Success
status int/String Y order status cash status returns string type, payment status returns int type

2.Request example

{
  "dateTime": "20220101105500",
  "merchantCode": "S820211021094748000001",
  "orderNum": "T1642593166888",
  "platOrderNum": "PRE1642593166888",
  "queryType": "ORDER_QUERY",
  "sign": "lGw1OJcuUL0MGaIq44U2u2bFM5dalJJuT/G6mQWbIBT9dmVAJaLwR125emPDXYYSdnOtNxja86A2VJJLf40BCg2HevHolebvt2ay3ukCQaUhwNkIGz4KF0Ud+XMUA36LoFTWZbDYv9y8vgCnWxwZFKj7ePrfLxc+TA7jpqv65lQ\u003d"
}

3.Order query example for pay api

{
  "success": true,
  "code": 1000,
  "message": "Success",
  "data": {
    "msg": "Payment Success",
    "platOrderNum": "PRE1483771634191044608",
    "amount": "150",
    "fee": "16",
    "orderNum": "T1642593166888",
    "platRespCode": "SUCCESS",
    "platRespMessage": "success",
    "status": "SUCCESS"
  }
}

4.Order query example for cash api

{
  "success": true,
  "code": 1000,
  "message": "Success",
  "data": {
    "msg": "test cash",
    "platOrderNum": "W0620220119174331000001",
    "amount": "125",
    "fee": "7",
    "orderNum": "186888188666",
    "platRespCode": "SUCCESS",
    "platRespMessage": "success",
    "status": 2
  }
}

Ⅶ、Bank account query

1. Bank account query


import com.google.gson.JsonObject;
public class OrderQuery {
  // test account
  private static final String MCH_CODE = "S820211021094748000001";  // merchant code
  private static final String PLAT_PUBLIC_KEY = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC2JoMfFqLsSJjAiCahEnlP3aRj8yCT+WHzR+VvPBTw9S1i7iYWb+MY09CG/HYuHF4+IxshXDJygmndxKf/esuwPybS8mAd//yubHpmZsmBqg1FffT8VH1APa6ZRWASUp4U01ZrbCCp35QA8FuWrJGMJxGx4xk7KUtV2yujxC8noQIDAQAB";  // platform public key
  private static final String MCH_PRIVATE_KEY = "MIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBAJU8gKFKD0luIYx7X8+JRdCIE0UDBctS6LjXxWLEv/EO7jDBTid6zYP1KmNgpd2DAWWtBFBSQ+gcNwVZZSBHJiSDqVvvJVs2FEbeBvfdv4X93+IYRAXksBasSW5Tpdshbo82pVL4V7wuKCuFLk9UxBHbpQjWAbfyF66RmwIbZD71AgMBAAECgYBjPe7UU2nDDSfmQg0++CyjNjqKRC5QPfxhH6w1uF1kMueXKJWOj42n2RutJpJmsj31nY8m0u4xpsG4HvCu/GGSFhhKZCHLvzp41oY2ubYj9nuFNU//81LycQjulWo2y0UUBY0k2piEt+SwPaiUNbT6nMxNMjlnjRe2okp/3rw+KQJBANG3YlZWoVbCEqzy64bJJLxiPsCA5ErGB0NzRGitq44xkhqGtR8ZZQyVz40pruNa58d73O2xyJSy5+fmZGn4E+sCQQC2LBnguj0CSCKub0mPDcunTTz9V79VXBBZdlB1/YGmRUx2s4sQrJNZS7rL4EqBQ3maIRnG+s+AXCSTfsYrV6CfAkEAxugnVfpelhoGepEAgNuggyivmgfl/2Gpm/jk5l/qOjib+ZrQiQmeBPzGWX4yiSM8eMDrP2sC8r5pJFMp5DRONwJBAJ4n4XuSFJ9jgwCPy3vvzSv9SYLk6E6yM9uHdUlKgoGYzk6Lh6M9QFuY/J49plFdBDiEnj16yCU3WeXXfTJpzB8CQQDMNMR/rIOTE9xGybS3mlQbt22AUnO6XhupWcckEKW4nPGxATwYBQzCY3i/9FTGN0vA+9ZPC2cwHtNxI2kXf3Vp";  // merchant private key
  private static final String orderQueryUrl = "https://tl-openapi.toppay.asia/gateway/query";

  public static void main(String[] args) throws Exception {
    query();
  }
  private static void query() throws Exception {
    Map<String, String> requestParams = new TreeMap<>();
    requestParams.put("merchantCode", MCH_CODE);
    requestParams.put("currency", "THB"); // currency(THB)

    StringBuilder stringBuilder = new StringBuilder();
    for (String key : requestParams.keySet()) {
      stringBuilder.append(requestParams.get(key));  // stitching parameters
    }

    String keyStr = stringBuilder.toString();  // get the string to be encrypted
    System.out.println("keyStr:" + keyStr);
    String signedStr = TopPayRequestUtil.privateEncrypt(keyStr, TopPayRequestUtil.getPrivateKey(MCH_PRIVATE_KEY));  // private key encryption
    requestParams.put("sign", signedStr);

    String postJson = new Gson().toJson(requestParams);
    System.out.println("Post Json Params:" + postJson);

    String responseJson = TopPayRequestUtil.doPost(orderQueryUrl, postJson);  // send post json request
    System.out.println("Response Msg:" + responseJson);
  }
}

Request address

POST https://tl-openapi.toppay.asia/gateway/interface/getBalance

Request param

param required description example
merchantCode Y merchant code S820211021094748000001
currency N currency THB(If no currency is passed, the balance of all currency units will be displayed)
sign Y RSA sign ja6R8eukQ...

Request param

param type required description example
success BOOLEAN Y response status true/false
code int Y response code 1000 means success, others are failure
message String Y response message return specific response information
data Json Y data The following parameters are all returned in data, or null if failed
mchId String Y merchant code S8202110212321300001
mchName String Y merchant name test
mchNo String Y merchant number TP123
currency string Y currency IDR
balance String Y balance 1000.00
freeze String Y freeze 10.00
waitingSettleAmount String Y waiting settle amount 200.00
freezeWaitingSettleAmount String Y freeze waiting settle amount 100.00
totalAmount String Y total amount(balance+freeze+waiting settle amount +freeze waiting settle amount) 20000.00

2.Request example

{
  "merchantCode": "S8202110212321300001",
  "currency": "THB",
  "sign": "X/o+IQUzLJqYe9Feid9Uww72mJGOvhJSJEIfo1EUChrZyVZnzGHtd61QhOqRmXCtAwk7V7k="
}

3.Response example

{
  "success": true,
  "code": 1000,
  "message": "SUCCESS",
  "data": [
    {
      "mchId": "S82022091232130000001",
      "mchName": "test",
      "mchNo": "test",
      "country": "THAILAND",
      "currency": "THB",
      "balance": "1000000.01",
      "freeze": "10.00",
      "waitingSettleAmount": "10.00",
      "freezeWaitingSettleAmount": "20.00",
      "totalAmount": "1000040.01"
    }
  ]
}

Ⅷ、Append

1. Pay business

a. Status param

Field Remark
INIT_ORDER The order has just been initialized
NO_PAY The order has not been paid
SUCCESS The order has been paid successfully
PAY_CANCEL The order has been canceled
PAY_ERROR The order has failed to be paid

2. Cash business

a. Status param

Field Remark
0 Todo
1 Accepted
2 Success
4 Failed
5 Bank doing

b. BankCode param

Bank Abbreviation Bank Name Bank Code
KBANK Kasikorn Bank Plc. 001
BBL Bangkok Bank Plc. 003
KTB Krung Thai Bank 004
ABN ABN Amro Bank N.V. 005
TTB TMBThanachart 007
SCB Siam Commercial Bank 010
UOB UOB Bank Plc. 016
BAY Bank of Ayudhya / Krungsri 017
CIMB CIMB Thai Bank Public Company Limited 018
LHBANK Land and Houses Bank Public Company Limited 020
GSB Government Savings Bank 022
KKP Kiatnakin Phatra Bank Public Company Limited 023
CITI Citibank N.A. 024
GHB Government Housing Bank 025
BAAC Bank for Agriculture and Agricultural Cooperatives 026
MHCB Mizuho Corporate Bank Limited 027
IBANK Islamic Bank of Thailand 028
TISCO TISCO Bank Plc. 029