NAV
java php

TopPay API Reference

This document is intended for technical personnel with development capabilities You are welcome to contact us, please use Telegram Messenger 👨‍💻 Cindy Welcome to consult.

Explanation

Request method

HTTP POST

ContentType

application/json

Signature

The dark 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 Utils
 * </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(); 
    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("Exception encountered while encrypting string [" + data + "]", 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("Exception encountered while decrypting string [" + data + "]", e);
    }
  }

  /**
   * Get private key
   * @param privateKey
   */
  public static RSAPrivateKey getPrivateKey(String privateKey) throws NoSuchAlgorithmException, InvalidKeySpecException {
    //Obtain the private key object through the PKCS#8 encoded Key instruction
    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
   */
  public static RSAPublicKey getPublicKey(String publicKey) throws NoSuchAlgorithmException, InvalidKeySpecException {
    //Obtain the public key object through the X509 encoded Key instruction
    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 when encrypting and 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");
    post.setEntity(s);
    HttpResponse res = client.execute(post);
    if(res.getStatusLine().getStatusCode() == HttpStatus.SC_OK){
      return EntityUtils.toString(res.getEntity());
    }
    return null;
  }
}

Signature rules:

RSA-based signature verification method
After sorting the keys of all non-empty parameters according to ASCII, take the parameter values (excluding Key) and splice them.
Use RAS algorithm to calculate the string and calculate the signature string

Params

Param Ex
merchantCode S820211021094748000001
orderNum T1642592278863
payMoney 150.60
notifyUrl your notify ur
expiryPeriod 1440

Concatenate strings

First, sort according to the parameter Key according to ASCII, and then encrypt the string after sorting

StrA = 2022-01-01 10:55:00test1440S820211021094748000001014JackMayour notify urlT1642593166888150.60082122965511Test Pay

Signature encryption

Use the key pair you configured in the TopPay merchant backend and use your private key to encrypt and calculate RSA (StrA) to obtain the final signature string.

String sign = IMLn23c4orM+7pZhHoRmbjrol4X33jeAqFxbZuQ+pnznBIGhb6Ail3qQPmKwcuhNCt536nmldpbWI72 k1lDxd0zZ95ZHElcNzwTFHFKtd8063uy6rFaxaW6DQ47t4U/95dpGfHAZe0GiIFAQ6xQquaoLINyQa4QqL+cpB JFEg1dyW6GYLFSdJnx7ycQvFYllmOpGZmdPLny62GvrCWvkiIARUsmc9fpkpTx5UQEDTgmhwdCKBkhHVsx2AiQ bYDxZ5WBuU1GZeiJjPuzSxvzWP6VoQBsfpwTI5kdJs6aQCekGO2/YScD+tGgrm2J89Pc/axPcb1xZzsi5SxpWh feabQ\u003d\u003d

Configure merchant public key information

1.Merchant backend address

https://br-merchant.toppayment.com

2.Bind Google verification code

Log in to the merchant backend->Personal Center->Security Information, use Google Authenticator to scan the QR code on the page to bind your account

3.RSA key pair generation address

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

https://www.bchrt.com/tools/rsa/

http://www.usey.cn/rsa

4.Configure public key

Log in to the merchant backend -> Collection and payment configuration -> API configuration, fill in your public key information and save. Configuration completed

5.Get the platform public key

Log in to the merchant backend -> Collection and Payment Configuration -> API Configuration, and save the platform public key displayed there for signature verification and decryption.

Fiat currency (BRL) collection and placing orders

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 {

  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://br-openapi.toppay.asia/gateway/prepaidOrder";
  private static final String cashUrl = "https://br-openapi.toppay.asia/gateway/cash";
  private static final String payNotify = "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", "S820211021094748000001");//Merchant ID, obtained from the merchant platform
    requestParams.put("orderType", "0"); // Order type (0:fiat currency (BRL) transaction)
    requestParams.put("orderNum", "T1642592278863"); // Merchant order number
    requestParams.put("notifyUrl", payNotify);// Notify Url
    requestParams.put("description", "PAY"); // description
    requestParams.put("name", "AAA"); // user name 

    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);
    System.out.println("Response Msg:" + responseJson);
  }
}


