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 |