NAV
java php

一、TopPay API Reference

本文档面向具有开发能力的技术人员 Java语言可以直接参考右侧的Java代码示例 欢迎您联系我们,请在Telegram Messenger 👨‍💻 Cindy 欢迎咨询.

二、说明

统一请求方式

HTTP POST

ContentType

application/json

签名sign

右侧阴暗区域为签名工具类

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签名工具类
 * </p>
 *
 * @author TopPay
 */
public class TopPayRequestUtil {

  /**
   * 验证签名
   * @param params
   * @return
   */
  public static boolean verifySign(JsonObject params, String publickey) throws InvalidKeySpecException, NoSuchAlgorithmException {
    String platSign = params.remove("platSign").getAsString(); // 签名
    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);
  }

  /**
   * 私钥加密
   * @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("加密字符串[" + data + "]时遇到异常", e);
    }
  }

  /**
   * 公钥解密
   * @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("解密字符串[" + data + "]时遇到异常", e);
    }
  }

  /**
   * 得到私钥
   * @param privateKey 密钥字符串(经过base64编码)
   */
  public static RSAPrivateKey getPrivateKey(String privateKey) throws NoSuchAlgorithmException, InvalidKeySpecException {
    //通过PKCS#8编码的Key指令获得私钥对象
    KeyFactory keyFactory = KeyFactory.getInstance("RSA");
    PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(Base64.decodeBase64(privateKey));
    RSAPrivateKey key = (RSAPrivateKey) keyFactory.generatePrivate(pkcs8KeySpec);
    return key;
  }

  /**
   * 得到公钥
   * @param publicKey 密钥字符串(经过base64编码)
   */
  public static RSAPublicKey getPublicKey(String publicKey) throws NoSuchAlgorithmException, InvalidKeySpecException {
    //通过X509编码的Key指令获得公钥对象
    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("加解密阀值为["+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");//发送json数据需要设置contentType
    post.setEntity(s);
    HttpResponse res = client.execute(post);
    if(res.getStatusLine().getStatusCode() == HttpStatus.SC_OK){
      return EntityUtils.toString(res.getEntity());// 返回json格式:

    }
    return null;
  }
}

签名统一生成规则:

基于RSA的签名验证方式。
将所有非空参数的key按照ASCII排序后,取参数值(不包含Key)进行拼接后
采用RAS算法对字符串计算,算出签名字符串.

参数示例值

参数 类型
merchantCode S820211021094748000001
orderNum T1642592278863
payMoney 150.60
notifyUrl your notify ur
dateTime 2022-01-01 10:55:00
expiryPeriod 1440

拼接字符串

示例
首先根据参数Key按照ASCII排序,排序后加密字符串.
StrA = 2022-01-01 10:55:[email protected] notify
urlT1642593166888150.60082122965511Test Pay

计算签名

使用您在TopPay商户后台配置的密钥对,用您的私钥进行加密计算RSA(StrA)获取到最终的签名字符串
sign = IMLn23c4orM+7pZhHoRmbjrol4X33jeAqFxbZuQ+pnznBIGhb6Ail3qQPmKwcuhNCt536nmldpbWI72
k1lDxd0zZ95ZHElcNzwTFHFKtd8063uy6rFaxaW6DQ47t4U/95dpGfHAZe0GiIFAQ6xQquaoLINyQa4QqL+cpB
JFEg1dyW6GYLFSdJnx7ycQvFYllmOpGZmdPLny62GvrCWvkiIARUsmc9fpkpTx5UQEDTgmhwdCKBkhHVsx2AiQ
bYDxZ5WBuU1GZeiJjPuzSxvzWP6VoQBsfpwTI5kdJs6aQCekGO2/YScD+tGgrm2J89Pc/axPcb1xZzsi5SxpWh
feabQ\u003d\u003d

三、配置商户公钥信息

1.绑定谷歌验证码

登录商户后台->个人中心->安全信息,使用谷歌验证器扫描页面二维码绑定您的账号

2.RSA密钥对生成地址

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

3.配置公钥

点击收付款配置->API配置,填入您的公钥信息并保存.配置完成

4.商户后台地址

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

四、法币(泰铢)代收下单

1.代码示例