<?php
    // platform public key, from Secret key config
    $platPublicKey = 'MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiaKBgQCcEUIvQ/5L+SWbHOeR8VFeZvLbUk7V7OeEAQlQwIVLSZMTef3KtsOKKAsUYPf/aAcKRzZZXECODsPQiDPcdZvM/rFkgrFWkR7lPjTj5SiPxGaiK2Z2sne7A8aDF7fV/D7lfmEwNdZ7FWKVEB84/81BHnlGUwb5HpRTISG+boSO6wIDAQAB';
    // mch privateKey
    $mchPrivateKey = 'MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAMigm7rtWnTeNagwFzGTH+Uw1ypbiy7VhIoFJbgSYSSHdCaXWdT/l2+2fQlEYgAETVZ/IXB29MCnrf3O0dwRFXiipIbsm5zyqSLiS6cKXe8zN1/PlQWUbEt5wyWm0GADB/4bV6eu6gA7sGXmjQqrzfKZkcie3aK7+7ry1NFxTI51AgMBAAECgYEAklqXQAVlt1tiSQ7L3J425jp6u6uMHN4lkYmvuleuBbfKQ1yla3wIPLYjAF+iHeEFidOz0Rb19JRdmIkHDkJoJg2W27LvO6RdUwzgRnsuA3OuNz97w08B3aXXbPmB91nTFjKSlUsbh3IQWP71noxW+iKn844EW5hC5Gvn4L3quAECQQDrz1r0VKIbBSBB2aLuz1XyD/TBT2aRhvOKf0XtTRiQhNjtJxoQmvNbbhvUwj8an7HyCuihAbdbrC2ymFFyOSDZAkEA2c4Yudi48C6COrroi1cWgPlEFeGJXP/V1k5loZ1n2vstYAGPhAB4wUnFBLDvMqaBzWJt7MRkiazT8KnBQCDY/QJAMXpNlEyZwt+deBOpO0BnwSWV7mWxmMFfImU4D+WITPbC7aexsWBBxaJh1o93XCe715RwYTAR//stj3akSDoyaQJAa4FKuxC51/Nc3Fg9R+modeiTLqmv/3NXvPvdNjRXesLX1rduex0wfVdII9ShfEKrdxDKaT9W0NyzD+r6NAkCkQJBAMAnTgPYf0f7rh417GdoP7R7Nwi8KBKwPHlmfRukibOQlKt9xjqpsKJwglLn8pcnXbYbswXIdqzuBvIGAe3OWNg=';
    // Merchant ID, obtained from the merchant platform
    $merchantCode = 'S820211021094748000001';
     //Order type (0:fiat currency (BRL) transaction)
    $orderType = '0';
     // Merchant order number
    $orderNum = 'TEST1231231231';
    // User name
    $name = 'AAA';
    // description
    $description = 'PAY;
    // Notify Url
    $notifyUrl = 'http://123/callback';
    $params = array(
        'merchantCode' => $merchantCode,
        'orderType' => $orderType,
        'orderNum' => $orderNum,
        'description' => $description,
        'name' => $name,
        'notifyUrl' => $notifyUrl,
    );

    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://br-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 "description :". $result['description'] . "\n";
        echo "url :". $result['url'] . "\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 collection and ordering modes, one is to obtain payment information through our cashier, and the other is to directly request the API to obtain return information. You can choose according to your own needs.

Cashier : POST https://br-openapi.toppay.asia/gateway/prepaidOrder

3.Request parameters

Cashier :

Param Type Required Description Ex
merchantCode string(32) Y Merchant ID, obtained from the merchant platform S820211021094748000001
orderType string(10) Y order type 0:Fiat Currency (BRL) Transaction
orderNum string(32) Y Merchant order number ASD12312312331
payMoney int(10) Y Pay Money(Maximum 6 decimal places allowed) 1.000001
name string(32) N Customer name customer name
description string(50) N Description description
notifyUrl string(100) Y Notify Url https://host:port/notifyUrl
sign string(255) Y Sign fnbSOvY83pr8hXg+FdNNYi2ubQUGNv/qGYc4TjRl+XxO2jo92dyjKHFU9/4hNECilMooOcH

4.Request parameter example

request parameter example


{
    "merchantCode": "S820211021094748000001",
    "orderType": "0",
    "orderNum": "T1642593166888",
    "notifyUrl": "your notify url",
    "description": "description",
    "sign": "fnbSOvY83pr8hXg+FdNNYi2ubQUGNv/qGYc4TjRl+Xxd1yc9fpkpTx5UQEDTgmhwdCKBkhHVsx2AiQbYDxZ5WBuU1GZeiJ"
}

5.Response

Param Type Required Description Ex
platRespCode String Y code FAIL\SUCCESS
platRespMessage String Y Message Request Transaction Success
platOrderNum String Y Platform order number PI1453242857400963072
orderNum String Y Merchant order number 23645782
name String N Customer name customer name
payMoney string(10) N Pay Money(Only two decimal places allowed) Mode 2,returned when 'platRespCode' is SUCCESS
url String N url Mode 1,returned when 'platRespCode' is SUCCESS
payData String N pay info Mode 2,returned when 'platRespCode' is SUCCESS

6.Success Response

response example


{
    "platRespCode": "SUCCESS",
    "platRespMessage": "Request Transaction Success",
    "platOrderNum": "PRE1483771634191044608",
    "orderNum": "T1642593166888",
    "name": "customer name",
    "description": "description",
    "url": "https://br-openapi.toppay.asia/..."
}

Fail Response

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

7.Pay Notify

When verifying the signature, you must use the Platform Public Key provided in Merchant Backstage - Collection and Payment Configuration-API Configuration for decryption! ! !

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 the SUCCESS string

Otherwise TopPay will continue to initiate 5 notifications.


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);
        System.out.println(verifyResult);
    }
}

<?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 Required Description Ex
code Y code 00
msg Y Message SUCCESS
method Y method PIX
status Y status INIT_ORDER
NO_PAY
SUCCESS
PAY_CANCEL
PAY_ERROR
platOrderNum Y Platform order number BK_1563278763273
orderNum Y Merchant order number T1231511321515
payMoney Y Pay Money 100.12
payFee Y Pay fee 5.32
name N Customer name customer name
description N Description description
platSign Y Platform Sign ja6R8eukQY9jc8zrhtf34654ungj7u8sdgdfjfs

8.Notify Example

{
    "code": "00",
    "msg": "SUCCESS",
    "status": "SUCCESS",
    "method": "PIX",
    "platOrderNum": "PRE1483771634191044608",
    "orderNum": "T1642593166888",
    "payMoney": "150",
    "payFee": "150",
    "name": "customer",
    "description": "description",
    "platSign": "ja6R8eukQY9jc8zrhtf34654ungj7u8sdgdfjfs"
}

Digital currency payment order

Collection orders support fiat currency (BRL) and digital currency (USDT/BTC/ETH/TRX) transactions If you want to use digital currency transactions, please set orderType=1;

Distinguish transactions between different users through merchant user IDs

Our digital collection of orders is divided into two modes: with order mode and without order mode.

Ex: Cashier version (v1.0 and v3.0 belong to the single mode version; v2.0 and v4.0 belong to the single mode version)

Ex: v1.0, v2.0-only display payment address

Ex: v3.0, v4.0-display QR code and payment address in two ways