代码示例仅供参考,具体参数说明请参考请求参数说明


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 {
  // 测试账号
  private static final String MCH_CODE = "S820211021094748000001";  // 此乃测试商户号,请使用自己申请的真实商户号和对应的密钥
  private static final String PLAT_PUBLIC_KEY = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC2JoMfFqLsSJjAiCahEnlP3aRj8yCT+WHzR+VvPBTw9S1i7iYWb+MY09CG/HYuHF4+IxshXDJygmndxKf/esuwPybS8mAd//yubHpmZsmBqg1FffT8VH1APa6ZRWASUp4U01ZrbCCp35QA8FuWrJGMJxGx4xk7KUtV2yujxC8noQIDAQAB";  // 平台公钥
  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";  // 商户私钥
  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"); // 订单类型(0-法币(泰铢)交易)
    requestParams.put("method", "BankTransfer"); //  当使用网银时传入对应的银行简称,使用二维码时传qrPay,也可不传
    requestParams.put("transAccNo", "1234567890"); // 使用网银时必传用户付款的卡号,一定要真实卡号,否则交易会失败
    requestParams.put("orderNum", "T1642592278863"); // 商户订单号
    requestParams.put("payMoney", "150.12");  // 订单金额
    requestParams.put("notifyUrl", payNotify);// 回调地址
    requestParams.put("dateTime", "20220101235959");// 时间戳 格式 yyyyMMddHHmmss

    StringBuilder stringBuilder = new StringBuilder();
    for (String key : requestParams.keySet()) {
      stringBuilder.append(requestParams.get(key));  // 拼接参数
    }

    String keyStr = stringBuilder.toString();  // 得到待加密的字符串
    System.out.println("keyStr:" + keyStr);
    String signedStr = TopPayRequestUtil.privateEncrypt(keyStr, TopPayRequestUtil.getPrivateKey(MCH_PRIVATE_KEY));  // 私钥加密
    requestParams.put("sign", signedStr);

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

    String responseJson = TopPayRequestUtil.doPost(payUrl, postJson);  // 发送 post json请求
    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=';
    // 商户ID,从商户信息中获取
    // merchent ID from idntask, from User info
    $merchantCode = 'YOUR_MERCHANT_CODE_HERE';
     //订单类型(0-法币(泰铢)交易)
    $orderType = '0';
     // 商户订单号
    // Merchant system unique order number
    $orderNum = 'TEST1231231231';
    // 支付金额 pay money
    $payMoney = '15.12';
    // 回调地址
    // url for callback
    $notifyUrl = 'http://example.com/callback';
    // 订单时间
    $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.请求地址

我们提供了两种代收下单模式,一种是通过我们的收银台进行获取支付信息,一种是直接请求API获取返回信息,您可以根据自身需求,自行选择。

收银台(模式1): POST https://tl-openapi.toppay.asia/gateway/prepaidOrder

直连模式(模式2): POST https://tl-openapi.toppay.asia/gateway/payment

注:所有的参数中,不要填写中文!!!

3.请求参数

收银台(模式1):

参数 类型 必填 描述 示例
merchantCode string(32) Y 商户ID,在商户平台获取 S820211021094748000001
orderType string(10) Y 订单类型 0-法币(泰铢)交易
orderNum string(32) Y 商户订单号 10000001
transAccNo string(16) N 用户付款卡号(真实)使用网银转账时必传 1234567890
payMoney string(10) Y 付款金额(只允许两位小数位) 20.54
notifyUrl string(100) Y 订单支付成功异步通知地址(用来接收订单交易成功后的通知) https://host:port/notifyUrl
dateTime string(32) Y 时间戳格式:yyyyMMddHHmmss 20190101235959
method string(32) N 支付方式
1.如果需要指定支付方式,可以在右侧的示例支付方式列表中选择其一;
2.如果不指定支付方式,则可不传该参数(仅限收银台模式),默认显示所有支持的支付方式。
qrPay(二维码扫码)
BankTransfer(网银转账)
sign string(255) Y 签名 fnbSOvY83pr8hXg+FdNNYi2ubQUGNv/qGYc4TjRl+XxO2jo92dyjKHFU9/4hNECilMooOcH

直连模式(模式2):

参数 类型 必填 描述 示例
merchantCode string(32) Y 商户ID,在商户平台获取 S820211021094748000001
orderType string(10) Y 订单类型 0-法币(泰铢)交易
orderNum string(32) Y 商户订单号 10000001
payMoney string(10) Y 付款金额(只允许两位小数位) 20.54
notifyUrl string(100) Y 订单支付成功异步通知地址(用来接收订单交易成功后的通知) https://host:port/notifyUrl
dateTime string(32) Y 时间戳格式:yyyyMMddHHmmss 20190101235959
method string(32) Y 支付方式 BankTransfer(网银转账)
qrPay(二维码扫码)
transAccNo string(16) N 用户付款卡号(真实)使用网银转账时必传 1234567890
sign string(255) Y 签名 fnbSOvY83pr8hXg+FdNNYi2ubQUGNv/qGYc4TjRl+XxO2jo92dyjKHFU9/4hNECilMooOcH

4.请求报文示例

模式1,(method和transAccNo参数可不传,跳转的页面不一样)


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

模式2(method参数必传,当使用qrPay时可不传transAccNo,使用网银转账时必传transAccNo)

{
    "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.响应参数

参数 类型 必填 描述 示例
platRespCode String Y 请求业务是否成功 FAIL:失败\SUCCESS:成功
platRespMessage String Y 接口响应信息提示 Request Transaction Success
platOrderNum String Y 平台订单号 PI1453242857400963072
payMoney string Y 支付金额 150.32
orderNum String Y 商户订单号 23645782
bankName String N 银行名称 KABNK
url String N 收银台链接 请求收银台下单(模式1),'platRespCode'为SUCCESS时返回
payData String N 响应参数 直联模式(模式2),'platRespCode'为SUCCESS时返回

6.成功响应报文示例

收银台下单(模式1)成功响应报文示例

模式1响应报文示例


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

模式2(使用qrPay时,payData 返回的是二维码序列号,使用网银转账时,返回的是收款卡号)


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

失败响应报文示例

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

7.代收异步通知

进行验签时,要用 商户后台-收付款配置-API配置中提供的平台公钥进行解密!!!

进行验签时,要按照实际回调的参数进行验签,不要使用固定参数

接受异步通知后,需响应 SUCCESS 字符串

否则TopPay将继续发起5次通知。


import com.google.gson.JsonObject;

public class TopPayNotify {
    // 测试账号
    private static final String MCH_CODE = "S820211021094748000001";  // 商户号
    private static final String PLAT_PUBLIC_KEY = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC2JoMfFqLsSJjAiCahEnlP3aRj8yCT+WHzR+VvPBTw9S1i7iYWb+MY09CG/HYuHF4+IxshXDJygmndxKf/esuwPybS8mAd//yubHpmZsmBqg1FffT8VH1APa6ZRWASUp4U01ZrbCCp35QA8FuWrJGMJxGx4xk7KUtV2yujxC8noQIDAQAB";  // 平台公钥
    public static void main(String[] args) throws Exception {
        // 代收
        JsonObject notifyBody = new jsonObject();
        boolean verifyResult = TopPayRequestUtil.verifySign(notifyBody,PLAT_PUBLIC_KEY);
        if (verifyResult) {
            // ... 签名验证通过,处理正常的业务逻辑
        } else {
            // ... 签名验证错误
        }
    }
}

<?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;
}
参数 描述 示例
code 响应状态 00
msg 响应信息 SUCCESS
method 支付方式 网银转账:下单时的银行简称
二维码扫码:qrPay
status 支付结果 INIT_ORDER:订单初始化
NO_PAY:未支付
SUCCESS:支付成功
PAY_CANCEL:撤销
PAY_ERROR:支付失败
platOrderNum 平台订单号 BK_1563278763273
orderNum 商户订单号 T1231511321515
payMoney 代收金额 100000
payFee 手续费 500
transAccNo 用户付款卡号 123456
如果method是网银转账才会返回
platSign 平台签名 ja6R8eukQY9jc8zrhtf34654ungj7u8sdgdfjfs

8.异步通知报文示例

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

五、数字代收下单

代收下单支持法币(泰铢)与数字货币(USDT/BTC/ETH/TRX)交易 如果您想使用数字货币交易,请设置orderType=1;

通过商户用户ID来区分不同用户的交易

我们的数字代收订单分两个模式:有单模式和无单模式

Ex: 收银台版本(v1.0和v3.0属于有单模式版本;v2.0和v4.0属于无单模式)

Ex: v1.0、v2.0-只展示支付地址

Ex: v3.0、v4.0-展示二维码和支付地址两种方式

使用数字货币进行交易时,币种和链网络是必传项,您需要告诉我们您想使用何种数字货币和链网络(TRC20/BEP20/OMNI/ERC20/TRX)进行交易 我们后续会推出其他币种和网络的交易,敬请期待

1.代码示例

代码示例仅供参考,具体参数说明请参考请求参数说明


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 {
  // 测试账号
  private static final String MCH_CODE = "S820211021094748000001";  // 商户号
  private static final String PLAT_PUBLIC_KEY = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC2JoMfFqLsSJjAiCahEnlP3aRj8yCT+WHzR+VvPBTw9S1i7iYWb+MY09CG/HYuHF4+IxshXDJygmndxKf/esuwPybS8mAd//yubHpmZsmBqg1FffT8VH1APa6ZRWASUp4U01ZrbCCp35QA8FuWrJGMJxGx4xk7KUtV2yujxC8noQIDAQAB";  // 平台公钥
  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";  // 商户私钥
  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", "1"); // 订单类型(1-数字货币交易)
    requestParams.put("mchUserId", "100001"); // 商户用户ID
    requestParams.put("method", "USDT"); // 数字货币类型USDT/BTC/ETH/TRX(可不传)
    requestParams.put("orderNum", "T1642592278863"); // 商户订单号(有单模式必传,无单模式不传)
    requestParams.put("payMoney", "1.000001");  // 订单金额(最大支持6位小数)
    requestParams.put("name", "JackMa");// 客户名称
    requestParams.put("phone", "082122965511"); // 手机号
    requestParams.put("email", "[email protected]");// 客户邮箱
    requestParams.put("notifyUrl", payNotify);// 回调地址
    requestParams.put("dateTime", "20220101235959");// 时间戳 格式 yyyyMMddHHmmss
    requestParams.put("currency", "USDT"); // 数字货币币种(如果指定了method,则必传)
    requestParams.put("netWork", "TRC20"); // 链网络(如果指定了method,则必传)
    requestParams.put("orderVersion", "v1.0"); // 收银台版本(v1.0和v3.0属于有单模式版本;v2.0和v4.0属于无单模式)

    StringBuilder stringBuilder = new StringBuilder();
    for (String key : requestParams.keySet()) {
      stringBuilder.append(requestParams.get(key));  // 拼接参数
    }

    String keyStr = stringBuilder.toString();  // 得到待加密的字符串
    System.out.println("keyStr:" + keyStr);
    String signedStr = TopPayRequestUtil.privateEncrypt(keyStr, TopPayRequestUtil.getPrivateKey(MCH_PRIVATE_KEY));  // 私钥加密
    requestParams.put("sign", signedStr);

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

    String responseJson = TopPayRequestUtil.doPost(payUrl, postJson);  // 发送 post json请求
    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=';
    // 商户ID,从商户信息中获取
    // merchent ID from idntask, from User info
    $merchantCode = 'YOUR_MERCHANT_CODE_HERE';
    // 商户用户ID 
    $mchUserId = 'YOUR_MERCHANT_USDR_ID';
    // 支付金额 pay money(最大支持6位小数)
    $payMoney = '1.000001';
    // 支付方式 参考: (USDT/BTC/ETH/TRX)
    $method = 'USDT';
    //订单类型(1-数字货币交易)
    $orderType = '1';
    // 商户订单号
    // Merchant system unique order number
    $orderNum = 'T'.date("YmdHis",time());
    //时间戳 格式 yyyyMMddHHmmss
    $dateTime = date("YmdHis",time());
    // 邮箱
    // Customer's email address
    $email = '[email protected]';
    // 手机号码
    // Customer's mobile number
    $phone = '082112345678';
    // 在付款确认页面显示的转账对象
    // Display name on bank confirmation display
    $name = 'Neo';
    // 回调地址
    // url for callback
    $notifyUrl = 'http://example.com/callback';
    // 订单过期时间 Order expiration time
    // 数字货币币种(如果指定了method,则必传)
    $currency = 'USDT';
    // 链网络(如果指定了method,则必传)
    $netWork = 'TRC20';
    // 收银台版本(v1.0和v3.0属于有单模式版本;v2.0和v4.0属于无单模式)
    $orderVersion = 'v1.0';
    $params = array(
        'merchantCode' => $merchantCode,
        'orderType' => $orderType,
        'mchUserId' => $mchUserId,
        'method' => $method,
        'orderNum' => $orderNum,
        'payMoney' => $payMoney,
        'name' => $name,
        'email' => $email,
        'phone' => $phone,
        'notifyUrl' => $notifyUrl,
        'dateTime' => $dateTime,
        'currency' => $currency,
        'netWork' => $netWork,
        'orderVersion' => $orderVersion
    );

    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 "mchUserId :". $result['mchUserId'] . "\n";
        echo "platOrderNum :". $result['platOrderNum'] . "\n";
        echo "orderNum :". $result['orderNum'] . "\n";
        echo "method :". $result['method'] . "\n";
        echo "name :". $result['name'] . "\n";
        echo "email :". $result['email'] . "\n";
        echo "vaNumber :". $result['vaNumber'] . "\n";
        echo "payMoney :". $result['payMoney'] . "\n";
        echo "payFee :". $result['payFee'] . "\n";
        echo "currency :". $result['currency'] . "\n";
        echo "netWork :". $result['netWork'] . "\n";
        echo "orderVersion :". $result['orderVersion'] . "\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.请求地址

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

注:所有的参数中,不要填写中文!!!

3.数字代收请求参数

参数 类型 必填 描述 示例
merchantCode string(32) Y 商户ID,在商户平台获取 S820211021094748000001
orderType string(10) Y 订单类型 1-数字货币交易
mchUserId string(32) Y 商户用户ID(您的用户唯一标识,请勿传特殊字符、空格等) 100001
method string(10) N 支付方式(如果需要指定支付方式,可以在右侧的示例支付方式列表中选择其一;如果不指定支付方式,则可不传该参数,可以在我们的收银台页面中选择某个支付方式。) USDT
BTC
ETH
TRX
(备注:数字货币对应的支付方式)
currency string(14) N 数字货币币种(如果指定支付方式,则必传) USDT
netWork string(30) N 链网络(如果指定支付方式,则必传) TRC20
orderNum string(32) N 商户订单号(有单模式必传,无单模式不传) TEST123456789
payMoney int(10) Y 付款金额(最大允许6位小数) 1.000001
notifyUrl string(100) Y 订单支付成功异步通知地址(用来接收订单交易成功后的通知) https://host:port/notifyUrl
dateTime string(32) Y 时间戳格式:yyyyMMddHHmmss 20190101235959
name string(16) Y 客户名称 Jack
email string(64) Y 用户邮箱 [email protected]
phone string(14) Y 用户手机号码 1234567890
orderVersion string(10) N 收银台模式必传
API模式不传
收银台版本(v1.0和v3.0属于有单模式版本;v2.0和v4.0属于无单模式)
v1.0
sign string(255) Y 签名 fnbSOvY83pr8hXg+FdNNYi2ubQUGNv/qGYc4TjRl+XxO2jo92dyjKHFU9/4hNECilMooOcH

4.请求报文示例

{
    "merchantCode": "S820211021094748000001",
    "mchUserId": "100001",
    "orderType": "1",
    "method": "USDT",
    "currency": "USDT",
    "netWork": "TRC20",
    "orderNum": "T1642593166888",
    "payMoney": "1.000001",
    "notifyUrl": "your notify url",
    "dateTime": "2022-01-01 10:55:00",
    "name": "JackMa",
    "email": "[email protected]",
    "phone": "082122965511",
    "sign": "fnbSOvY83pr8hXg+FdNNYi2ubQUGNv/qGYc4TjRl+Xxd1yc9fpkpTx5UQEDTgmhwdCKBkhHVsx2AiQbYDxZ5WBuU1GZeiJ"
}

5.响应参数

参数 类型 必填 描述 示例
platRespCode String Y 请求业务是否成功 FAIL:失败\SUCCESS:成功
platRespMessage String Y 接口响应信息提示 Request Transaction Success
mchUserId String Y 商户用户ID 10001
platOrderNum String Y 平台订单号 PI1453242857400963072
orderNum String Y 商户订单号 23645782
currency String Y 币种 USDT
netWork String Y 链网络 TRC20
payMoney string Y 支付金额 1.000001
url String Y 支付连接 'platRespCode'为'SUCCESS'时返回

6.成功响应报文示例

{
  "platRespCode": "SUCCESS",
  "url": "https://id-openapi.toppay.asia/cashier?orderNum=PRE1626161123977859130123",
  "mchUserId": "10001",
  "platOrderNum": "PRE1626161123977859130",
  "payMoney": "1.000001",
  "currency": "USDT",
  "netWork": "TRC20",
  "platSign": "U79dat+VITTQ8xAI1wsxtFlK2DwcVvZ6ypC+QFIDaEy4oNxZECRy+INAcqIWZHL1m6/pge1SOEbVss8ZZPsZbtRZiefhtH+6qyu99MU+1rGdu+oSXSNhP4+2aDucg/SylS3+TkjKJf+IowTX7d2TJEbDh011JLOc9zglkhqVEc0FVIbBmKInZ/+TaLhDfFt6Sqmf85GCP7V5JwW1arIUwUjlGkCs3TtvHfpDVaMi2fl+cfNGYSrCOZfursVwjiwJmka+44FyaGrrEOE9tKwODiZo/jg9FLZnp2eRZwIIwef8CFg7eqx13uo/y61g0D9pzH17IVcr7Mc8BrweO7X4Pw==",
  "platRespMessage": "Request Transaction Success"
}

失败响应报文示例

{
    "platRespCode": "FAIL",
    "platRespMessage": "the orderNum already exists"
}

7.数字代收异步通知

请注意:当前业务只有在订单支付成功的时候才有回调通知接收到。

数字货币有两种特殊情况:无单模式以及支付金额与下单金额不符,为此我们将异步通知进行了调整,如下:

1.如果是上述特殊情况,我们会生成一笔新的成功订单进行通知,您需要根据通知的信息进行验证,并生成新的订单;

2.根据通知的商户订单号(orderNum)查询是否您的系统存在该订单,建议您在下单成功时同时存储我们的平台订单号(platOrderNum),做双步校验;

3.根据通知的参数specialStatus(0-默认,1-特殊状态)判断,如果为1则判断为上述特殊情况.

TopPay结果异步通知后,需响应 SUCCESS字符串,不包含引号,不是Json格式。

否则TopPay将继续向下游发起5次通知。


import com.google.gson.JsonObject;

public class TopPayNotify {
    // 测试账号
    private static final String MCH_CODE = "S820211021094748000001";  // 商户号
    private static final String PLAT_PUBLIC_KEY = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC2JoMfFqLsSJjAiCahEnlP3aRj8yCT+WHzR+VvPBTw9S1i7iYWb+MY09CG/HYuHF4+IxshXDJygmndxKf/esuwPybS8mAd//yubHpmZsmBqg1FffT8VH1APa6ZRWASUp4U01ZrbCCp35QA8FuWrJGMJxGx4xk7KUtV2yujxC8noQIDAQAB";  // 平台公钥
    public static void main(String[] args) throws Exception {
        // 代收
        JsonObject notifyBody = new jsonObject();
        boolean verifyResult = TopPayRequestUtil.verifySign(notifyBody,PLAT_PUBLIC_KEY);
        if (verifyResult) {
            // ... 签名验证通过,处理正常的业务逻辑
        } else {
            // ... 签名验证错误
        }
    }
}

<?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;
}
参数 描述 示例
code 响应状态 00
msg 响应信息 SUCCESS
mchUserId 商户用户ID 10001
platOrderNum 平台订单号 BK_1563278763273
orderNum 商户订单号 T1231511321515
method 支付方式 USDT
currency 币种 USDT
netWork 链网络 TRC20
status 支付结果 INIT_ORDER: 订单初始化
NO_PAY: 未支付
SUCCESS: 支付成功
PAY_CANCEL: 撤销
PAY_ERROR: 支付失败
payMoney 代收金额 100000
payFee 手续费 500
email 客户邮箱 [email protected]
hashCode 交易哈希 5e5c356af0ewrhgnf3d757h8a6a5506cc66354620
sendAddress 发送地址 TDBbbeAB32WE576DVGE82GEC5BhsZs4
specialStatus 特殊状态(0-默认,1-特殊状态) 0
platSign 平台签名 ja6R8eukQY9jc8z

8.异步通知报文示例

{
  "code": "00",
  "msg": "SUCCESS",
  "mchUserId": "100001",
  "platOrderNum": "UPI1483771634191044608",
  "orderNum": "T1642593166888",
  "method": "USDT",
  "currency": "USDT",
  "netWork": "TRC20",
  "status": "SUCCESS",
  "payMoney": "1.0000001",
  "payFee": "0.000016",
  "email": "[email protected]",
  "phone": "123456789",
  "hashCode": "5e5c356af0ewrhgnf3d757h8a6a5506cc66354620",
  "sendAddress": "TDBbbeAB32WE576DVGE82GEC5BhsZs4",
  "specialStatus": "0",
  "platSign": "ja6R8eukQY9jc8zrhtf34654ungj7u8sdgdfjfs"
}

六、法币(泰铢)代付下单

1.代码示例

代码示例仅供参考,具体参数说明请参考请求参数说明

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";  // 商户号
  private static final String PLAT_PUBLIC_KEY = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC2JoMfFqLsSJjAiCahEnlP3aRj8yCT+WHzR+VvPBTw9S1i7iYWb+MY09CG/HYuHF4+IxshXDJygmndxKf/esuwPybS8mAd//yubHpmZsmBqg1FffT8VH1APa6ZRWASUp4U01ZrbCCp35QA8FuWrJGMJxGx4xk7KUtV2yujxC8noQIDAQAB";  // 平台公钥
  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";  // 商户私钥
  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"); // 商户订单号
    requestParams.put("method", "Disbursement"); // 收款方式(默认传Disbursement)
    requestParams.put("orderType", "0"); // 订单类型(0-法币(泰铢)交易)
    requestParams.put("money", "125.12"); // 订单金额,支持两位小数位
    requestParams.put("feeType", "0");  //  手续费类型(0-帐内扣除,1-帐外扣除)
    requestParams.put("dateTime", "20200101235959");// 时间戳 格式 yyyyMMddHHmmss
    requestParams.put("number", "2021071209403321313122");     // 客户银行卡号
    requestParams.put("bankCode", "001");       // 银行编码:参考附录I 代付
    //name原文参与签名,但是在调用API时需要进行Unicode编码
    requestParams.put("name", "จางซาน");  // 客户名称
    requestParams.put("mobile", "082122965511"); // 客户手机号,可不传
    requestParams.put("email", "[email protected]"); // 客户邮箱,可不传
    //description原文参与签名,但是在调用API时需要进行Unicode编码
    requestParams.put("description", "คำอธิบาย");    // 描述
    requestParams.put("notifyUrl", cashNotify);  // 回调地址
    StringBuilder stringBuilder = new StringBuilder();
    for (String key : requestParams.keySet()) {
      stringBuilder.append(requestParams.get(key));  // 拼接参数
    }

    String keyStr = stringBuilder.toString();  // 得到待加密的字符串
    System.out.println("keyStr:" + keyStr);
    String signedStr = TopPayRequestUtil.privateEncrypt(keyStr, TopPayRequestUtil.getPrivateKey(MCH_PRIVATE_KEY));  // 私钥加密
    requestParams.put("sign", signedStr);


    //签名完成后,对name和description进行编码 UnicodeUtil示例代码参考 本节第9项 泰文Unicode
    requestParams.put("name", UnicodeUtil.toUnicode("จางซาน", true));  // 客户名称
    requestParams.put("description", UnicodeUtil.toUnicode("คำอธิบาย", true));    // 描述

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

    String responseJson = TopPayRequestUtil.doPost(cashUrl, postJson);  // 发送 post json请求
    System.out.println("Response Msg:" + responseJson);

    boolean pass = TopPayRequestUtil.verifySign(new Gson().fromJson(responseJson, JsonObject.class), PLAT_PUBLIC_KEY);  // 签名验证
    if (pass) {
      // ... 签名验证通过,执行正常的业务逻辑
    } else {
      // ... 签名验证错误
    }
  }
}