When using digital currency for transactions, the currency and chain network are required. You need to tell us which digital currency and chain network (TRC20/BEP20/OMNI/ERC20/TRX) you want to use for transactions. We will launch transactions in other currencies and networks in the future, so stay tuned

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 {

  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://br-openapi.toppay.asia/gateway/prepaidOrder";
  private static final String cashUrl = "https://br-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"); // Order Type (1:Digital Currency Transaction)
    requestParams.put("mchUserId", "100001"); // Merchant User ID
    requestParams.put("method", "USDT"); // USDT/BTC/ETH/TRX
    requestParams.put("orderNum", "T1642592278863"); // Merchant order number(If there is a single mode, it must be transmitted; if there is no single mode, it will not be transmitted.)
    requestParams.put("payMoney", "1.000001");  // Order amount (up to 6 decimal places supported)
    requestParams.put("name", "JackMa");// Customer name
    requestParams.put("notifyUrl", payNotify);// Notify Url
    requestParams.put("currency", "USDT"); // Digital currency currency (required if method is specified)
    requestParams.put("netWork", "TRC20"); //Chain network (if method is specified, it must be passed)
    requestParams.put("orderVersion", "v1.0"); // Cashier version (v1.0 and v3.0 belong to the single mode version; v2.0 and v4.0 belong to the single mode version)

    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); 
    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=';
    // Merchant ID, obtained from the merchant platform
    $merchantCode = 'YOUR_MERCHANT_CODE_HERE';
    // Merchant User ID 
    $mchUserId = 'YOUR_MERCHANT_USDR_ID';
    // Pay Money
    $payMoney = '1.000001';
    // (USDT/BTC/ETH/TRX)
    $method = 'USDT';
    //Order Type (1:Digital Currency Transaction)
    $orderType = '1';
    // Merchant order number
    $orderNum = 'T'.date("YmdHis",time());
    // Display name on bank confirmation display
    $name = 'Neo';
    // Notify Url
    // url for callback
    $notifyUrl = 'http://example.com/callback';
    // Order expiration time
    //  Digital currency currency (required if method is specified)
    $currency = 'USDT';
    // Chain network (if method is specified, it must be passed)
    $netWork = 'TRC20';
    // Cashier version (v1.0 and v3.0 belong to the single mode version; v2.0 and v4.0 belong to the single mode version)
    $orderVersion = 'v1.0';
    $params = array(
        'merchantCode' => $merchantCode,
        'orderType' => $orderType,
        'mchUserId' => $mchUserId,
        'method' => $method,
        'orderNum' => $orderNum,
        'payMoney' => $payMoney,
        'name' => $name,
        'notifyUrl' => $notifyUrl,
        '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://br-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 "url :". $result['url'] . "\n";
        echo "payMoney :". $result['payMoney'] . "\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.Request Address

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

3.Request Params

Param Type Required Description Ex
merchantCode string(32) Y Merchant ID, obtained from the merchant platform S820211021094748000001
orderType string(10) Y Order Type 1(Digital Currency Transaction)
mchUserId string(32) Y Merchant User ID(User’s unique identifier, please do not pass special characters, spaces.) 100001
method string(10) N Method USDT
BTC
ETH
TRX
currency string(14) N Digital currency currency (required if payment method is specified) USDT
netWork string(30) N Chain network (required if payment method is specified) TRC20
orderNum string(32) N Merchant order number(If there is a single mode, it must be transmitted, but if there is no single mode, it will not be transmitted) TEST123456789
payMoney int(10) Y Pay Money(Maximum 6 decimal places allowed) 1.000001
notifyUrl string(100) Y Notify Url https://host:port/notifyUrl
name string(16) Y Customer name Jack
orderVersion string(10) N version (v1.0 and v3.0 are versions with single mode; v2.0 and v4.0 are versions without single mode.) v1.0
sign string(255) Y Sign fnbSOvY83pr8hXg+FdNNYi2ubQUGNv/qGYc4TjRl+XxO2jo92dyjKHFU9/4hNECilMooOcH

4.Request parameter example

{
    "merchantCode": "S820211021094748000001",
    "mchUserId": "100001",
    "orderType": "1",
    "method": "USDT",
    "currency": "USDT",
    "netWork": "TRC20",
    "orderNum": "T1642593166888",
    "payMoney": "1.000001",
    "notifyUrl": "your notify url",
    "name": "JackMa",
    "sign": "fnbSOvY83pr8hXg+FdNNYi2ubQUGNv/qGYc4TjRl+Xxd1yc9fpkpTx5UQEDTgmhwdCKBkhHVsx2AiQbYDxZ5WBuU1GZeiJ"
}

5.Rsponse

Param Type Required Description Ex
platRespCode String Y code FAIL\SUCCESS
platRespMessage String Y Message Request Transaction Success
mchUserId String Y Merchant User ID 10001
platOrderNum String Y Platform order number PI1453242857400963072
orderNum String Y Merchant order number 23645782
currency String Y Currency USDT
netWork String Y Net Work TRC20
payMoney string Y Pay Money 1.000001
url String Y url 'platRespCode' is 'SUCCESS' to return

6.Success Rsponse

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

Fail Response

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

7. Digital collection asynchronous notification

Please note: The current business will only receive callback notifications when the order payment is successful.

There are two special situations in digital currency: no order mode and the payment amount does not match the order amount. For this reason, we have adjusted the asynchronous notification as follows:

1. If it is the above special situation, we will generate a new successful order for notification. You need to verify based on the notification information and generate a new order;

2. Check whether the order exists in your system according to the notified Merchant order number (orderNum). It is recommended that you also store our platform order number (platOrderNum) when placing the order successfully and do a two-step verification;

3. Judge according to the parameter specialStatus of the notification (0-default, 1-special status). If it is 1, it is judged to be the above special situation.

After TopPay results are notified asynchronously, you need to respond with the SUCCESS string, which does not contain quotes and is not in Json format.

Otherwise, TopPay will continue to send 5 notifications to the downstream.


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);
        System.out.println(verifyResult);

    }
}

<?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 Description Ex
code code 00
msg Message SUCCESS
mchUserId Merchant User ID 10001
platOrderNum Platform order number BK_1563278763273
orderNum Merchant order number T1231511321515
method Method USDT
currency Currency USDT
netWork Net Work TRC20
status Status INIT_ORDER
NO_PAY
SUCCESS
PAY_CANCEL
PAY_ERROR
payMoney Pay Money 100000
payFee 手续费 500
hashCode Hash Code 5e5c356af0ewrhgnf3d757h8a6a5506cc66354620
sendAddress Send Address TDBbbeAB32WE576DVGE82GEC5BhsZs4
specialStatus Special status (0-default, 1-special status) 0
platSign Plat Sign ja6R8eukQY9jc8z

8.Notify Params

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

Legal currency (BRL) withdrawal order

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.util.Map;
import java.util.TreeMap;
public class TopPayDemo {
  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://br-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", "S820211021094748000001");
    requestParams.put("orderNum", "186888188666"); // Merchant order number
    requestParams.put("method", "DISBURSEMENT"); // Method(DISBURSEMENT)
    requestParams.put("orderType", "0"); // Order type (0:fiat currency (BRL) transaction)
    requestParams.put("money", "125.12"); // Order amount, supports two decimal places
    requestParams.put("feeType", "0");  // Fee Type (0:on account deduction, 1:off account deduction)
    requestParams.put("pixType", "CPF");     // PIX Type
    requestParams.put("pixAccount", "123123123");     // PIX Account
    requestParams.put("taxNumber", "123123123");     // Tax ID number
    requestParams.put("name", "custmener");  // Customer name
    requestParams.put("description", "description");    // description
    requestParams.put("notifyUrl", cashNotify);  // Notify Url
    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); 
    System.out.println("Response Msg:" + responseJson);

    boolean pass = TopPayRequestUtil.verifySign(new Gson().fromJson(responseJson, JsonObject.class), PLAT_PUBLIC_KEY);  
  }
}


<?php
    $platPublicKey = 'MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiaKBgQCcEUIvQ/5L+SWbHOeR8VFeZvLbUk7V7OeEAQlQwIVLSZMTef3KtsOKKAsUYPf/aAcKRzZZXECODsPQiDPcdZvM/rFkgrFWkR7lPjTj5SiPxGaiK2Z2sne7A8aDF7fV/D7lfmEwNdZ7FWKVEB84/81BHnlGUwb5HpRTISG+boSO6wIDAQAB';
    $mchPrivateKey = 'MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAMigm7rtWnTeNagwFzGTH+Uw1ypbiy7VhIoFJbgSYSSHdCaXWdT/l2+2fQlEYgAETVZ/IXB29MCnrf3O0dwRFXiipIbsm5zyqSLiS6cKXe8zN1/PlQWUbEt5wyWm0GADB/4bV6eu6gA7sGXmjQqrzfKZkcie3aK7+7ry1NFxTI51AgMBAAECgYEAklqXQAVlt1tiSQ7L3J425jp6u6uMHN4lkYmvuleuBbfKQ1yla3wIPLYjAF+iHeEFidOz0Rb19JRdmIkHDkJoJg2W27LvO6RdUwzgRnsuA3OuNz97w08B3aXXbPmB91nTFjKSlUsbh3IQWP71noxW+iKn844EW5hC5Gvn4L3quAECQQDrz1r0VKIbBSBB2aLuz1XyD/TBT2aRhvOKf0XtTRiQhNjtJxoQmvNbbhvUwj8an7HyCuihAbdbrC2ymFFyOSDZAkEA2c4Yudi48C6COrroi1cWgPlEFeGJXP/V1k5loZ1n2vstYAGPhAB4wUnFBLDvMqaBzWJt7MRkiazT8KnBQCDY/QJAMXpNlEyZwt+deBOpO0BnwSWV7mWxmMFfImU4D+WITPbC7aexsWBBxaJh1o93XCe715RwYTAR//stj3akSDoyaQJAa4FKuxC51/Nc3Fg9R+modeiTLqmv/3NXvPvdNjRXesLX1rduex0wfVdII9ShfEKrdxDKaT9W0NyzD+r6NAkCkQJBAMAnTgPYf0f7rh417GdoP7R7Nwi8KBKwPHlmfRukibOQlKt9xjqpsKJwglLn8pcnXbYbswXIdqzuBvIGAe3OWNg=';
    // Merchant ID, obtained from the merchant platform
    $merchantCode = 'YOUR_MERCHANT_CODE_HERE';
    // Merchant order number
    $orderNum = 'T'.date("YmdHis",time());
    // Withdraw method 
    $method = 'DISBURSEMENT';
    // Order Type
    $orderType = '0';
    // Withdraw money
    $money = '20000';
    // Fee Type (0:on account deduction, 1:off account deduction)
    $feeType = '1';
    // PIX Type
    $pixType = 'CPF';
    // PIX Account
    $pixAccount = '123123123123';
    // Tax ID number
    $taxNumber = '45324532434';
    // description
    $description = 'description';
    // Notify Url
    $notifyUrl = 'http://example.com/callback';
    $params = array(
        'merchantCode' => $merchantCode,
        'orderType' => $orderType,
        'method' => $method,
        'orderNum' => $orderNum,
        'money' => $money,
        'feeType' => $feeType,
        'name' => $name,
        'pixType' => $pixType,
        'pixAccount' => $pixAccount,
        'taxNumber' => $taxNumber,
        '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;

    $params['name'] = $name;
    $params['description'] = $description;

    $params_string = json_encode($params);
    $url = 'https://br-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 "feeType :". $result['feeType'] . "\n";
        echo "name :". $result['name'] . "\n";
        echo "pixType :". $result['pixType'] . "\n";
        echo "pixAccount :". $result['pixAccount'] . "\n";
        echo "taxNumber :". $result['taxNumber'] . "\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://br-openapi.toppay.asia/gateway/cash

3.Request Params

Param Type Required Description Ex
merchantCode string Y Merchant ID, obtained from the merchant platform S820211021094748000001
orderType string(10) Y Order Type 0:Fiat Currency (BRL) Transaction
method string(10) Y Method DISBURSEMENT
orderNum string Y Merchant order number 10000001
money string Y Withdraw Money 150.12(Supports two decimal places)
feeType String Y Fee Type 0(on account deduction)
1(off account deduction)
name String Y Customer name Jack
pixType string Y PIX Type CPF(11 digits)
CNPJ(14 digits)
PHONE(Starting with +55, the number is 10-11 digits)
EMAIL(Email format)
EVP
BRCODE
pixAccount string Y PIX Account Based on pixType, just pass the corresponding account number; if pixType is CPF, then pixAccount passes CPF; if pixType is PHONE, then pixAccount passes PHONE; and so on...
taxNumber string Y Tax Number CPF/CNPJ
notifyUrl string Y Notify Url https://123123.com
description string N Description description
sign string Y Sign Yg+ePvTFhiRrARcZKBcRG0l89rqisPIuZQStYqBIwSMPaqvqbc3dFevgS9jt

4.Request parameter example

{
  "merchantCode": "S820211021094748000001",
  "orderType": "0",
  "method": "DISBURSEMENT",
  "orderNum": "186888188666",
  "money": "100",
  "feeType": "1",
  "name": "test cash name",
  "pixType": "CPF",
  "pixAccount": "123456789",
  "taxNumber": "123456789",
  "notifyUrl": "your notify url",
  "description": "test cash",
  "sign": "Yg+ePvTFhiRrARcZKBcRG0l89rqisPIuZQStYqBIwSMPaqwH77qRXI1J+jElOBpa"
}

5.Response

Param Type Required Description Ex
platRespCode String Y Code FAIL\SUCCESS
platRespMessage String Y Message SUCCESS
platOrderNum String Y Platform order number PI1453242857400963072
orderNum String Y Merchant order number 23645782
status int Y Status Please refer to Order status description for details.
statusMsg String Y Status Info Apply
money string Y Withdraw Money 150000
feeType String Y Fee Type 0(on account deduction)
1(off account deduction)
fee String Y Fee 500
name String Y Customer name Jack
pixType string Y PIX Type CPF(11 digits)
CNPJ(14 digits)
PHONE(Starting with +55, the number is 10-11 digits)
EMAIL(Email format)
EVP
pixAccount string Y PIX Account Based on pixType, just pass the corresponding account number; if pixType is CPF, then pixAccount passes CPF; if pixType is PHONE, then pixAccount passes PHONE; and so on...
taxNumber string Y Tax Number CPF/CNPJ
description String Y Description description
platSign String Y Sign PI1453242857400963072

6.Response

{
  "platRespCode": "SUCCESS",
  "platRespMessage": "Request success",
  "platOrderNum": "W0620220119174331000001",
  "orderNum": "186888188666",
  "status": 0,
  "statusMsg": "Apply",
  "money": "50000",
  "feeType": "0",
  "fee": "1",
  "name": "test cash name",
  "pixType": "CPF",
  "pixAccount": "123456",
  "taxNumber": "123456",
  "description": "test cash",
  "platSign": "E5uNF7B9NXyhtlRo2I7/KVHN4Sbz0c3VbwCLpH3vjUpv6Cai+bmJA/Q8dVE2RJRe1+dsbzg=="
}

7. Withdraw Notify

When verifying the signature, you must use the Platform Public Key provided in Merchant Backstage - Collection and Payment Configuration-API Configuration for decryption! ! !

After TopPay results are notified asynchronously, the SUCCESS string needs to be responded to.

Otherwise, TopPay will continue to send 5 notifications to the downstream.

Param Description Ex
platOrderNum Platform order number BK_1563278763273
orderNum Merchant order number T1231511321515
money Withdrawal amount 150.12
feeType Fee Type 0(on account deduction)
1(off account deduction)
fee fee 500
name Customer name Jack
pixType PIX Type CPF(11 digits)
CNPJ(14 digits)
PHONE(Starting with +55, the number is 10-11 digits)
EMAIL(Email format)
EVP
pixAccount PIX Account Based on pixType, just pass the corresponding account number; if pixType is CPF, then pixAccount passes CPF; if pixType is PHONE, then pixAccount passes PHONE; and so on...
taxNumber Tax Number CPF/CNPJ
status Status Please refer to Order status description for details.
statusMsg Status description Payout Success
description Description description
platSign Plat Sign ja6R8eukQY9jc8...

8.Notify Example

{
  "platOrderNum": "W0620220119174331000001",
  "orderNum": "186888188666",
  "money": "50000",
  "feeType": "0",
  "fee": "7",
  "name": "test cash name",
  "pixType": "CPF",
  "pixAccount": "123456",
  "taxNumber": "123456",
  "status": "2",
  "statusMsg": "SUCCESS",
  "description": "test cash",
  "platSign": "LGEpz2LjbZ6Iyvn+zLc/+t26AaH0aEhHVD62lSCdo6XIkAg86AUncCvmym62wVoE3r2+dHnv27qi/01UQDcqFK8DYioRCcydYSjB4QRVezG3fcZlhWrACmWGacnXkE7p5zChL7pK5h0HuBhbo1zKt4FunQR6QMmcBVfv7YfB3W0"

}

Digital currency withdrawal order

Payment orders support legal currency (BRL) and digital currency (USDT/BTC/ETH/TRX) transactions. If you want to use digital currency transactions, please set orderType=1 and pass in the corresponding currency currency and network netWork When using digital currency for transactions, the currency and chain network are must-have items You need to tell us which digital currency and chain network (TRC20/BEP20/OMNI/ERC20/TRX) you want to use for transactions When trading with digital currency, you need to pass in your inAddress to receive the digital currency We will launch transactions in other currencies and networks in the future, so stay tuned

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.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://br-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", "USDT"); // USDT/BTC/ETH/TRX
    requestParams.put("orderType", "1"); // Order Type (1:Digital Currency Transaction)
    requestParams.put("money", "1.000001"); // Order amount, supports up to 6 decimal places
    requestParams.put("feeType", "1");  //  0(on account deduction),1(off account deduction)
    requestParams.put("name", "test cash name");  // Customer name
    requestParams.put("description", "test cash");    // description
    requestParams.put("notifyUrl", cashNotify);  // Notify Url
    requestParams.put("currency", "USDT"); // Currency
    requestParams.put("netWork", "TRC20"); // Net Work
    requestParams.put("inAddress", "zkif74bhvkf8934rgg6"); //  Receiving address

    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); 
    System.out.println("Response Msg:" + responseJson);

    boolean pass = TopPayRequestUtil.verifySign(new Gson().fromJson(responseJson, JsonObject.class), PLAT_PUBLIC_KEY);  
    if (pass) {

    } else {

    }
  }
}