<?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=';
    // 商户ID,从商户信息中获取
    // 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';
    //订单类型(0-法币(泰铢)交易)
    $orderType = '0';
    // 出款金额 withdraw money
    $money = '20000';
    // 手续费类型(0-帐内扣除,1-帐外扣除)
    $feeType = '1';
    // 时间戳 格式 yyyyMMddHHmmss
    $dateTime = date("YmdHis",time());
    // 客户银行卡号
    $number = '123456';
    // 银行编码(详情参考文档底部)
    $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;

    //原文参与签名后 需要使用unicode编码 编码方式参考 本节第9项 泰文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.请求地址

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

注:所有的参数中,不要填写中文!!!

3.请求参数

参数 类型 必填 描述 示例
merchantCode string Y 商户ID,在商户平台获取 S820211021094748000001
orderType string(10) Y 订单类型 0-法币(泰铢)交易
method string(10) Y 收款方式 默认传Disbursement
orderNum string Y 商户订单号 10000001
money string Y 代付金额 150.12(支持两位小数点位)
feeType String Y 手续费类型 0:代付金额内扣除,1:手续费另计
bankCode string Y 银行编号 014(参考附录Ⅱ BankCode小节)
number string Y 客户银行卡号 12312431241
name String Y 客户名称 Jack
mobile string N 用户手机号码 1234567890
email string N 用户邮箱 [email protected]
notifyUrl string Y 回调地址 https://123123.com
dateTime string Y 时间戳格式:yyyyMMddHHmmss 20200101235959
description string Y 按请求参数返回 代付下单
sign string Y 签名 Yg+ePvTFhiRrARcZKBcRG0l89rqisPIuZQStYqBIwSMPaqvqbc3dFevgS9jt