2.Request Address

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

3.Request Params

Param Type Required Description Ex
merchantCode string Y Merchant ID, obtained from the merchant platform S820211021094748000001
orderType string(10) Y Order Type 1(Digital currency trading)
method string(10) Y Method USDT
BTC
ETH
TRX
orderNum string Y Merchant order number 186888188666
money string Y Withdrawal amount 1.000001(Supports up to 6 decimal places);If the feeType is 0, please use the amount with 3 decimal places to place the payment order.
feeType String Y Fee Type 0(on account deduction)
1(off account deduction)
name String Y Customer name Jack
notifyUrl string Y Notify Url 1234567890
currency string(14) Y Currency USDT
netWork string(30) Y Net Work TRC20
inAddress string Y Receiveing Address vboj3457vbiae5y35y

4.Request parameter example

{
  "merchantCode": "S820211021094748000001",
  "orderType": "1",
  "method": "USDT",
  "orderNum": "186888188666",
  "money": "1.00000001",
  "feeType": "1",
  "name": "test cash name",
  "notifyUrl": "your notify url",
  "currency": "USDT",
  "netWork": "TRC20",
  "inAddress": "vboj3457vbiae5y35y",
  "sign": "Yg+ePvTFhiRrARcZKBcRG0l89rqisPIuZQStYqBIwSMPaqwH77qRXI1J+jElOBpa"
}

5.Response

Param Type Description Ex
platRespCode String Code FAIL\SUCCESS
platRespMessage String Message success
platOrderNum String Platform order number PI1453242857400963072
status String Status 0
statusMsg String Status Info Apply
orderNum String Merchant order number 23645782
money string Withdrawal amount 1.00000001
feeType String Order Type 0(on account deduction)
1(off account deduction)
name String Customer name Jack
currency string Currency USDT
netWork string Net Work TRC20
platSign String Sign PI1453242857400963072

6.Response Example

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

7.Digital payment Notify

After receiving the asynchronous notification of the result, you need to respond with the SUCCESS string, which does not contain quotes and is not in Json format.

Otherwise, TopPay will continue to send 5 notifications to the downstream.

Param Description Ex
platOrderNum Platform order number BK_1563278763273
orderNum Merchant order number T1231511321515
money Withdrawal amount 1.000001(Supports up to 6 decimal places)
feeType Fee Type 0(on account deduction)
1(off account deduction)
fee Fee 500
name Customer name Neo
status Status Please refer to Order status description for details.
statusMsg Status description Payout Success
hashCode Hash 5e5c356af0ewrhgnf3d757h8a6a5506cc66354620
inAddress Receiving Address TDBbbeAB32WE576DVGE82GEC5BhsZs4
sendAddress Send Address TDBbbeAB32WE576DVGE82GEC5BhsZs4
platSign Plat Sign ja6R8eukQY9jc8...