4.请求报文示例

{
  "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.响应参数

参数 类型 必填 描述 示例
platRespCode String Y 请求业务是否成功 FAIL:失败\SUCCESS:成功
platRespMessage String Y 接口响应信息提示 请求成功
platOrderNum String Y 平台订单号 PI1453242857400963072
orderNum String Y 商户订单号 23645782
status int Y 订单状态 0-待处理
1-处理中
2-代付成功
4-代付失败
5-银行代付中
statusMsg String Y 订单状态信息 Apply
money string Y 代付金额 150000
fee String Y 手续费金额 12.25
feeType String Y 手续费类型 0:订单内扣除,1:手续费另计
bankCode String N 银行编号 014(参考附录Ⅱ BankCode小节)
number String Y 客户银行卡号 12312431241
name String Y 客户名称 Jack
description String Y 按请求参数返回 代付下单
platSign String Y 签名 PI1453242857400963072

6.代付响应报文示例

{
  "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.代付异步通知

进行验签时,要用 商户后台-收付款配置-API配置中提供的平台公钥进行解密!!!

TopPay结果异步通知后,需响应 SUCCESS 字符串.

否则TopPay将继续向下游发起5次通知。

参数 描述 示例
platOrderNum 平台订单号 BK_1563278763273
orderNum 商户订单号 T1231511321515
money 代付金额 150.12(支持小数点)
feeType 订单结果状态 手续费类型, 0:订单内扣除,1:手续费另计
fee 手续费 500
name 客户名称 Neo
number 客户银行卡号 45649849659456
bankCode 到账银行 014(参考附录Ⅱ BankCode小节)
status 订单状态 0-待处理
1-处理中
2-代付成功
4-代付失败
5-银行代付中
statusMsg 订单状态描述 Payout Success
description 订单描述 商户上传原样返回
platSign 平台签名 ja6R8eukQY9jc8...

8.异步通知报文示例

{
  "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.泰文Unicode

法币(泰铢)代付下单,namedescription如果使用泰文,则在下单时需要对其进行Unicode编码转换

需要注意!参数签名时,请使用泰文原文参与签名,否则会验签失败!!!


import org.apache.commons.lang3.StringUtils;

/**
 * Unicode工具类
 * 
 */
public class UnicodeUtil {

  public static void main(String[] args) {
    String str = "ข้อความต้นฉบับ";
    System.out.println("原始字符串:" + str);
    String unicodeStr = toUnicode(str, true);
    System.out.println("转换后的Unicode字符串:" + unicodeStr);
    String originalStr = toString(unicodeStr);
    System.out.println("转换回原始字符串:" + originalStr);
  }

  /**
   * 将字符串转换为Unicode编码的字符串
   *
   * @param originalText 待转换的原文
   * @param isSkipAscii  是否跳过ASCII字符(只跳过可见字符)
   * @return 转换后的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 转字符串
   *
   * @param unicode 待转换原文
   * @return 转换后的字符串
   */
  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);//写入Unicode符之前的部分
      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;//跳过整个Unicode符
        } catch (NumberFormatException e) {
          //非法Unicode符,跳过
          sb.append(unicode, pos, i + 2);//写入"\\u"
          pos = i + 2;
        }
      } else {
        //非Unicode符,结束
        break;
      }
    }

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

  /**
   * 是否为可见ASCII字符,可见字符位于32~126之间
   *
   * @param ch 待校验字符
   * @return 是否为可见ASCII字符
   */
  public static boolean isAsciiPrintable(char ch) {
    return ch >= 32 && ch < 127;
  }

  /**
   * 转换char为unicode
   *
   * @param ch 待转换char
   * @return 转换后的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;
?>

七、数字代付下单

代付下单支持法币(泰铢)与数字货币(USDT/BTC/ETH/TRX)交易 如果您想使用数字货币交易,请设置orderType=1,并传入对应的货币币种Currenecy和网络netWork 使用数字货币进行交易时,币种和链网络是必传项 您需要告诉我们您想使用何种数字币和链网络(TRC20/BEP20/OMNI/ERC20/TRX)进行交易 当使用数字货币进行交易时,您需要传入您的inAddress用以收取数字货币 我们后续会推出其他币种和网络的交易,敬请期待

1.代码示例

代码示例仅供参考,具体参数说明请参考请求参数说明

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";  // 商户号
  private static final String PLAT_PUBLIC_KEY = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC2JoMfFqLsSJjAiCahEnlP3aRj8yCT+WHzR+VvPBTw9S1i7iYWb+MY09CG/HYuHF4+IxshXDJygmndxKf/esuwPybS8mAd//yubHpmZsmBqg1FffT8VH1APa6ZRWASUp4U01ZrbCCp35QA8FuWrJGMJxGx4xk7KUtV2yujxC8noQIDAQAB";  // 平台公钥
  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";  // 商户私钥
  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"); // 商户订单号
    requestParams.put("method", "USDT"); // 收款方式(USDT/BTC/ETH/TRX)
    requestParams.put("orderType", "1"); // 订单类型(1-数字货币交易)
    requestParams.put("money", "1.000001"); // 订单金额,最大支持6位小数
    requestParams.put("feeType", "1");  //  手续费类型(0:代付金额内扣除,1:手续费另计)
    requestParams.put("dateTime", "20200101235959");// 时间戳 格式 yyyyMMddHHmmss
    requestParams.put("name", "test cash name");  // 客户名称
    requestParams.put("mobile", "082122965511"); // 客户手机号
    requestParams.put("email", "[email protected]"); // 客户邮箱
    requestParams.put("description", "test cash");    // 描述
    requestParams.put("notifyUrl", cashNotify);  // 回调地址
    requestParams.put("currency", "USDT"); // 数字货币币种(当orderType=1(数字货币交易)时,是必填项,否则会无法完成交易)
    requestParams.put("netWork", "TRC20"); // 链网络(当orderType=1(数字货币交易)时,是必填项,否则无法完成交易)
    requestParams.put("inAddress", "zkif74bhvkf8934rgg6"); // 入账地址(当orderType=1(数字货币交易)时,是必填项,否则无法完成交易)

    StringBuilder stringBuilder = new StringBuilder();
    for (String key : requestParams.keySet()) {
      stringBuilder.append(requestParams.get(key));  // 拼接参数
    }

    String keyStr = stringBuilder.toString();  // 得到待加密的字符串
    System.out.println("keyStr:" + keyStr);
    String signedStr = TopPayRequestUtil.privateEncrypt(keyStr, TopPayRequestUtil.getPrivateKey(MCH_PRIVATE_KEY));  // 私钥加密
    requestParams.put("sign", signedStr);

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

    String responseJson = TopPayRequestUtil.doPost(cashUrl, postJson);  // 发送 post json请求
    System.out.println("Response Msg:" + responseJson);

    boolean pass = TopPayRequestUtil.verifySign(new Gson().fromJson(responseJson, JsonObject.class), PLAT_PUBLIC_KEY);  // 签名验证
    if (pass) {
      // ... 签名验证通过,执行正常的业务逻辑
    } else {
      // ... 签名验证错误
    }
  }
}

2.请求地址

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

注:所有的参数中,不要填写中文!!!

3.请求参数

参数 类型 必填 描述 示例
merchantCode string Y 商户ID,在商户平台获取 S820211021094748000001
orderType string(10) Y 订单类型 1-数字货币交易
method string(10) Y 收款方式 USDT
BTC
ETH
TRX
orderNum string Y 商户订单号 186888188666
money string Y 代付金额 1.000001(最大支持6位小数)如果feeType选择0的话,因为涉及到手续费,所以麻烦您先以3位小数的金额进行代付下单
feeType String Y 手续费类型 0:代付金额内扣除
1:手续费另计
name String Y 客户名称 Jack
mobile string Y 用户手机号码 1234567890
email string Y 用户邮箱 [email protected]
notifyUrl string Y 用户手机号码 1234567890
dateTime string Y 时间戳格式:yyyyMMddHHmmss 20200101235959
currency string(14) Y 数字货币币种 USDT
netWork string(30) Y 链网络 TRC20
inAddress string Y 入账地址 vboj3457vbiae5y35y

4.请求报文示例

{
  "merchantCode": "S820211021094748000001",
  "orderType": "1",
  "method": "USDT",
  "orderNum": "186888188666",
  "money": "1.00000001",
  "feeType": "1",
  "name": "test cash name",
  "mobile": "082122965511",
  "email": "[email protected]",
  "notifyUrl": "your notify url",
  "dateTime": "2021-07-12 09:41:00",
  "currency": "USDT",
  "netWork": "TRC20",
  "inAddress": "vboj3457vbiae5y35y",
  "sign": "Yg+ePvTFhiRrARcZKBcRG0l89rqisPIuZQStYqBIwSMPaqwH77qRXI1J+jElOBpa"
}

5.响应参数

参数 类型 描述 示例
platRespCode String 请求业务是否成功 FAIL:失败\SUCCESS:成功
platRespMessage String 接口响应信息提示 请求成功
platOrderNum String 平台订单号 PI1453242857400963072
status String 订单状态 0
statusMsg String 订单状态信息 Apply
orderNum String 商户订单号 23645782
money string 代付金额 1.00000001
fee String 手续费金额 12.25
feeType String 手续费类型 0:代付金额内扣除
1:手续费另计
name String 客户名称 Jack
currency string 数字货币币种 USDT
netWork string 链网络 TRC20
platSign String 签名 PI1453242857400963072

6.响应报文示例

{
  "platRespCode": "SUCCESS",
  "platRespMessage": "Request success",
  "platOrderNum": "W0620220119174331000001",
  "orderNum": "186888188666",
  "status": "0",
  "statusMsg": "Apply",
  "money": "50000",
  "fee": "7",
  "feeType": "1",
  "currency": "USDT",
  "netWork": "TRC20",
  "platSign": "E5uNF7B9NXyhtlRo2I7/KVHN4Sbz0c3VbwCLpH3vjUpv6Cai+bmJA/Q8dVE2RJRe1+dsbzg=="
}

7.数字代付异步通知

接收到结果异步通知后,需响应 SUCCESS字符串,不包含引号,不是Json格式。

否则TopPay将继续向下游发起5次通知。

参数 描述 示例
platOrderNum 平台订单号 BK_1563278763273
orderNum 商户订单号 T1231511321515
money 代付金额 1.000001(最大支持6位小数)
feeType 订单结果状态 手续费类型, 0:代付金额内扣除,1:手续费另计
fee 手续费 500
name 客户名称 Neo
status 订单状态 0-待处理
1-处理中
2-代付成功
4-代付失败
5-银行代付中
statusMsg 订单状态描述 Payout Success
hashCode 交易哈希 5e5c356af0ewrhgnf3d757h8a6a5506cc66354620
inAddress 接收地址 TDBbbeAB32WE576DVGE82GEC5BhsZs4
sendAddress 发送地址 TDBbbeAB32WE576DVGE82GEC5BhsZs4
platSign 平台签名 ja6R8eukQY9jc8...

8.异步通知报文示例

{
  "platOrderNum": "W0620220119174331000001",
  "orderNum": "186888188666",
  "money": "1.00000001",
  "fee": "0.0001",
  "feeType": "1",
  "currency": "USDT",
  "netWork": "TRC20",
  "name": "test cash name",
  "status": "2",
  "statusMsg": "SUCCESS",
  "hashCode": "5e5c356af0ewrhgnf3d757h8a6a5506cc66354620",
  "inAddress": "Twrgtehsd576gsdre876d2545C5Br23324",
  "sendAddress": "TDBbbeAB32WE576DVGE82GEC5BhsZs4",
  "platSign": "LGEpz2LjbZ6Iyvn+zLc/+t26AaH0aEhHVD62lSCdo6XIkAg86AUncCvmym62wVoE3r2+dHnv27qi/01UQDcqFK8DYioRCcydYSjB4QRVezG3fcZlhWrACmWGacnXkE7p5zChL7pK5h0HuBhbo1zKt4FunQR6QMmcBVfv7YfB3W0"
}

八、订单查询

1.订单查询


import com.google.gson.JsonObject;
public class OrderQuery {
  // 测试账号
  private static final String MCH_CODE = "S820211021094748000001";  // 商户号
  private static final String PLAT_PUBLIC_KEY = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC2JoMfFqLsSJjAiCahEnlP3aRj8yCT+WHzR+VvPBTw9S1i7iYWb+MY09CG/HYuHF4+IxshXDJygmndxKf/esuwPybS8mAd//yubHpmZsmBqg1FffT8VH1APa6ZRWASUp4U01ZrbCCp35QA8FuWrJGMJxGx4xk7KUtV2yujxC8noQIDAQAB";  // 平台公钥
  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";  // 商户私钥
  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("queryType", "CASH_QUERY"); // 支付渠道
    requestParams.put("orderNum", "186888188666"); // 商户订单号
    requestParams.put("platOrderNum", "PRE186888188666"); // 平台订单号
    requestParams.put("dateTime", "20220101105500");// 时间戳 格式 yyyyMMddHHmmss

    StringBuilder stringBuilder = new StringBuilder();
    for (String key : requestParams.keySet()) {
      stringBuilder.append(requestParams.get(key));  // 拼接参数
    }

    String keyStr = stringBuilder.toString();  // 得到待加密的字符串
    System.out.println("keyStr:" + keyStr);
    String signedStr = TopPayRequestUtil.privateEncrypt(keyStr, TopPayRequestUtil.getPrivateKey(MCH_PRIVATE_KEY));  // 私钥加密
    requestParams.put("sign", signedStr);

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

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

请求地址

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

注:商户订单号和平台订单号两者必需传递其中一个,也可以同时传递

请求参数

参数 是否必填(Y-是,N-否) 类型 示例
merchantCode Y 商户ID S820190712000002
queryType Y 查询类型 代收:ORDER_QUERY.代付:CASH_QUERY
orderNum Y 商户订单号 T1231511321515
platOrderNum Y 平台订单号 PRE1234567890
dateTime Y 时间戳 20191018105510 yyyy-MM-dd HH:mm:ss
sign Y RSA签名 ja6R8eukQ...

响应参数说明(格式参考-代收订单查询响应报文示例)

参数 类型 必填 描述 示例
success BOOLEAN Y 接口响应 true/false
code int Y 接口响应码 1000代表成功,其他的都为失败
message String Y 接口响应信息 返回具体响应信息
data Json Y 接口响应参数 以下参数都在data中返回,如失败则为null
msg String Y 订单状态详细信息 Request Transaction Success
platOrderNum String Y 平台订单号 PI1453242857400963072
amount String Y 支付金额 1500
fee string Y 手续费金额 5
orderNum String Y 商户订单号 23645782
inAddress string N 入账地址 TLRx8JXsDidC7PYVLmeD6Bhk5k5CUjnPV3
sendAddress String N 出账地址 TLRx8JcxDidC7PYVLmeD6Bhk5k5CUjnPV3
platRespCode String Y 请求业务是否成功 FAIL:失败\SUCCESS:成功
platRespMessage String Y 接口响应信息提示 Request Transaction Success
status int/String Y 订单状态 代收状态返回string类型,代付状态返回int类型

2.请求报文示例

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

3.代收订单查询响应报文示例

{
  "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.代付订单查询响应报文示例

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

九、账户余额查询

1.账户余额查询


import com.google.gson.JsonObject;
public class OrderQuery {
  // 测试账号
  private static final String MCH_CODE = "S820211021094748000001";  // 商户号
  private static final String PLAT_PUBLIC_KEY = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC2JoMfFqLsSJjAiCahEnlP3aRj8yCT+WHzR+VvPBTw9S1i7iYWb+MY09CG/HYuHF4+IxshXDJygmndxKf/esuwPybS8mAd//yubHpmZsmBqg1FffT8VH1APa6ZRWASUp4U01ZrbCCp35QA8FuWrJGMJxGx4xk7KUtV2yujxC8noQIDAQAB";  // 平台公钥
  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";  // 商户私钥
  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"); // 币种(THB)

    StringBuilder stringBuilder = new StringBuilder();
    for (String key : requestParams.keySet()) {
      stringBuilder.append(requestParams.get(key));  // 拼接参数
    }

    String keyStr = stringBuilder.toString();  // 得到待加密的字符串
    System.out.println("keyStr:" + keyStr);
    String signedStr = TopPayRequestUtil.privateEncrypt(keyStr, TopPayRequestUtil.getPrivateKey(MCH_PRIVATE_KEY));  // 私钥加密
    requestParams.put("sign", signedStr);

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

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

请求地址

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

请求参数

参数 必填 类型 示例
merchantCode Y 商户ID S820211021094748000001
currency N 币种 THB(不传展示所有货币单位的余额)
sign Y RSA签名 ja6R8eukQ...

响应参数

参数 类型 必填 描述 示例
success BOOLEAN Y 接口响应 true/false
code int Y 接口响应码 1000代表成功,其他的都为失败
message String Y 接口响应信息 返回具体响应信息
data Json Y 接口响应参数 以下参数都在data中返回,如失败则为null
mchId String Y 商户ID S8202110212321300001
mchName String Y 商户名称 test
mchNo String Y 商户ID TP123
currency string Y 币种 THB
balance String Y 可用余额 1000.00
freeze String Y 冻结余额 10.00
waitingSettleAmount String Y 待结算金额 200.00
freezeWaitingSettleAmount String Y 冻结待结算金额 100.00
totalAmount String Y 全部金额(可用余额+冻结余额+待结算金额+冻结待结算金额) 20000.00

2.请求报文示例

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

3.响应报文示例

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

十、可选参数附录

Ⅰ 代收业务

1 Status 参数

字段值 说明
INIT_ORDER 订单初始化
NO_PAY 未支付
SUCCESS 支付成功
PAY_CANCEL 撤销
PAY_ERROR 支付失败

Ⅱ 代付业务

1 Status 参数

字段值 说明
0 待处理
1 已受理
2 代付成功
4 代付失败
5 银行代付中

2 BankCode 参数

银行简称 银行名称 银行编码
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