8.Notify Example

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

Order Query


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://br-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"); // Merchant order number
    requestParams.put("platOrderNum", "PRE186888188666"); // Platform order number

    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); 
    System.out.println("Response Msg:" + responseJson);
  }
}

Request Address

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

Request Params

Param Required Type Ex
merchantCode Y Merchant ID, obtained from the merchant platform S820190712000002
queryType Y Query Type Payment use ORDER_QUERY.Withdraw use CASH_QUERY
orderNum Y Merchant order number T1231511321515
platOrderNum Y Platform order number PRE1234567890
sign Y Sign ja6R8eukQ...

2.Request parameter example

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

Response Params

Param Type Required Description Ex
success BOOLEAN Y boolean true/false
code int Y code 1000 represents success, everything else represents failure.
message String Y Message Message
data Json Y Data The following parameters are returned in data, or null if failed
platRespCode String Y Plat Code FAIL\SUCCESS
platRespMessage String Y Plat Message Request Transaction Success
msg String Y Status Info Request Transaction Success
platOrderNum String Y Platform order number PI1453242857400963072
amount String Y money 1500
fee string Y fee 5
orderNum String Y Merchant order number 23645782
inAddress string N Receiving Address TLRx8JXsDidC7PYVLmeD6Bhk5k5CUjnPV3
sendAddress String N Send Address TLRx8JcxDidC7PYVLmeD6Bhk5k5CUjnPV3
status String Y Status Please refer to Order status description for details.

3.Payment Response Example

{
  "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.Withdraw Response Example

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

Balance Query


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://br-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", "BRL"); // Currency(BRL)

    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); 
    System.out.println("Response Msg:" + responseJson);
  }
}

Request Address

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

Request Params

Param required Description Ex
merchantCode Y Merchant ID, obtained from the merchant platform S820211021094748000001
currency N Currency BRL(If the specified currency is not passed, the balance in all currency units is displayed.)
sign Y Sign ja6R8eukQ...

Response

Param Type Required Description Ex
success BOOLEAN Y boolean true/false
code int Y Code 1000 is success,other is fail
message String Y Message Message
data Json Y Data The following parameters are returned in data, or null if failed
mchId String Y Merchant ID, obtained from the merchant platform S8202110212321300001
mchName String Y Mch Name test
mchNo String Y Merchant ID, obtained from the merchant platform TP123
currency string Y Currency BRL
balance String Y Available Balance 1000.00
freeze String Y Freeze balance 10.00
waitingSettleAmount String Y Amount to be settled 200.00
freezeWaitingSettleAmount String Y Freeze the amount pending settlement 100.00
totalAmount String Y Total amount (available balance + frozen balance + pending settlement amount + frozen pending settlement amount) 20000.00

2.Request parameter example

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

3.Response Example

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

Order status description

Payment

status remark
INIT_ORDER Pending
NO_PAY No Pay
SUCCESS SUCCESS(Final state)
PAY_CANCEL CANCEL(Final state)
PAY_ERROR Fail(Final state)

Withdraw

status remark
0 Pending
1 Processing
2 Success(Final state)
4 Fail(Final state)
5 Withdrawing