# 欢迎 👏

{% hint style="info" %}
所有主流加密数字货币的商业支付系统
{% endhint %}

### 准备工作 <a href="#zhun-bei-gong-zuo" id="zhun-bei-gong-zuo"></a>

欢迎阅读 `API` 支付接入文档。在开始接入之前，您需要：

1. 访问并登录 商户后台
2. 在商户后台创建支付应用，创建后会生成用于 API 调用的 `APP_ID` 和 `APP_SECRET`。
3. 阅读 [接入须知](/chinese/shuo-ming/jie-ru-xu-zhi) 相关内容。

现在您可以尝试通过接口发起 [下单](/chinese/zhi-fu-ding-dan/chuang-jian-ding-dan) 请求。

### 遇到问题？ <a href="#yu-dao-wen-ti" id="yu-dao-wen-ti"></a>

如您在接入过程中遇到任何问题，请优先阅读我们的 [接入须知](/chinese/shuo-ming/jie-ru-xu-zhi) 文档。


# 说明


# 接入须知

#### 请求域名 <a href="#qing-qiu-yu-ming" id="qing-qiu-yu-ming"></a>

```
https://api.tokenpay.me
```

### 编码 <a href="#bian-ma" id="bian-ma"></a>

统一编码为 `utf-8`。

### 密钥 <a href="#mi-yue" id="mi-yue"></a>

API文档中提及的 `APP_ID` 和 `APP_SECRECT`，可在商户后台应用管理中获取。

### 字段必选 <a href="#zi-duan-bi-xuan" id="zi-duan-bi-xuan"></a>

对于接口必选参数标记为 `true` 的字段，必须传入具体的值。

### 数据提交 <a href="#shu-ju-ti-jiao" id="shu-ju-ti-jiao"></a>

查询类接口统一使用 `GET` 方法请求，操作类接口统一使用 `POST` 的方法请求。

`POST` 请求头的 `content-type` 为：`application/json`


# 安全须知

### 密钥 <a href="#mi-yue" id="mi-yue"></a>

商户应用的 `APP_ID` 和 `APP_SECRECT` 非常重要，请勿显示在任何网页代码、网址参数中。

### 接口安全 <a href="#jie-kou-an-quan" id="jie-kou-an-quan"></a>

商户可在商户后台配置应用的 `IP白名单`，防范因密钥泄漏导致的资产安全问题。

### HTTPS <a href="#https" id="https"></a>

API 所有接口均采用 `HTTPS` 加密协议传输，部分接口需要提供 `notify_url & redirect_url`，建议商户对服务器部署 `HTTPS` 服务，保障数据的通信安全。


# 支付方式

支付接入方式主要为： `平台代收` 和 `平台代收（白标）`

### 支付方式介绍 <a href="#zhi-fu-fang-shi-jie-shao" id="zhi-fu-fang-shi-jie-shao"></a>

#### 平台代收 <a href="#ping-tai-dai-shou" id="ping-tai-dai-shou"></a>

接入简单，不需要商户准备收款钱包，并且支持`多公链` `多币种` `多钱包`支付，资金`无需归集`，可`跨链提币`，提供`一体化收银台`（支持自适应 PC,H5），`多币种报表`，`多链报表`，`帐变明细`可查，真正做到用户无忧，一站式收款服务。

#### 平台代收（白标） <a href="#ping-tai-dai-shou" id="ping-tai-dai-shou"></a>

平台代收的基础上提供白标服务，在您的网站上进行加密货币支付，无支付`LOGO`，专为品牌商户定制化的收银台


# 签名生成

{% hint style="info" %}
说明

商户可以按照下述步骤生成请求的签名，平台会在收到请求后进行签名的验证。如果签名验证不通过，将会拒绝处理请求，并返回相应的[业务状态码](/chinese/cuo-wu-ma/ye-wu-zhuang-tai-ma)。
{% endhint %}

### 准备 <a href="#zhun-bei" id="zhun-bei"></a>

商户需要注册有商户号，并通过商户后台创建支付应用，获取应用 `APP_ID` 和 `APP_SECRECT`。

### 条件 <a href="#tiao-jian" id="tiao-jian"></a>

本文档所有 `POST` 方法的接口都需要验证签名，其他接口暂不需验证。

### 构造签名串 <a href="#gou-zao-qian-ming-chuan" id="gou-zao-qian-ming-chuan"></a>

签名串一共有四行，每一行为一个参数。行尾以 `\n`（换行符，ASCII 编码值为 0x0A）结束，最后一行不用加`\n`。如果参数本身以 `\n`结束，也需要附加一个`\n`。

```
URL\n
请求时间戳\n
请求随机串\n
请求报文主体
```

我们以[查询订单](/chinese/zhi-fu-ding-dan/cha-xun-ding-dan)接口为例:

第一步，获取请求的绝对 URL，并去除域名部分得到参与签名的 URL。如果请求中有查询参数，URL 末尾应附加有'?'和对应的查询字符串。

```
/v1/transaction/query
```

第二步，获取发起请求时的系统当前时间戳（毫秒），即格林威治时间 1970 年 01 月 01 日 00 时 00 分 00 秒起至现在的总秒数，作为请求时间戳。平台会拒绝处理很久之前发起的请求，请商户保持自身系统的时间准确。

```
1554208460000
```

第三步，生成一个 32 位`随机字符串`。

```
593BEC0C930BF1AFEB40B4A08C8FB242
```

第四步，获取请求中的请求报文主体（request body）。

```json
{
    "app_id": "8e4b8c2e7cxxxxxxxx1a1cbd3d59e0bd",
    "mch_id": "12345678",
    "transaction_id": "e98b30294xxxxxxxxxxxx97a9d9e09ce",
    "out_trade_no": "fb72xxxx-xxxx-xxxx-xxxx-xxxx8a7b52cb"
}
```

第五步，按照前述规则，构造的请求签名串为：

{% code overflow="wrap" %}

```
/v1/transaction/query\n
1554208460\n
593BEC0C930BF1AFEB40B4A08C8FB242\n
{"app_id":"8e4b8c2e7cxxxxxxxx1a1cbd3d59e0bd","mch_id":"12345678","transaction_id":"e98b30294xxxxxxxxxxxx97a9d9e09ce","out_trade_no":"fb72xxxx-xxxx-xxxx-xxxx-xxxx8a7b52cb"}
```

{% endcode %}

### 加密签名串 <a href="#jia-mi-qian-ming-chuan" id="jia-mi-qian-ming-chuan"></a>

下面以 javascript 加密过程为例:

{% code overflow="wrap" %}

```javascript
let cryptoJs = require("crypto-js");
let key = CryptoJS.enc.Utf8.parse("9db664697xxxxxxxxxxxx2d27a3c925c") //APP的密钥
//AES加密
let ciphertext = cryptoJs.AES.encrypt(签名串, key, {
  mode: CryptoJS.mode.ECB,
  padding: CryptoJS.pad.Pkcs7,
}).toString();
```

{% endcode %}

加密后示例：

{% code overflow="wrap" %}

```
QCwHvoBM9TJ2wokF8hhaoS34P0nkJpYMisBUizpOj5q/77I6+KFPVvFUCaaUiu+KFctisJFU1DfJdCHrLpJIx9CirX5ku3L9TMGihFcEG8MGoh2dwDvunH8JgJOVV9ClSkpXqjad4flSuYMoxPOZqPHr+ktOLZ3pPzs12BMqmbZVNIe+oOezTZsQ8xxxxRgOJzwU/AbouZSl2xto7DcYCjvNSnw7BkuzBFgTfxVXB3+R7e+1SpdeJajuCKGKvYMVTe7slS5j/4LQ4vcr1QqOPhpoemsOV92tPhgQ0iGw3GKpLIEOoDAwy2+ojzP5XERh
```

{% endcode %}

### 拼接签名信息 <a href="#pin-jie-qian-ming-xin-xi" id="pin-jie-qian-ming-xin-xi"></a>

签名信息的拼接格式如下：\
app\_id=`APP_ID`,mch\_id=`商户ID`,nonce\_str=`第三步生成的随机字符串`,timestamp=`第二步生成的时间戳`,signature=`加密签名串`

### 设置 HTTP 头 <a href="#she-zhi-http-tou" id="she-zhi-http-tou"></a>

本文档 API 通过 HTTP `Authorization` 头来传递签名。 `Authorization` 由`认证类型`和`签名信息`两个部分组成，目前`认证类型` 仅支持 `TTPAY-AES-256-ECB`

Authorization 头的示例如下：（注意，示例因为排版可能存在换行，实际数据应在一行）

{% code overflow="wrap" %}

```
Authorization: TTPAY-AES-256-ECB app_id=8e4b8c2e7cxxxxxxxx1a1cbd3d59e0bd,mch_id=12345678,nonce_str=593BEC0C930BF1AFEB40B4A08C8FB242,timestamp=1554208460,signature=QCwHvoBM9TJ2wokF8hhaoS34P0nkJpYMisBUizpOj5q/77I6+KFPVvFUCaaUiu+KFctisJFU1DfJdCHrLpJIx9CirX5ku3L9TMGihFcEG8MGoh2dwDvunH8JgJOVV9ClSkpXqjad4flSuYMoxPOZqPHr+ktOLZ3pPzs12BMqmbZVNIe+oOezTZsQ8xxxxRgOJzwU/AbouZSl2xto7DcYCjvNSnw7BkuzBFgTfxVXB3+R7e+1SpdeJajuCKGKvYMVTe7slS5j/4LQ4vcr1QqOPhpoemsOV92tPhgQ0iGw3GKpLIEOoDAwy2+ojzP5XERh"
```

{% endcode %}

最终我们可以组一个包含了签名的 HTTP 请求了。

{% code overflow="wrap" %}

```sh
$ curl https://api.tokenpay.me/v1/transaction/query -H "Content-Type: application/json" -H 'Authorization: TTPAY-AES-256-ECB app_id=8e4b8c2e7cxxxxxxxx1a1cbd3d59e0bd,mch_id=12345678,nonce_str=593BEC0C930BF1AFEB40B4A08C8FB242,timestamp=1554208460,signature=QCwHvoBM9TJ2wokF8hhaoS34P0nkJpYMisBUizpOj5q/77I6+KFPVvFUCaaUiu+KFctisJFU1DfJdCHrLpJIx9CirX5ku3L9TMGihFcEG8MGoh2dwDvunH8JgJOVV9ClSkpXqjad4flSuYMoxPOZqPHr+ktOLZ3pPzs12BMqmbZVNIe+oOezTZsQ8xxxxRgOJzwU/AbouZSl2xto7DcYCjvNSnw7BkuzBFgTfxVXB3+R7e+1SpdeJajuCKGKvYMVTe7slS5j/4LQ4vcr1QqOPhpoemsOV92tPhgQ0iGw3GKpLIEOoDAwy2+ojzP5XERh' -X POST -d '{"out_trade_no": "fb72xxxx-xxxx-xxxx-xxxx-xxxx8a7b52cb", "transaction_id":"e98b30294xxxxxxxxxxxx97a9d9e09ce", "app_id":"8e4b8c2e7cxxxxxxxx1a1cbd3d59e0bd", "mch_id":"12345678" }'
```

{% endcode %}

### 演示代码 <a href="#yan-shi-dai-ma" id="yan-shi-dai-ma"></a>

{% tabs %}
{% tab title="Java" %}

{% code overflow="wrap" %}

```java
package com.example.http;

import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.JSONObject;
import com.sun.istack.internal.NotNull;
import okhttp3.*;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.security.Security;
import java.util.Base64;

public class HttpApplication {
    private static String SECRET = "AES";
    private static String CIPHER_ALGORITHM = "AES/ECB/PKCS7Padding";
    private static String schema = "TTPAY-AES-256-ECB ";

    public static void main(String[] args) throws Exception {
        String key = "xxxxxxxx";    // 应用密钥
        String reqURL = "/v1/transaction/query";    // 请求接口

        OkHttpClient client = new OkHttpClient();
        JSONObject params = new JSONObject();

        try {
            params.put("app_id", "xxxxxxxx");           // 应用ID
            params.put("mch_id", "xxxxxxxx");           // 商户ID
            params.put("transaction_id", "xxxxxxxx");   // 平台订单号
            params.put("out_trade_no", "xxxxxxxx");     // 商户订单号
        } catch (JSONException e) {
            e.printStackTrace();
        }

        Security.addProvider(new BouncyCastleProvider());

        // 签名
        String auth = auth(reqURL, params, key);

        RequestBody body = RequestBody.create(MediaType.parse("application/json;charset=utf-8"), params.toString());
        Request request = new Request.Builder()
        .header("Authorization", auth)
        .url(reqURL)
        .post(body)
        .build();

        client.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                System.out.println("http request error");
            }

            @Override
            public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
                System.out.println(response.body().string());
            }
        });
    }

    /**
    * 签名
    * @param reqURL 请求URL
    * @param raw 报文主体
    * @param key 应用密钥
    * @return 签名信息
    */
    public static String auth(String reqURL, JSONObject raw, String key) throws Exception {
        HttpUrl parseReqURL = HttpUrl.parse(reqURL);
        String url = parseReqURL.encodedPath();
        String appID = raw.getString("app_id");
        String mchID = raw.getString("mch_id");
        long currentTimeMillis = System.currentTimeMillis();
        String timestamp = String.valueOf(currentTimeMillis);
        String nonceStr = randomString(32);
        String message = url + "\n" + timestamp + "\n" + nonceStr + "\n" + raw.toString();
        String aes256ECBPkcs7PaddingEncrypt = aes256ECBPkcs7PaddingEncrypt(message, key);

        return schema + "app_id=" + appID + ",mch_id=" + mchID + ",nonce_str=" + nonceStr + ",timestamp=" + timestamp + ",signature=" + aes256ECBPkcs7PaddingEncrypt;
    }

    /**
    * 生成随机字符串
    * @param len 字符长度
    * @return 随机字符串
    */
    public static String randomString(Integer ...len) {
        int e = len.length <= 0 ? 32 : len[0];
        String str = "ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678";
        int strLen = str.length();
        StringBuilder stringBuilder = new StringBuilder();

        for (int i = 0; i < e; i++) {
            double random = Math.random();
            int v = (int) Math.floor(random * strLen);
            char charAt = str.charAt(v);

            stringBuilder.append(charAt);
        }

        return stringBuilder.toString();
    }

    /**
    * AES加密
    * @param str 字符串
    * @param key 密钥
    * @return 加密字符串
    * @throws Exception 异常信息
    */
    public static String aes256ECBPkcs7PaddingEncrypt(String str, String key) throws Exception {
        Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
        byte[] keyBytes = key.getBytes(StandardCharsets.UTF_8);

        cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(keyBytes, SECRET));

        byte[] doFinal = cipher.doFinal(str.getBytes(StandardCharsets.UTF_8));

        return new String(Base64.getEncoder().encode(doFinal));
    }

    /**
    * AES解密
    * @param str 字符串
    * @param key 密钥
    * @return 解密字符串
    * @throws Exception 异常信息
    */
    public static String aes256ECBPkcs7PaddingDecrypt(String str, String key) throws Exception {
        Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
        byte[] keyBytes = key.getBytes(StandardCharsets.UTF_8);

        cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(keyBytes, SECRET));

        byte[] doFinal = cipher.doFinal(Base64.getDecoder().decode(str));

        return new String(doFinal);
    }
}
```

{% endcode %}
{% endtab %}

{% tab title="Go" %}

{% code overflow="wrap" %}

```go
package main

import (
	"bytes"
	"encoding/base64"
	"encoding/json"
	"fmt"
	"io"
	"math/rand"
	"net/http"
	"time"

	"github.com/forgoer/openssl"
)

const (
	SignatureMessageFormat = "%s\n%d\n%s\n%s" // 数字签名原文格式
	HeaderAuthorizationFormat = "%s app_id=%s,mch_id=%s,nonce_str=%s,timestamp=%d,signature=%s"
)

type QueryReq struct {
	AppID         string `json:"app_id"`
	MchID         string `json:"mch_id"`
	TransactionID string `json:"transaction_id,omitempty"`
	OutTradeNo    string `json:"out_trade_no,omitempty"`
}

func main() {

	appSecret := "**********"           // 应用密钥
	reqPath := "/v1/transaction/query"  // 请求接口路径
	queryReq := QueryReq{
		AppID:         "**********",    // 应用ID
		MchID:         "**********",    // 商户ID
		TransactionID: "**********",    // 平台订单号
		OutTradeNo:    "**********",    // 商户订单号
	}

	b, _ := json.Marshal(queryReq)

    // 签名
	authorization, err := GenerateAuthorizationHeader(queryReq.AppID, queryReq.MchID, reqPath, string(b), appSecret)
	if err != nil {
		panic(err)
	}

    // 请求接口
	url := "" + reqPath

	payload := bytes.NewBuffer(b)

	req, _ := http.NewRequest("POST", url, payload)

	req.Header.Set("Accept", "application/json")
	req.Header.Set("Content-Type", "application/json")
	req.Header.Set("Authorization", authorization)

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(string(body))
}

// 签名
func GenerateAuthorizationHeader(appID, mchID, reqURL, signBody, appSecret string) (string, error) {
	nonceStr := RandomString(32)
	timestamp := time.Now().Unix()
	message := fmt.Sprintf(SignatureMessageFormat, reqURL, timestamp, nonceStr, signBody)

	signatureResult, err := AesECBEncrypt(message, appSecret)
	if err != nil {
		return "", err
	}
	authorization := fmt.Sprintf(
		HeaderAuthorizationFormat, getAuthorizationType(), appID,
		mchID, nonceStr, timestamp, signatureResult,
	)
	return authorization, nil
}

// AES加密
func AesECBEncrypt(orig, key string) (string, error) {
	dst, _ := openssl.AesECBEncrypt([]byte(orig), []byte(key), openssl.PKCS7_PADDING)
	return base64.StdEncoding.EncodeToString(dst), nil
}

// AES解密
func AesECBDecrypt(crypted, key string) (string, error) {
	x := len(crypted) * 3 % 4
	switch {
	case x == 2:
		crypted += "=="
	case x == 1:
		crypted += "="
	}
	crytedByte, err := base64.StdEncoding.DecodeString(crypted)
	if err != nil {
		return "", err
	}
	origData, err := openssl.AesECBDecrypt(crytedByte, []byte(key), openssl.PKCS7_PADDING)
	if err != nil {
		return "", err
	}
	return string(origData), err
}

// 生成随机字符
func RandomString(length int) string {
	str := []byte("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
	var result []byte
	rnd := rand.New(rand.NewSource(time.Now().UnixNano()))
	for i := 0; i < length; i++ {
		result = append(result, str[rnd.Intn(len(str))])
	}
	return string(result)
}

func getAuthorizationType() string {
	return "TTPAY-AES-256-ECB"
}
```

{% endcode %}
{% endtab %}

{% tab title="PHP" %}

{% code overflow="wrap" %}

```php
<?php
$key = "xxxxxxxx";                // 应用密钥
$APP_ID = "xxxxxxxx";             // 应用ID
$mchID = "xxxxxxxx";              // 商户ID
$transactionID = "xxxxxxxx";      // 平台订单号
$outTradeNo = "xxxxxxxx";         // 商户订单号
$url = "/v1/transaction/query";   // 接口路径
$timestamp = time()*1000;         // 当前时间戳
$nonce = generateStr(32);         // 32位随机字符串

// 生成随机字符串
function generateStr($length) {
  $chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
  $res ='';

  for ( $i = 0; $i < $length; $i++ ) {
    $res .= $chars[ mt_rand(0, strlen($chars) - 1) ];
  }

  return $res;
}

// 报文主体
$body = '{"app_id":"'.$APP_ID.'","mch_id":"'.$mchID.'","transaction_id":"'.$transactionID.'","out_trade_no":"'.$outTradeNo.'"}';

// 构造签名串
$message = $url."\n".$timestamp."\n".$nonce."\n".$body;

// 加密签名串
$cipher = "aes-256-ecb";
$sign = openssl_encrypt($message, $cipher, $key);

// 拼接签名信息
$schema = 'TTPAY-AES-256-ECB';
$authorization = sprintf('%s app_id=%s,mch_id=%s,nonce_str=%s,timestamp=%d,signature=%s', $schema, $APP_ID, $mchID, $nonce, $timestamp, $sign);

// 设置HTTP头
$header[] = "Accept: application/json";
$header[] = "Content-Type: application/json";
$header[] = "Authorization: $authorization";

// 请求接口
$curl = curl_init();
curl_setopt($curl, CURLOPT_HTTPHEADER, $header);
curl_setopt($curl, CURLOPT_URL, "".$url);
curl_setopt($curl, CURLOPT_POSTFIELDS, $body);
curl_setopt($curl, CURLOPT_POST, 1);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
$result = curl_exec($curl);
curl_close($curl);

var_export($result);
```

{% endcode %}

<br>
{% endtab %}

{% tab title="JavaScript" %}

{% code overflow="wrap" %}

```javascript
let cryptoJs = require("crypto-js");

let jsonObj = JSON.parse(pm.request.body.raw); //把提交上来的body字符串转成对象
let jsonStr = JSON.stringify(jsonObj)//重新把对象字符串，目的是压缩一下，避免body里面的换行影响签名
let appID = jsonObj.app_id;
let mchID = jsonObj.mch_id;

// 生成当前时间戳
let timestamp = Math.round(new Date() / 1000).toString()

//定义随机字符串
var nonceStr = randomString(); // 随机字符串
function randomString(e) {
    e = e || 32;
    var t = "ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678",
    a = t.length,
    n = "";
    for (i = 0; i < e; i++) n += t.charAt(Math.floor(Math.random() * a));
    return n
}

//获取完整路径的path
var reqURL = "/" + pm.request.url.path.join("/");

//拼接签名明文
message = reqURL + "\n" + timestamp + "\n" + nonceStr + "\n" + jsonStr

let key = CryptoJS.enc.Utf8.parse("********************************") // 应用密钥
//AES加密
let ciphertext = cryptoJs.AES.encrypt(message, key, {
    mode: CryptoJS.mode.ECB,
    padding: CryptoJS.pad.Pkcs7,
  }).toString();

//拼接放在Header的authorization，TTPAY-{加密方式},目前仅支持AES-256-ECB
let authorization = 'TTPAY-AES-256-ECB app_id=' + appID + ',mch_id=' + mchID + ',nonce_str=' + nonceStr + ',timestamp=' + timestamp + ',signature=' + ciphertext

pm.request.headers.upsert({ key: "authorization", value: authorization })
```

{% endcode %}
{% endtab %}
{% endtabs %}


# 签名验证

{% hint style="info" %}
说明

商户可以按照下述步骤验证应答或者回调的签名。

如果验证商户的请求签名正确，在应答的 HTTP 头部中包括应答签名。我们建议商户验证应答签名。

同样的，在回调的 HTTP 头部中包括回调报文的签名。商户必须 验证回调的签名，以确保回调是由 我们 发送。
{% endhint %}

### 构造验签名串 <a href="#gou-zao-yan-qian-ming-chuan" id="gou-zao-yan-qian-ming-chuan"></a>

首先，商户先从应答中获取以下信息。

* HTTP 头 Timestamp 中的应答时间戳。
* HTTP 头 Nonce 中的应答随机串。
* 应答主体（response Body），需要按照接口返回的顺序进行验签，错误的顺序将导致验签失败。

签名串一共有三行，每一行为一个参数。行尾以 `\n`（换行符，ASCII 编码值为 0x0A）结束，最后一行不用加`\n`。如果参数本身以 `\n`结束，也需要附加一个`\n`。

```
应答时间戳\n
应答随机串\n
应答报文主体
```

如某个应答的 HTTP 报文为：

{% code overflow="wrap" %}

```
HTTP/1.1 200 OK
Server: nginx
Date: Tue, 02 Apr 2019 12:59:40 GMT
Content-Type: application/json; charset=utf-8
Content-Length: 2204
Connection: keep-alive
Keep-Alive: timeout=8
Content-Language: zh-CN
TTPay-Nonce: c5ac7061fccab6bf3e254dcf98995b8c
TTPay-Signature: CtcbzwtQjN8rnOXItEBJ5aQFSnIXESeV28Pr2YEmf9wsDQ8Nx25ytW6FXBCAFdrr0mgqngX3AD9gNzjnNHzSGTPBSsaEkIfhPF4b8YRRTpny88tNLyprXA0GU5ID3DkZHpjFkX1hAp/D0fva2GKjGRLtvYbtUk/OLYqFuzbjt3yOBzJSKQqJsvbXILffgAmX4pKql+Ln+6UPvSCeKwznvtPaEx+9nMBmKu7Wpbqm/+2ksc0XwjD+xlvlECkCxfD/OJ4gN3IurE0fpjxIkvHDiinQmk51BI7zQD8k1znU7r/spPqB+vZjc5ep6DC5wZUpFu5vJ8MoNKjCu8wnzyCFdA==
TTPay-Timestamp: 1554209980
Cache-Control: no-cache, must-revalidate

{"app_id":"xxxx"}
```

{% endcode %}

则验签名串为

```
1554209980
c5ac7061fccab6bf3e254dcf98995b8c
{"app_id":"xxxx"}
```

### 获取应答签名 <a href="#huo-qu-ying-da-qian-ming" id="huo-qu-ying-da-qian-ming"></a>

我们 的应答签名通过 HTTP 头 Signature 传递。（注意，示例因为排版可能存在换行，实际数据应在一行）

{% code overflow="wrap" %}

```
CtcbzwtQjN8rnOXItEBJ5aQFSnIXESeV28Pr2YEmf9wsDQ8Nx25ytW6FXBCAFdrr0mgqngX3AD9gNzjnNHzSGTPBSsaEkIfhPF4b8YRRTpny88tNLyprXA0GU5ID3DkZHpjFkX1hAp/D0fva2GKjGRLtvYbtUk/OLYqFuzbjt3yOBzJSKQqJsvbXILffgAmX4pKql+Ln+6UPvSCeKwznvtPaEx+9nMBmKu7Wpbqm/+2ksc0XwjD+xlvlECkCxfD/OJ4gN3IurE0fpjxIkvHDiinQmk51BI7zQD8k1znU7r/spPqB+vZjc5ep6DC5wZUpFu5vJ8MoNKjCu8wnzyCFdA==
```

{% endcode %}

### 判断签名 <a href="#pan-duan-qian-ming" id="pan-duan-qian-ming"></a>

使用`AES-256-ECB`的方法生成签名（可参考[签名生成](/chinese/shuo-ming/qian-ming-sheng-cheng#jia-mi-qian-ming-chuan)）。生成后的签名跟应答签名做对比。不一致则表示数据遭到篡改。


# 解密回调

{% hint style="info" %}
说明

为了保证安全性，支付在回调通知接口中，对关键信息进行了 AES-256-GCM 加密，商户收到报文后，要解密出明文，解密时使用 APP 的密钥。本章节详细介绍了加密报文的格式，以及如何进行解密。
{% endhint %}

### 加密报文格式 <a href="#jia-mi-bao-wen-ge-shi" id="jia-mi-bao-wen-ge-shi"></a>

首先，商户先从应答中获取以下信息。

* AES-GCM 是一种 NIST 标准的 [认证加密](https://zh.wikipedia.org/wiki/%E8%AE%A4%E8%AF%81%E5%8A%A0%E5%AF%86)算法， 是一种能够同时保证数据的保密性、 完整性和真实性的一种加密模式。它最广泛的应用是在 TLS 中
* 回调报文使用的加密密钥为 APP 的密钥。。
* 对于加密的数据，我们使用了一个独立的 JSON 对象来表示。为了方便阅读，示例做了 Pretty 格式化，并加入了注释。

```json
{
    "original_type": "transaction", // 加密前的对象类型
    "algorithm": "AEAD_AES_256_GCM", // 加密算法

    // Base64编码后的密文
    "ciphertext": "...",

    // 加密使用的随机串初始化向量）
    "nonce": "...",
}
```

注意：加密的随机串，跟签名时使用的随机串没有任何关系，是不一样的。

### 解密 <a href="#jie-mi" id="jie-mi"></a>

* 算法接口的细节，可以参考 [rfc5116](https://datatracker.ietf.org/doc/html/rfc5116)。
* 大部分编程语言（较新版本）都支持了 AEAD\_AES\_256\_GCM。开发者可以参考下列的示例，了解如何使用您的编程语言实现解密。

### 代码示例 <a href="#dai-ma-shi-li" id="dai-ma-shi-li"></a>

{% tabs %}
{% tab title="Java" %}
{% code overflow="wrap" fullWidth="true" %}

```java
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;
import javax.crypto.Cipher;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.GCMParameterSpec;
import javax.crypto.spec.SecretKeySpec;

public class AesUtil {
  static final int KEY_LENGTH_BYTE = 32;
  static final int TAG_LENGTH_BIT = 128;
  private final byte[] aesKey;

    public AesUtil(byte[] key) {
      if (key.length != KEY_LENGTH_BYTE) {
        throw new IllegalArgumentException("无效的AppSecret，长度必须为32个字节");
        }
      this.aesKey = key;
    }

  public String decryptToString( byte[] nonce, String ciphertext)
  throws GeneralSecurityException, IOException {
    try {
        Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
        SecretKeySpec key = new SecretKeySpec(aesKey, "AES");
        GCMParameterSpec spec = new GCMParameterSpec(TAG_LENGTH_BIT, nonce);

        cipher.init(Cipher.DECRYPT_MODE, key, spec);

        return new String(cipher.doFinal(Base64.getDecoder().decode(ciphertext)), "utf-8");
       } catch (NoSuchAlgorithmException | NoSuchPaddingException e) {
         throw new IllegalStateException(e);
       } catch (InvalidKeyException | InvalidAlgorithmParameterException e) {
         throw new IllegalArgumentException(e);
        }
    }
}

```

{% endcode %}

<br>
{% endtab %}

{% tab title="PHP" %}

{% code overflow="wrap" %}

````php
class AesUtil {
  /**
  * AES key
  *
  * @var string
  */
  private $aesKey;

  const KEY_LENGTH_BYTE = 32;
  const AUTH_TAG_LENGTH_BYTE = 16;

 /**
  * Constructor
  */
  public
  function __construct($aesKey) {
    if (strlen($aesKey) != self::KEY_LENGTH_BYTE) {
      throw new InvalidArgumentException('无效的AppSecret，长度应为32个字节');
    }
     $this - > aesKey = $aesKey;
    }

   /**
    * Decrypt AEAD_AES_256_GCM ciphertext
    *
    * @param string    $associatedData     AES GCM additional authentication data
    * @param string    $nonceStr           AES GCM nonce
    * @param string    $ciphertext         AES GCM cipher text
    *
    * @return string|bool      Decrypted string on success or FALSE on failure
    */
  public
  function decryptToString($associatedData, $nonceStr, $ciphertext) {
    $ciphertext = \base64_decode($ciphertext);
    if (strlen($ciphertext) <= self::AUTH_TAG_LENGTH_BYTE) {
      return false;
    }

    // ext-sodium (default installed on >= PHP 7.2)
    if (function_exists('\sodium_crypto_aead_aes256gcm_is_available') && \sodium_crypto_aead_aes256gcm_is_available()) {
        return \sodium_crypto_aead_aes256gcm_decrypt($ciphertext, $associatedData, $nonceStr, $this - > aesKey);
      }

    // ext-libsodium (need install libsodium-php 1.x via pecl)
    if (function_exists('\Sodium\crypto_aead_aes256gcm_is_available') && \Sodium\crypto_aead_aes256gcm_is_available()) {
      return \Sodium\crypto_aead_aes256gcm_decrypt($ciphertext, $associatedData, $nonceStr, $this - > aesKey);
    }

    // openssl (PHP >= 7.1 support AEAD)
    if (PHP_VERSION_ID >= 70100 && in_array('aes-256-gcm', \openssl_get_cipher_methods())) {
    $ctext = substr($ciphertext, 0, -self::AUTH_TAG_LENGTH_BYTE);
    $authTag = substr($ciphertext, -self::AUTH_TAG_LENGTH_BYTE);

    return \openssl_decrypt($ctext, 'aes-256-gcm', $this - > aesKey, \OPENSSL_RAW_DATA, $nonceStr,$authTag, $associatedData);

    }
    throw new \RuntimeException('AEAD_AES_256_GCM需要PHP 7.1以上或者安装libsodium-php');
  }
}

  </CodeGroupItem>

  <CodeGroupItem title="Java">

```java:no-line-numbers
OkHttpClient client = new OkHttpClient().newBuilder()
   .build();
MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "<body data here>");
Request request = new Request.Builder()
   .url("https://api.ttpay.io/v1/wallet/update")
   .method("POST", body)
   .addHeader("Authorization", "<Authorization>")
   .addHeader("User-Agent", "TTPay API (https://ttpay.io)")
   .addHeader("Content-Type", "application/json")
   .build();
Response response = client.newCall(request).execute();
````

{% endcode %}
{% endtab %}

{% tab title="Aspnet" %}

{% code overflow="wrap" %}

```aspnet
public class AesGcm {
  private static string ALGORITHM = "AES/GCM/NoPadding";
  private static int TAG_LENGTH_BIT = 128;
  private static int NONCE_LENGTH_BYTE = 12;
  private static string AES_KEY = "yourkeyhere";

  public static string AesGcmDecrypt(string associatedData, string nonce, string ciphertext)
  {
    GcmBlockCipher gcmBlockCipher = new GcmBlockCipher(new AesEngine());
    AeadParameters aeadParameters = new AeadParameters(
      new KeyParameter(Encoding.UTF8.GetBytes(AES_KEY)),
      128,
      Encoding.UTF8.GetBytes(nonce),
      Encoding.UTF8.GetBytes(associatedData));
    gcmBlockCipher.Init(false, aeadParameters);

    byte[] data = Convert.FromBase64String(ciphertext);
    byte[] plaintext = new byte[gcmBlockCipher.GetOutputSize(data.Length)];
    int length = gcmBlockCipher.ProcessBytes(data, 0, data.Length, plaintext, 0);
    gcmBlockCipher.DoFinal(plaintext, length);
    return Encoding.UTF8.GetString(plaintext);
  }
}
```

{% endcode %}
{% endtab %}

{% tab title="Python" %}

{% code overflow="wrap" %}

```python
  from cryptography.hazmat.primitives.ciphers.aead import AESGCM
  import base64
  def decrypt(nonce, ciphertext, associated_data):

    key = "Your32Apiv3Key"

    key_bytes = str.encode(key)
    nonce_bytes = str.encode(nonce)
    ad_bytes = str.encode(associated_data)
    data = base64.b64decode(ciphertext)

    aesgcm = AESGCM(key_bytes)
    return aesgcm.decrypt(nonce_bytes, data, ad_bytes)
```

{% endcode %}
{% endtab %}
{% endtabs %}


# 数据结构

{% hint style="info" %}
说明

CurrencyDetail
{% endhint %}

#### 币种详情 <a href="#bi-zhong-xiang-qing" id="bi-zhong-xiang-qing"></a>

| 名称                       | 类型      | 说明                    | 示例                                                           |
| ------------------------ | ------- | --------------------- | ------------------------------------------------------------ |
| network                  | string  | 网络                    | 示例值：`TRX`、`TRC10`、`TRC20`、`TRC721`、`TRC1155`、`ERC20`、`BEP20` |
| chain                    | string  | 所属公链                  | 示例值：`TRON`、`ETHEREUM`、`BSC`                                  |
| code                     | string  | 币种代码                  |                                                              |
| currency                 | string  | 币种                    |                                                              |
| name                     | string  | 名称                    |                                                              |
| logo                     | string  | LOGO                  |                                                              |
| contract\_address        | string  | 合约地址                  |                                                              |
| decimal                  | integer | 精度                    |                                                              |
| is\_fiat                 | integer | 是否是法币                 | 是 `1` 否`0`                                                   |
| payment\_qr\_code        | integer | 是否支持扫码支付              | 是 `1` 否`0`                                                   |
| payment\_connect\_wallet | integer | 是否支持 ConnectWallet 支付 | 是 `1` 否`0`                                                   |
| payment\_tron\_link      | integer | 是否支持 tronlink 支付      | 是 `1` 否`0`                                                   |
| min\_payment\_amount     | integer | 最小支付金额                |                                                              |
| max\_payment\_amount     | integer | 最大支付金额                |                                                              |

#### 交易详情 <a href="#jiao-yi-xiang-qing" id="jiao-yi-xiang-qing"></a>

{% hint style="info" %}
说明

TransactionDetail
{% endhint %}

| 名称                         | 类型      | 说明                                                       | 示例                                                           |
| -------------------------- | ------- | -------------------------------------------------------- | ------------------------------------------------------------ |
| out\_trade\_no             | string  | 商户订单号                                                    |                                                              |
| transaction\_id            | string  | 平台订单号                                                    |                                                              |
| description                | string  | 订单描述（utf8-mb4）                                           |                                                              |
| block\_no                  | integer | 区块号，也可以通过这个查询区块 hash                                     |                                                              |
| create\_time               | integer | 订单创建时间                                                   |                                                              |
| block\_time                | integer | 区块时间                                                     |                                                              |
| pay\_time                  | integer | 支付时间(成功才有)                                               |                                                              |
| tx\_id                     | string  | 交易 hash                                                  |                                                              |
| from\_address              | string  | 支付地址                                                     |                                                              |
| contract\_address          | string  | 合约地址                                                     |                                                              |
| to\_address                | string  | 资金转入地址                                                   |                                                              |
| amount                     | integer | 订单金额                                                     |                                                              |
| decimals                   | integer | 订单金额精度                                                   |                                                              |
| pay\_amount                | integer | 实际支付金额                                                   |                                                              |
| pay\_decimal               | integer | 实际支付金额精度                                                 |                                                              |
| pay\_currency              | string  | 实际支付币种                                                   |                                                              |
| pay\_chain                 | string  | 实际支付公链 TRON、ETHEREUM、BSC                                 |                                                              |
| attach                     | string  | 附加数据，在查询 API 和支付通知中原样返回，可作为自定义参数使用，实际情况下只有支付完成状态才会返回该字段。 |                                                              |
| service\_amount            | integer | 手续费                                                      |                                                              |
| service\_amount\_currency  | string  | 手续费币种                                                    |                                                              |
| handle\_status             | integer | 处理状态                                                     | 1待处理 2处理中 3已处理 4待验证                                          |
| status                     | integer | 状态                                                       | 1 未支付 2 支付成功 3 转入退款 4 已关闭                                    |
| currency                   | object  | 支付币种详情                                                   |                                                              |
| currency.network           | string  | 网络                                                       | 示例值：`TRX`、`TRC10`、`TRC20`、`TRC721`、`TRC1155`、`ERC20`、`BEP20` |
| currency.chain             | string  | 所属公链                                                     | 示例值：`TRON`、`ETHEREUM`、`BSC`                                  |
| currency.code              | string  | 币种代码                                                     |                                                              |
| currency.currency          | string  | 币种                                                       |                                                              |
| currency.name              | string  | 名称                                                       |                                                              |
| currency.contract\_address | string  | 合约地址                                                     |                                                              |
| currency.decimal           | integer | 精度                                                       |                                                              |

#### 交易通知详情 <a href="#jiao-yi-tong-zhi-xiang-qing" id="jiao-yi-tong-zhi-xiang-qing"></a>

{% hint style="info" %}
说明

TransactionNotifyDetail
{% endhint %}

| 名称                | 类型             | 说明                                                       | 示例                            |
| ----------------- | -------------- | -------------------------------------------------------- | ----------------------------- |
| out\_trade\_no    | string         | 商户订单号                                                    |                               |
| transaction\_id   | string         | 平台订单号                                                    |                               |
| description       | string         | 订单描述（utf8-mb4）                                           |                               |
| block\_no         | integer        | 区块号，也可以通过这个查询区块 hash                                     |                               |
| create\_time      | integer        | 订单创建时间                                                   |                               |
| block\_time       | integer        | 区块时间                                                     |                               |
| pay\_time         | integer        | 支付时间(成功才有)                                               |                               |
| tx\_id            | string         | 交易 hash                                                  |                               |
| from\_address     | string         | 支付地址                                                     |                               |
| contract\_address | string         | 合约地址                                                     |                               |
| to\_address       | string         | 资金转入地址                                                   |                               |
| amount            | integer        | 订单金额                                                     |                               |
| decimals          | integer        | 订单金额精度                                                   |                               |
| currency          | CurrencyDetail | 币种详情                                                     |                               |
| pay\_amount       | integer        | 实际支付金额                                                   |                               |
| pay\_decimal      | integer        | 实际支付金额精度                                                 |                               |
| pay\_currency     | string         | 实际支付币种                                                   |                               |
| pay\_chain        | string         | 实际支付公链 TRON、ETHEREUM、BSC                                 |                               |
| attach            | string         | 附加数据，在查询 API 和支付通知中原样返回，可作为自定义参数使用，实际情况下只有支付完成状态才会返回该字段。 |                               |
| handle\_status    | integer        | 处理状态                                                     | 1`待处理` 2`处理中` 3`已处理` 4`待验证`   |
| status            | integer        | 状态                                                       | 1`未支付` 2`支付成功` 3`转入退款` 4`已关闭` |
| sign              | string         | 签名                                                       |                               |
| price\_rate       | folat          | 汇率                                                       |                               |

#### 代付交易详情 <a href="#dai-fu-jiao-yi-xiang-qing" id="dai-fu-jiao-yi-xiang-qing"></a>

{% hint style="info" %}
说明

PayAnotherTransactionDetail
{% endhint %}

| 名称                         | 类型      | 说明       | 说明                                                                           |
| -------------------------- | ------- | -------- | ---------------------------------------------------------------------------- |
| out\_trade\_no             | string  | 商户订单号    | 示例值：`fb72xxxx-xxxx-xxxx-xxxx-xxxx8a7b52cb`                                   |
| transaction\_id            | string  | 平台订单号    | 示例值：`e98b30294xxxxxxxxxxxx97a9d9e09ce`                                       |
| trade\_type                | string  | 交易类型     | DAPP、TRANSFER、API                                                            |
| description                | string  | 订单描述     | 示例值：`充值`                                                                     |
| block\_no                  | integer | 区块号      | 示例值：`33215220`                                                               |
| create\_time               | integer | 订单创建时间   | 示例值：`1673407302044`                                                          |
| block\_time                | integer | 区块时间     | 示例值：`1673407329000`                                                          |
| pay\_time                  | integer | 支付时间     | 示例值：`1673407329000`                                                          |
| tx\_id                     | string  | 交易 hash  | 示例值：`9fdf0ab5823e23225f93bcc644af30a6ab83b6583a8e29e359ee80219802a33a`       |
| from\_address              | string  | 支付地址     | 示例值：`TULRFYoFuEmUbxxxxxxxx8nQYFHJ88888`                                      |
| contract\_address          | string  | 合约地址     | 示例值：`TR7NHqjeKQxGTxxxxxxxxpL8otSzgjLj6t`                                     |
| to\_address                | string  | 收款地址     | 示例值：`TQjxEW2Z3p9wjoxxxxxxxxgJUrWXBun91w`                                     |
| amount                     | number  | 订单金额     | 示例值：`15000000`                                                               |
| pay\_chain                 | integer | 实际支付公链   | 示例值：`TRON`、`ETHEREUM`、`BSC`[查看支持公链](/chinese/huo-bi/cha-xun-bi-zhong-xin-xi) |
| decimals                   | integer | 代币精度     | 示例值：`6`                                                                      |
| pay\_network               | string  | 类型       | 示例值：TRX、TRC10、TRC20、TRC721、TRC1155、ERC20、BEP20                               |
| pay\_currency              | string  | 实际支付币种   |                                                                              |
| pay\_amount                | integer | 实际支付金额   |                                                                              |
| pay\_decimal               | integer | 实际支付金额精度 |                                                                              |
| attach                     | string  | 自定义参数    | 在查询 API 和支付通知中原样返回，可作为自定义参数使用，实际情况下只有支付完成状态才会返回该字段                           |
| service\_amount            | number  | 手续费      | 示例值：`45000`                                                                  |
| service\_rate              | folat   | 服务费费率    |                                                                              |
| service\_amount\_currency  | string  | 手续费      | 示例值：`USDT`                                                                   |
| status                     | integer | 状态       | 示例值：`1`未支付 `2`支付成功 `3`转入退款 `4`已关闭                                            |
| handle\_status             | integer | 处理状态     | 示例值：`1`待处理 `2`处理中 `3`已处理 `4`待验证                                              |
| currency                   | object  | 支付代币     |                                                                              |
| currency.network           | string  | 网络       | 示例值：`TRX`、`TRC10`、`TRC20`、`TRC721`、`TRC1155`、`ERC20`、`BEP20`                 |
| currency.chain             | string  | 所属公链     | 示例值：`TRON`、`ETHEREUM`、`BSC`                                                  |
| currency.code              | string  | 币种代码     |                                                                              |
| currency.currency          | string  | 币种       |                                                                              |
| currency.name              | string  | 名称       |                                                                              |
| currency.contract\_address | string  | 合约地址     |                                                                              |
| currency.decimal           | integer | 精度       |                                                                              |

#### 商户余额

{% hint style="info" %}
说明

merchantBalance
{% endhint %}

| 名称           | 类型      | 说明    | 说明                                                           |
| ------------ | ------- | ----- | ------------------------------------------------------------ |
| merchant\_id | integer | 商家 ID | 示例值：`1234567890`                                             |
| mch\_id      | string  | 商户 ID | 示例值：`12345678`                                               |
| network      | string  | 网络    | 示例值：`TRX`、`TRC10`、`TRC20`、`TRC721`、`TRC1155`、`ERC20`、`BEP20` |
| chain        | string  | 所属公链  | 示例值：`TRON`、`ETHEREUM`、`BSC`                                  |
| balance      | string  | 余额    |                                                              |
| currency     | string  | 币种    |                                                              |
| decimal      | integer | 精度    |                                                              |
| create\_time | integer | 创建时间  | 示例值：`1673333676`                                             |
| modify\_time | integer | 修改时间  | 示例值：`1673333676`                                             |
| cash\_time   | integer | 提现时间  | 示例值：`1673333676`                                             |


# 货币


# 查询币种信息

{% hint style="info" %}
说明

可查询平台所支持的所有支付币种
{% endhint %}

### 接口地址 <a href="#jie-kou-di-zhi" id="jie-kou-di-zhi"></a>

```
GET https://api.tokenpay.me/v1/currency/index
```

### 接口参数 <a href="#jie-kou-can-shu" id="jie-kou-can-shu"></a>

无

### 接口返回 <a href="#jie-kou-fan-hui" id="jie-kou-fan-hui"></a>

| 名称          | 类型      | 说明                                                                      | 说明                           |
| ----------- | ------- | ----------------------------------------------------------------------- | ---------------------------- |
| code        | integer | [业务状态码](/chinese/cuo-wu-ma/ye-wu-zhuang-tai-ma)                         | 业务状态码 0 成功 非 0 表示具体原因参考`msg` |
| msg         | string  | 状态业务消息                                                                  | 状态业务消息                       |
| request\_id | string  | 请求 ID                                                                   | 请求 ID                        |
| data        | array   | [CurrencyDetail](/chinese/shuo-ming/shu-ju-jie-gou#bi-zhong-xiang-qing) | 内容                           |

### 返回示例 <a href="#fan-hui-shi-li" id="fan-hui-shi-li"></a>

{% code overflow="wrap" %}

```json
{
    "code": 0,
    "msg": "ok",
    "request_id": "a4b4460f-4e47-4492-848c-ccd25540db2d",
    "data": [
        {
            "network": "BNB",
            "chain": "BSC",
            "code": "BINANCE_BNB",
            "currency": "BNB",
            "name": "Binance Coin",
            "logo": "https://xxx/binance_busd.png",
            "contract_address": "",
            "decimal": 18,
            "payment_qr_code": 1,
            "payment_connect_wallet": 1,
            "payment_tron_link": 0,
            "min_payment_amount": "0",
            "max_payment_amount": "0"
        },
        {
            "network": "BEP20",
            "chain": "BSC",
            "code": "BINANCE_BUSD",
            "currency": "BUSD",
            "name": "Binance USD",
            "logo": "https://xxx/binance_busd.png",
            "contract_address": "0xe9e7CEA3DedcA5984780Bafc599bD69ADd087D56",
            "decimal": 18,
            "payment_qr_code": 1,
            "payment_connect_wallet": 1,
            "payment_tron_link": 0,
            "min_payment_amount": "0",
            "max_payment_amount": "0"
        }
    ]
}
```

{% endcode %}

### 代码示例 <a href="#dai-ma-shi-li" id="dai-ma-shi-li"></a>

{% tabs %}
{% tab title="Shell" %}

{% code overflow="wrap" %}

```sh
curl --location --request GET 'https://api.tokenpay.me/v1/currency/index' \
--header 'Authorization: <Authorization>' \
--header 'User-Agent: tokenpay.me Client/1.0.0 (https://api.tokenpay.me)' \
--header 'Content-Type: application/json' \
--data-raw '<body data here>'
```

{% endcode %}
{% endtab %}

{% tab title="Go" %}

{% code overflow="wrap" %}

```go
package main

import (
   "fmt"
   "strings"
   "net/http"
   "io/ioutil"
)

func main() {

   url := "https://api.tokenpay.me/v1/currency/index"
   method := "GET"

   payload := strings.NewReader(`<body data here>`)

   client := &http.Client {
   }
   req, err := http.NewRequest(method, url, payload)

   if err != nil {
      fmt.Println(err)
      return
   }
   req.Header.Add("Authorization", "<Authorization>")
   req.Header.Add("User-Agent", "tokenpay.me Client/1.0.0 (https://api.tokenpay.me)")
   req.Header.Add("Content-Type", "application/json")

   res, err := client.Do(req)
   if err != nil {
      fmt.Println(err)
      return
   }
   defer res.Body.Close()

   body, err := ioutil.ReadAll(res.Body)
   if err != nil {
      fmt.Println(err)
      return
   }
   fmt.Println(string(body))
}
```

{% endcode %}
{% endtab %}

{% tab title="PHP" %}

{% code overflow="wrap" %}

```php
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
   CURLOPT_URL => 'https://api.tokenpay.me/v1/currency/index',
   CURLOPT_RETURNTRANSFER => true,
   CURLOPT_ENCODING => '',
   CURLOPT_MAXREDIRS => 10,
   CURLOPT_TIMEOUT => 0,
   CURLOPT_FOLLOWLOCATION => true,
   CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
   CURLOPT_CUSTOMREQUEST => 'GET',
   CURLOPT_POSTFIELDS =>'<body data here>',
   CURLOPT_HTTPHEADER => array(
      'Authorization: <Authorization>',
      'User-Agent: tokenpay.me Client/1.0.0 (https://api.tokenpay.me)',
      'Content-Type: application/json'
   ),
));

$response = curl_exec($curl);

curl_close($curl);
echo $response;
```

{% endcode %}

<br>
{% endtab %}

{% tab title="Python" %}

{% code overflow="wrap" %}

```python
import http.client
import json

conn = http.client.HTTPSConnection("api.tokenpay.me")
payload = "<body data here>"
headers = {
   'Authorization': '<Authorization>',
   'User-Agent': 'tokenpay.me Client/1.0.0 (https://api.tokenpay.me)',
   'Content-Type': 'application/json'
}
conn.request("GET", "/v1/currency/index", payload, headers)
res = conn.getresponse()
data = res.read()
print(data.decode("utf-8"))
```

{% endcode %}
{% endtab %}

{% tab title="Java" %}

{% code overflow="wrap" %}

```java
OkHttpClient client = new OkHttpClient().newBuilder()
   .build();
MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "<body data here>");
Request request = new Request.Builder()
   .url("https://api.tokenpay.me/v1/currency/index")
   .method("GET", body)
   .addHeader("Authorization", "<Authorization>")
   .addHeader("User-Agent", "tokenpay.me Client/1.0.0 (https://api.tokenpay.me)")
   .addHeader("Content-Type", "application/json")
   .build();
Response response = client.newCall(request).execute();
```

{% endcode %}
{% endtab %}
{% endtabs %}


# 余额查询

{% hint style="info" %}
说明

查询余额详情以及实时状态
{% endhint %}

## **接口地址** <a href="#jie-kou-di-zhi" id="jie-kou-di-zhi"></a>

```
POST https://api.tokenpay.me/v1/merchant/balance
```

## **接口参数**

| 名称       | 位置   | 类型     | 必选 | 说明                                                             |
| -------- | ---- | ------ | -- | -------------------------------------------------------------- |
| mch\_id  | body | string | 是  | 商户 ID，示例值：`12345678`                                           |
| chain    | body | string | 是  | 所属公链，示例值：`TRON`                                                |
| currency | body | string | 是  | 币种，示例值：`TRX` [查看支持币种](/chinese/huo-bi/cha-xun-bi-zhong-xin-xi) |

## **接口返回**

| 名称          | 类型      | 说明                                                                  | 说明                           |
| ----------- | ------- | ------------------------------------------------------------------- | ---------------------------- |
| code        | integer | [业务状态码](https://ttpay.gitbook.io/api/cuo-wu-ma/ye-wu-zhuang-tai-ma) | 业务状态码 0 成功 非 0 表示具体原因参考`msg` |
| msg         | string  | 状态业务消息                                                              | 状态业务消息                       |
| request\_id | string  | 请求 ID                                                               | 请求 ID                        |
| data        | array   | [merchantBalance](/chinese/shuo-ming/shu-ju-jie-gou#shang-hu-yu-e)  | 内容                           |

## **返回示例**

```json
{
    "code": 0,
    "msg": "ok",
    "request_id": "08250916-a677-4a36-a090-323807ac644c",
    "data": {
     "merchant_id": 167,
        "mch_id": "12345678",
        "network": "TRC20",
        "chain": "TRON",
        "balance": "54670000",
        "currency": "USDT",
        "decimal": 6,
        "create_time": 1724237814113,
        "modify_time": 1724239248394,
        "cash_time": 0
    }
}
```

## **代码示例**

{% tabs %}
{% tab title="Shell" %}

```sh
curl --location --request GET 'https://api.tokenpay.me/v1/merchant/balance
--header 'Authorization: '
--header 'User-Agent: Tokenpay API (https://tokenpay.me)'
--header 'Content-Type: application/json'
--data-raw ''
```

{% endtab %}

{% tab title="Go" %}

```go
package main

import (
   "fmt"
   "strings"
   "net/http"
   "io/ioutil"
)

func main() {

   url := "https://api.tokenpay.me/v1/merchant/balance"
   method := "GET"

   payload := strings.NewReader(`<body data here>`)

   client := &http.Client {
   }
   req, err := http.NewRequest(method, url, payload)

   if err != nil {
      fmt.Println(err)
      return
   }
   req.Header.Add("Authorization", "<Authorization>")
   req.Header.Add("User-Agent", "Tokenpay API (https://tokenpay.me)")
   req.Header.Add("Content-Type", "application/json")

   res, err := client.Do(req)
   if err != nil {
      fmt.Println(err)
      return
   }
   defer res.Body.Close()

   body, err := ioutil.ReadAll(res.Body)
   if err != nil {
      fmt.Println(err)
      return
   }
   fmt.Println(string(body))
}
```

{% endtab %}

{% tab title="PHP" %}

```php
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
   CURLOPT_URL => 'https://api.tokenpay.me/v1/merchant/balance',
   CURLOPT_RETURNTRANSFER => true,
   CURLOPT_ENCODING => '',
   CURLOPT_MAXREDIRS => 10,
   CURLOPT_TIMEOUT => 0,
   CURLOPT_FOLLOWLOCATION => true,
   CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
   CURLOPT_CUSTOMREQUEST => 'GET',
   CURLOPT_POSTFIELDS =>'<body data here>',
   CURLOPT_HTTPHEADER => array(
      'Authorization: <Authorization>',
      'User-Agent: Tokenpay API (https://api.tokenpay.me)',
      'Content-Type: application/json'
   ),
));

$response = curl_exec($curl);

curl_close($curl);
echo $response;
```

{% endtab %}

{% tab title="Python" %}

```python
import http.client
import json

conn = http.client.HTTPSConnection("https://api.tokenpay.io")
payload = "<body data here>"
headers = {
   'Authorization': '<Authorization>',
   'User-Agent': 'TokenpayAPI (https://tokenpay.io)',
   'Content-Type': 'application/json'
}
conn.request("GET", "/v1/merchant/balance", payload, headers)
res = conn.getresponse()
data = res.read()
print(data.decode("utf-8"))
```

{% endtab %}

{% tab title="Java" %}

```java
OkHttpClient client = new OkHttpClient().newBuilder()
   .build();
MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "<body data here>");
Request request = new Request.Builder()
   .url("https://api.tokenpay.me/v1/merchant/balance")
   .method("GET", body)
   .addHeader("Authorization", "<Authorization>")
   .addHeader("User-Agent", "Tokenpay API (https://tokenpay.io)")
   .addHeader("Content-Type", "application/json")
   .build();
Response response = client.newCall(request).execute();
```

{% endtab %}
{% endtabs %}


# 支付订单


# 创建订单

{% hint style="info" %}
说明

创建订单后接口会返回收款链接，用户通过链接进入收银台进行支付。

若商户设置了白标应用，前端代码还需接入JS-SDK，查看[SDK](https://www.npmjs.com/package/@ttpay/payment_modal)
{% endhint %}

### 接口地址 <a href="#jie-kou-di-zhi" id="jie-kou-di-zhi"></a>

```
POST https://api.tokenpay.me/v1/transaction/prepayment
```

### 接口参数 <a href="#jie-kou-can-shu" id="jie-kou-can-shu"></a>

| 名称             | 位置     | 类型      | 必选 | 说明                                                                         |
| -------------- | ------ | ------- | -- | -------------------------------------------------------------------------- |
| app\_id        | header | string  | 是  | 应用 ID，示例值：`8e4b8c2e7cxxxxxxxx1a1cbd3d59e0bd`                               |
| mch\_id        | body   | string  | 是  | 商户 ID，示例值：`12345678`                                                       |
| description    | body   | string  | 否  | 订单描述，示例值：`充值`                                                              |
| out\_trade\_no | body   | string  | 是  | 商户订单号，商家自行生成唯一订单号                                                          |
| expire\_second | body   | integer | 是  | 有效期(秒)，示例值：`3600`                                                          |
| amount         | body   | number  | 是  | 订单金额，示例值：`15000000`                                                        |
| chain          | body   | string  | 是  | 所属公链，示例值：`TRON`                                                            |
| currency       | body   | string  | 是  | 币种，示例值：`TRX` [查看支持币种](/chinese/huo-bi/cha-xun-bi-zhong-xin-xi)             |
| to\_address    | body   | string  | 否  | 收款钱包（注：收款钱包为`监听订单`的应用必填）                                                   |
| attach         | body   | string  | 否  | 自定义参数(如用户ID等唯一标识)，在查询 API 和支付通知中原样返回，实际情况下只有支付完成状态才会返回该字段                  |
| locale         | body   | string  | 否  | 语言：`zh_cn`中文、 `en`英文，使用收银台将根据此设置显示默认语言。                                    |
| notify\_url    | body   | string  | 否  | 回调地址，示例值：`https://xxx/xxx` [建议使用 https](/chinese/shuo-ming/an-quan-xu-zhi) |
| return\_url    | body   | string  | 否  | 返回地址，当支付完成或失败，点击返回按钮的地址，可以是 https 或 app 的路由。                               |
| order\_type    | body   | string  | 是  | 支付方式，示例值：`platform_order` 平台代收                                             |

#### 参数示例 <a href="#can-shu-shi-li" id="can-shu-shi-li"></a>

```json
{
  "app_id": "d549a3ac0e4641f998c6675fc539ba21",
  "mch_id": "12345678",
  "description": "充值",
  "out_trade_no": "fb72xxxx-xxxx-xxxx-xxxx-xxxx8a7b52cb",
  "expire_second": 600,
  "amount": 9,
  "chain": "TRON",
  "currency": "USDT",
  "to_address": "TQjxEW2Z3p9wjoxxxxxxxxgJUrWXBun91w",
  "attach": "anim dolore",
  "locale": "zh_cn",
  "notify_url": "https://xxx/xxx",
  "return_url": "https://xxxx/xxx?id=xxxx",
  "order_type": "platform_order"
}
```

{% hint style="info" %}
说明

app\_id 可通过商户后台创建应用获取。
{% endhint %}

### 接口返回 <a href="#jie-kou-fan-hui" id="jie-kou-fan-hui"></a>

| 名称           | 类型      | 说明                                              | 说明                                                                                        |
| ------------ | ------- | ----------------------------------------------- | ----------------------------------------------------------------------------------------- |
| code         | integer | [业务状态码](/chinese/cuo-wu-ma/ye-wu-zhuang-tai-ma) |                                                                                           |
| msg          | string  | 状态描述                                            |                                                                                           |
| request\_id  | string  | 请求 ID                                           |                                                                                           |
| data         | object  | 数据对象                                            |                                                                                           |
| prepay\_id   | string  | 预支付 ID                                          | 预支付交易会话标识。用于后续接口调用中使用，该值有效期为创建订单时设置的 `expire_second` 参数，也可直接访问`payment_url`完成支付           |
| payment\_url | string  | 支付收银台 URL                                       | `payment_url`为拉起支付收银台的中间页面，可通过访问该 url 完成支付，`payment_url`的有效期为创建订单时设置的 `expire_second` 参数。 |

### 返回示例 <a href="#fan-hui-shi-li" id="fan-hui-shi-li"></a>

{% code overflow="wrap" %}

```json
{
    "code": 0,
    "msg": "ok",
    "request_id": "9b9e08ab-48e5-4efa-83e7-97e5e3fe3d0c",
    "data": {
        "prepay_id": "15809074c5bbc36bce27exxxxxxxxxxxxxxxxxxxxa4ca0a281d7e1260624a1c2",
        "payment_url": "/pay/order?prepay_id=15809074c5bbc36bce27exxxxxxxxxxxxxxxxxxxxa4ca0a281d7e1260624a1c2"
    }
}
```

{% endcode %}

### 代码示例 <a href="#dai-ma-shi-li" id="dai-ma-shi-li"></a>

{% tabs %}
{% tab title="Shell" %}

{% code overflow="wrap" %}

```sh
curl --location --request POST 'https://api.tokenpay.me/v1/transaction/prepayment' \
--header 'Authorization: <Authorization>' \
--header 'User-Agent: tokenpay API (https://tokenpay.me)' \
--header 'Content-Type: application/json' \
--data-raw '<body data here>'
```

{% endcode %}
{% endtab %}

{% tab title="Go" %}

{% code overflow="wrap" %}

```go
package main

import (
   "fmt"
   "strings"
   "net/http"
   "io/ioutil"
)

func main() {

   url := "https://api.tokenpay.me/v1/transaction/prepayment"
   method := "POST"

   payload := strings.NewReader(`<body data here>`)

   client := &http.Client {
   }
   req, err := http.NewRequest(method, url, payload)

   if err != nil {
      fmt.Println(err)
      return
   }
   req.Header.Add("Authorization", "<Authorization>")
   req.Header.Add("User-Agent", "tokenpay API (https://tokenpay.me)")
   req.Header.Add("Content-Type", "application/json")

   res, err := client.Do(req)
   if err != nil {
      fmt.Println(err)
      return
   }
   defer res.Body.Close()

   body, err := ioutil.ReadAll(res.Body)
   if err != nil {
      fmt.Println(err)
      return
   }
   fmt.Println(string(body))
}
```

{% endcode %}
{% endtab %}

{% tab title="PHP" %}

{% code overflow="wrap" %}

```php
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
   CURLOPT_URL => 'https://api.tokenpay.me/v1/transaction/prepayment',
   CURLOPT_RETURNTRANSFER => true,
   CURLOPT_ENCODING => '',
   CURLOPT_MAXREDIRS => 10,
   CURLOPT_TIMEOUT => 0,
   CURLOPT_FOLLOWLOCATION => true,
   CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
   CURLOPT_CUSTOMREQUEST => 'POST',
   CURLOPT_POSTFIELDS =>'<body data here>',
   CURLOPT_HTTPHEADER => array(
      'Authorization: <Authorization>',
      'User-Agent: tokenpay API (https://tokenpay.me)',
      'Content-Type: application/json'
   ),
));

$response = curl_exec($curl);

curl_close($curl);
echo $response;
```

{% endcode %}

<br>
{% endtab %}

{% tab title="Python" %}

{% code overflow="wrap" %}

```python
import http.client
import json

conn = http.client.HTTPSConnection("https://api.tokenpay.me")
payload = "<body data here>"
headers = {
   'Authorization': '<Authorization>',
   'User-Agent': 'tokenpay API (https://tokenpay.me)',
   'Content-Type': 'application/json'
}
conn.request("POST", "/v1/transaction/prepayment", payload, headers)
res = conn.getresponse()
data = res.read()
print(data.decode("utf-8"))
```

{% endcode %}
{% endtab %}

{% tab title="Java" %}

{% code overflow="wrap" %}

```java
OkHttpClient client = new OkHttpClient().newBuilder()
   .build();
MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "<body data here>");
Request request = new Request.Builder()
   .url("https://api.tokenpay.me/v1/transaction/prepayment")
   .method("POST", body)
   .addHeader("Authorization", "<Authorization>")
   .addHeader("User-Agent", "tokenpay API (https://tokenpay.me)")
   .addHeader("Content-Type", "application/json")
   .build();
Response response = client.newCall(request).execute();
```

{% endcode %}
{% endtab %}
{% endtabs %}


# 查询订单

{% hint style="info" %}
说明

查询支付订单详情以及实时状态
{% endhint %}

### 接口地址 <a href="#jie-kou-di-zhi" id="jie-kou-di-zhi"></a>

```
POST https://api.tokenpay.me/v1/transaction/query
```

### 接口参数 <a href="#jie-kou-can-shu" id="jie-kou-can-shu"></a>

| 名称              | 位置     | 类型     | 必选 | 说明                                           |
| --------------- | ------ | ------ | -- | -------------------------------------------- |
| out\_trade\_no  | query  | string | 否  | 商户订单号（`out_trade_no`和`transaction_id`至少传一个）  |
| transaction\_id | query  | string | 否  | 平台订单号（`out_trade_no`和`transaction_id`至少传一个）  |
| app\_id         | header | string | 是  | 应用 ID，示例值：`8e4b8c2e7cxxxxxxxx1a1cbd3d59e0bd` |
| mch\_id         | body   | string | 是  | 商户 ID，示例值：`12345678`                         |

### 接口返回 <a href="#jie-kou-fan-hui" id="jie-kou-fan-hui"></a>

| 名称          | 类型                                                                        | 必选    | 说明                                              |
| ----------- | ------------------------------------------------------------------------- | ----- | ----------------------------------------------- |
| code        | integer                                                                   | true  | [业务状态码](/chinese/cuo-wu-ma/ye-wu-zhuang-tai-ma) |
| msg         | string                                                                    | true  | 状态说明                                            |
| request\_id | string                                                                    | true  |                                                 |
| data        | [TransactionDetail](/chinese/shuo-ming/shu-ju-jie-gou#jiao-yi-xiang-qing) | false |                                                 |

### 返回示例 <a href="#fan-hui-shi-li" id="fan-hui-shi-li"></a>

{% code overflow="wrap" %}

```json
{
    "code": 0,
    "msg": "ok",
    "request_id": "08250916-a677-4a36-a090-323807ac644c",
    "data": {
        "out_trade_no": "fb722ca8-ed7b-444b-9f58-0b5c8a7b52cb",
        "transaction_id": "e98b3029477f4bdcb971797a9d9e09ce",
        "trade_state": "SUCCESS",
        "description": "充值",
        "block_no": 33215220,
        "create_time": 1673407302044,
        "block_time": 1673407329000,
        "expire_time": 1673407902044,
        "expire_second": 0,
        "pay_time": 1673407329000,
        "close_time": 0,
        "tx_id": "9fdf0ab5823e23225f93bcc644af30a6ab83b6583a8e29e359ee80219802a33a",
        "from_address": "TULRFYoFuEmUbxxxxxxxx8nQYFHJ88888",
        "contract_address": "",
        "to_address": "TQjxEW2Z3p9wjoxxxxxxxxgJUrWXBun91w",
        "amount": 15000000,
        "chain": "TRON",
        "decimals": 6,
        "attach": "anim dolore",
        "service_amount": 45000,
        "service_amount_currency": "USDT",
        "notify_url": "/console/callback/pay",
        "notify_num": 1,
        "notify_status": 2,
        "status": 2,
        "currency": {
            "type": "TRX",
            "chain": "TRON",
            "code": "TRON_TRX",
            "currency": "TRX",
            "name": "TRX",
            "sub_name": "TRON",
            "logo": "https://xxx/trx_busd.png",
            "contract_address": "",
            "decimal": 6,
        }
    }
}
```

{% endcode %}

### 代码示例 <a href="#dai-ma-shi-li" id="dai-ma-shi-li"></a>

{% tabs %}
{% tab title="Shell" %}

{% code overflow="wrap" %}

```sh
curl --location --request GET 'https://api.tokenpay.me/v1/transaction/query' \
--header 'Authorization: <Authorization>' \
--header 'User-Agent: tokenpay API (https://tokenpay.me)' \
--header 'Content-Type: application/json' \
--data-raw '<body data here>'
```

{% endcode %}
{% endtab %}

{% tab title="Go" %}

{% code overflow="wrap" %}

```go
package main

import (
   "fmt"
   "strings"
   "net/http"
   "io/ioutil"
)

func main() {

   url := "https://api.tokenpay.me/v1/transaction/query"
   method := "GET"

   payload := strings.NewReader(`<body data here>`)

   client := &http.Client {
   }
   req, err := http.NewRequest(method, url, payload)

   if err != nil {
      fmt.Println(err)
      return
   }
   req.Header.Add("Authorization", "<Authorization>")
   req.Header.Add("User-Agent", "tokenpay API (https://tokenpay.me)")
   req.Header.Add("Content-Type", "application/json")

   res, err := client.Do(req)
   if err != nil {
      fmt.Println(err)
      return
   }
   defer res.Body.Close()

   body, err := ioutil.ReadAll(res.Body)
   if err != nil {
      fmt.Println(err)
      return
   }
   fmt.Println(string(body))
}
```

{% endcode %}
{% endtab %}

{% tab title="PHP" %}

{% code overflow="wrap" %}

```php
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
   CURLOPT_URL => 'https://api.tokenpay.me/v1/transaction/query',
   CURLOPT_RETURNTRANSFER => true,
   CURLOPT_ENCODING => '',
   CURLOPT_MAXREDIRS => 10,
   CURLOPT_TIMEOUT => 0,
   CURLOPT_FOLLOWLOCATION => true,
   CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
   CURLOPT_CUSTOMREQUEST => 'GET',
   CURLOPT_POSTFIELDS =>'<body data here>',
   CURLOPT_HTTPHEADER => array(
      'Authorization: <Authorization>',
      'User-Agent: tokenpay API (https://tokenpay.meo)',
      'Content-Type: application/json'
   ),
));

$response = curl_exec($curl);

curl_close($curl);
echo $response;
```

{% endcode %}

<br>
{% endtab %}

{% tab title="Python" %}

{% code overflow="wrap" %}

```python
import http.client
import json

conn = http.client.HTTPSConnection("https://api.tokenpay.me")
payload = "<body data here>"
headers = {
   'Authorization': '<Authorization>',
   'User-Agent': 'tokenpay API (https://tokenpay.me)',
   'Content-Type': 'application/json'
}
conn.request("GET", "/v1/transaction/query", payload, headers)
res = conn.getresponse()
data = res.read()
print(data.decode("utf-8"))
```

{% endcode %}
{% endtab %}

{% tab title="Java" %}

{% code overflow="wrap" %}

```java
OkHttpClient client = new OkHttpClient().newBuilder()
   .build();
MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "<body data here>");
Request request = new Request.Builder()
   .url("https://api.tokenpay.me/v1/transaction/query")
   .method("GET", body)
   .addHeader("Authorization", "<Authorization>")
   .addHeader("User-Agent", "tokenpay API (https://tokenpay.me)")
   .addHeader("Content-Type", "application/json")
   .build();
Response response = client.newCall(request).execute();
```

{% endcode %}
{% endtab %}
{% endtabs %}


# 回调通知

{% hint style="info" %}
说明

支付完成后，支付中心会把相关支付结果和相关信息发送给商户，商户需要接收处理，并返回应答。 对后台通知交互时，如果支付中心收到商户的应答不是成功或超时，支付中心则认为通知失败，会在一定的策略定期重新发起通知，尽可能提高通知的成功率，但不保证通知最终能成功。 （通知频率为0s/15s/30s/3m/10m/20m/30m/60m/3h/6h）
{% endhint %}

{% hint style="warning" %}
注意

注意：同样的通知可能会多次发送给商户系统。商户系统必须能够正确处理重复的通知。 推荐的做法是，当收到通知进行处理时，首先检查对应业务数据的状态，判断该通知是否已经处理过，如果没有处理过再进行处理，如果处理过直接返回结果成功。在对业务数据进行状态检查和处理之前，要采用数据锁进行并发控制，以避免函数重入造成的数据混乱。
{% endhint %}

{% hint style="danger" %}
警告

特别提醒：商户系统对于订单回调的内容一定要做签名验证，并校验返回的订单金额是否与商户侧的订单金额一致，防止数据泄漏导致出现“假通知”，造成资金损失。
{% endhint %}

### 接口地址 <a href="#jie-kou-di-zhi" id="jie-kou-di-zhi"></a>

```
POST 统一下单接口提交的参数notify_url设置，如果无法访问链接，您的业务系统将无法接收到支付中心的通知。
```

### 请求Body <a href="#qing-qiu-body" id="qing-qiu-body"></a>

| 名称               | 类型     | 说明                                                                                                                                               | 说明 |
| ---------------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------ | -- |
| app\_id          | string | 应用ID                                                                                                                                             |    |
| mch\_id          | string | 商户ID                                                                                                                                             |    |
| create\_time     | time   | 通知时间                                                                                                                                             |    |
| resource\_type   | string | 通知的资源数据类型，支付成功通知为encrypt-resource                                                                                                                |    |
| event\_type      | string | 通知的类型，支付成功通知的类型为TRANSACTION.SUCCESS                                                                                                              |    |
| resource         | object | 通知资源数据                                                                                                                                           |    |
| » original\_type | string | 原始回调类型，为transaction                                                                                                                              |    |
| » algorithm      | string | 对开启结果数据进行加密的加密算法，目前只支持AES-256-ECB                                                                                                                |    |
| » ciphertext     | string | Base64编码后的开启/停用结果数据密文，如果开启将返回加密后的内容，解密后是[交易通知详情 TransactionNotifyDetail](/chinese/shuo-ming/shu-ju-jie-gou#jiao-yi-tong-zhi-xiang-qing)的json字符串。 |    |
| » nonce          | string | 加密使用的随机串                                                                                                                                         |    |

### 请求示例 <a href="#qing-qiu-shi-li" id="qing-qiu-shi-li"></a>

{% code overflow="wrap" %}

```json
{
	"app_id": "xxxxx",
	"mch_id": "zzzzzz",
	"create_time": "2023-06-26T17:21:17.754429+08:00",
	"resource_type": "encrypt-resource",
	"event_type": "TRANSACTION.SUCCESS",
	"resource": {
		"original_type": "transaction",
		"algorithm": "AEAD_AES_256_GCM",
		"ciphertext": "I/psKgdkVwxbkEIWtwRxfxLzViuRS+gJTQSdLf+lmK7awoqUcIJisTAJx0Qbv4K6wV8WgyMRFYHD5CCLKmFNU2OnmEm2f2vGhaoS2h28A9BEGx1CWEUw3tfldf/+VWlBAnIBylFjHzbSo7fgn7S3fFEAZHTxoy+9jNIoynqHZbn4Y6eucj1YCw0ZmuKHPpPPrvclbhHmaZHfau+SKyag3C0/cj7zu4mBkRZ39zuk9B7DAADzaRENOZ/ZyibU+zs3gibnCbI2NWEnQWIiCi7vK0jq/FCBWytHihQM364zlVrPPCBDbv2MSqk4fyAM7IDeT6h/z/2kmDOQ6aFPYlLojIkgCCOIevQITS9E+BS1rgmmH+DRKsJNiD257aLhX2/F53VEnjfqqKdDs2lqfX0dCMLqselGUT981fFKceXg+r6hQqcUzLlF28XL5NrfVPreRDo6jI2K0tCy9cOx+cxH3yoDzOFBzM0RlxWqvUhRsMv9ZGfpgCZ0o9HxNObqLjVCQzE5SWPXvmkw+QpWk0oNUvpCEDhj9Vfq6XCV8j3tT3tZTYCa5UQy9VCdmval/2vb50QaAgDYXU6PH/9Xv7AXg6kg29iK+Ec0euxZxosRoVczzRg+0Arl/zvBcphWNIUTdx5IcA12WtP+krk9NNGtj7igk21DhcseJrKBpG7ll9O/Wmq1L8BwW+ypuJS+kHV61jRNYMFJY48Pt11Zoukgqu94kzrhz+KET8q463zlyu/Kp2z5yWI8xwvOtuyjosszfm6/YFQTFdhcmHY3X1yz44NaVG9FPev1QPoPmI7K3Jqa0Q8Q5kQTbe/KrB0eyRpXtyAaShOEeiS2ypmFAC81/m4mjuTd24yAjBcTIfBYzjxwjPbKfv+OYKahDwJP1b7EhsM+Sgu48wQ+pp6wc8TYCOkiRR1pKeb3kaxpQGzlq7VNbWHFPw9TDiyCIEnr8T5eiJtzJJ0U0iIfqN5WHk7iHiNK4Y4TvmdF4f6UyeMTHvaprvzUZI8il5wvoCgIiRUY7qvv5V/KL4ZWHN6Y3EEvQmP4WDo3Wx5IFW8C1gkyFv8lQ1COSNYMPog6RLAI0rNvKZjvc4baWwcHmk/fM92X19F2Y0DArqLFFUTJVE5bUQXQexiUO1e8IL07wqY=",
		"nonce": "d8816e8d6dca4409b790a4bcaa25c621"
	}
}
```

{% endcode %}

### 返回示例 <a href="#fan-hui-shi-li" id="fan-hui-shi-li"></a>

```
success
```

成功收到回调请求后请返回 `success` 以告知通知服务器。当通知服务器收到 `success` 后，将停止通知。否则将会按照 0s/15s/30s/3m/10m/20m/30m/60m/3h/6h 的频率通知10次。


# 关闭订单

{% hint style="info" %}
说明

用于用户手动取消订单或商家取消订单
{% endhint %}

### 接口地址 <a href="#jie-kou-di-zhi" id="jie-kou-di-zhi"></a>

```
POST https://api.tokenpay.me/v1/transaction/close
```

### 接口参数 <a href="#jie-kou-can-shu" id="jie-kou-can-shu"></a>

| 名称              | 位置     | 类型     | 必选 | 说明                                           |
| --------------- | ------ | ------ | -- | -------------------------------------------- |
| app\_id         | header | string | 是  | 应用 ID，示例值：`8e4b8c2e7cxxxxxxxx1a1cbd3d59e0bd` |
| mch\_id         | body   | string | 是  | 商户 ID，示例值：`12345678`                         |
| transaction\_id | body   | string | 否  | 平台订单号，示例值：`2a1cfa6568xxxxxxxx3050957024c559` |

#### 参数示例 <a href="#can-shu-shi-li" id="can-shu-shi-li"></a>

```json
{
  "app_id": "8e4b8c2e7cxxxxxxxx1a1cbd3d59e0bd",
  "mch_id": "12345678",
  "transaction_id": "2a1cfa6568xxxxxxxx3050957024c559"
}
```

### 接口返回 <a href="#jie-kou-fan-hui" id="jie-kou-fan-hui"></a>

| 名称          | 类型      | 说明                                              | 说明   |
| ----------- | ------- | ----------------------------------------------- | ---- |
| code        | integer | [业务状态码](/chinese/cuo-wu-ma/ye-wu-zhuang-tai-ma) | none |
| msg         | string  | 状态描述                                            | none |
| request\_id | string  | 请求 ID                                           | none |

### 返回示例 <a href="#fan-hui-shi-li" id="fan-hui-shi-li"></a>

```json
{
  "code": 0,
  "msg": "成功",
  "request_id": "f23ade4a-e5ca-48f4-a4bb-59114ac360ba",
}
```

### 代码示例 <a href="#dai-ma-shi-li" id="dai-ma-shi-li"></a>

{% tabs %}
{% tab title="Shell" %}

{% code overflow="wrap" %}

```sh
curl --location --request POST 'https://api.tokenpay.me/v1/transaction/close' \
--header 'Authorization: <Authorization>' \
--header 'User-Agent: tokenpay API (https://tokenpay.me)' \
--header 'Content-Type: application/json' \
--data-raw '<body data here>'
```

{% endcode %}
{% endtab %}

{% tab title="Go" %}

```go
package main

import (
   "fmt"
   "strings"
   "net/http"
   "io/ioutil"
)

func main() {

   url := "https://api.tokenpay.me/v1/transaction/close"
   method := "POST"

   payload := strings.NewReader(`<body data here>`)

   client := &http.Client {
   }
   req, err := http.NewRequest(method, url, payload)

   if err != nil {
      fmt.Println(err)
      return
   }
   req.Header.Add("Authorization", "<Authorization>")
   req.Header.Add("User-Agent", "tokenpay API (https://tokenpay.me)")
   req.Header.Add("Content-Type", "application/json")

   res, err := client.Do(req)
   if err != nil {
      fmt.Println(err)
      return
   }
   defer res.Body.Close()

   body, err := ioutil.ReadAll(res.Body)
   if err != nil {
      fmt.Println(err)
      return
   }
   fmt.Println(string(body))
}
```

{% endtab %}

{% tab title="PHP" %}

```php
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
   CURLOPT_URL => 'https://api.tokenpay.me/v1/transaction/close',
   CURLOPT_RETURNTRANSFER => true,
   CURLOPT_ENCODING => '',
   CURLOPT_MAXREDIRS => 10,
   CURLOPT_TIMEOUT => 0,
   CURLOPT_FOLLOWLOCATION => true,
   CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
   CURLOPT_CUSTOMREQUEST => 'POST',
   CURLOPT_POSTFIELDS =>'<body data here>',
   CURLOPT_HTTPHEADER => array(
      'Authorization: <Authorization>',
      'User-Agent: token API (https://tokenpay.me)',
      'Content-Type: application/json'
   ),
));

$response = curl_exec($curl);

curl_close($curl);
echo $response;
```

<br>
{% endtab %}

{% tab title="Python" %}

```python
import http.client
import json

conn = http.client.HTTPSConnection("https://api.tokenpay.me")
payload = "<body data here>"
headers = {
   'Authorization': '<Authorization>',
   'User-Agent': 'tokenpay API (https://tokenpay.me)',
   'Content-Type': 'application/json'
}
conn.request("POST", "/v1/transaction/close", payload, headers)
res = conn.getresponse()
data = res.read()
print(data.decode("utf-8"))
```

{% endtab %}

{% tab title="Java" %}

```java
OkHttpClient client = new OkHttpClient().newBuilder()
   .build();
MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "<body data here>");
Request request = new Request.Builder()
   .url("https://api.tokenpay.me/v1/transaction/close")
   .method("POST", body)
   .addHeader("Authorization", "<Authorization>")
   .addHeader("User-Agent", "tokenpay API (https://tokenpay.me)")
   .addHeader("Content-Type", "application/json")
   .build();
Response response = client.newCall(request).execute();
```

{% endtab %}
{% endtabs %}


# 代付


# 查询代付订单

{% hint style="info" %}
说明

查询代付的订单信息
{% endhint %}

### 接口地址 <a href="#jie-kou-di-zhi" id="jie-kou-di-zhi"></a>

```
POST https://api.tokenpay.me/v1/payanother/query
```

### 接口参数 <a href="#jie-kou-can-shu" id="jie-kou-can-shu"></a>

| 名称              | 位置   | 类型     | 必选 | 说明                                           |
| --------------- | ---- | ------ | -- | -------------------------------------------- |
| app\_id         | body | string | 是  | 应用 ID，示例值：`8e4b8c2e7cxxxxxxxx1a1cbd3d59e0bd` |
| mch\_id         | body | string | 是  | 商户 ID，示例值：`12345678`                         |
| out\_trade\_no  | body | string | 否  | 商户订单号（`out_trade_no`和`transaction_id`至少传一个）  |
| transaction\_id | body | string | 否  | 平台订单号（`out_trade_no`和`transaction_id`至少传一个）  |

### 接口返回 <a href="#jie-kou-fan-hui" id="jie-kou-fan-hui"></a>

| 名称          | 类型                                                                                         | 必选    | 说明                                              |
| ----------- | ------------------------------------------------------------------------------------------ | ----- | ----------------------------------------------- |
| code        | integer                                                                                    | true  | [业务状态码](/chinese/cuo-wu-ma/ye-wu-zhuang-tai-ma) |
| msg         | string                                                                                     | true  | 状态说明                                            |
| request\_id | string                                                                                     | true  |                                                 |
| data        | [PayAnotherTransactionDetail](/chinese/shuo-ming/shu-ju-jie-gou#dai-fu-jiao-yi-xiang-qing) | false |                                                 |

### 返回示例 <a href="#fan-hui-shi-li" id="fan-hui-shi-li"></a>

{% code overflow="wrap" %}

```json
{
    "code": 0,
    "msg": "ok",
    "request_id": "08250916-a677-4a36-a090-323807ac644c",
    "data": {
        "out_trade_no": "fb722ca8-ed7b-444b-9f58-0b5c8a7b52cb",
        "transaction_id": "e98b3029477f4bdcb971797a9d9e09ce",
        "trade_state": "SUCCESS",
        "description": "充值",
        "block_no": 33215220,
        "create_time": 1673407302044,
        "block_time": 1673407329000,
        "expire_time": 1673407902044,
        "expire_second": 0,
        "pay_time": 1673407329000,
        "close_time": 0,
        "tx_id": "9fdf0ab5823e23225f93bcc644af30a6ab83b6583a8e29e359ee80219802a33a",
        "from_address": "TULRFYoFuEmUbxxxxxxxx8nQYFHJ88888",
        "contract_address": "",
        "to_address": "TQjxEW2Z3p9wjoxxxxxxxxgJUrWXBun91w",
        "amount": 15000000,
        "chain": "TRON",
        "decimals": 6,
        "attach": "anim dolore",
        "service_amount": 45000,
        "service_amount_currency": "USDT",
        "notify_url": "/console/callback/pay",
        "notify_num": 1,
        "notify_status": 2,
        "status": 2,
        "currency": {
            "type": "TRX",
            "chain": "TRON",
            "code": "TRON_TRX",
            "currency": "TRX",
            "name": "TRX",
            "sub_name": "TRON",
            "logo": "https://xxx/trx_busd.png",
            "contract_address": "",
            "decimal": 6,
        }
    }
}
```

{% endcode %}

### 代码示例 <a href="#dai-ma-shi-li" id="dai-ma-shi-li"></a>

{% tabs %}
{% tab title="Shell" %}

```sh
curl --location --request GET 'https://api.tokenpay.me/v1/payanother/query' \
--header 'Authorization: <Authorization>' \
--header 'User-Agent: tokenpay API (https://tokenpay.me)' \
--header 'Content-Type: application/json' \
--data-raw '<body data here>'
```

{% endtab %}

{% tab title="Go" %}

```go
package main

import (
   "fmt"
   "strings"
   "net/http"
   "io/ioutil"
)

func main() {

   url := "https://api.tokenpay.meo/v1/payanother/query"
   method := "GET"

   payload := strings.NewReader(`<body data here>`)

   client := &http.Client {
   }
   req, err := http.NewRequest(method, url, payload)

   if err != nil {
      fmt.Println(err)
      return
   }
   req.Header.Add("Authorization", "<Authorization>")
   req.Header.Add("User-Agent", "tokenpay API (https://tokenpay.me)")
   req.Header.Add("Content-Type", "application/json")

   res, err := client.Do(req)
   if err != nil {
      fmt.Println(err)
      return
   }
   defer res.Body.Close()

   body, err := ioutil.ReadAll(res.Body)
   if err != nil {
      fmt.Println(err)
      return
   }
   fmt.Println(string(body))
}
```

{% endtab %}

{% tab title="PHP" %}

```php
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
   CURLOPT_URL => 'https://api.tokenpay.me/v1/payanother/query',
   CURLOPT_RETURNTRANSFER => true,
   CURLOPT_ENCODING => '',
   CURLOPT_MAXREDIRS => 10,
   CURLOPT_TIMEOUT => 0,
   CURLOPT_FOLLOWLOCATION => true,
   CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
   CURLOPT_CUSTOMREQUEST => 'GET',
   CURLOPT_POSTFIELDS =>'<body data here>',
   CURLOPT_HTTPHEADER => array(
      'Authorization: <Authorization>',
      'User-Agent: tokenpay API (https://tokenpay.me)',
      'Content-Type: application/json'
   ),
));

$response = curl_exec($curl);

curl_close($curl);
echo $response;
```

<br>
{% endtab %}

{% tab title="Python" %}

```python
import http.client
import json

conn = http.client.HTTPSConnection("https://api.tokenpay.me")
payload = "<body data here>"
headers = {
   'Authorization': '<Authorization>',
   'User-Agent': 'tokenpay API (https://tokenpay.me)',
   'Content-Type': 'application/json'
}
conn.request("GET", "/v1/payanother/query", payload, headers)
res = conn.getresponse()
data = res.read()
print(data.decode("utf-8"))
```

{% endtab %}

{% tab title="Java" %}

```java
OkHttpClient client = new OkHttpClient().newBuilder()
   .build();
MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "<body data here>");
Request request = new Request.Builder()
   .url("https://api.tokenpay.me/v1/payanother/query")
   .method("GET", body)
   .addHeader("Authorization", "<Authorization>")
   .addHeader("User-Agent", "tokenpay API (https://tokenpay.me)")
   .addHeader("Content-Type", "application/json")
   .build();
Response response = client.newCall(request).execute();
```

{% endtab %}
{% endtabs %}


# 发起代付

{% hint style="info" %}
说明

发起代付订单
{% endhint %}

### 接口地址 <a href="#jie-kou-di-zhi" id="jie-kou-di-zhi"></a>

```
POST https://api.tokenpay.me/v1/payanother/payment
```

### 接口参数 <a href="#jie-kou-can-shu" id="jie-kou-can-shu"></a>

| 名称             | 位置   | 类型     | 必选 | 说明                                                                                |
| -------------- | ---- | ------ | -- | --------------------------------------------------------------------------------- |
| app\_id        | body | string | 是  | 应用 ID，示例值：`8e4b8c2e7cxxxxxxxx1a1cbd3d59e0bd`                                      |
| mch\_id        | body | string | 是  | 商户 ID，示例值：`12345678`                                                              |
| description    | body | string | 否  | 描述，示例值：`1234567890`                                                               |
| out\_trade\_no | body | string | 否  | 商户订单号（`out_trade_no`和`transaction_id`至少传一个）                                       |
| amount         | body | string | 是  | 代付金额                                                                              |
| chain          | body | string | 是  | 所属公链，示例值：`TRON`、`ETHEREUM`、`BSC`[查看支持公链](/chinese/huo-bi/cha-xun-bi-zhong-xin-xi) |
| currency       | body | string | 是  | 币种，示例值：`TRX`、`USDT`、`ETH`[查看支持币种](/chinese/huo-bi/cha-xun-bi-zhong-xin-xi)        |
| to\_address    | body | string | 是  | 收款钱包                                                                              |
| attach         | body | string | 否  | 自定义参数，在查询 API 和支付通知中原样返回，可作为自定义参数使用，实际情况下只有支付完成状态才会返回该字段                          |
| notify\_url    | body | string | 否  | 回调地址，示例值：`https://xxx/xxx` [建议使用 https](/chinese/shuo-ming/an-quan-xu-zhi)        |

{% hint style="info" %}
说明

app\_id 可通过商户后台创建应用获取。
{% endhint %}

### 接口返回 <a href="#jie-kou-fan-hui" id="jie-kou-fan-hui"></a>

| 名称          | 类型                                                                                         | 必选    | 说明                                              |
| ----------- | ------------------------------------------------------------------------------------------ | ----- | ----------------------------------------------- |
| code        | integer                                                                                    | true  | [业务状态码](/chinese/cuo-wu-ma/ye-wu-zhuang-tai-ma) |
| msg         | string                                                                                     | true  | 状态说明                                            |
| request\_id | string                                                                                     | true  |                                                 |
| data        | [PayAnotherTransactionDetail](/chinese/shuo-ming/shu-ju-jie-gou#dai-fu-jiao-yi-xiang-qing) | false |                                                 |

### 返回示例 <a href="#fan-hui-shi-li" id="fan-hui-shi-li"></a>

```json
{
    "code": 0,
    "msg": "ok",
    "request_id": "08250916-a677-4a36-a090-323807ac644c",
    "data": {
        "out_trade_no": "fb722ca8-ed7b-444b-9f58-0b5c8a7b52cb",
        "transaction_id": "e98b3029477f4bdcb971797a9d9e09ce",
        "trade_state": "SUCCESS",
        "description": "充值",
        "block_no": 33215220,
        "create_time": 1673407302044,
        "block_time": 1673407329000,
        "expire_time": 1673407902044,
        "expire_second": 0,
        "pay_time": 1673407329000,
        "close_time": 0,
        "tx_id": "9fdf0ab5823e23225f93bcc644af30a6ab83b6583a8e29e359ee80219802a33a",
        "from_address": "TULRFYoFuEmUbxxxxxxxx8nQYFHJ88888",
        "contract_address": "",
        "to_address": "TQjxEW2Z3p9wjoxxxxxxxxgJUrWXBun91w",
        "amount": 15000000,
        "chain": "TRON",
        "decimals": 6,
        "attach": "anim dolore",
        "service_amount": 45000,
        "service_amount_currency": "USDT",
        "notify_url": "/console/callback/pay",
        "notify_num": 1,
        "notify_status": 2,
        "status": 2,
        "currency": {
            "type": "TRX",
            "chain": "TRON",
            "code": "TRON_TRX",
            "currency": "TRX",
            "name": "TRX",
            "sub_name": "TRON",
            "logo": "https://xxx/trx_busd.png",
            "contract_address": "",
            "decimal": 6,
        }
    }
}
```

### 代码示例 <a href="#dai-ma-shi-li" id="dai-ma-shi-li"></a>

{% tabs %}
{% tab title="Shell" %}

```sh
curl --location --request POST 'https://api.tokenpay.me/v1/payanother/payment' \
--header 'Authorization: <Authorization>' \
--header 'User-Agent: tokenpay API (https://tokenpay.me)' \
--header 'Content-Type: application/json' \
--data-raw '<body data here>'
```

{% endtab %}

{% tab title="Go" %}

```go
package main

import (
   "fmt"
   "strings"
   "net/http"
   "io/ioutil"
)

func main() {

   url := "https://api.tokenpay.me/v1/payanother/payment"
   method := "POST"

   payload := strings.NewReader(`<body data here>`)

   client := &http.Client {
   }
   req, err := http.NewRequest(method, url, payload)

   if err != nil {
      fmt.Println(err)
      return
   }
   req.Header.Add("Authorization", "<Authorization>")
   req.Header.Add("User-Agent", "tokenpay API (https://tokenpay.me)")
   req.Header.Add("Content-Type", "application/json")

   res, err := client.Do(req)
   if err != nil {
      fmt.Println(err)
      return
   }
   defer res.Body.Close()

   body, err := ioutil.ReadAll(res.Body)
   if err != nil {
      fmt.Println(err)
      return
   }
   fmt.Println(string(body))
}
```

{% endtab %}

{% tab title="PHP" %}

```php
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
   CURLOPT_URL => 'https://api.tokenpay.me/v1/payanother/payment',
   CURLOPT_RETURNTRANSFER => true,
   CURLOPT_ENCODING => '',
   CURLOPT_MAXREDIRS => 10,
   CURLOPT_TIMEOUT => 0,
   CURLOPT_FOLLOWLOCATION => true,
   CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
   CURLOPT_CUSTOMREQUEST => 'POST',
   CURLOPT_POSTFIELDS =>'<body data here>',
   CURLOPT_HTTPHEADER => array(
      'Authorization: <Authorization>',
      'User-Agent: tokenpay API (https://tokenpay.meo)',
      'Content-Type: application/json'
   ),
));

$response = curl_exec($curl);

curl_close($curl);
echo $response;
```

<br>
{% endtab %}

{% tab title="Python" %}

```python
import http.client
import json

conn = http.client.HTTPSConnection("https://api.tokenpay.me")
payload = "<body data here>"
headers = {
   'Authorization': '<Authorization>',
   'User-Agent': 'tokenpay API (https://tokenpay.me)',
   'Content-Type': 'application/json'
}
conn.request("POST", "/v1/payanother/payment", payload, headers)
res = conn.getresponse()
data = res.read()
print(data.decode("utf-8"))
```

{% endtab %}

{% tab title="Java" %}

```java
OkHttpClient client = new OkHttpClient().newBuilder()
   .build();
MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "<body data here>");
Request request = new Request.Builder()
   .url("https://api.tokenpay.me/v1/payanother/payment")
   .method("POST", body)
   .addHeader("Authorization", "<Authorization>")
   .addHeader("User-Agent", "tokenpay API (https://tokenpay.me)")
   .addHeader("Content-Type", "application/json")
   .build();
Response response = client.newCall(request).execute();
```

{% endtab %}
{% endtabs %}


# 代付手续费查询

{% hint style="info" %}
说明

查询代付手续费信息
{% endhint %}

### 接口地址

```
POST https://api.tokenpay.me/v1/payanother/estimated_fee
```

### 接口参数

| 名称          | 位置   | 类型     | 必选 | 说明                                                                                                          |
| ----------- | ---- | ------ | -- | ----------------------------------------------------------------------------------------------------------- |
| mch\_id     | body | string | 是  | 商户ID。示范值：`12345678`                                                                                         |
| chain       | body | string | 是  | 所属公链，示例值：`TRON`、`ETHEREUM`、`BSC`[查看支持公链](https://apidoc.tokenpay.me/chinese/huo-bi/cha-xun-bi-zhong-xin-xi) |
| currency    | body | string | 是  | 币种，示例值：`TRX`、`USDT`、`ETH`[查看支持币种](https://apidoc.tokenpay.me/chinese/huo-bi/cha-xun-bi-zhong-xin-xi)        |
| to\_address | body | string | 是  | <p>收款钱包</p><p><br></p>                                                                                      |
| app\_id     | body | string | 是  | 应用 ID，示例值：`8e4b8c2e7cxxxxxxxx1a1cbd3d59e0bd`                                                                |

{% hint style="info" %}
说明

app\_id 可通过商户后台创建应用获取。
{% endhint %}

### 接口返回

| 名称          | 类型      | 必选    | 说明                                                                        |
| ----------- | ------- | ----- | ------------------------------------------------------------------------- |
| code        | integer | true  | [业务状态码](https://apidoc.tokenpay.me/chinese/cuo-wu-ma/ye-wu-zhuang-tai-ma) |
| msg         | string  | true  | 状态说明                                                                      |
| request\_id | string  | true  |                                                                           |
| data        | object  | false | 数据对象                                                                      |
| chain       | string  |       | 所属公链                                                                      |
| currency    | string  |       | 货币                                                                        |
| to\_address | string  |       | 收款钱包                                                                      |
| fee         | string  |       | 手续费                                                                       |
| decimals    | string  |       | 订单金额精度                                                                    |

### 返回示例

```java
{
    "code": 0,
    "msg": "ok",
    "request_id": "0f262d68-a7bc-4ff4-beeb-994a1e6bcd53",
    "data": {
        "chain": "TRON",
        "currency": "USDT",
        "to_address": "TPKcSZqWWAJyE7KTKUveSfgWM75sZrr9JG",
        "fee": "2500000",
        "decimals": 6
    }
}
```

### 代码示例

{% tabs %}
{% tab title="Shell" %}

```sh
curl --location --request POST 'https://api.tokenpay.me/v1/payanother/estimated_fee'
--header 'Authorization: '
--header 'User-Agent: tokenpay API (https://tokenpay.me)'
--header 'Content-Type: application/json'
--data-raw ''
```

{% endtab %}

{% tab title="Go" %}

```go
package main

import (
   "fmt"
   "strings"
   "net/http"
   "io/ioutil"
)

func main() {

   url := "https://api.tokenpay.me/v1/payanother/estimated_fee"
   method := "POST"

   payload := strings.NewReader(`<body data here>`)

   client := &http.Client {
   }
   req, err := http.NewRequest(method, url, payload)

   if err != nil {
      fmt.Println(err)
      return
   }
   req.Header.Add("Authorization", "<Authorization>")
   req.Header.Add("User-Agent", "tokenpay API (https://tokenpay.me)")
   req.Header.Add("Content-Type", "application/json")

   res, err := client.Do(req)
   if err != nil {
      fmt.Println(err)
      return
   }
   defer res.Body.Close()

   body, err := ioutil.ReadAll(res.Body)
   if err != nil {
      fmt.Println(err)
      return
   }
   fmt.Println(string(body))
}
```

{% endtab %}

{% tab title="PHP" %}

```php
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
   CURLOPT_URL => 'https://api.tokenpay.me/v1/payanother/estimated_fee',
   CURLOPT_RETURNTRANSFER => true,
   CURLOPT_ENCODING => '',
   CURLOPT_MAXREDIRS => 10,
   CURLOPT_TIMEOUT => 0,
   CURLOPT_FOLLOWLOCATION => true,
   CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
   CURLOPT_CUSTOMREQUEST => 'POST',
   CURLOPT_POSTFIELDS =>'<body data here>',
   CURLOPT_HTTPHEADER => array(
      'Authorization: <Authorization>',
      'User-Agent: tokenpay API (https://tokenpay.meo)',
      'Content-Type: application/json'
   ),
));

$response = curl_exec($curl);

curl_close($curl);
echo $response;
```

{% endtab %}

{% tab title="Python" %}

```python
import http.client
import json

conn = http.client.HTTPSConnection("https://api.tokenpay.me")
payload = "<body data here>"
headers = {
   'Authorization': '<Authorization>',
   'User-Agent': 'tokenpay API (https://tokenpay.me)',
   'Content-Type': 'application/json'
}
conn.request("POST", "/v1/payanother/estimated_fee", payload, headers)
res = conn.getresponse()
data = res.read()
print(data.decode("utf-8"))
```

{% endtab %}

{% tab title="Java" %}

```java
OkHttpClient client = new OkHttpClient().newBuilder()
   .build();
MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "<body data here>");
Request request = new Request.Builder()
   .url("https://api.tokenpay.me/v1/payanother/estimated_fee")
   .method("POST", body)
   .addHeader("Authorization", "<Authorization>")
   .addHeader("User-Agent", "tokenpay API (https://tokenpay.me)")
   .addHeader("Content-Type", "application/json")
   .build();
Response response = client.newCall(request).execute();
```

{% endtab %}
{% endtabs %}


# 回调通知

{% hint style="info" %}
说明

代付完成后，支付中心会把相关代付结果和相关信息发送给商户，商户需要接收处理，并返回应答。 对后台通知交互时，如果支付中心收到商户的应答不是成功或超时，支付中心则认为通知失败，会在一定的策略定期重新发起通知，尽可能提高通知的成功率，但不保证通知最终能成功。 （通知频率为0s/15s/30s/3m/10m/20m/30m/60m/3h/6h）
{% endhint %}

{% hint style="warning" %}
注意

注意：同样的通知可能会多次发送给商户系统。商户系统必须能够正确处理重复的通知。 推荐的做法是，当收到通知进行处理时，首先检查对应业务数据的状态，判断该通知是否已经处理过，如果没有处理过再进行处理，如果处理过直接返回结果成功。在对业务数据进行状态检查和处理之前，要采用数据锁进行并发控制，以避免函数重入造成的数据混乱。
{% endhint %}

{% hint style="danger" %}
警告

特别提醒：商户系统对于代付回调的内容一定要做签名验证，并校验返回的代付金额是否与商户侧的代付金额一致，防止数据泄漏导致出现“假通知”，造成资金损失。
{% endhint %}

## **接口地址**

```
POST 统一下单接口提交的参数notify_url设置，如果无法访问链接，您的业务系统将无法接收到支付中心的通知。
```

## **请求Body** <a href="#qing-qiu-body" id="qing-qiu-body"></a>

<table><thead><tr><th>名称</th><th>类型</th><th width="247">说明</th><th>说明</th></tr></thead><tbody><tr><td>app_id</td><td>string</td><td>应用ID</td><td></td></tr><tr><td>mch_id</td><td>string</td><td>商户ID</td><td></td></tr><tr><td>create_time</td><td>time</td><td>通知时间</td><td></td></tr><tr><td>resource_type</td><td>string</td><td>通知的资源数据类型，支付成功通知为encrypt-resource</td><td></td></tr><tr><td>event_type</td><td>string</td><td>通知的类型，支付成功通知的类型为PAYPAYANOTHER.SUCCESS</td><td></td></tr><tr><td>resource</td><td>object</td><td>通知资源数据</td><td></td></tr><tr><td>» original_type</td><td>string</td><td>原始回调类型，为payanother</td><td></td></tr><tr><td>» algorithm</td><td>string</td><td>对开启结果数据进行加密的加密算法，目前只支持AES-256-ECB</td><td></td></tr><tr><td>» ciphertext</td><td>string</td><td>Base64编码后的开启/停用结果数据密文，如果开启将返回加密后的内容，解密后是<a href="/pages/aI7q9ciB2x8bvoQDqbp9#dai-fu-jiao-yi-xiang-qing">代付通知详情 PayAnotherTransactionDetail</a>的json字符串。</td><td></td></tr><tr><td>» nonce</td><td>string</td><td>加密使用的随机串</td><td></td></tr></tbody></table>

## **请求示例**

```json
{
	"app_id": "xxxxx",
	"mch_id": "zzzzzz",
	"create_time": "2023-06-26T17:21:17.754429+08:00",
	"resource_type": "encrypt-resource",
	"event_type": "PAYPAYANOTHER.SUCCESS",
	"resource": {
		"original_type": "payanother",
		"algorithm": "AEAD_AES_256_GCM",
		"ciphertext": "I/psKgdkVwxbkEIWtwRxfxLzViuRS+gJTQSdLf+lmK7awoqUcIJisTAJx0Qbv4K6wV8WgyMRFYHD5CCLKmFNU2OnmEm2f2vGhaoS2h28A9BEGx1CWEUw3tfldf/+VWlBAnIBylFjHzbSo7fgn7S3fFEAZHTxoy+9jNIoynqHZbn4Y6eucj1YCw0ZmuKHPpPPrvclbhHmaZHfau+SKyag3C0/cj7zu4mBkRZ39zuk9B7DAADzaRENOZ/ZyibU+zs3gibnCbI2NWEnQWIiCi7vK0jq/FCBWytHihQM364zlVrPPCBDbv2MSqk4fyAM7IDeT6h/z/2kmDOQ6aFPYlLojIkgCCOIevQITS9E+BS1rgmmH+DRKsJNiD257aLhX2/F53VEnjfqqKdDs2lqfX0dCMLqselGUT981fFKceXg+r6hQqcUzLlF28XL5NrfVPreRDo6jI2K0tCy9cOx+cxH3yoDzOFBzM0RlxWqvUhRsMv9ZGfpgCZ0o9HxNObqLjVCQzE5SWPXvmkw+QpWk0oNUvpCEDhj9Vfq6XCV8j3tT3tZTYCa5UQy9VCdmval/2vb50QaAgDYXU6PH/9Xv7AXg6kg29iK+Ec0euxZxosRoVczzRg+0Arl/zvBcphWNIUTdx5IcA12WtP+krk9NNGtj7igk21DhcseJrKBpG7ll9O/Wmq1L8BwW+ypuJS+kHV61jRNYMFJY48Pt11Zoukgqu94kzrhz+KET8q463zlyu/Kp2z5yWI8xwvOtuyjosszfm6/YFQTFdhcmHY3X1yz44NaVG9FPev1QPoPmI7K3Jqa0Q8Q5kQTbe/KrB0eyRpXtyAaShOEeiS2ypmFAC81/m4mjuTd24yAjBcTIfBYzjxwjPbKfv+OYKahDwJP1b7EhsM+Sgu48wQ+pp6wc8TYCOkiRR1pKeb3kaxpQGzlq7VNbWHFPw9TDiyCIEnr8T5eiJtzJJ0U0iIfqN5WHk7iHiNK4Y4TvmdF4f6UyeMTHvaprvzUZI8il5wvoCgIiRUY7qvv5V/KL4ZWHN6Y3EEvQmP4WDo3Wx5IFW8C1gkyFv8lQ1COSNYMPog6RLAI0rNvKZjvc4baWwcHmk/fM92X19F2Y0DArqLFFUTJVE5bUQXQexiUO1e8IL07wqY=",
		"nonce": "d8816e8d6dca4409b790a4bcaa25c621"
	}
}
```

## **返回示例**

```
success
```

成功收到回调请求后请返回 `success` 以告知通知服务器。当通知服务器收到 `success` 后，将停止通知。否则将会按照 0s/15s/30s/3m/10m/20m/30m/60m/3h/6h 的频率通知10次。

[<br>](https://ttpay.gitbook.io/api/zhi-fu-ding-dan/cha-xun-ding-dan)

<br>


# 关闭代付

{% hint style="info" %}
说明

用于用户手动取消代付或商家取消代付
{% endhint %}

## **接口地址**

```
POST https://api.tokenpay.me/v1/payanother/close
```

## **接口参数**

<table><thead><tr><th>名称	</th><th width="119">位置</th><th>类型	</th><th>必选</th><th>说明</th></tr></thead><tbody><tr><td>app_id</td><td>header</td><td>string</td><td>是</td><td>应用 ID，示例值：<code>8e4b8c2e7cxxxxxxxx1a1cbd3d59e0bd</code></td></tr><tr><td>mch_id</td><td>body</td><td>string</td><td>是</td><td>商户 ID，示例值：<code>12345678</code></td></tr><tr><td>payanother_id</td><td>body</td><td>string</td><td>否</td><td>平台订单号，示例值：<code>2a1cfa6568xxxxxxxx3050957024c559</code></td></tr></tbody></table>

**参数示例**

```
{
  "app_id": "8e4b8c2e7cxxxxxxxx1a1cbd3d59e0bd",
  "mch_id": "12345678",
  "payanother_id": "2a1cfa6568xxxxxxxx3050957024c559"
}
```

## **接口返回**

| 名称          | 类型      | 说明                                                                  | 说明   |
| ----------- | ------- | ------------------------------------------------------------------- | ---- |
| code        | integer | [业务状态码](https://ttpay.gitbook.io/api/cuo-wu-ma/ye-wu-zhuang-tai-ma) | none |
| msg         | string  | 状态描述                                                                | none |
| request\_id | string  | 请求 ID                                                               | none |

## **返回示例** <a href="#fan-hui-shi-li" id="fan-hui-shi-li"></a>

```
{
  "code": 0,
  "msg": "成功",
  "request_id": "f23ade4a-e5ca-48f4-a4bb-59114ac360ba",
}
```

## **代码示例**

{% tabs %}
{% tab title="Shell" %}

```sh
curl --location --request POST 'https://api.tokenpay.me/v1/payanother/close' \
--header 'Authorization: <Authorization>' \
--header 'User-Agent: tokenpay API (https://tokenpay.me)' \
--header 'Content-Type: application/json' \
--data-raw '<body data here>'
```

{% endtab %}

{% tab title="Go" %}

```go
package main

import (
   "fmt"
   "strings"
   "net/http"
   "io/ioutil"
)

func main() {

   url := "https://api.tokenpay.me/v1/payanother/close"
   method := "POST"

   payload := strings.NewReader(`<body data here>`)

   client := &http.Client {
   }
   req, err := http.NewRequest(method, url, payload)

   if err != nil {
      fmt.Println(err)
      return
   }
   req.Header.Add("Authorization", "<Authorization>")
   req.Header.Add("User-Agent", "tokenpay API (https://tokenpay.me)")
   req.Header.Add("Content-Type", "application/json")

   res, err := client.Do(req)
   if err != nil {
      fmt.Println(err)
      return
   }
   defer res.Body.Close()

   body, err := ioutil.ReadAll(res.Body)
   if err != nil {
      fmt.Println(err)
      return
   }
   fmt.Println(string(body))
}
```

{% endtab %}

{% tab title="PHP" %}

```php
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
   CURLOPT_URL => 'https://api.tokenpay.me/v1/payanother/close',
   CURLOPT_RETURNTRANSFER => true,
   CURLOPT_ENCODING => '',
   CURLOPT_MAXREDIRS => 10,
   CURLOPT_TIMEOUT => 0,
   CURLOPT_FOLLOWLOCATION => true,
   CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
   CURLOPT_CUSTOMREQUEST => 'POST',
   CURLOPT_POSTFIELDS =>'<body data here>',
   CURLOPT_HTTPHEADER => array(
      'Authorization: <Authorization>',
      'User-Agent: tokenpay API (https://tokenpay.me)',
      'Content-Type: application/json'
   ),
));

$response = curl_exec($curl);

curl_close($curl);
echo $response;
```

{% endtab %}

{% tab title="Python" %}

```python
import http.client
import json

conn = http.client.HTTPSConnection("https://api.tokenpay.me")
payload = "<body data here>"
headers = {
   'Authorization': '<Authorization>',
   'User-Agent': 'tokenpay API (https://tokenpay.me)',
   'Content-Type': 'application/json'
}
conn.request("POST", "/v1/payanother/close", payload, headers)
res = conn.getresponse()
data = res.read()
print(data.decode("utf-8"))
```

{% endtab %}

{% tab title="Java" %}

```java
OkHttpClient client = new OkHttpClient().newBuilder()
   .build();
MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "<body data here>");
Request request = new Request.Builder()
   .url("https://api.tokenpay.me/v1/payanother/close")
   .method("POST", body)
   .addHeader("Authorization", "<Authorization>")
   .addHeader("User-Agent", "tokenpay API (https://tokenpay.me)")
   .addHeader("Content-Type", "application/json")
   .build();
Response response = client.newCall(request).execute();
```

{% endtab %}
{% endtabs %}

\ <br>

<br>


# 钱包


# 添加监听钱包

{% hint style="info" %}
说明

添加[监听模式](/chinese/shuo-ming/zhi-fu-fang-shi)下的钱包
{% endhint %}

### 接口地址 <a href="#jie-kou-di-zhi" id="jie-kou-di-zhi"></a>

```
POST https://api.tokenpay.me/v1/wallet/insert
```

### 接口参数 <a href="#jie-kou-can-shu" id="jie-kou-can-shu"></a>

| 名称              | 位置     | 类型     | 必选 | 说明                                                                                |
| --------------- | ------ | ------ | -- | --------------------------------------------------------------------------------- |
| app\_id         | header | string | 是  | 应用 ID，示例值：`8e4b8c2e7cxxxxxxxx1a1cbd3d59e0bd`                                      |
| mch\_id         | body   | string | 是  | 商户 ID，示例值：`12345678`                                                              |
| name            | body   | string | 否  | 钱包备注，在[监听钱包模式](/chinese/shuo-ming/zhi-fu-fang-shi)下，可用作标识`一用户一钱包`唯一信息，如`用户ID`     |
| wallet\_address | body   | string | 是  | 钱包地址，示例值：`TQjxEW2Z3pxxxxxxxxxxxxgJUrWXVAC92T`                                     |
| chain           | body   | string | 是  | 所属公链，示例值：`TRON`、`ETHEREUM`、`BSC`[查看支持公链](/chinese/huo-bi/cha-xun-bi-zhong-xin-xi) |

#### 参数示例 <a href="#can-shu-shi-li" id="can-shu-shi-li"></a>

```json
{
  "mch_id": "12345678",
  "app_id": "8e4b8c2e7cxxxxxxxx1a1cbd3d59e0bd",
  "wallet_address": "TQjxEW2Z3pxxxxxxxxxxxxgJUrWXVAC92T",
  "chain": "TRON",
  "name": "28713"
}
```

### 接口返回 <a href="#jie-kou-fan-hui" id="jie-kou-fan-hui"></a>

| 名称          | 类型                                                                              | 必选    | 说明                                              |
| ----------- | ------------------------------------------------------------------------------- | ----- | ----------------------------------------------- |
| code        | integer                                                                         | true  | [业务状态码](/chinese/cuo-wu-ma/ye-wu-zhuang-tai-ma) |
| msg         | string                                                                          | true  | 状态说明                                            |
| request\_id | string                                                                          | true  |                                                 |
| data        | [WalletDetail](/chinese/shuo-ming/shu-ju-jie-gou#jian-ting-qian-bao-xiang-qing) | false |                                                 |

### 返回示例 <a href="#fan-hui-shi-li" id="fan-hui-shi-li"></a>

```json
{
    "code": 0,
    "msg": "ok",
    "request_id": "60eeeab2-7896-4f80-8088-4251d262dea6",
    "data": {
        "app_id": "8e4b8c2e7cxxxxxxxx1a1cbd3d59e0bd",
        "mch_id": "12345678",
        "name": "28713",
        "chain": "TRON",
        "wallet_address": "TQjxEW2Z3pxxxxxxxxxxxxgJUrWXVAC92T",
        "create_time": 1675236993,
        "last_time": 0
    }
}
```

### 代码示例 <a href="#dai-ma-shi-li" id="dai-ma-shi-li"></a>

{% tabs %}
{% tab title="Shell" %}

```sh
curl --location --request POST 'https://api.tokenpay.me/v1/wallet/insert' \
--header 'Authorization: <Authorization>' \
--header 'User-Agent: tokenpay API (https://tokenpay.me)' \
--header 'Content-Type: application/json' \
--data-raw '<body data here>'
```

{% endtab %}

{% tab title="Go" %}

```go
package main

import (
   "fmt"
   "strings"
   "net/http"
   "io/ioutil"
)

func main() {

   url := "https://api.tokenpay.me/v1/wallet/insert"
   method := "POST"

   payload := strings.NewReader(`<body data here>`)

   client := &http.Client {
   }
   req, err := http.NewRequest(method, url, payload)

   if err != nil {
      fmt.Println(err)
      return
   }
   req.Header.Add("Authorization", "<Authorization>")
   req.Header.Add("User-Agent", "tokenpay API (https://tokenpay.me)")
   req.Header.Add("Content-Type", "application/json")

   res, err := client.Do(req)
   if err != nil {
      fmt.Println(err)
      return
   }
   defer res.Body.Close()

   body, err := ioutil.ReadAll(res.Body)
   if err != nil {
      fmt.Println(err)
      return
   }
   fmt.Println(string(body))
}
```

{% endtab %}

{% tab title="PHP" %}

```php
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
   CURLOPT_URL => 'https://api.tokenpay.me/v1/wallet/insert',
   CURLOPT_RETURNTRANSFER => true,
   CURLOPT_ENCODING => '',
   CURLOPT_MAXREDIRS => 10,
   CURLOPT_TIMEOUT => 0,
   CURLOPT_FOLLOWLOCATION => true,
   CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
   CURLOPT_CUSTOMREQUEST => 'POST',
   CURLOPT_POSTFIELDS =>'<body data here>',
   CURLOPT_HTTPHEADER => array(
      'Authorization: <Authorization>',
      'User-Agent: tokenpay API (https://tokenpay.me)',
      'Content-Type: application/json'
   ),
));

$response = curl_exec($curl);

curl_close($curl);
echo $response;
```

<br>
{% endtab %}

{% tab title="Python" %}

```python
import http.client
import json

conn = http.client.HTTPSConnection("https://api.tokenpay.me")
payload = "<body data here>"
headers = {
   'Authorization': '<Authorization>',
   'User-Agent': 'tokenpay API (https://tokenpay.me)',
   'Content-Type': 'application/json'
}
conn.request("POST", "/v1/wallet/insert", payload, headers)
res = conn.getresponse()
data = res.read()
print(data.decode("utf-8"))
```

{% endtab %}

{% tab title="Java" %}

{% code overflow="wrap" %}

```java
OkHttpClient client = new OkHttpClient().newBuilder()
   .build();
MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "<body data here>");
Request request = new Request.Builder()
   .url("https://api.tokenpay.me/v1/wallet/insert")
   .method("POST", body)
   .addHeader("Authorization", "<Authorization>")
   .addHeader("User-Agent", "tokenpay API (https://tokenpay.me)")
   .addHeader("Content-Type", "application/json")
   .build();
Response response = client.newCall(request).execute();
```

{% endcode %}
{% endtab %}
{% endtabs %}


# 更新监听钱包

{% hint style="info" %}
说明

更新[监听模式](/chinese/shuo-ming/zhi-fu-fang-shi)下的钱包
{% endhint %}

### 接口地址 <a href="#jie-kou-di-zhi" id="jie-kou-di-zhi"></a>

```
POST https://api.tokenpay.me/v1/wallet/update
```

### 接口参数 <a href="#jie-kou-can-shu" id="jie-kou-can-shu"></a>

| 名称              | 位置     | 类型     | 必选 | 说明                                                                                |
| --------------- | ------ | ------ | -- | --------------------------------------------------------------------------------- |
| app\_id         | header | string | 是  | 应用ID，示例值：`8e4b8c2e7cxxxxxxxx1a1cbd3d59e0bd`                                       |
| mch\_id         | body   | string | 是  | 商户ID，示例值：`12345678`                                                               |
| name            | body   | string | 否  | 钱包备注，在[监听钱包模式](/chinese/shuo-ming/zhi-fu-fang-shi)下，可用作标识`一用户一钱包`唯一信息，如`用户ID`     |
| wallet\_address | body   | string | 是  | 钱包地址，示例值：`TQjxEW2Z3pxxxxxxxxxxxxgJUrWXVAC92T`                                     |
| chain           | body   | string | 是  | 所属公链，示例值：`TRON`、`ETHEREUM`、`BSC`[查看支持公链](/chinese/huo-bi/cha-xun-bi-zhong-xin-xi) |

#### 参数示例 <a href="#can-shu-shi-li" id="can-shu-shi-li"></a>

```json
{
  "mch_id": "12345678",
  "app_id": "8e4b8c2e7cxxxxxxxx1a1cbd3d59e0bd",
  "wallet_address": "TQjxEW2Z3pxxxxxxxxxxxxgJUrWXVAC92T",
  "chain": "TRON",
  "name": "28713"
}
```

### 接口返回 <a href="#jie-kou-fan-hui" id="jie-kou-fan-hui"></a>

| 名称          | 类型                                                                              | 必选    | 说明                                              |
| ----------- | ------------------------------------------------------------------------------- | ----- | ----------------------------------------------- |
| code        | integer                                                                         | true  | [业务状态码](/chinese/cuo-wu-ma/ye-wu-zhuang-tai-ma) |
| msg         | string                                                                          | true  | 状态说明                                            |
| request\_id | string                                                                          | true  |                                                 |
| data        | [WalletDetail](/chinese/shuo-ming/shu-ju-jie-gou#jian-ting-qian-bao-xiang-qing) | false |                                                 |

### 返回示例 <a href="#fan-hui-shi-li" id="fan-hui-shi-li"></a>

```json
{
    "code": 0,
    "msg": "ok",
    "request_id": "60eeeab2-7896-4f80-8088-4251d262dea6",
    "data": {
        "app_id": "8e4b8c2e7cxxxxxxxx1a1cbd3d59e0bd",
        "mch_id": "12345678",
        "name": "28713",
        "chain": "TRON",
        "wallet_address": "TQjxEW2Z3pxxxxxxxxxxxxgJUrWXVAC92T",
        "create_time": 1675236993,
        "last_time": 0
    }
}
```

{% tabs %}
{% tab title="Shell" %}

```sh
curl --location --request POST 'https://api.tokenpay.me/v1/wallet/update' \
--header 'Authorization: <Authorization>' \
--header 'User-Agent: tokenpay API (https://tokenpay.me)' \
--header 'Content-Type: application/json' \
--data-raw '<body data here>'
```

{% endtab %}

{% tab title="Go" %}

```go
package main

import (
   "fmt"
   "strings"
   "net/http"
   "io/ioutil"
)

func main() {

   url := "https://api.tokenpay.me/v1/wallet/update"
   method := "POST"

   payload := strings.NewReader(`<body data here>`)

   client := &http.Client {
   }
   req, err := http.NewRequest(method, url, payload)

   if err != nil {
      fmt.Println(err)
      return
   }
   req.Header.Add("Authorization", "<Authorization>")
   req.Header.Add("User-Agent", "tokenpay API (https://tokenpay.me)")
   req.Header.Add("Content-Type", "application/json")

   res, err := client.Do(req)
   if err != nil {
      fmt.Println(err)
      return
   }
   defer res.Body.Close()

   body, err := ioutil.ReadAll(res.Body)
   if err != nil {
      fmt.Println(err)
      return
   }
   fmt.Println(string(body))
}
```

{% endtab %}

{% tab title="PHP" %}

```php
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
   CURLOPT_URL => 'https://api.tokenpay.me/v1/wallet/update',
   CURLOPT_RETURNTRANSFER => true,
   CURLOPT_ENCODING => '',
   CURLOPT_MAXREDIRS => 10,
   CURLOPT_TIMEOUT => 0,
   CURLOPT_FOLLOWLOCATION => true,
   CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
   CURLOPT_CUSTOMREQUEST => 'POST',
   CURLOPT_POSTFIELDS =>'<body data here>',
   CURLOPT_HTTPHEADER => array(
      'Authorization: <Authorization>',
      'User-Agent: tokenpay API (https://tokenpay.me)',
      'Content-Type: application/json'
   ),
));

$response = curl_exec($curl);

curl_close($curl);
echo $response;
```

{% endtab %}

{% tab title="Python" %}

```python
import http.client
import json

conn = http.client.HTTPSConnection("https://api.tokenpay.me")
payload = "<body data here>"
headers = {
   'Authorization': '<Authorization>',
   'User-Agent': 'tokenpay API (https://tokenpay.me)',
   'Content-Type': 'application/json'
}
conn.request("POST", "/v1/wallet/update", payload, headers)
res = conn.getresponse()
data = res.read()
print(data.decode("utf-8"))
```

{% endtab %}

{% tab title="Java" %}

```java
OkHttpClient client = new OkHttpClient().newBuilder()
   .build();
MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "<body data here>");
Request request = new Request.Builder()
   .url("https://api.tokenpay.me/v1/wallet/update")
   .method("POST", body)
   .addHeader("Authorization", "<Authorization>")
   .addHeader("User-Agent", "tokenpay API (https://tokenpay.me)")
   .addHeader("Content-Type", "application/json")
   .build();
Response response = client.newCall(request).execute();
```

{% endtab %}
{% endtabs %}


# 删除监听钱包

{% hint style="info" %}
说明

删除[监听模式](/chinese/shuo-ming/zhi-fu-fang-shi)下的钱包
{% endhint %}

### 接口地址 <a href="#jie-kou-di-zhi" id="jie-kou-di-zhi"></a>

```
POST https://api.tokenpay.me/v1/wallet/delete
```

### 接口参数 <a href="#jie-kou-can-shu" id="jie-kou-can-shu"></a>

| 名称              | 位置     | 类型     | 必选 | 说明                                            |
| --------------- | ------ | ------ | -- | --------------------------------------------- |
| app\_id         | header | string | 是  | 应用 ID，示例值：`8e4b8c2e7cxxxxxxxx1a1cbd3d59e0bd`  |
| mch\_id         | body   | string | 是  | 商户 ID，示例值：`12345678`                          |
| wallet\_address | body   | string | 否  | 钱包地址，示例值：`TQjxEW2Z3pxxxxxxxxxxxxgJUrWXVAC92T` |
| chain           | body   | string | 是  | 公链，示例值：`TRON`                                 |

#### 参数示例 <a href="#can-shu-shi-li" id="can-shu-shi-li"></a>

```json
{
  "mch_id": "12345678",
  "app_id": "8e4b8c2e7cxxxxxxxx1a1cbd3d59e0bd",
  "wallet_address": "TQjxEW2Z3pxxxxxxxxxxxxgJUrWXVAC92T",
  "chain": "TRON",
}
```

### 接口返回 <a href="#jie-kou-fan-hui" id="jie-kou-fan-hui"></a>

| 名称          | 类型      | 说明                                              | 说明 |
| ----------- | ------- | ----------------------------------------------- | -- |
| code        | integer | [业务状态码](/chinese/cuo-wu-ma/ye-wu-zhuang-tai-ma) |    |
| msg         | string  | 状态描述                                            |    |
| request\_id | string  | 请求 ID                                           |    |

### 返回示例 <a href="#fan-hui-shi-li" id="fan-hui-shi-li"></a>

```json
{
    "code": 0,
    "msg": "成功",
    "request_id": "b5506db8-fe9b-4ea6-bbc9-4497e70c03b6",
}
```

### 代码示例 <a href="#dai-ma-shi-li" id="dai-ma-shi-li"></a>

{% tabs %}
{% tab title="Shell" %}

{% code overflow="wrap" %}

```sh
curl --location --request POST 'https://api.tokenpay.me/v1/wallet/delete' \
--header 'Authorization: <Authorization>' \
--header 'User-Agent: tokenpay API (https://tokenpay.me)' \
--header 'Content-Type: application/json' \
--data-raw '<body data here>'
```

{% endcode %}
{% endtab %}

{% tab title="Go" %}

```go
package main

import (
   "fmt"
   "strings"
   "net/http"
   "io/ioutil"
)

func main() {

   url := "https://api.tokenpay.me/v1/wallet/delete"
   method := "POST"

   payload := strings.NewReader(`<body data here>`)

   client := &http.Client {
   }
   req, err := http.NewRequest(method, url, payload)

   if err != nil {
      fmt.Println(err)
      return
   }
   req.Header.Add("Authorization", "<Authorization>")
   req.Header.Add("User-Agent", "tokenpay API (https://tokenpay.me)")
   req.Header.Add("Content-Type", "application/json")

   res, err := client.Do(req)
   if err != nil {
      fmt.Println(err)
      return
   }
   defer res.Body.Close()

   body, err := ioutil.ReadAll(res.Body)
   if err != nil {
      fmt.Println(err)
      return
   }
   fmt.Println(string(body))
}
```

{% endtab %}

{% tab title="PHP" %}

```php
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
   CURLOPT_URL => 'https://api.tokenpay.me/v1/wallet/delete',
   CURLOPT_RETURNTRANSFER => true,
   CURLOPT_ENCODING => '',
   CURLOPT_MAXREDIRS => 10,
   CURLOPT_TIMEOUT => 0,
   CURLOPT_FOLLOWLOCATION => true,
   CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
   CURLOPT_CUSTOMREQUEST => 'POST',
   CURLOPT_POSTFIELDS =>'<body data here>',
   CURLOPT_HTTPHEADER => array(
      'Authorization: <Authorization>',
      'User-Agent: tokenpay API (https://tokenpay.me)',
      'Content-Type: application/json'
   ),
));

$response = curl_exec($curl);

curl_close($curl);
echo $response;
```

{% endtab %}

{% tab title="Python" %}

```python
import http.client
import json

conn = http.client.HTTPSConnection("https://api.tokenpay.me")
payload = "<body data here>"
headers = {
   'Authorization': '<Authorization>',
   'User-Agent': 'tokenpay API (https://tokenpay.me)',
   'Content-Type': 'application/json'
}
conn.request("POST", "/v1/wallet/delete", payload, headers)
res = conn.getresponse()
data = res.read()
print(data.decode("utf-8"))
```

{% endtab %}

{% tab title="Java" %}

```java
OkHttpClient client = new OkHttpClient().newBuilder()
   .build();
MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "<body data here>");
Request request = new Request.Builder()
   .url("https://api.tokenpay.me/v1/wallet/delete")
   .method("POST", body)
   .addHeader("Authorization", "<Authorization>")
   .addHeader("User-Agent", "tokenpay API (https://tokenpay.me)")
   .addHeader("Content-Type", "application/json")
   .build();
Response response = client.newCall(request).execute();
```

{% endtab %}
{% endtabs %}


# 查询监听钱包

{% hint style="info" %}
说明

可查询[监听模式](/chinese/shuo-ming/zhi-fu-fang-shi)下的钱包
{% endhint %}

### 接口地址 <a href="#jie-kou-di-zhi" id="jie-kou-di-zhi"></a>

```
GET https://api.tokenpay.me/v1/wallet/query
```

### 接口参数 <a href="#jie-kou-can-shu" id="jie-kou-can-shu"></a>

| 名称              | 位置     | 类型     | 必选 | 说明                                            |
| --------------- | ------ | ------ | -- | --------------------------------------------- |
| app\_id         | header | string | 是  | 应用 ID，示例值：`8e4b8c2e7cxxxxxxxx1a1cbd3d59e0bd`  |
| mch\_id         | body   | string | 是  | 商户 ID，示例值：`12345678`                          |
| wallet\_address | query  | string | 否  | 钱包地址，示例值：`TQjxEW2Z3pxxxxxxxxxxxxgJUrWXVAC92T` |

### 接口返回 <a href="#jie-kou-fan-hui" id="jie-kou-fan-hui"></a>

| 名称          | 类型                                                                              | 必选    | 说明                                              |
| ----------- | ------------------------------------------------------------------------------- | ----- | ----------------------------------------------- |
| code        | integer                                                                         | true  | [业务状态码](/chinese/cuo-wu-ma/ye-wu-zhuang-tai-ma) |
| msg         | string                                                                          | true  | 状态说明                                            |
| request\_id | string                                                                          | true  |                                                 |
| data        | [WalletDetail](/chinese/shuo-ming/shu-ju-jie-gou#jian-ting-qian-bao-xiang-qing) | false |                                                 |

### 返回示例 <a href="#fan-hui-shi-li" id="fan-hui-shi-li"></a>

```json
{
    "code": 0,
    "msg": "ok",
    "request_id": "ac054f57-22bf-45aa-b2b7-2275a6daae6f",
    "data": {
        "app_id": "8e4b8c2e7cxxxxxxxx1a1cbd3d59e0bd",
        "mch_id": "12345678",
        "name": "28713",
        "chain": "TRON",
        "wallet_address": "TQjxEW2Z3pxxxxxxxxxxxxgJUrWXVAC92T",
        "create_time": 1673333676,
        "last_time": 0
    }
}
```

### 代码示例 <a href="#dai-ma-shi-li" id="dai-ma-shi-li"></a>

{% tabs %}
{% tab title="Shell" %}

```sh
curl --location --request GET 'https://api.tokenpay.me/v1/wallet/query' \
--header 'Authorization: <Authorization>' \
--header 'User-Agent: tokenpay API (https://tokenpay.me)' \
--header 'Content-Type: application/json' \
--data-raw '<body data here>'
```

{% endtab %}

{% tab title="Go" %}

```go
package main

import (
   "fmt"
   "strings"
   "net/http"
   "io/ioutil"
)

func main() {

   url := "https://api.tokenpay.me/v1/wallet/query"
   method := "GET"

   payload := strings.NewReader(`<body data here>`)

   client := &http.Client {
   }
   req, err := http.NewRequest(method, url, payload)

   if err != nil {
      fmt.Println(err)
      return
   }
   req.Header.Add("Authorization", "<Authorization>")
   req.Header.Add("User-Agent", "tokenpay API (https://tokenpay.me)")
   req.Header.Add("Content-Type", "application/json")

   res, err := client.Do(req)
   if err != nil {
      fmt.Println(err)
      return
   }
   defer res.Body.Close()

   body, err := ioutil.ReadAll(res.Body)
   if err != nil {
      fmt.Println(err)
      return
   }
   fmt.Println(string(body))
}
```

{% endtab %}

{% tab title="PHP" %}

```php
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
   CURLOPT_URL => 'https://api.tokenpay.me/v1/wallet/query',
   CURLOPT_RETURNTRANSFER => true,
   CURLOPT_ENCODING => '',
   CURLOPT_MAXREDIRS => 10,
   CURLOPT_TIMEOUT => 0,
   CURLOPT_FOLLOWLOCATION => true,
   CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
   CURLOPT_CUSTOMREQUEST => 'GET',
   CURLOPT_POSTFIELDS =>'<body data here>',
   CURLOPT_HTTPHEADER => array(
      'Authorization: <Authorization>',
      'User-Agent: tokenpay API (https://tokenpay.me)',
      'Content-Type: application/json'
   ),
));

$response = curl_exec($curl);

curl_close($curl);
echo $response;
```

<br>
{% endtab %}

{% tab title="Python" %}

```python
import http.client
import json

conn = http.client.HTTPSConnection("https://api.tokenpay.me")
payload = "<body data here>"
headers = {
   'Authorization': '<Authorization>',
   'User-Agent': 'tokenpay API (https://tokenpay.me)',
   'Content-Type': 'application/json'
}
conn.request("GET", "/v1/wallet/query", payload, headers)
res = conn.getresponse()
data = res.read()
print(data.decode("utf-8"))
```

{% endtab %}

{% tab title="Java" %}

```java
OkHttpClient client = new OkHttpClient().newBuilder()
   .build();
MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "<body data here>");
Request request = new Request.Builder()
   .url("https://api.tokenpay.me/v1/wallet/query")
   .method("GET", body)
   .addHeader("Authorization", "<Authorization>")
   .addHeader("User-Agent", "tokenpay API (https://tokenpay.me)")
   .addHeader("Content-Type", "application/json")
   .build();
Response response = client.newCall(request).execute();
```

{% endtab %}
{% endtabs %}


# 回调通知

{% hint style="info" %}
说明

支付完成后，支付中心会把相关支付结果和相关信息发送给商户，商户需要接收处理，并返回应答。 对后台通知交互时，如果支付中心收到商户的应答不是成功或超时，支付中心则认为通知失败，会在一定的策略定期重新发起通知，尽可能提高通知的成功率，但不保证通知最终能成功。 （通知频率为0s/15s/30s/3m/10m/20m/30m/60m/3h/6h）
{% endhint %}

{% hint style="warning" %}
注意

注意：同样的通知可能会多次发送给商户系统。商户系统必须能够正确处理重复的通知。 推荐的做法是，当收到通知进行处理时，首先检查对应业务数据的状态，判断该通知是否已经处理过，如果没有处理过再进行处理，如果处理过直接返回结果成功。在对业务数据进行状态检查和处理之前，要采用数据锁进行并发控制，以避免函数重入造成的数据混乱。
{% endhint %}

{% hint style="danger" %}
警告

特别提醒：商户系统对于订单回调的内容一定要做签名验证，并校验返回的订单金额是否与商户侧的订单金额一致，防止数据泄漏导致出现“假通知”，造成资金损失。
{% endhint %}

### 接口地址 <a href="#jie-kou-di-zhi" id="jie-kou-di-zhi"></a>

```
POST 统一下单接口提交的参数notify_url设置，如果无法访问链接，您的业务系统将无法接收到支付中心的通知。
```

### 请求Body <a href="#qing-qiu-body" id="qing-qiu-body"></a>

| 名称               | 类型     | 说明                                                                                                                                               | 说明 |
| ---------------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------ | -- |
| app\_id          | string | 应用ID                                                                                                                                             |    |
| mch\_id          | string | 商户ID                                                                                                                                             |    |
| create\_time     | time   | 通知时间                                                                                                                                             |    |
| resource\_type   | string | 通知的资源数据类型，支付成功通知为encrypt-resource                                                                                                                |    |
| event\_type      | string | 通知的类型，支付成功通知的类型为TRANSACTION.SUCCESS                                                                                                              |    |
| resource         | object | 通知资源数据                                                                                                                                           |    |
| » original\_type | string | 原始回调类型，为transaction                                                                                                                              |    |
| » algorithm      | string | 对开启结果数据进行加密的加密算法，目前只支持AES-256-ECB                                                                                                                |    |
| » ciphertext     | string | Base64编码后的开启/停用结果数据密文，如果开启将返回加密后的内容，解密后是[交易通知详情 TransactionNotifyDetail](/chinese/shuo-ming/shu-ju-jie-gou#jiao-yi-tong-zhi-xiang-qing)的json字符串。 |    |
| » nonce          | string | 加密使用的随机串                                                                                                                                         |    |

### 请求示例 <a href="#qing-qiu-shi-li" id="qing-qiu-shi-li"></a>

{% code overflow="wrap" %}

```json
{
	"app_id": "xxxxx",
	"mch_id": "zzzzzz",
	"create_time": "2023-06-26T17:21:17.754429+08:00",
	"resource_type": "encrypt-resource",
	"event_type": "TRANSACTION.SUCCESS",
	"resource": {
		"original_type": "transaction",
		"algorithm": "AEAD_AES_256_GCM",
		"ciphertext": "I/psKgdkVwxbkEIWtwRxfxLzViuRS+gJTQSdLf+lmK7awoqUcIJisTAJx0Qbv4K6wV8WgyMRFYHD5CCLKmFNU2OnmEm2f2vGhaoS2h28A9BEGx1CWEUw3tfldf/+VWlBAnIBylFjHzbSo7fgn7S3fFEAZHTxoy+9jNIoynqHZbn4Y6eucj1YCw0ZmuKHPpPPrvclbhHmaZHfau+SKyag3C0/cj7zu4mBkRZ39zuk9B7DAADzaRENOZ/ZyibU+zs3gibnCbI2NWEnQWIiCi7vK0jq/FCBWytHihQM364zlVrPPCBDbv2MSqk4fyAM7IDeT6h/z/2kmDOQ6aFPYlLojIkgCCOIevQITS9E+BS1rgmmH+DRKsJNiD257aLhX2/F53VEnjfqqKdDs2lqfX0dCMLqselGUT981fFKceXg+r6hQqcUzLlF28XL5NrfVPreRDo6jI2K0tCy9cOx+cxH3yoDzOFBzM0RlxWqvUhRsMv9ZGfpgCZ0o9HxNObqLjVCQzE5SWPXvmkw+QpWk0oNUvpCEDhj9Vfq6XCV8j3tT3tZTYCa5UQy9VCdmval/2vb50QaAgDYXU6PH/9Xv7AXg6kg29iK+Ec0euxZxosRoVczzRg+0Arl/zvBcphWNIUTdx5IcA12WtP+krk9NNGtj7igk21DhcseJrKBpG7ll9O/Wmq1L8BwW+ypuJS+kHV61jRNYMFJY48Pt11Zoukgqu94kzrhz+KET8q463zlyu/Kp2z5yWI8xwvOtuyjosszfm6/YFQTFdhcmHY3X1yz44NaVG9FPev1QPoPmI7K3Jqa0Q8Q5kQTbe/KrB0eyRpXtyAaShOEeiS2ypmFAC81/m4mjuTd24yAjBcTIfBYzjxwjPbKfv+OYKahDwJP1b7EhsM+Sgu48wQ+pp6wc8TYCOkiRR1pKeb3kaxpQGzlq7VNbWHFPw9TDiyCIEnr8T5eiJtzJJ0U0iIfqN5WHk7iHiNK4Y4TvmdF4f6UyeMTHvaprvzUZI8il5wvoCgIiRUY7qvv5V/KL4ZWHN6Y3EEvQmP4WDo3Wx5IFW8C1gkyFv8lQ1COSNYMPog6RLAI0rNvKZjvc4baWwcHmk/fM92X19F2Y0DArqLFFUTJVE5bUQXQexiUO1e8IL07wqY=",
		"nonce": "d8816e8d6dca4409b790a4bcaa25c621"
	}
}
```

{% endcode %}

### 返回示例 <a href="#fan-hui-shi-li" id="fan-hui-shi-li"></a>

```
success
```

成功收到回调请求后请返回 `success` 以告知通知服务器。当通知服务器收到 `success` 后，将停止通知。否则将会按照 0s/15s/30s/3m/10m/20m/30m/60m/3h/6h 的频率通知10次。


# 错误码


# 业务状态码

| 状态码   | 说明           | 建议                                                   |
| ----- | ------------ | ---------------------------------------------------- |
| 0     | 成功           |                                                      |
| 100   | 请求参数错误       | 通常出现在`POST`请求上，请检查 json 结构是否正确                       |
| 103   | 无效签名         | 请查看 [生成签名](/chinese/shuo-ming/qian-ming-sheng-cheng) |
| 104   | 签名过期         | 请重新签名或检查服务器时间。                                       |
| 11000 | 操作失败，请稍后再试   | 通常是业务发生变化，或不能操作，可放弃或重试，根据 `msg` 的提示进行调整              |
| 11001 | 操作过于频繁，请稍后再试 | 针对`app_id`限制每秒钟请求 `5` 次。请降低请求频率或新增应用                 |
| 11003 | 缺少必要参数       | 请仔细核对文档和实际请求的参数类型和值是否合理有效                            |
| 12001 | 数据已存在        |                                                      |
| 12002 | 数据不存在        |                                                      |
| 12003 | 数据为空         |                                                      |
| 20000 | 应用不存在        |                                                      |
| 20001 | 应用已被禁用       |                                                      |
| 20002 | 余额不足         | 请到用户中心 充值                                            |
| 20003 | 配额不足         |                                                      |
| 20004 | 请求频率受限       |                                                      |
| 20005 | 无效参数         | 根据 `msg` 的提示进行调整                                     |


# Welcome 👏

{% hint style="info" %}
Tokenpay

Commercial payment system for whole mainstream cryptocurrencies.
{% endhint %}

### Preparation <a href="#preparation" id="preparation"></a>

Welcome to read the `API` payment access document. Before starting access, you need to do something:

1. Access and login [merchant backstage](https://ttpay.io/console?lang=en).
2. Create a payment app in the merchant backstage, and it will be generated `APP_ID` and `APP_PSECRET` for API calls after creation..
3. Read [access instructions](/description/access-instructions) relevant content.

You can try to [place an order](/order/order-creation) request by interface now.

### Having trouble? <a href="#having-trouble" id="having-trouble"></a>

If you encounter any problems during the access process. Please preferentially read our [access instructions](/description/access-instructions) document.&#x20;


# Description


# Access instructions

#### Domain Name <a href="#domain-name" id="domain-name"></a>

```
https://api.tokenpay.me
```

### Code <a href="#code" id="code"></a>

Unified code as `utf-8`.

### Secret key <a href="#secret-key" id="secret-key"></a>

API document mentions `APP_ID` and `APP_SECRECT` that can be obtained in the [merchant backstage](https://ttpay.io/console?lang=en).

### Field required <a href="#field-required" id="field-required"></a>

For fields marked `true` as a mandatory parameter for the interface, a specific value must be passed in.

### Data submission <a href="#data-submission" id="data-submission"></a>

Query class interface unified uses `GET` method request, and operation class interface unified use `POST` method request.

`POST` request header fields are `content-type`: `application/json`.


# Safety information

### Secret key <a href="#secret-key" id="secret-key"></a>

Merchants apply `APP_ID` and `APP_SECRECT` which is very important. Do not display in any web code or url parameters.

### Interface security <a href="#interface-security" id="interface-security"></a>

The `IP white list` of the merchant can configure the application in the merchant backstage to prevent asset security problems caused by key leakage.

### HTTPS <a href="#https" id="https"></a>

API All interfaces are transmitted using the `HTTPS` encryption protocol, some interfaces need to be provided `notify_url & redirect_url`. It is recommended that merchants deploy `HTTPS` services to the server to ensure the security of data communication.


# Payment method

The main payment access method:  `platform collection` and `platform collection(white label)`

Method introduction

The first two `access methods` require merchants to prepare their own wallets, and the funds are transferred to the merchant's own wallet. The platform is only responsible for notifying the merchant through asynchronous callbacks after monitoring the receipt records.

#### Platform collection <a href="#platform-collection" id="platform-collection"></a>

It simply accesses, and there is no need for the merchant to prepare a collection wallet. It also supports `multi-chain` `multi-currency` `multi-wallet` payment, funds `do not need to be collected`. It can `cross-chain withdrawal` and provide `integrated cash register`(support to adapt PC, H5).`multi-currency report`、`multi-ink report` and `account detail` can trace. The method does users worry-free and a one-stop collection service.

#### Platform collection（white label） <a href="#platform-collection" id="platform-collection"></a>

System Wallet based white label services, cryptocurrency payments on your website, `no payment logo`, customized cash registers for branded merchants


# Signature generation

{% hint style="info" %}
TIP

Merchants can follow the steps below to generate the signature of the request, and the platform will verify the signature after receiving the request. If the signature verification fails, the request is refused and the appropriate [status code](/error-code/status-code) is returned.
{% endhint %}

### Preparation <a href="#preparation" id="preparation"></a>

Merchants need to register with a merchant number and create a payment application through the merchant backstage to obtain `APP_ID` and `APP_SECRECT`.

### Condition <a href="#condition" id="condition"></a>

All interfaces of the `POST` method in this document need to validate the signature, and other interfaces do not need to validate for the moment.

### Generation <a href="#generation" id="generation"></a>

The signature string has four lines, one parameter per action. The line ends with `\n` (line break, The ASCII encoding value is 0x0A), and don't add `\n` on the last line. If the parameter itself ends in `\n` , you also need to attach an `\n` .

```
URL\n
Request timestamp\n
Request random string\n
Request message body
```

Let's take [order inquiry](/order/order-inquiry) as an example.

The first step is to get the absolute URL of the request and remove the domain name part to get the participating signed URL. If there are query parameters in the request, the URL should be appended with '? 'and the corresponding query string.

```
/v1/transaction/query
```

The second step is to obtain the current timestamp (milliseconds) of the system when the request is initiated. That is to say, the total number of seconds from 00:00 00 GMT on January 1, 1970, to the present, as the request timestamp. The platform will refuse to process requests made long ago, please keep the time of the merchant's own system accurate.

```
1554208460
```

The third step is to generate a 32-bit `random string`.

```
593BEC0C930BF1AFEB40B4A08C8FB242
```

The fourth step is to obtain the request message body in the request(request body).

```json
{
    "app_id": "8e4b8c2e7cxxxxxxxx1a1cbd3d59e0bd",
    "mch_id": "12345678",
    "transaction_id": "e98b30294xxxxxxxxxxxx97a9d9e09ce",
    "out_trade_no": "fb72xxxx-xxxx-xxxx-xxxx-xxxx8a7b52cb"
}
```

The fifth step is to construct the request signature string according to the previous rules as follows:

```html
/v1/transaction/query\n
1554208460\n
593BEC0C930BF1AFEB40B4A08C8FB242\n
{"app_id":"8e4b8c2e7cxxxxxxxx1a1cbd3d59e0bd","mch_id":"12345678","transaction_id":"e98b30294xxxxxxxxxxxx97a9d9e09ce","out_trade_no":"fb72xxxx-xxxx-xxxx-xxxx-xxxx8a7b52cb"}
```

### Encryption <a href="#encryption" id="encryption"></a>

Take the javascript encryption process as an example:

```json
let cryptoJs = require("crypto-js");
let key = CryptoJS.enc.Utf8.parse("9db664697xxxxxxxxxxxx2d27a3c925c") //the secret key of APP
//AES encryption
let ciphertext = cryptoJs.AES.encrypt(Signature string, key, {
  mode: CryptoJS.mode.ECB,
  padding: CryptoJS.pad.Pkcs7,
}).toString();
```

Example after encryption:

```
QCwHvoBM9TJ2wokF8hhaoS34P0nkJpYMisBUizpOj5q/77I6+KFPVvFUCaaUiu+KFctisJFU1DfJdCHrLpJIx9CirX5ku3L9TMGihFcEG8MGoh2dwDvunH8JgJOVV9ClSkpXqjad4flSuYMoxPOZqPHr+ktOLZ3pPzs12BMqmbZVNIe+oOezTZsQ8xxxxRgOJzwU/AbouZSl2xto7DcYCjvNSnw7BkuzBFgTfxVXB3+R7e+1SpdeJajuCKGKvYMVTe7slS5j/4LQ4vcr1QqOPhpoemsOV92tPhgQ0iGw3GKpLIEOoDAwy2+ojzP5XERh
```

### Concatenate <a href="#concatenate" id="concatenate"></a>

The splice format of signature information is as follows:\
app\_id=`APP_ID`, mch\_id=`Merchant ID`, nonce\_str=`The random string generated in step 3`,timestamp=`The timestamp generated in step 2`, signature=`Cryptographic signature string`.

### HTTP header <a href="#http-header" id="http-header"></a>

The document API passes the signature through an HTTP `Authorization` header. `Authorization` consists of two parts: `authentication type` and `signature information`. `authentication type` only supports `TTPAY-AES-256-ECB` for the moment.

```
Authorization: authentication type  signature information
```

Authorization header as follows: (Notes: Example because typesetting may contain line breaks, the actual data should be on one line)

```
Authorization: TTPAY-AES-256-ECB app_id=8e4b8c2e7cxxxxxxxx1a1cbd3d59e0bd,mch_id=12345678,nonce_str=593BEC0C930BF1AFEB40B4A08C8FB242,timestamp=1554208460,signature=QCwHvoBM9TJ2wokF8hhaoS34P0nkJpYMisBUizpOj5q/77I6+KFPVvFUCaaUiu+KFctisJFU1DfJdCHrLpJIx9CirX5ku3L9TMGihFcEG8MGoh2dwDvunH8JgJOVV9ClSkpXqjad4flSuYMoxPOZqPHr+ktOLZ3pPzs12BMqmbZVNIe+oOezTZsQ8xxxxRgOJzwU/AbouZSl2xto7DcYCjvNSnw7BkuzBFgTfxVXB3+R7e+1SpdeJajuCKGKvYMVTe7slS5j/4LQ4vcr1QqOPhpoemsOV92tPhgQ0iGw3GKpLIEOoDAwy2+ojzP5XERh"
```

Finally, we can create an HTTP request that contains a signature.

```sh
$ curl https://api.tokenpay.me/v1/transaction/query -H "Content-Type: application/json" -H 'Authorization: TTPAY-AES-256-ECB
 app_id=8e4b8c2e7cxxxxxxxx1a1cbd3d59e0bd,mch_id=12345678,nonce_str=593BEC0C930BF1AFEB40B4A08C8FB242,timestamp=1554208460,signature=QCwHvoBM9TJ2wokF8hhaoS34P0nkJpYMisBUizpOj5q/77I6+KFPVvFUCaaUiu+KFctisJFU1DfJdCHrLpJIx9CirX5ku3L9TMGihFcEG8MGoh2dwDvunH8JgJOVV9ClSkpXqjad4flSuYMoxPOZqPHr+ktOLZ3pPzs12BMqmbZVNIe+oOezTZsQ8xxxxRgOJzwU/AbouZSl2xto7DcYCjvNSnw7BkuzBFgTfxVXB3+R7e+1SpdeJajuCKGKvYMVTe7slS5j/4LQ4vcr1QqOPhpoemsOV92tPhgQ0iGw3GKpLIEOoDAwy2+ojzP5XERh' -X POST -d '{"out_trade_no": "fb72xxxx-xxxx-xxxx-xxxx-xxxx8a7b52cb", "transaction_id":"e98b30294xxxxxxxxxxxx97a9d9e09ce", "app_id":"8e4b8c2e7cxxxxxxxx1a1cbd3d59e0bd", "mch_id":"12345678" }'
```

### Demo code <a href="#demo-code" id="demo-code"></a>

{% tabs %}
{% tab title="Java" %}

```java
package com.example.http;

import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.JSONObject;
import com.sun.istack.internal.NotNull;
import okhttp3.*;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.security.Security;
import java.util.Base64;

public class HttpApplication {
    private static String SECRET = "AES";
    private static String CIPHER_ALGORITHM = "AES/ECB/PKCS7Padding";
    private static String schema = "TTPAY-AES-256-ECB ";

    public static void main(String[] args) throws Exception {
        String key = "xxxxxxxx";    // AppSecret
        String reqURL = "/v1/transaction/query";    // Request interface

        OkHttpClient client = new OkHttpClient();
        JSONObject params = new JSONObject();

        try {
            params.put("app_id", "xxxxxxxx");           // Application ID
            params.put("mch_id", "xxxxxxxx");           // Merchat ID
            params.put("transaction_id", "xxxxxxxx");   // Platform order number
            params.put("out_trade_no", "xxxxxxxx");     // Merchat order number
        } catch (JSONException e) {
            e.printStackTrace();
        }

        Security.addProvider(new BouncyCastleProvider());

        // Signature
        String auth = auth(reqURL, params, key);

        RequestBody body = RequestBody.create(MediaType.parse("application/json;charset=utf-8"), params.toString());
        Request request = new Request.Builder()
        .header("Authorization", auth)
        .url(reqURL)
        .post(body)
        .build();

        client.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                System.out.println("http request error");
            }

            @Override
            public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
                System.out.println(response.body().string());
            }
        });
    }

    /**
    * Signature
    * @param reqURL Request URL
    * @param raw Message body
    * @param key AppSecret
    * @return Signature information
    */
    public static String auth(String reqURL, JSONObject raw, String key) throws Exception {
        HttpUrl parseReqURL = HttpUrl.parse(reqURL);
        String url = parseReqURL.encodedPath();
        String appID = raw.getString("app_id");
        String mchID = raw.getString("mch_id");
        long currentTimeMillis = System.currentTimeMillis();
        String timestamp = String.valueOf(currentTimeMillis);
        String nonceStr = randomString(32);
        String message = url + "\n" + timestamp + "\n" + nonceStr + "\n" + raw.toString();
        String aes256ECBPkcs7PaddingEncrypt = aes256ECBPkcs7PaddingEncrypt(message, key);

        return schema + "app_id=" + appID + ",mch_id=" + mchID + ",nonce_str=" + nonceStr + ",timestamp=" + timestamp + ",signature=" + aes256ECBPkcs7PaddingEncrypt;
    }

    /**
    * Generate random string
    * @param len String length
    * @return Random string
    */
    public static String randomString(Integer ...len) {
        int e = len.length <= 0 ? 32 : len[0];
        String str = "ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678";
        int strLen = str.length();
        StringBuilder stringBuilder = new StringBuilder();

        for (int i = 0; i < e; i++) {
            double random = Math.random();
            int v = (int) Math.floor(random * strLen);
            char charAt = str.charAt(v);

            stringBuilder.append(charAt);
        }

        return stringBuilder.toString();
    }

    /**
    * AES encryption
    * @param str String
    * @param key Secret key
    * @return Cryptographic string
    * @throws Exception Abnormal information
    */
    public static String aes256ECBPkcs7PaddingEncrypt(String str, String key) throws Exception {
        Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
        byte[] keyBytes = key.getBytes(StandardCharsets.UTF_8);

        cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(keyBytes, SECRET));

        byte[] doFinal = cipher.doFinal(str.getBytes(StandardCharsets.UTF_8));

        return new String(Base64.getEncoder().encode(doFinal));
    }

    /**
    * AES encryption
    * @param str String
    * @param key Secret key
    * @return Decryption string
    * @throws Exception Abnormal information
    */
    public static String aes256ECBPkcs7PaddingDecrypt(String str, String key) throws Exception {
        Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
        byte[] keyBytes = key.getBytes(StandardCharsets.UTF_8);

        cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(keyBytes, SECRET));

        byte[] doFinal = cipher.doFinal(Base64.getDecoder().decode(str));

        return new String(doFinal);
    }
}
```

{% endtab %}

{% tab title="Go" %}

```go
package main

import (
	"bytes"
	"encoding/base64"
	"encoding/json"
	"fmt"
	"io"
	"math/rand"
	"net/http"
	"time"

	"github.com/forgoer/openssl"
)

const (
	SignatureMessageFormat = "%s\n%d\n%s\n%s" // The original format of the digital signature
	HeaderAuthorizationFormat = "%s app_id=%s,mch_id=%s,nonce_str=%s,timestamp=%d,signature=%s"
)

type QueryReq struct {
	AppID         string `json:"app_id"`
	MchID         string `json:"mch_id"`
	TransactionID string `json:"transaction_id,omitempty"`
	OutTradeNo    string `json:"out_trade_no,omitempty"`
}

func main() {

	appSecret := "**********"           // AppSecret
	reqPath := "/v1/transaction/query"  // Request interface path
	queryReq := QueryReq{
		AppID:         "**********",    // Application ID
		MchID:         "**********",    // Merchat ID
		TransactionID: "**********",    // Platform order number
		OutTradeNo:    "**********",    // Merchat order number
	}

	b, _ := json.Marshal(queryReq)

    // Signature
	authorization, err := GenerateAuthorizationHeader(queryReq.AppID, queryReq.MchID, reqPath, string(b), appSecret)
	if err != nil {
		panic(err)
	}

    // Request interface
	url := "" + reqPath

	payload := bytes.NewBuffer(b)

	req, _ := http.NewRequest("POST", url, payload)

	req.Header.Set("Accept", "application/json")
	req.Header.Set("Content-Type", "application/json")
	req.Header.Set("Authorization", authorization)

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(string(body))
}

// Signature
func GenerateAuthorizationHeader(appID, mchID, reqURL, signBody, appSecret string) (string, error) {
	nonceStr := RandomString(32)
	timestamp := time.Now().Unix()
	message := fmt.Sprintf(SignatureMessageFormat, reqURL, timestamp, nonceStr, signBody)

	signatureResult, err := AesECBEncrypt(message, appSecret)
	if err != nil {
		return "", err
	}
	authorization := fmt.Sprintf(
		HeaderAuthorizationFormat, getAuthorizationType(), appID,
		mchID, nonceStr, timestamp, signatureResult,
	)
	return authorization, nil
}

// AES encryption
func AesECBEncrypt(orig, key string) (string, error) {
	dst, _ := openssl.AesECBEncrypt([]byte(orig), []byte(key), openssl.PKCS7_PADDING)
	return base64.StdEncoding.EncodeToString(dst), nil
}

// AES encryption
func AesECBDecrypt(crypted, key string) (string, error) {
	x := len(crypted) * 3 % 4
	switch {
	case x == 2:
		crypted += "=="
	case x == 1:
		crypted += "="
	}
	crytedByte, err := base64.StdEncoding.DecodeString(crypted)
	if err != nil {
		return "", err
	}
	origData, err := openssl.AesECBDecrypt(crytedByte, []byte(key), openssl.PKCS7_PADDING)
	if err != nil {
		return "", err
	}
	return string(origData), err
}

// Generate random character
func RandomString(length int) string {
	str := []byte("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
	var result []byte
	rnd := rand.New(rand.NewSource(time.Now().UnixNano()))
	for i := 0; i < length; i++ {
		result = append(result, str[rnd.Intn(len(str))])
	}
	return string(result)
}

func getAuthorizationType() string {
	return "TTPAY-AES-256-ECB"
}
```

{% endtab %}

{% tab title="PHP" %}

```php
<?php
$key = "xxxxxxxx";                //  AppSecret
$APP_ID = "xxxxxxxx";              // Application ID
$mchID = "xxxxxxxx";              // Merchat ID
$transactionID = "xxxxxxxx";      // Platform order number
$outTradeNo = "xxxxxxxx";         // Merchat order number
$url = "/v1/transaction/query";   // Interface path
$timestamp = time();              // Current timestamp
$nonce = generateStr(32);         // 32-bit random string

// Generate random string
function generateStr($length) {
  $chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
  $res ='';

  for ( $i = 0; $i < $length; $i++ ) {
    $res .= $chars[ mt_rand(0, strlen($chars) - 1) ];
  }

  return $res;
}

// Message body
$body = '{"app_id":"'.$APP_ID.'","mch_id":"'.$mchID.'","transaction_id":"'.$transactionID.'","out_trade_no":"'.$outTradeNo.'"}';

// Construct signature string
$message = $url."\n".$timestamp."\n".$nonce."\n".$body;

// Encrypt signature string
$cipher = "aes-256-ecb";
$sign = openssl_encrypt($message, $cipher, $key);

// Split signature information
$schema = 'TTPAY-AES-256-ECB';
$authorization = sprintf('%s app_id=%s,mch_id=%s,nonce_str=%s,timestamp=%d,signature=%s', $schema, $APP_ID, $mchID, $nonce, $timestamp, $sign);

// Set HTTP header
$header[] = "Accept: application/json";
$header[] = "Content-Type: application/json";
$header[] = "Authorization: $authorization";

// Request interface
$curl = curl_init();
curl_setopt($curl, CURLOPT_HTTPHEADER, $header);
curl_setopt($curl, CURLOPT_URL, "".$url);
curl_setopt($curl, CURLOPT_POSTFIELDS, $body);
curl_setopt($curl, CURLOPT_POST, 1);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
$result = curl_exec($curl);
curl_close($curl);

var_export($result);
```

<br>
{% endtab %}

{% tab title="JavaScript" %}

```javascript
let cryptoJs = require("crypto-js");

let jsonObj = JSON.parse(pm.request.body.raw); //Convert the submitted body string into an object
let jsonStr = JSON.stringify(jsonObj)//Turn the object back into a string to compress, avoiding line breaks in the body that affect signature compression.
let appID = jsonObj.app_id;
let mchID = jsonObj.mch_id;

// Generate the current timestamp
let timestamp = Math.round(new Date() / 1000).toString()

//Define random string
var nonceStr = randomString(); // Random string
function randomString(e) {
    e = e || 32;
    var t = "ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678",
    a = t.length,
    n = "";
    for (i = 0; i < e; i++) n += t.charAt(Math.floor(Math.random() * a));
    return n
}

//Get the full path
var reqURL = "/" + pm.request.url.path.join("/");

//Splice signature plaintext
message = reqURL + "\n" + timestamp + "\n" + nonceStr + "\n" + jsonStr

let key = CryptoJS.enc.Utf8.parse("********************************") // AppSecret
//AES encryption
let ciphertext = cryptoJs.AES.encrypt(message, key, {
    mode: CryptoJS.mode.ECB,
    padding: CryptoJS.pad.Pkcs7,
  }).toString();

//Splice on the authorization of Header, TTPAY-{EncryMode)},currently supports only AES-256-ECB
let authorization = 'TTPAY-AES-256-ECB app_id=' + appID + ',mch_id=' + mchID + ',nonce_str=' + nonceStr + ',timestamp=' + timestamp + ',signature=' + ciphertext

pm.request.headers.upsert({ key: "authorization", value: authorization })
```

{% endtab %}
{% endtabs %}


# Signature verification

{% hint style="info" %}
TIP

The merchant can verify the signature of the response or callback by following the steps below.

If the request signature of the verified merchant is correct, tokenpay includes the reply signature in the HTTP header of the reply. We recommend that merchants verify the response signature.

Similarly, tokenpay includes the signature of the callback packet in the HTTP header of the callback. The merchant must verify the signature of the callback to ensure that the callback was sent by tokenpay.
{% endhint %}

### Concatenate <a href="#concatenate" id="concatenate"></a>

Firstly, the merchant obtains the following information from the response.

* Reply timestamp in HTTP header TTPay-Timestamp.
* Reply to a random string in the HTTP header TTPay-Nonce.
* Response Body, check the interface according to the order returned by the interface. An incorrect order will cause the check failure.

The signature string has three lines, one parameter per action. The line ends with `\n` (line break, The ASCII encoding value is 0x0A), and don't add `\n` on the last line. If the parameter itself ends in `\n` , you also need to attach an `\n`.

```
Reply timestamp\n
Reply random string\n
Reply message body
```

For example, an HTTP reply message is as follows:

```
HTTP/1.1 200 OK
Server: nginx
Date: Tue, 02 Apr 2019 12:59:40 GMT
Content-Type: application/json; charset=utf-8
Content-Length: 2204
Connection: keep-alive
Keep-Alive: timeout=8
Content-Language: zh-CN
TTPay-Nonce: c5ac7061fccab6bf3e254dcf98995b8c
TTPay-Signature: CtcbzwtQjN8rnOXItEBJ5aQFSnIXESeV28Pr2YEmf9wsDQ8Nx25ytW6FXBCAFdrr0mgqngX3AD9gNzjnNHzSGTPBSsaEkIfhPF4b8YRRTpny88tNLyprXA0GU5ID3DkZHpjFkX1hAp/D0fva2GKjGRLtvYbtUk/OLYqFuzbjt3yOBzJSKQqJsvbXILffgAmX4pKql+Ln+6UPvSCeKwznvtPaEx+9nMBmKu7Wpbqm/+2ksc0XwjD+xlvlECkCxfD/OJ4gN3IurE0fpjxIkvHDiinQmk51BI7zQD8k1znU7r/spPqB+vZjc5ep6DC5wZUpFu5vJ8MoNKjCu8wnzyCFdA==
TTPay-Timestamp: 1554209980
Cache-Control: no-cache, must-revalidate

{"app_id":"xxxx"}
```

Then the signature string is

```
1554209980
c5ac7061fccab6bf3e254dcf98995b8c
{"app_id":"xxxx"}
```

### Reply <a href="#reply" id="reply"></a>

The tokenpay reply signature is transmitted through the HTTP header TTPay-Signature. (Note: Example because typesetting may contain line breaks, the actual data should be on one line)

```
CtcbzwtQjN8rnOXItEBJ5aQFSnIXESeV28Pr2YEmf9wsDQ8Nx25ytW6FXBCAFdrr0mgqngX3AD9gNzjnNHzSGTPBSsaEkIfhPF4b8YRRTpny88tNLyprXA0GU5ID3DkZHpjFkX1hAp/D0fva2GKjGRLtvYbtUk/OLYqFuzbjt3yOBzJSKQqJsvbXILffgAmX4pKql+Ln+6UPvSCeKwznvtPaEx+9nMBmKu7Wpbqm/+2ksc0XwjD+xlvlECkCxfD/OJ4gN3IurE0fpjxIkvHDiinQmk51BI7zQD8k1znU7r/spPqB+vZjc5ep6DC5wZUpFu5vJ8MoNKjCu8wnzyCFdA==
```

### Judgment <a href="#judgment" id="judgment"></a>

Use the method of `AES-256-ECB` to generate signatures (You can reference [signature generation](/description/signature-generation)). The generated signature is compared with the reply signature. If not, the data is tampered with.


# Decrypt callback

{% hint style="info" %}
TIP

In order to ensure security, tokenpay payment encrypts the key information in the callback notification interface with AES-256-GCM. After the merchant receiving the message, and needs to decrypt the plaintext. The key of APP is used for decryption. This chapter describes the format of the encrypted message and how to decrypt it.
{% endhint %}

### Encrypt message format <a href="#encrypt-message-format" id="encrypt-message-format"></a>

First, the merchant get the following information from the answer.

* AES-GCM is a NIST-standardized [authenticated encryption](https://en.wikipedia.org/wiki/Authenticated_encryption)algorithm, a mode of encryption that simultaneously guarantees the confidentiality, integrity, and authenticity of data. It is most widely used in TLS.
* The key used for the callback message is the APP key.
* For the encrypted data, we use a separate JSON object to represent it. In order to read conveniently, the example uses Pretty formatting and adds comments.

```json
{
    "original_type": "transaction", // Object types before encryption
    "algorithm": "AEAD_AES_256_GCM", // Encryption algorithm

    // After encoding with Base6
    "ciphertext": "...",

    // Random string initialization vector used for encryption
    "nonce": "...",
}
```

Note: The encrypted random string has nothing to do with the random string used for signing. They're not the same.

### Decryption <a href="#decryption" id="decryption"></a>

* Algorithmic interface details, you can refer to [rfc5116](https://datatracker.ietf.org/doc/html/rfc5116).
* Most of the programming languages (newer version) both support AEAD\_AES\_256\_GCM. Developers can refer to the following example, and learn how to implement decryption using your programming language.

### Code example <a href="#code-example" id="code-example"></a>

{% tabs %}
{% tab title="Java" %}

```java
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;
import javax.crypto.Cipher;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.GCMParameterSpec;
import javax.crypto.spec.SecretKeySpec;

public class AesUtil {
  static final int KEY_LENGTH_BYTE = 32;
  static final int TAG_LENGTH_BIT = 128;
  private final byte[] aesKey;

    public AesUtil(byte[] key) {
      if (key.length != KEY_LENGTH_BYTE) {
        throw new IllegalArgumentException("无效的AppSecret，长度必须为32个字节");
        }
      this.aesKey = key;
    }

  public String decryptToString(byte[] nonce, String ciphertext)
  throws GeneralSecurityException, IOException {
    try {
        Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
        SecretKeySpec key = new SecretKeySpec(aesKey, "AES");
        GCMParameterSpec spec = new GCMParameterSpec(TAG_LENGTH_BIT, nonce);

        cipher.init(Cipher.DECRYPT_MODE, key, spec);

        return new String(cipher.doFinal(Base64.getDecoder().decode(ciphertext)), "utf-8");
       } catch (NoSuchAlgorithmException | NoSuchPaddingException e) {
         throw new IllegalStateException(e);
       } catch (InvalidKeyException | InvalidAlgorithmParameterException e) {
         throw new IllegalArgumentException(e);
        }
    }
}

```

<br>
{% endtab %}

{% tab title="PHP" %}

````php
class AesUtil {
  /**
  * AES key
  *
  * @var string
  */
  private $aesKey;

  const KEY_LENGTH_BYTE = 32;
  const AUTH_TAG_LENGTH_BYTE = 16;

 /**
  * Constructor
  */
  public
  function __construct($aesKey) {
    if (strlen($aesKey) != self::KEY_LENGTH_BYTE) {
      throw new InvalidArgumentException('无效的AppSecret，长度应为32个字节');
    }
     $this - > aesKey = $aesKey;
    }

   /**
    * Decrypt AEAD_AES_256_GCM ciphertext
    *
    * @param string    $associatedData     AES GCM additional authentication data
    * @param string    $nonceStr           AES GCM nonce
    * @param string    $ciphertext         AES GCM cipher text
    *
    * @return string|bool      Decrypted string on success or FALSE on failure
    */
  public
  function decryptToString($associatedData, $nonceStr, $ciphertext) {
    $ciphertext = \base64_decode($ciphertext);
    if (strlen($ciphertext) <= self::AUTH_TAG_LENGTH_BYTE) {
      return false;
    }

    // ext-sodium (default installed on >= PHP 7.2)
    if (function_exists('\sodium_crypto_aead_aes256gcm_is_available') && \sodium_crypto_aead_aes256gcm_is_available()) {
        return \sodium_crypto_aead_aes256gcm_decrypt($ciphertext, $associatedData, $nonceStr, $this - > aesKey);
      }

    // ext-libsodium (need install libsodium-php 1.x via pecl)
    if (function_exists('\Sodium\crypto_aead_aes256gcm_is_available') && \Sodium\crypto_aead_aes256gcm_is_available()) {
      return \Sodium\crypto_aead_aes256gcm_decrypt($ciphertext, $associatedData, $nonceStr, $this - > aesKey);
    }

    // openssl (PHP >= 7.1 support AEAD)
    if (PHP_VERSION_ID >= 70100 && in_array('aes-256-gcm', \openssl_get_cipher_methods())) {
    $ctext = substr($ciphertext, 0, -self::AUTH_TAG_LENGTH_BYTE);
    $authTag = substr($ciphertext, -self::AUTH_TAG_LENGTH_BYTE);

    return \openssl_decrypt($ctext, 'aes-256-gcm', $this - > aesKey, \OPENSSL_RAW_DATA, $nonceStr,$authTag, $associatedData);

    }
    throw new \RuntimeException('AEAD_AES_256_GCM需要PHP 7.1以上或者安装libsodium-php');
  }
}

  </CodeGroupItem>

  <CodeGroupItem title="Java">

```java:no-line-numbers
OkHttpClient client = new OkHttpClient().newBuilder()
   .build();
MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "<body data here>");
Request request = new Request.Builder()
   .url("https://api.ttpay.io/v1/wallet/update")
   .method("POST", body)
   .addHeader("Authorization", "<Authorization>")
   .addHeader("User-Agent", "TTPay API (https://ttpay.io)")
   .addHeader("Content-Type", "application/json")
   .build();
Response response = client.newCall(request).execute();
````

{% endtab %}

{% tab title="Aspnet" %}

```
public class AesGcm {
  private static string ALGORITHM = "AES/GCM/NoPadding";
  private static int TAG_LENGTH_BIT = 128;
  private static int NONCE_LENGTH_BYTE = 12;
  private static string AES_KEY = "yourkeyhere";

  public static string AesGcmDecrypt(string associatedData, string nonce, string ciphertext)
  {
    GcmBlockCipher gcmBlockCipher = new GcmBlockCipher(new AesEngine());
    AeadParameters aeadParameters = new AeadParameters(
      new KeyParameter(Encoding.UTF8.GetBytes(AES_KEY)),
      128,
      Encoding.UTF8.GetBytes(nonce),
      Encoding.UTF8.GetBytes(associatedData));
    gcmBlockCipher.Init(false, aeadParameters);

    byte[] data = Convert.FromBase64String(ciphertext);
    byte[] plaintext = new byte[gcmBlockCipher.GetOutputSize(data.Length)];
    int length = gcmBlockCipher.ProcessBytes(data, 0, data.Length, plaintext, 0);
    gcmBlockCipher.DoFinal(plaintext, length);
    return Encoding.UTF8.GetString(plaintext);
  }
}
```

{% endtab %}

{% tab title="Python" %}

```python
  from cryptography.hazmat.primitives.ciphers.aead import AESGCM
  import base64
  def decrypt(nonce, ciphertext, associated_data):

    key = "Your32Apiv3Key"

    key_bytes = str.encode(key)
    nonce_bytes = str.encode(nonce)
    ad_bytes = str.encode(associated_data)
    data = base64.b64decode(ciphertext)

    aesgcm = AESGCM(key_bytes)
    return aesgcm.decrypt(nonce_bytes, data, ad_bytes)
```

{% endtab %}
{% endtabs %}


# Data structure

#### Currency detail <a href="#currency-detail" id="currency-detail"></a>

{% hint style="info" %}
TIP

CurrencyDetail
{% endhint %}

| Name                     | Type    | Description                                 | Example                                                                 |
| ------------------------ | ------- | ------------------------------------------- | ----------------------------------------------------------------------- |
| network                  | string  | Network                                     | Example value: `TRX`、`TRC10`、`TRC20`、`TRC721`、`TRC1155`、`ERC20`、`BEP20` |
| chain                    | string  | Owned public chain                          | Example value: `TRON`、`ETHEREUM`、`BSC`                                  |
| code                     | string  | Currency code                               |                                                                         |
| currency                 | string  | Currency                                    |                                                                         |
| name                     | integer | Name                                        |                                                                         |
| logo                     | integer | LOGO                                        |                                                                         |
| contract\_address        | integer | Contract address                            |                                                                         |
| decimal                  | integer |                                             |                                                                         |
| Accuracy                 |         |                                             |                                                                         |
| is\_fiat                 | integer | Whether is it a fiat currency               | Yes `1` No `0`                                                          |
| payment\_qr\_code        | integer | Whether to support payment by scanning code | Yes `1` No `0`                                                          |
| payment\_connect\_wallet | integer | Whether to support payment by ConnectWallet | Yes `1` No `0`                                                          |
| payment\_tron\_link      | integer | Whether to support payment by tronlink      | Yes `1` No `0`                                                          |
| min\_payment\_amount     | integer | Minimum payment amount                      |                                                                         |
| max\_payment\_amount     | integer | Maximum payment amount                      |                                                                         |

#### Transaction detail <a href="#transaction-detail" id="transaction-detail"></a>

{% hint style="info" %}
TIP

TransactionDetail
{% endhint %}

| Name                       | Type    | Description                                                                                                                                                                          | Example                                                                |
| -------------------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------- |
| out\_trade\_no             | string  | Merchant order number                                                                                                                                                                |                                                                        |
| transaction\_id            | string  | Platform order number                                                                                                                                                                |                                                                        |
| description                | string  | Order description（utf8-mb4）                                                                                                                                                          |                                                                        |
| block\_no                  | integer | Block number, you can also query the block hash through this param                                                                                                                   |                                                                        |
| create\_time               | integer | Order creation time                                                                                                                                                                  |                                                                        |
| block\_time                | integer | Block time                                                                                                                                                                           |                                                                        |
| pay\_time                  | integer | Payment time ( only for success )                                                                                                                                                    |                                                                        |
| tx\_id                     | string  | Transaction hash                                                                                                                                                                     |                                                                        |
| from\_address              | string  | Payment address                                                                                                                                                                      |                                                                        |
| contract\_address          | string  | Contract address                                                                                                                                                                     |                                                                        |
| to\_address                | string  | Fund transfer address                                                                                                                                                                |                                                                        |
| amount                     | integer | Transaction amount                                                                                                                                                                   |                                                                        |
| decimals                   | integer | Transaction amount accuracy                                                                                                                                                          |                                                                        |
| pay\_amount                | integer | Amount actually paid                                                                                                                                                                 |                                                                        |
| pay\_decimal               | integer | Amount actually paid accuracy                                                                                                                                                        |                                                                        |
| pay\_currency              | string  | Actual payment currency                                                                                                                                                              |                                                                        |
| pay\_chain                 | string  | Actual payment public chain: TRON、ETHEREUM、BSC                                                                                                                                       |                                                                        |
| attach                     | string  | Additional data, returned as-is in the query API and payment notifications, can be used as a custom parameter, in practice only payment completion status is returned to this field. |                                                                        |
| service\_amount            | integer | Service charge                                                                                                                                                                       |                                                                        |
| service\_amount\_currency  | string  | Service charge currency                                                                                                                                                              |                                                                        |
| status                     | integer | Status                                                                                                                                                                               | 1: Unpaid 2: Successful payment 3: Forward refund 4: Closed            |
| currency                   | object  | Payment currency details                                                                                                                                                             |                                                                        |
| currency.network           | string  | Network                                                                                                                                                                              | Example value：`TRX`、`TRC10`、`TRC20`、`TRC721`、`TRC1155`、`ERC20`、`BEP20` |
| currency.chain             | string  | Owned public chain                                                                                                                                                                   | Example value：`TRON`、`ETHEREUM`、`BSC`                                  |
| currency.code              | string  | Currency code                                                                                                                                                                        |                                                                        |
| currency.currency          | string  | Currency                                                                                                                                                                             |                                                                        |
| currency.name              | string  | Name                                                                                                                                                                                 |                                                                        |
| currency.contract\_address | string  | Contract address                                                                                                                                                                     |                                                                        |
| currency.decimal           | integer |                                                                                                                                                                                      |                                                                        |

#### Notice details <a href="#notice-details" id="notice-details"></a>

{% hint style="info" %}
TIP

transactionNotifyDetail
{% endhint %}

| Name              | Type           | Description                                                                                                                                                                          | Example                                                                 |
| ----------------- | -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------- |
| out\_trade\_no    | string         | Merchant order number                                                                                                                                                                |                                                                         |
| transaction\_id   | string         | Platform order number                                                                                                                                                                |                                                                         |
| description       | string         | Order description（utf8-mb4）                                                                                                                                                          |                                                                         |
| block\_no         | integer        | Block number, you can also query the block hash through this param                                                                                                                   |                                                                         |
| create\_time      | integer        | Order creation time                                                                                                                                                                  |                                                                         |
| block\_time       | integer        | Block time                                                                                                                                                                           |                                                                         |
| pay\_time         | integer        | Payment time ( only for success )                                                                                                                                                    |                                                                         |
| tx\_id            | string         | Transaction hash                                                                                                                                                                     |                                                                         |
| from\_address     | string         | Payment address                                                                                                                                                                      |                                                                         |
| contract\_address | string         | Contract address                                                                                                                                                                     |                                                                         |
| to\_address       | string         | Fund transfer address                                                                                                                                                                |                                                                         |
| amount            | integer        | Transaction amount                                                                                                                                                                   |                                                                         |
| decimals          | integer        | Transaction amount accuracy                                                                                                                                                          |                                                                         |
| currency          | CurrencyDetail | CurrencyDetail                                                                                                                                                                       |                                                                         |
| pay\_amount       | integer        | Amount actually paid                                                                                                                                                                 |                                                                         |
| pay\_decimal      | integer        | Amount actually paid accuracy                                                                                                                                                        |                                                                         |
| pay\_currency     | string         | Actual payment currency                                                                                                                                                              |                                                                         |
| pay\_chain        | string         | Actual payment public chain TRON、ETHEREUM、BSC                                                                                                                                        |                                                                         |
| attach            | string         | Additional data, returned as-is in the query API and payment notifications, can be used as a custom parameter, in practice only payment completion status is returned to this field. |                                                                         |
| handle\_status    | integer        | Treatment Status                                                                                                                                                                     | 1: `Pending`; 2: `In progress`; 3:`Processed`; 4:`Wait for verificatio` |
| status            | integer        | Status                                                                                                                                                                               | 1:`Unpaid`; 2:`Successful payment`; 3:`Forward refund`; 4:`Closed`;     |
| sign              | string         | Signature                                                                                                                                                                            |                                                                         |
| price\_rate       | folat          | Currency exchange rate                                                                                                                                                               |                                                                         |

#### Payout detial <a href="#payanother-detial" id="payanother-detial"></a>

{% hint style="info" %}
TIP

PayoutTransactionDetail
{% endhint %}

| Name                       | Type    | Description                       | Description                                                                                                                                                     |
| -------------------------- | ------- | --------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| out\_trade\_no             | string  | Merchant order number             | Example value: `fb72xxxx-xxxx-xxxx-xxxx-xxxx8a7b52cb`                                                                                                           |
| transaction\_id            | string  | Platform order number             | Example value: `e98b30294xxxxxxxxxxxx97a9d9e09ce`                                                                                                               |
| trade\_type                | string  | Type of transaction               | Example value: DAPP、TRANSFER、API                                                                                                                                |
| description                | string  | Order description                 | Example value: `recharge`                                                                                                                                       |
| block\_no                  | integer | Block number                      | Example value: `33215220`                                                                                                                                       |
| create\_time               | integer | Order creation time               | Example value: `1673407302044`                                                                                                                                  |
| block\_time                | integer | Block time                        | Example value: `1673407329000`                                                                                                                                  |
| pay\_time                  | integer | Payment time                      | Example value: `1673407329000`                                                                                                                                  |
| tx\_id                     | string  | Transaction hash                  | Example value: `9fdf0ab5823e23225f93bcc644af30a6ab83b6583a8e29e359ee80219802a33a`                                                                               |
| from\_address              | string  | Payment address                   | Example value: `TULRFYoFuEmUbxxxxxxxx8nQYFHJ88888`                                                                                                              |
| contract\_address          | string  | Contract address                  | Example value: `TR7NHqjeKQxGTxxxxxxxxpL8otSzgjLj6t`                                                                                                             |
| to\_address                | string  | Collection address                | Example value: `TQjxEW2Z3p9wjoxxxxxxxxgJUrWXBun91w`                                                                                                             |
| amount                     | number  | Transaction amount                | Example value: `15000000`                                                                                                                                       |
| pay\_chain                 | integer | Actual payment public chain       | Example value: `TRON`、`ETHEREUM`、`BSC`. [View support public chain](/currency/currency-information)                                                             |
| decimals                   | integer | Token accuracy                    | Example value: `6`                                                                                                                                              |
| pay\_network               | string  | Payment network                   | Example value: TRX、TRC10、TRC20、TRC721、TRC1155、ERC20、BEP20                                                                                                       |
| pay\_currency              | string  | Actual currency of payment        |                                                                                                                                                                 |
| pay\_amount                | integer | Actual payments                   |                                                                                                                                                                 |
| pay\_decimal               | integer | Accuracy of actual payment amount |                                                                                                                                                                 |
| attach                     | string  | Self-defined parameter            | Returns as-is in the query API and payment notifications, can be used as a custom parameter, in practice only payment completion status will return this field. |
| service\_amount            | number  | Service charge                    | Example value: `45000`                                                                                                                                          |
| service\_rate              | folat   | Service charge rates              |                                                                                                                                                                 |
| service\_amount\_currency  | string  | Service charge                    | Example value: `USDT`                                                                                                                                           |
| status                     | integer | Status                            | Example value: `1`: Unpaid; `2`: Successful payment; `3`:Forward refund; `4`: Closed;                                                                           |
| handle\_status             | integer | Handle status                     | Example values: `1 :` Pending `2` : Processing `3` : Processed `4` : Pending verification                                                                       |
| currency                   | object  | Payment token details             |                                                                                                                                                                 |
| currency.network           | string  | Network                           | Example value：`TRX`、`TRC10`、`TRC20`、`TRC721`、`TRC1155`、`ERC20`、`BEP20`                                                                                          |
| currency.chain             | string  | Owned public chain                | Example value：`TRON`、`ETHEREUM`、`BSC`                                                                                                                           |
| currency.code              | string  | Currency code                     |                                                                                                                                                                 |
| currency.currency          | string  | Currency                          |                                                                                                                                                                 |
| currency.name              | string  | Name                              |                                                                                                                                                                 |
| currency.contract\_address | string  | Contract address                  |                                                                                                                                                                 |
| currency.decimal           | integer |                                   |                                                                                                                                                                 |

#### **merchantBalance**

{% hint style="info" %}
TIP

merchantBalance
{% endhint %}

| Name         | Type    | Description        | Description                                                             |
| ------------ | ------- | ------------------ | ----------------------------------------------------------------------- |
| merchant\_id | integer | Merchant ID        | Example value: `1234567890`                                             |
| mch\_id      | string  | Merchant ID        | Example value: `12345678`                                               |
| network      | string  | Network            | Example value: `TRX`、`TRC10`、`TRC20`、`TRC721`、`TRC1155`、`ERC20`、`BEP20` |
| chain        | string  | Owned public chain | Example value: `TRON`、`ETHEREUM`、`BSC`                                  |
| balance      | string  | Balance            |                                                                         |
| currency     | string  | Currency           |                                                                         |
| decimal      | integer |                    |                                                                         |
| create\_time | integer | Creation time      | Example value: `1673333676`                                             |
| modify\_time | integer | Modify time        | Example value: `1673333676`                                             |
| cash\_time   | integer | Cash time          | Example value: `1673333676`                                             |


# Currency


# Currency information

{% hint style="info" %}
TIP

Check all payment currencies supported by the platform.
{% endhint %}

### Interface address <a href="#interface-address" id="interface-address"></a>

```
GET https://api.tokenpay.me/v1/currency/index
```

### Interface parameters <a href="#interface-parameters" id="interface-parameters"></a>

Nothing.

### Interface return <a href="#interface-return" id="interface-return"></a>

| Name        | Type    | Description                                                   | Description                                                                         |
| ----------- | ------- | ------------------------------------------------------------- | ----------------------------------------------------------------------------------- |
| code        | integer | [Service status code](/error-code/status-code)                | Service status code. 0: success, non 0: indicate the specific cause reference `msg` |
| msg         | string  | Status service message                                        | Status service message                                                              |
| request\_id | string  | Request ID                                                    | Request ID                                                                          |
| data        | array   | [CurrencyDetail](/description/data-structure#currency-detail) | Content                                                                             |

### Return example <a href="#return-example" id="return-example"></a>

```json
{
    "code": 0,
    "msg": "ok",
    "request_id": "a4b4460f-4e47-4492-848c-ccd25540db2d",
    "data": [
        {
            "network": "BNB",
            "chain": "BSC",
            "code": "BINANCE_BNB",
            "currency": "BNB",
            "name": "Binance Coin",
            "logo": "https://xxx/binance_busd.png",
            "contract_address": "",
            "decimal": 18,
            "payment_qr_code": 1,
            "payment_connect_wallet": 1,
            "payment_tron_link": 0,
            "min_payment_amount": "0",
            "max_payment_amount": "0"
        },
        {
            "network": "BEP20",
            "chain": "BSC",
            "code": "BINANCE_BUSD",
            "currency": "BUSD",
            "name": "Binance USD",
            "logo": "https://xxx/binance_busd.png",
            "contract_address": "0xe9e7CEA3DedcA5984780Bafc599bD69ADd087D56",
            "decimal": 18,
            "payment_qr_code": 1,
            "payment_connect_wallet": 1,
            "payment_tron_link": 0,
            "min_payment_amount": "0",
            "max_payment_amount": "0"
        }
    ]
}
```

### Example code <a href="#example-code" id="example-code"></a>

{% tabs %}
{% tab title="Shell" %}

```sh
curl --location --request GET 'https://api.tokenpay.me/v1/currency/index' \
--header 'key: <key>' \
--header 'User-Agent: tokenpay.me Client/1.0.0 (https://api.tokenpay.me)' \
--header 'Content-Type: application/json' \
--data-raw '<body data here>'
```

{% endtab %}

{% tab title="Go" %}

```go
package main

import (
   "fmt"
   "strings"
   "net/http"
   "io/ioutil"
)

func main() {

   url := "https://api.tokenpay.me/v1/currency/index"
   method := "GET"

   payload := strings.NewReader(`<body data here>`)

   client := &http.Client {
   }
   req, err := http.NewRequest(method, url, payload)

   if err != nil {
      fmt.Println(err)
      return
   }
   req.Header.Add("key", "<key>")
   req.Header.Add("User-Agent", "tokenpay.me Client/1.0.0 (https://api.tokenpay.me)")
   req.Header.Add("Content-Type", "application/json")

   res, err := client.Do(req)
   if err != nil {
      fmt.Println(err)
      return
   }
   defer res.Body.Close()

   body, err := ioutil.ReadAll(res.Body)
   if err != nil {
      fmt.Println(err)
      return
   }
   fmt.Println(string(body))
}
```

{% endtab %}

{% tab title="PHP" %}

```php
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
   CURLOPT_URL => 'https://api.tokenpay.me/v1/currency/index',
   CURLOPT_RETURNTRANSFER => true,
   CURLOPT_ENCODING => '',
   CURLOPT_MAXREDIRS => 10,
   CURLOPT_TIMEOUT => 0,
   CURLOPT_FOLLOWLOCATION => true,
   CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
   CURLOPT_CUSTOMREQUEST => 'GET',
   CURLOPT_POSTFIELDS =>'<body data here>',
   CURLOPT_HTTPHEADER => array(
      'key: <key>',
      'User-Agent: tokenpay.me Client/1.0.0 (https://api.tokenpay.me)',
      'Content-Type: application/json'
   ),
));

$response = curl_exec($curl);

curl_close($curl);
echo $response;
```

<br>
{% endtab %}

{% tab title="Python" %}

```python
import http.client
import json

conn = http.client.HTTPSConnection("api.tokenpay.me")
payload = "<body data here>"
headers = {
   'key': '<key>',
   'User-Agent': 'tokenpay.me Client/1.0.0 (https://api.tokenpay.me)',
   'Content-Type': 'application/json'
}
conn.request("GET", "/v1/currency/index", payload, headers)
res = conn.getresponse()
data = res.read()
print(data.decode("utf-8"))
```

{% endtab %}

{% tab title="Java" %}

```java
OkHttpClient client = new OkHttpClient().newBuilder()
   .build();
MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "<body data here>");
Request request = new Request.Builder()
   .url("https://api.tokenpay.me/v1/currency/index")
   .method("GET", body)
   .addHeader("key", "<key>")
   .addHeader("User-Agent", "tokenpay.me Client/1.0.0 (https://api.tokenpay.me)")
   .addHeader("Content-Type", "application/json")
   .build();
Response response = client.newCall(request).execute();
```

{% endtab %}
{% endtabs %}


# Balance Inquiry

{% hint style="info" %}
TIP

Check account balance and real-time status
{% endhint %}

### Interface address <a href="#interface-address" id="interface-address"></a>

```
POST https://api.tokenpay.me/v1/merchant/balance
```

### Interface parameters <a href="#interface-parameters" id="interface-parameters"></a>

| Name     | Location | Type   | Required | Description                                                                                                          |
| -------- | -------- | ------ | -------- | -------------------------------------------------------------------------------------------------------------------- |
| mch\_id  | body     | string | Yes      | Merchant ID, example value:`12345678`                                                                                |
| chain    | body     | string | Yes      | Owned public chain, example value:`TRON`                                                                             |
| currency | body     | string | Yes      | Currency, example value:`TRX`. [View supported currencies](https://apidoc.tokenpay.me/currency/currency-information) |

### Interface return <a href="#interface-return" id="interface-return"></a>

| Name        | Type    | Description                                                              | Description                                                                         |
| ----------- | ------- | ------------------------------------------------------------------------ | ----------------------------------------------------------------------------------- |
| code        | integer | [Service status code](https://apidoc.tokenpay.me/error-code/status-code) | Service status code. 0: success, non 0: indicate the specific cause reference `msg` |
| msg         | string  | Status service message                                                   | Status service message                                                              |
| request\_id | string  | Request ID                                                               | Request ID                                                                          |
| data        | array   | [merchantBalance](/description/data-structure#merchantbalance)           | Content                                                                             |

### Return example

```json
{
    "code": 0,
    "msg": "ok",
    "request_id": "08250916-a677-4a36-a090-323807ac644c",
    "data": {
     "merchant_id": 167,
        "mch_id": "12345678",
        "network": "TRC20",
        "chain": "TRON",
        "balance": "54670000",
        "currency": "USDT",
        "decimal": 6,
        "create_time": 1724237814113,
        "modify_time": 1724239248394,
        "cash_time": 0
    }
}
```

### Example code <a href="#example-code" id="example-code"></a>

{% tabs %}
{% tab title="Shell" %}

```sh
curl --location --request GET 'https://api.tokenpay.me/v1/merchant/balance
--header 'Authorization: '
--header 'User-Agent: Tokenpay API (https://tokenpay.me)'
--header 'Content-Type: application/json'
--data-raw ''
```

{% endtab %}

{% tab title="Go" %}

```go
package main

import (
   "fmt"
   "strings"
   "net/http"
   "io/ioutil"
)

func main() {

   url := "https://api.tokenpay.me/v1/merchant/balance"
   method := "GET"

   payload := strings.NewReader(`<body data here>`)

   client := &http.Client {
   }
   req, err := http.NewRequest(method, url, payload)

   if err != nil {
      fmt.Println(err)
      return
   }
   req.Header.Add("Authorization", "<Authorization>")
   req.Header.Add("User-Agent", "Tokenpay API (https://tokenpay.me)")
   req.Header.Add("Content-Type", "application/json")

   res, err := client.Do(req)
   if err != nil {
      fmt.Println(err)
      return
   }
   defer res.Body.Close()

   body, err := ioutil.ReadAll(res.Body)
   if err != nil {
      fmt.Println(err)
      return
   }
   fmt.Println(string(body))
}
```

{% endtab %}

{% tab title="PHP" %}

```php
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
   CURLOPT_URL => 'https://api.tokenpay.me/v1/merchant/balance',
   CURLOPT_RETURNTRANSFER => true,
   CURLOPT_ENCODING => '',
   CURLOPT_MAXREDIRS => 10,
   CURLOPT_TIMEOUT => 0,
   CURLOPT_FOLLOWLOCATION => true,
   CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
   CURLOPT_CUSTOMREQUEST => 'GET',
   CURLOPT_POSTFIELDS =>'<body data here>',
   CURLOPT_HTTPHEADER => array(
      'Authorization: <Authorization>',
      'User-Agent: Tokenpay API (https://api.tokenpay.me)',
      'Content-Type: application/json'
   ),
));

$response = curl_exec($curl);

curl_close($curl);
echo $response;
```

{% endtab %}

{% tab title="Python" %}

```python
import http.client
import json

conn = http.client.HTTPSConnection("https://api.tokenpay.io")
payload = "<body data here>"
headers = {
   'Authorization': '<Authorization>',
   'User-Agent': 'TokenpayAPI (https://tokenpay.io)',
   'Content-Type': 'application/json'
}
conn.request("GET", "/v1/merchant/balance", payload, headers)
res = conn.getresponse()
data = res.read()
print(data.decode("utf-8"))
```

{% endtab %}

{% tab title="Java" %}

```java
OkHttpClient client = new OkHttpClient().newBuilder()
   .build();
MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "<body data here>");
Request request = new Request.Builder()
   .url("https://api.tokenpay.me/v1/merchant/balance")
   .method("GET", body)
   .addHeader("Authorization", "<Authorization>")
   .addHeader("User-Agent", "Tokenpay API (https://tokenpay.io)")
   .addHeader("Content-Type", "application/json")
   .build();
Response response = client.newCall(request).execute();
```

{% endtab %}
{% endtabs %}

<br>


# Order


# Order creation

{% hint style="info" %}
TIP

After the order is created, the interface will return the payment link, and the user will enter the cash register through the link to pay.

If the merchant has set up a white label application, the front-end code also needs to be connected to JS-SDK. View [SDK](https://www.npmjs.com/package/@ttpay/payment_modal)
{% endhint %}

### Interface address <a href="#interface-address" id="interface-address"></a>

```
POST https://api.tokenpay.me/v1/transaction/prepayment
```

### Interface parameters <a href="#interface-parameters" id="interface-parameters"></a>

| Name           | Location | Type    | Required | Description                                                                                                                                                                                                |
| -------------- | -------- | ------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| app\_id        | header   | string  | Yes      | Application ID, example value:`8e4b8c2e7cxxxxxxxx1a1cbd3d59e0bd`                                                                                                                                           |
| mch\_id        | body     | string  | Yes      | Merchant ID, example value:`12345678`                                                                                                                                                                      |
| description    | body     | string  | No       | Order description, example value:`recharge`                                                                                                                                                                |
| out\_trade\_no | body     | string  | Yes      | Merchant order number, the merchant generates its own unique order number                                                                                                                                  |
| expire\_second | body     | integer | Yes      | Expiry date(second), example value:`3600`                                                                                                                                                                  |
| amount         | body     | number  | Yes      | Order amount, example value:`15000000`                                                                                                                                                                     |
| chain          | body     | string  | Yes      | Owned public chain, example value:`TRON`                                                                                                                                                                   |
| currency       | body     | string  | Yes      | Currency, example value:`TRX`. [View supported currencies](/currency/currency-information)                                                                                                                 |
| to\_address    | body     | string  | No       | Collection wallet( Notes: payment wallet is required for the application of `monitor order`)                                                                                                               |
| attach         | body     | string  | No       | Custom parameters (such as unique identifiers like user IDs) are returned unchanged in query APIs and payment notifications. In practice, this field is only returned when the payment status is complete. |
| locale         | body     | string  | No       | Language: `zh_cn` Chinese、 `en` English.Using cash register will display the default language based on this setting.                                                                                       |
| notify\_url    | body     | string  | No       | Callback url, example value:`https://xxx/xxx`. [Suggest using https](/description/safety-information)                                                                                                      |
| return\_url    | body     | string  | No       | Return address, when payment is complete or fails, click the return button on the address. And it can be the https or the route of the app.                                                                |
| order\_type    | body     | string  | Yes      | Payment method, example value: `platform_order` platform collection                                                                                                                                        |

#### Parameters example <a href="#parameters-example" id="parameters-example"></a>

```json
{
  "app_id": "d549a3ac0e4641f998c6675fc539ba21",
  "mch_id": "12345678",
  "description": "recharge",
  "out_trade_no": "fb72xxxx-xxxx-xxxx-xxxx-xxxx8a7b52cb",
  "expire_second": 600,
  "amount": 9,
  "chain": "TRON",
  "currency": "USDT",
  "to_address": "TQjxEW2Z3p9wjoxxxxxxxxgJUrWXBun91w",
  "attach": "anim dolore",
  "locale": "zh_cn",
  "notify_url": "https://xxx/xxx",
  "return_url": "https://xxxx/xxx?id=xxxx",
  "order_type": "platform_order"
}
```

{% hint style="info" %}
TIP

app\_id through the merchant backstage [creating an application](https://ttpay.io/console/pages/app-list/pay-app) to obtain.
{% endhint %}

### Interface return <a href="#interface-return" id="interface-return"></a>

| Name         | Type    | Description                            | Description                                                                                                                                                                                                                                           |
| ------------ | ------- | -------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| code         | integer | [Status code](/error-code/status-code) |                                                                                                                                                                                                                                                       |
| msg          | string  | Status description                     |                                                                                                                                                                                                                                                       |
| request\_id  | string  | Request ID                             |                                                                                                                                                                                                                                                       |
| data         | object  | Data object                            |                                                                                                                                                                                                                                                       |
| prepay\_id   | string  | Prepayment ID                          | Prepayment transaction session ID. It is used for subsequent interface calls, and its value is valid for the `expire_second` parameter set when the order is created, or you can access the `payment_url` directly to complete the payment.           |
| payment\_url | string  | Paymwnt cash register URL              | `payment_url` is to pull up the middle page of the payment cash register, you can complete the payment by visiting this url. You can pay by visiting the url. `payment_url` is valid for the `expire_second` parameter set when the order is created. |

### Return example <a href="#return-example" id="return-example"></a>

```json
{
    "code": 0,
    "msg": "ok",
    "request_id": "9b9e08ab-48e5-4efa-83e7-97e5e3fe3d0c",
    "data": {
        "prepay_id": "15809074c5bbc36bce27exxxxxxxxxxxxxxxxxxxxa4ca0a281d7e1260624a1c2",
        "payment_url": "/pay/order?prepay_id=15809074c5bbc36bce27exxxxxxxxxxxxxxxxxxxxa4ca0a281d7e1260624a1c2"
    }
}
```

### Example code <a href="#example-code" id="example-code"></a>

{% tabs %}
{% tab title="Shell" %}

```sh
curl --location --request POST 'https://api.tokenpay.me/v1/transaction/prepayment' \
--header 'Authorization: <Authorization>' \
--header 'User-Agent: tokenpay API (https://tokenpay.me)' \
--header 'Content-Type: application/json' \
--data-raw '<body data here>'
```

{% endtab %}

{% tab title="Go" %}

```go
package main

import (
   "fmt"
   "strings"
   "net/http"
   "io/ioutil"
)

func main() {

   url := "https://api.tokenpay.me/v1/transaction/prepayment"
   method := "POST"

   payload := strings.NewReader(`<body data here>`)

   client := &http.Client {
   }
   req, err := http.NewRequest(method, url, payload)

   if err != nil {
      fmt.Println(err)
      return
   }
   req.Header.Add("Authorization", "<Authorization>")
   req.Header.Add("User-Agent", "tokenpay API (https://tokenpay.me)")
   req.Header.Add("Content-Type", "application/json")

   res, err := client.Do(req)
   if err != nil {
      fmt.Println(err)
      return
   }
   defer res.Body.Close()

   body, err := ioutil.ReadAll(res.Body)
   if err != nil {
      fmt.Println(err)
      return
   }
   fmt.Println(string(body))
}
```

{% endtab %}

{% tab title="PHP" %}

```php
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
   CURLOPT_URL => 'https://api.tokenpay.me/v1/transaction/prepayment',
   CURLOPT_RETURNTRANSFER => true,
   CURLOPT_ENCODING => '',
   CURLOPT_MAXREDIRS => 10,
   CURLOPT_TIMEOUT => 0,
   CURLOPT_FOLLOWLOCATION => true,
   CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
   CURLOPT_CUSTOMREQUEST => 'POST',
   CURLOPT_POSTFIELDS =>'<body data here>',
   CURLOPT_HTTPHEADER => array(
      'Authorization: <Authorization>',
      'User-Agent: tokenpay API (https://tokenpay.me)',
      'Content-Type: application/json'
   ),
));

$response = curl_exec($curl);

curl_close($curl);
echo $response;
```

<br>
{% endtab %}

{% tab title="Python" %}

```python
import http.client
import json

conn = http.client.HTTPSConnection("https://api.tokenpay.me")
payload = "<body data here>"
headers = {
   'Authorization': '<Authorization>',
   'User-Agent': 'tokenpay API (https://tokenpay.me)',
   'Content-Type': 'application/json'
}
conn.request("POST", "/v1/transaction/prepayment", payload, headers)
res = conn.getresponse()
data = res.read()
print(data.decode("utf-8"))
```

{% endtab %}

{% tab title="Java" %}

```java
OkHttpClient client = new OkHttpClient().newBuilder()
   .build();
MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "<body data here>");
Request request = new Request.Builder()
   .url("https://api.tokenpay.me/v1/transaction/prepayment")
   .method("POST", body)
   .addHeader("Authorization", "<Authorization>")
   .addHeader("User-Agent", "tokenpay API (https://tokenpay.me)")
   .addHeader("Content-Type", "application/json")
   .build();
Response response = client.newCall(request).execute();
```

{% endtab %}
{% endtabs %}


# Order inquiry

{% hint style="info" %}
TIP

Order detail inquiry and real-time status
{% endhint %}

### Interface address <a href="#interface-address" id="interface-address"></a>

```
POST https://api.tokenpay.me/v1/transaction/query
```

### Interface parameters <a href="#interface-parameters" id="interface-parameters"></a>

| Name            | Location | Type   | Required | Description                                                                  |
| --------------- | -------- | ------ | -------- | ---------------------------------------------------------------------------- |
| out\_trade\_no  | query    | string | No       | Merchant order number（`out_trade_no` and `transaction_id` pass at least one） |
| transaction\_id | query    | string | No       | Platform order number（`out_trade_no` and `transaction_id` pass at least one） |
| app\_id         | header   | string | Yes      | Application ID, example value: `8e4b8c2e7cxxxxxxxx1a1cbd3d59e0bd`            |
| mch\_id         | body     | string | Yes      | Merchant ID, example value: `12345678`                                       |

### Interface return <a href="#interface-return" id="interface-return"></a>

| Name        | Type                                                                | Required | Description                            |
| ----------- | ------------------------------------------------------------------- | -------- | -------------------------------------- |
| code        | integer                                                             | true     | [Status code](/error-code/status-code) |
| msg         | string                                                              | true     | Statements                             |
| request\_id | string                                                              | true     |                                        |
| data        | [TransactionDetail](/description/data-structure#transaction-detail) | false    |                                        |

### Return example <a href="#return-example" id="return-example"></a>

```json
{
    "code": 0,
    "msg": "ok",
    "request_id": "08250916-a677-4a36-a090-323807ac644c",
    "data": {
        "out_trade_no": "fb722ca8-ed7b-444b-9f58-0b5c8a7b52cb",
        "transaction_id": "e98b3029477f4bdcb971797a9d9e09ce",
        "trade_state": "SUCCESS",
        "description": "Recharge",
        "block_no": 33215220,
        "create_time": 1673407302044,
        "block_time": 1673407329000,
        "expire_time": 1673407902044,
        "expire_second": 0,
        "pay_time": 1673407329000,
        "close_time": 0,
        "tx_id": "9fdf0ab5823e23225f93bcc644af30a6ab83b6583a8e29e359ee80219802a33a",
        "from_address": "TULRFYoFuEmUbxxxxxxxx8nQYFHJ88888",
        "contract_address": "",
        "to_address": "TQjxEW2Z3p9wjoxxxxxxxxgJUrWXBun91w",
        "amount": 15000000,
        "chain": "TRON",
        "decimals": 6,
        "attach": "anim dolore",
        "service_amount": 45000,
        "service_amount_currency": "USDT",
        "notify_url": "/console/callback/pay",
        "notify_num": 1,
        "notify_status": 2,
        "status": 2,
        "currency": {
            "type": "TRX",
            "chain": "TRON",
            "code": "TRON_TRX",
            "currency": "TRX",
            "name": "TRX",
            "sub_name": "TRON",
            "logo": "https://xxx/trx_busd.png",
            "contract_address": "",
            "decimal": 6,
        }
    }
}
```

### Example code <a href="#example-code" id="example-code"></a>

{% tabs %}
{% tab title="Shell" %}

```sh
curl --location --request GET 'https://api.tokenpay.me/v1/transaction/query' \
--header 'Authorization: <Authorization>' \
--header 'User-Agent: tokenpay API (https://tokenpay.me)' \
--header 'Content-Type: application/json' \
--data-raw '<body data here>'
```

{% endtab %}

{% tab title="Go" %}

```go
package main

import (
   "fmt"
   "strings"
   "net/http"
   "io/ioutil"
)

func main() {

   url := "https://api.tokenpay.me/v1/transaction/query"
   method := "GET"

   payload := strings.NewReader(`<body data here>`)

   client := &http.Client {
   }
   req, err := http.NewRequest(method, url, payload)

   if err != nil {
      fmt.Println(err)
      return
   }
   req.Header.Add("Authorization", "<Authorization>")
   req.Header.Add("User-Agent", "tokenpay API (https://tokenpay.me)")
   req.Header.Add("Content-Type", "application/json")

   res, err := client.Do(req)
   if err != nil {
      fmt.Println(err)
      return
   }
   defer res.Body.Close()

   body, err := ioutil.ReadAll(res.Body)
   if err != nil {
      fmt.Println(err)
      return
   }
   fmt.Println(string(body))
}
```

{% endtab %}

{% tab title="PHP" %}

```php
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
   CURLOPT_URL => 'https://api.tokenpay.me/v1/transaction/query',
   CURLOPT_RETURNTRANSFER => true,
   CURLOPT_ENCODING => '',
   CURLOPT_MAXREDIRS => 10,
   CURLOPT_TIMEOUT => 0,
   CURLOPT_FOLLOWLOCATION => true,
   CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
   CURLOPT_CUSTOMREQUEST => 'GET',
   CURLOPT_POSTFIELDS =>'<body data here>',
   CURLOPT_HTTPHEADER => array(
      'Authorization: <Authorization>',
      'User-Agent: tokenpay API (https://tokenpay.me)',
      'Content-Type: application/json'
   ),
));

$response = curl_exec($curl);

curl_close($curl);
echo $response;
```

<br>
{% endtab %}

{% tab title="Python" %}

```python
import http.client
import json

conn = http.client.HTTPSConnection("https://api.tokenpay.me")
payload = "<body data here>"
headers = {
   'Authorization': '<Authorization>',
   'User-Agent': 'tokenpay API (https://tokenpay.me)',
   'Content-Type': 'application/json'
}
conn.request("GET", "/v1/transaction/query", payload, headers)
res = conn.getresponse()
data = res.read()
print(data.decode("utf-8"))
```

{% endtab %}

{% tab title="Java" %}

```java
OkHttpClient client = new OkHttpClient().newBuilder()
   .build();
MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "<body data here>");
Request request = new Request.Builder()
   .url("https://api.tokenpay.me/v1/transaction/query")
   .method("GET", body)
   .addHeader("Authorization", "<Authorization>")
   .addHeader("User-Agent", "tokenpay API (https://tokenpay.me)")
   .addHeader("Content-Type", "application/json")
   .build();
Response response = client.newCall(request).execute();
```

{% endtab %}
{% endtabs %}


# Callback notification

{% hint style="info" %}
TIP

After the payment is completed, the payment center will send the relevant payment results and relevant information to the merchant, and the merchant needs to receive processing and return the response. When interacting with background notifications, if the payment center receives a merchant response that is not successful or times out, the payment Center considers the notification to have failed. The notification will be re-initiated periodically according to a certain policy to maximize the success rate of the notification, but there is no guarantee that the notification will be successful. （The notification frequency is 0s/15s/30s/3m/10m/20m/30m/60m/3h/6h）
{% endhint %}

{% hint style="warning" %}
WARNING

Note: The same notification may be sent multiple times to the merchant system. And the merchant system must be able to handle correctly the same notification. Recommended practices are as follows. When processing a notification, firstly checking the status of the corresponding service data to determine whether the notification has been processed. If no, process it again. If yes, direct return a success result. Before state checking and processing of business data, concurrency control is performed using data locks to avoid data chaos caused by function reentrant.
{% endhint %}

{% hint style="danger" %}
DANGER

Attention: The merchant system must do signature verification for the content of the order callback, and verify whether the returned order amount is consistent with the order amount. The reason for doing these to prevent data leakage resulting in "false notice" resulting in loss of funds.
{% endhint %}

### Interface address <a href="#interface-address" id="interface-address"></a>

```
The notify url parameter submitted by the POST unified order interface is set. If you cannot access the link, your service system cannot receive the notification from the payment center.
```

### Request Body <a href="#request-body" id="request-body"></a>

| Name             | Type   | Description                                                                                                                                                                                                      | Description |
| ---------------- | ------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------- |
| app\_id          | string | Application                                                                                                                                                                                                      |             |
| mch\_id          | string | Merchant                                                                                                                                                                                                         |             |
| create\_time     | time   | Notification time                                                                                                                                                                                                |             |
| resource\_type   | string | The resource data type of the notification. Payment success notification is encrypt-resource                                                                                                                     |             |
| event\_type      | string | Notification type. The type of payment success notification is SUCCESS.                                                                                                                                          |             |
| resource         | object | Notification resource data                                                                                                                                                                                       |             |
| » original\_type | string | The original callback type is transaction                                                                                                                                                                        |             |
| » algorithm      | string | Currently, only AES-256-ECB is supported for the encryption algorithm that encrypts the result data                                                                                                              |             |
| » ciphertext     | string | Base64 encoded on/off result data ciphertext. If enabled, the encrypted content is returned. After decryption, it is a json string of [TransactionNotifyDetail](/description/data-structure#transaction-detail). |             |
| » nonce          | string | Encrypt using random strings                                                                                                                                                                                     |             |

### Request example <a href="#request-example" id="request-example"></a>

```json
{
	"app_id": "xxxxx",
	"mch_id": "zzzzzz",
	"create_time": "2023-06-26T17:21:17.754429+08:00",
	"resource_type": "encrypt-resource",
	"event_type": "TRANSACTION.SUCCESS",
	"resource": {
		"original_type": "transaction",
		"algorithm": "AEAD_AES_256_GCM",
		"ciphertext": "I/psKgdkVwxbkEIWtwRxfxLzViuRS+gJTQSdLf+lmK7awoqUcIJisTAJx0Qbv4K6wV8WgyMRFYHD5CCLKmFNU2OnmEm2f2vGhaoS2h28A9BEGx1CWEUw3tfldf/+VWlBAnIBylFjHzbSo7fgn7S3fFEAZHTxoy+9jNIoynqHZbn4Y6eucj1YCw0ZmuKHPpPPrvclbhHmaZHfau+SKyag3C0/cj7zu4mBkRZ39zuk9B7DAADzaRENOZ/ZyibU+zs3gibnCbI2NWEnQWIiCi7vK0jq/FCBWytHihQM364zlVrPPCBDbv2MSqk4fyAM7IDeT6h/z/2kmDOQ6aFPYlLojIkgCCOIevQITS9E+BS1rgmmH+DRKsJNiD257aLhX2/F53VEnjfqqKdDs2lqfX0dCMLqselGUT981fFKceXg+r6hQqcUzLlF28XL5NrfVPreRDo6jI2K0tCy9cOx+cxH3yoDzOFBzM0RlxWqvUhRsMv9ZGfpgCZ0o9HxNObqLjVCQzE5SWPXvmkw+QpWk0oNUvpCEDhj9Vfq6XCV8j3tT3tZTYCa5UQy9VCdmval/2vb50QaAgDYXU6PH/9Xv7AXg6kg29iK+Ec0euxZxosRoVczzRg+0Arl/zvBcphWNIUTdx5IcA12WtP+krk9NNGtj7igk21DhcseJrKBpG7ll9O/Wmq1L8BwW+ypuJS+kHV61jRNYMFJY48Pt11Zoukgqu94kzrhz+KET8q463zlyu/Kp2z5yWI8xwvOtuyjosszfm6/YFQTFdhcmHY3X1yz44NaVG9FPev1QPoPmI7K3Jqa0Q8Q5kQTbe/KrB0eyRpXtyAaShOEeiS2ypmFAC81/m4mjuTd24yAjBcTIfBYzjxwjPbKfv+OYKahDwJP1b7EhsM+Sgu48wQ+pp6wc8TYCOkiRR1pKeb3kaxpQGzlq7VNbWHFPw9TDiyCIEnr8T5eiJtzJJ0U0iIfqN5WHk7iHiNK4Y4TvmdF4f6UyeMTHvaprvzUZI8il5wvoCgIiRUY7qvv5V/KL4ZWHN6Y3EEvQmP4WDo3Wx5IFW8C1gkyFv8lQ1COSNYMPog6RLAI0rNvKZjvc4baWwcHmk/fM92X19F2Y0DArqLFFUTJVE5bUQXQexiUO1e8IL07wqY=",
		"nonce": "d8816e8d6dca4409b790a4bcaa25c621"
	}
}
```

### Return example <a href="#return-example" id="return-example"></a>

```
success
```

Please return `success` to notify the notification server after successfully receives the callback request. After the notification server receiving `success`, the notification stops. Otherwise, the notification will be sent 10 times at the frequency of 0s/15s/30s/3m/10m/20m/30m/60m/3h/6h.


# Order closure

{% hint style="info" %}
TIP

For users to manually cancel orders or merchants to cancel orders.
{% endhint %}

### Interface address <a href="#interface-address" id="interface-address"></a>

```
POST https://api.tokenpay.me/v1/transaction/close
```

### Interface parameters <a href="#interface-parameters" id="interface-parameters"></a>

| Name            | location | Type   | Required | Description                                                       |
| --------------- | -------- | ------ | -------- | ----------------------------------------------------------------- |
| app\_id         | header   | string | Yes      | App ID, example value: `8e4b8c2e7cxxxxxxxx1a1cbd3d59e0bd`         |
| mch\_id         | body     | string | Yes      | Merchant ID, example value: `12345678`                            |
| transaction\_id | body     | string | No       | Platform order, example value: `2a1cfa6568xxxxxxxx3050957024c559` |

#### Parameters example <a href="#parameters-example" id="parameters-example"></a>

```json
{
  "app_id": "8e4b8c2e7cxxxxxxxx1a1cbd3d59e0bd",
  "mch_id": "12345678",
  "transaction_id": "2a1cfa6568xxxxxxxx3050957024c559"
}
```

### Interface return <a href="#interface-return" id="interface-return"></a>

| Name        | Type    | Description                            | Description |
| ----------- | ------- | -------------------------------------- | ----------- |
| code        | integer | [Status code](/error-code/status-code) | none        |
| msg         | string  | Status description                     | none        |
| request\_id | string  | Request ID                             | none        |

### Return example <a href="#return-example" id="return-example"></a>

```json
{
  "code": 0,
  "msg": "success",
  "request_id": "f23ade4a-e5ca-48f4-a4bb-59114ac360ba",
}
```

### Example code <a href="#example-code" id="example-code"></a>

{% tabs %}
{% tab title="Shell" %}

```sh
curl --location --request POST 'https://api.tokenpay.me/v1/transaction/close' \
--header 'Authorization: <Authorization>' \
--header 'User-Agent: tokenpay API (https://tokenpay.me)' \
--header 'Content-Type: application/json' \
--data-raw '<body data here>'
```

{% endtab %}

{% tab title="Go" %}

```go
package main

import (
   "fmt"
   "strings"
   "net/http"
   "io/ioutil"
)

func main() {

   url := "https://api.tokenpay.me/v1/transaction/close"
   method := "POST"

   payload := strings.NewReader(`<body data here>`)

   client := &http.Client {
   }
   req, err := http.NewRequest(method, url, payload)

   if err != nil {
      fmt.Println(err)
      return
   }
   req.Header.Add("Authorization", "<Authorization>")
   req.Header.Add("User-Agent", "tokenpay API (https://tokenpay.me)")
   req.Header.Add("Content-Type", "application/json")

   res, err := client.Do(req)
   if err != nil {
      fmt.Println(err)
      return
   }
   defer res.Body.Close()

   body, err := ioutil.ReadAll(res.Body)
   if err != nil {
      fmt.Println(err)
      return
   }
   fmt.Println(string(body))
}
```

{% endtab %}

{% tab title="PHP" %}

```php
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
   CURLOPT_URL => 'https://api.tokenpay.me/v1/transaction/close',
   CURLOPT_RETURNTRANSFER => true,
   CURLOPT_ENCODING => '',
   CURLOPT_MAXREDIRS => 10,
   CURLOPT_TIMEOUT => 0,
   CURLOPT_FOLLOWLOCATION => true,
   CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
   CURLOPT_CUSTOMREQUEST => 'POST',
   CURLOPT_POSTFIELDS =>'<body data here>',
   CURLOPT_HTTPHEADER => array(
      'Authorization: <Authorization>',
      'User-Agent: tokenpay API (https://tokenpay.me)',
      'Content-Type: application/json'
   ),
));

$response = curl_exec($curl);

curl_close($curl);
echo $response;
```

{% endtab %}

{% tab title="Python" %}

```python
import http.client
import json

conn = http.client.HTTPSConnection("https://api.tokenpay.me")
payload = "<body data here>"
headers = {
   'Authorization': '<Authorization>',
   'User-Agent': 'tokenpay API (https://tokenpay.me)',
   'Content-Type': 'application/json'
}
conn.request("POST", "/v1/transaction/close", payload, headers)
res = conn.getresponse()
data = res.read()
print(data.decode("utf-8"))
```

{% endtab %}

{% tab title="Java" %}

```java
OkHttpClient client = new OkHttpClient().newBuilder()
   .build();
MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "<body data here>");
Request request = new Request.Builder()
   .url("https://api.tokenpay.me/v1/transaction/close")
   .method("POST", body)
   .addHeader("Authorization", "<Authorization>")
   .addHeader("User-Agent", "tokenpay API (https://tokenpay.me)")
   .addHeader("Content-Type", "application/json")
   .build();
Response response = client.newCall(request).execute();
```

{% endtab %}
{% endtabs %}


# Payout


# Payout inquiry

{% hint style="info" %}
TIP

Payout order information inquiry
{% endhint %}

### Interface address <a href="#interface-address" id="interface-address"></a>

```
POST https://api.tokenpay.me/v1/payanother/query
```

### Interface parameters <a href="#interface-parameters" id="interface-parameters"></a>

| Name            | Location | Type   | Required | Description                                                                   |
| --------------- | -------- | ------ | -------- | ----------------------------------------------------------------------------- |
| app\_id         | body     | string | Yes      | Application ID, example value:`8e4b8c2e7cxxxxxxxx1a1cbd3d59e0bd`              |
| mch\_id         | body     | string | Yes      | Merchant ID, example value:`12345678`                                         |
| out\_trade\_no  | body     | string | No       | Merchant order number (`out_trade_no` and `transaction_id` pass at least one) |
| transaction\_id | body     | string | No       | Platform order number (`out_trade_no` and `transaction_id` pass at least one) |

### Interface return <a href="#interface-return" id="interface-return"></a>

| Name        | Type                                                                     | Required | Description                            |
| ----------- | ------------------------------------------------------------------------ | -------- | -------------------------------------- |
| code        | integer                                                                  | true     | [Status code](/error-code/status-code) |
| msg         | string                                                                   | true     | Statements                             |
| request\_id | string                                                                   | true     |                                        |
| data        | [PayoutTransactionDetail](/description/data-structure#payanother-detial) | false    |                                        |

### Return example <a href="#return-example" id="return-example"></a>

```json
{
    "code": 0,
    "msg": "ok",
    "request_id": "08250916-a677-4a36-a090-323807ac644c",
    "data": {
        "out_trade_no": "fb722ca8-ed7b-444b-9f58-0b5c8a7b52cb",
        "transaction_id": "e98b3029477f4bdcb971797a9d9e09ce",
        "trade_state": "SUCCESS",
        "description": "recharge",
        "block_no": 33215220,
        "create_time": 1673407302044,
        "block_time": 1673407329000,
        "expire_time": 1673407902044,
        "expire_second": 0,
        "pay_time": 1673407329000,
        "close_time": 0,
        "tx_id": "9fdf0ab5823e23225f93bcc644af30a6ab83b6583a8e29e359ee80219802a33a",
        "from_address": "TULRFYoFuEmUbxxxxxxxx8nQYFHJ88888",
        "contract_address": "",
        "to_address": "TQjxEW2Z3p9wjoxxxxxxxxgJUrWXBun91w",
        "amount": 15000000,
        "chain": "TRON",
        "decimals": 6,
        "attach": "anim dolore",
        "service_amount": 45000,
        "service_amount_currency": "USDT",
        "notify_url": "/console/callback/pay",
        "notify_num": 1,
        "notify_status": 2,
        "status": 2,
        "currency": {
            "type": "TRX",
            "chain": "TRON",
            "code": "TRON_TRX",
            "currency": "TRX",
            "name": "TRX",
            "sub_name": "TRON",
            "logo": "https://xxx/trx_busd.png",
            "contract_address": "",
            "decimal": 6,
        }
    }
}
```

### Example code <a href="#example-code" id="example-code"></a>

{% tabs %}
{% tab title="Shell" %}

```sh
curl --location --request GET 'https://api.tokenpay.me/v1/payout/query' \
--header 'Authorization: <Authorization>' \
--header 'User-Agent: tokenpay API (https://tokenpay.me)' \
--header 'Content-Type: application/json' \
--data-raw '<body data here>'
```

{% endtab %}

{% tab title="Go" %}

```go
package main

import (
   "fmt"
   "strings"
   "net/http"
   "io/ioutil"
)

func main() {

   url := "https://api.tokenpay.me/v1/payout/query"
   method := "GET"

   payload := strings.NewReader(`<body data here>`)

   client := &http.Client {
   }
   req, err := http.NewRequest(method, url, payload)

   if err != nil {
      fmt.Println(err)
      return
   }
   req.Header.Add("Authorization", "<Authorization>")
   req.Header.Add("User-Agent", "tokenpay API (https://tokenpay.me)")
   req.Header.Add("Content-Type", "application/json")

   res, err := client.Do(req)
   if err != nil {
      fmt.Println(err)
      return
   }
   defer res.Body.Close()

   body, err := ioutil.ReadAll(res.Body)
   if err != nil {
      fmt.Println(err)
      return
   }
   fmt.Println(string(body))
}
```

{% endtab %}

{% tab title="PHP" %}

```php
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
   CURLOPT_URL => 'https://api.tokenpay.me/v1/payout/query',
   CURLOPT_RETURNTRANSFER => true,
   CURLOPT_ENCODING => '',
   CURLOPT_MAXREDIRS => 10,
   CURLOPT_TIMEOUT => 0,
   CURLOPT_FOLLOWLOCATION => true,
   CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
   CURLOPT_CUSTOMREQUEST => 'GET',
   CURLOPT_POSTFIELDS =>'<body data here>',
   CURLOPT_HTTPHEADER => array(
      'Authorization: <Authorization>',
      'User-Agent: tokenpay API (https://tokenpay.me)',
      'Content-Type: application/json'
   ),
));

$response = curl_exec($curl);

curl_close($curl);
echo $response;
```

<br>
{% endtab %}

{% tab title="Python" %}

```python
import http.client
import json

conn = http.client.HTTPSConnection("https://api.tokenpay.me")
payload = "<body data here>"
headers = {
   'Authorization': '<Authorization>',
   'User-Agent': 'tokenpay API (https://tokenpay.me)',
   'Content-Type': 'application/json'
}
conn.request("GET", "/v1/payout/query", payload, headers)
res = conn.getresponse()
data = res.read()
print(data.decode("utf-8"))
```

{% endtab %}

{% tab title="Java" %}

```java
OkHttpClient client = new OkHttpClient().newBuilder()
   .build();
MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "<body data here>");
Request request = new Request.Builder()
   .url("https://api.tokenpay.me/v1/payout/query")
   .method("GET", body)
   .addHeader("Authorization", "<Authorization>")
   .addHeader("User-Agent", "tokenpay API (https://tokenpay.me)")
   .addHeader("Content-Type", "application/json")
   .build();
Response response = client.newCall(request).execute();
```

{% endtab %}
{% endtabs %}


# Payout estimated fee inquiry

{% hint style="info" %}
TIP

Inquire about Payout estimated fees
{% endhint %}

### Interface address <a href="#interface-address" id="interface-address"></a>

```
POST https://api.tokenpay.me/v1/payanother/estimated_fee
```

### Interface parameters <a href="#interface-parameters" id="interface-parameters"></a>

| Name        | Location | Type   | Required | Description                                                                                                          |
| ----------- | -------- | ------ | -------- | -------------------------------------------------------------------------------------------------------------------- |
| mch\_id     | body     | string | Yes      | Merchant ID, example value:`12345678`                                                                                |
| chain       | body     | string | Yes      | Owned public chain, example value:`TRON`                                                                             |
| currency    | body     | string | Yes      | Currency, example value:`TRX`. [View supported currencies](https://apidoc.tokenpay.me/currency/currency-information) |
| to\_address | body     | string | Yes      | Collection wallet( Notes: payment wallet is required for the application of `payout`)                                |
| app\_id     | body     | string | Yes      | Application ID, example value:`8e4b8c2e7cxxxxxxxx1a1cbd3d59e0bd`                                                     |

{% hint style="info" %}
TIP

app\_id through the merchant backstage [creating an application](https://ttpay.io/console/pages/app-list/pay-app) to obtain.
{% endhint %}

### Interface return <a href="#interface-return" id="interface-return"></a>

| Name        | Type    | Required | Description                                                                                                          |
| ----------- | ------- | -------- | -------------------------------------------------------------------------------------------------------------------- |
| code        | integer | true     | [Status code](https://apidoc.tokenpay.me/error-code/status-code)                                                     |
| msg         | string  | true     | Status description                                                                                                   |
| request\_id | string  | true     | Request ID                                                                                                           |
| data        | object  | false    | Data object                                                                                                          |
| currency    | string  |          | Currency, example value:`TRX`. [View supported currencies](https://apidoc.tokenpay.me/currency/currency-information) |
| to\_address | string  |          | Collection wallet( Notes: payment wallet is required for the application of `payout`)                                |
| fee         | string  |          | fee                                                                                                                  |
| app\_id     | string  |          | Application ID, example value:`8e4b8c2e7cxxxxxxxx1a1cbd3d59e0bd`                                                     |

### Return example

```java

{
    "code": 0,
    "msg": "ok",
    "request_id": "0f262d68-a7bc-4ff4-beeb-994a1e6bcd53",
    "data": {
        "chain": "TRON",
        "currency": "USDT",
        "to_address": "TPKcSZqWWAJyE7KTKUveSfgWM75sZrr9JG",
        "fee": "2500000",
        "decimals": 6
    }
}

```

### Example code

{% tabs %}
{% tab title="Shell" %}

```sh
curl --location --request POST 'https://api.tokenpay.me/v1/payanother/estimated_fee'
--header 'Authorization: '
--header 'User-Agent: tokenpay API (https://tokenpay.me)'
--header 'Content-Type: application/json'
--data-raw ''
```

{% endtab %}

{% tab title="Go" %}

```go
package main

import (
   "fmt"
   "strings"
   "net/http"
   "io/ioutil"
)

func main() {

   url := "https://api.tokenpay.me/v1/payanother/estimated_fee"
   method := "POST"

   payload := strings.NewReader(`<body data here>`)

   client := &http.Client {
   }
   req, err := http.NewRequest(method, url, payload)

   if err != nil {
      fmt.Println(err)
      return
   }
   req.Header.Add("Authorization", "<Authorization>")
   req.Header.Add("User-Agent", "tokenpay API (https://tokenpay.me)")
   req.Header.Add("Content-Type", "application/json")

   res, err := client.Do(req)
   if err != nil {
      fmt.Println(err)
      return
   }
   defer res.Body.Close()

   body, err := ioutil.ReadAll(res.Body)
   if err != nil {
      fmt.Println(err)
      return
   }
   fmt.Println(string(body))
}
```

{% endtab %}

{% tab title="PHP" %}

```php
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
   CURLOPT_URL => 'https://api.tokenpay.me/v1/payanother/estimated_fee',
   CURLOPT_RETURNTRANSFER => true,
   CURLOPT_ENCODING => '',
   CURLOPT_MAXREDIRS => 10,
   CURLOPT_TIMEOUT => 0,
   CURLOPT_FOLLOWLOCATION => true,
   CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
   CURLOPT_CUSTOMREQUEST => 'POST',
   CURLOPT_POSTFIELDS =>'<body data here>',
   CURLOPT_HTTPHEADER => array(
      'Authorization: <Authorization>',
      'User-Agent: tokenpay API (https://tokenpay.meo)',
      'Content-Type: application/json'
   ),
));

$response = curl_exec($curl);

curl_close($curl);
echo $response;
```

{% endtab %}

{% tab title="Python" %}

```python
import http.client
import json

conn = http.client.HTTPSConnection("https://api.tokenpay.me")
payload = "<body data here>"
headers = {
   'Authorization': '<Authorization>',
   'User-Agent': 'tokenpay API (https://tokenpay.me)',
   'Content-Type': 'application/json'
}
conn.request("POST", "/v1/payanother/estimated_fee", payload, headers)
res = conn.getresponse()
data = res.read()
print(data.decode("utf-8"))
```

{% endtab %}

{% tab title="Java" %}

```java
OkHttpClient client = new OkHttpClient().newBuilder()
   .build();
MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "<body data here>");
Request request = new Request.Builder()
   .url("https://api.tokenpay.me/v1/payanother/estimated_fee")
   .method("POST", body)
   .addHeader("Authorization", "<Authorization>")
   .addHeader("User-Agent", "tokenpay API (https://tokenpay.me)")
   .addHeader("Content-Type", "application/json")
   .build();
Response response = client.newCall(request).execute();
```

{% endtab %}
{% endtabs %}


# Create Payout

{% hint style="info" %}
TIP

Initiate paying on your behalf first.
{% endhint %}

### Interface address <a href="#interface-address" id="interface-address"></a>

```
POST https://api.tokenpay.me/v1/payanother/payment
```

### Interface parameters <a href="#interface-parameters" id="interface-parameters"></a>

| Name           | Location | Type   | Required | Description                                                                                                                                                                                 |
| -------------- | -------- | ------ | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| app\_id        | body     | string | Yes      | Application ID, example value: `8e4b8c2e7cxxxxxxxx1a1cbd3d59e0bd`                                                                                                                           |
| mch\_id        | body     | string | Yes      | Merchant ID, example value: `12345678`                                                                                                                                                      |
| description    | body     | string | No       | Description, example value: `1234567890`                                                                                                                                                    |
| out\_trade\_no | body     | string | No       | Merchant order number（`out_trade_no` and `transaction_id` pass at least one）                                                                                                                |
| amount         | body     | string | Yes      | Payout amount                                                                                                                                                                               |
| chain          | body     | string | Yes      | Owned public chain, example value: `TRON`、`ETHEREUM`、`BSC`. [View supported public chains](/currency/currency-information)                                                                  |
| currency       | body     | string | Yes      | Currency, example value: `TRX`、`USDT`、`ETH`. [View supported currencies](/currency/currency-information)                                                                                    |
| to\_address    | body     | string | Yes      | Collection address                                                                                                                                                                          |
| attach         | body     | string | No       | Custom parameter. It returns as-is in the query API and payment notifications and can be used as a custom parameter. In practice, this field is returned only when the payment is complete. |
| notify\_url    | body     | string | No       | Callback url, example value: `https://xxx/xxx`, [suggest using https](/description/safety-information)                                                                                      |

{% hint style="info" %}
TIP

app\_id through the merchant backstage [creating an application](https://ttpay.io/console/pages/app-list/pay-app) to obtain.
{% endhint %}

### Interface return <a href="#interface-return" id="interface-return"></a>

| Name        | Time                                                                      | Required | Description                            |
| ----------- | ------------------------------------------------------------------------- | -------- | -------------------------------------- |
| code        | integer                                                                   | true     | [Status code](/error-code/status-code) |
| msg         | string                                                                    | true     | Statements                             |
| request\_id | string                                                                    | true     |                                        |
| data        | [PayoutTransactionDetail](/description/data-structure#transaction-detail) | false    |                                        |

### Example retrun <a href="#example-retrun" id="example-retrun"></a>

```json
{
    "code": 0,
    "msg": "ok",
    "request_id": "08250916-a677-4a36-a090-323807ac644c",
    "data": {
        "out_trade_no": "fb722ca8-ed7b-444b-9f58-0b5c8a7b52cb",
        "transaction_id": "e98b3029477f4bdcb971797a9d9e09ce",
        "trade_state": "SUCCESS",
        "description": "recharge",
        "block_no": 33215220,
        "create_time": 1673407302044,
        "block_time": 1673407329000,
        "expire_time": 1673407902044,
        "expire_second": 0,
        "pay_time": 1673407329000,
        "close_time": 0,
        "tx_id": "9fdf0ab5823e23225f93bcc644af30a6ab83b6583a8e29e359ee80219802a33a",
        "from_address": "TULRFYoFuEmUbxxxxxxxx8nQYFHJ88888",
        "contract_address": "",
        "to_address": "TQjxEW2Z3p9wjoxxxxxxxxgJUrWXBun91w",
        "amount": 15000000,
        "chain": "TRON",
        "decimals": 6,
        "attach": "anim dolore",
        "service_amount": 45000,
        "service_amount_currency": "USDT",
        "notify_url": "/console/callback/pay",
        "notify_num": 1,
        "notify_status": 2,
        "status": 2,
        "currency": {
            "type": "TRX",
            "chain": "TRON",
            "code": "TRON_TRX",
            "currency": "TRX",
            "name": "TRX",
            "sub_name": "TRON",
            "logo": "https://xxx/trx_busd.png",
            "contract_address": "",
            "decimal": 6,
        }
    }
}
```

### Example code <a href="#example-code" id="example-code"></a>

{% tabs %}
{% tab title="Shell" %}

```sh
curl --location --request POST 'https://api.tokenpay.me/v1/payout/payment' \
--header 'Authorization: <Authorization>' \
--header 'User-Agent: tokenpay API (https://tokenpay.me)' \
--header 'Content-Type: application/json' \
--data-raw '<body data here>'
```

{% endtab %}

{% tab title="Go" %}

```go
package main

import (
   "fmt"
   "strings"
   "net/http"
   "io/ioutil"
)

func main() {

   url := "https://api.tokenpay.me/v1/payout/payment"
   method := "POST"

   payload := strings.NewReader(`<body data here>`)

   client := &http.Client {
   }
   req, err := http.NewRequest(method, url, payload)

   if err != nil {
      fmt.Println(err)
      return
   }
   req.Header.Add("Authorization", "<Authorization>")
   req.Header.Add("User-Agent", "tokenpay API (https://tokenpay.me)")
   req.Header.Add("Content-Type", "application/json")

   res, err := client.Do(req)
   if err != nil {
      fmt.Println(err)
      return
   }
   defer res.Body.Close()

   body, err := ioutil.ReadAll(res.Body)
   if err != nil {
      fmt.Println(err)
      return
   }
   fmt.Println(string(body))
}
```

{% endtab %}

{% tab title="PHP" %}

```php
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
   CURLOPT_URL => 'https://api.tokenpay.me/v1/payout/payment',
   CURLOPT_RETURNTRANSFER => true,
   CURLOPT_ENCODING => '',
   CURLOPT_MAXREDIRS => 10,
   CURLOPT_TIMEOUT => 0,
   CURLOPT_FOLLOWLOCATION => true,
   CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
   CURLOPT_CUSTOMREQUEST => 'POST',
   CURLOPT_POSTFIELDS =>'<body data here>',
   CURLOPT_HTTPHEADER => array(
      'Authorization: <Authorization>',
      'User-Agent: tokenpay API (https://tokenpay.me)',
      'Content-Type: application/json'
   ),
));

$response = curl_exec($curl);

curl_close($curl);
echo $response;
```

<br>
{% endtab %}

{% tab title="Python" %}

```python
import http.client
import json

conn = http.client.HTTPSConnection("https://api.tokenpay.me")
payload = "<body data here>"
headers = {
   'Authorization': '<Authorization>',
   'User-Agent': 'tokenpay API (https://tokenpay.me)',
   'Content-Type': 'application/json'
}
conn.request("POST", "/v1/payout/payment", payload, headers)
res = conn.getresponse()
data = res.read()
print(data.decode("utf-8"))
```

{% endtab %}

{% tab title="Java" %}

```java
OkHttpClient client = new OkHttpClient().newBuilder()
   .build();
MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "<body data here>");
Request request = new Request.Builder()
   .url("https://api.tokenpay.me/v1/payout/payment")
   .method("POST", body)
   .addHeader("Authorization", "<Authorization>")
   .addHeader("User-Agent", "tokenpay API (https://tokenpay.me)")
   .addHeader("Content-Type", "application/json")
   .build();
Response response = client.newCall(request).execute();
```

{% endtab %}
{% endtabs %}


# Callback

{% hint style="info" %}
TIP

After the payout is completed, the system will send the relevant payout results and information to the merchant, and the merchant needs to receive and return the response. When interacting with background notifications, if the system receives a merchant response that is not successful or times out, the system considers the notification to have failed. The notification will be re-initiated periodically according to a certain policy to maximize the success rate of the notification, but there is no guarantee that the notification will be successful. （The notification frequency is 0s/15s/30s/3m/10m/20m/30m/60m/3h/6h）
{% endhint %}

{% hint style="warning" %}
WARNING

Note: The same notification may be sent multiple times to the merchant. And the merchant must be able to handle correctly the duplicate notification. Recommended practices are as follows, When processing a notification, firstly checking the status of the payout to determine whether the notification has been processed. If no, process it again. If yes, direct return a success result. Before state checking and processing of business data, concurrency control is performed using data locks to avoid data chaos caused by function reentrant.
{% endhint %}

{% hint style="danger" %}
DANGER

Merchants must do signature verification on the content of the payout callback and check whether the returned payment amount is correct, to prevent data leakage and the emergence of “fake notification”, resulting in loss of funds.
{% endhint %}

## **POST**

{% code fullWidth="false" %}

```
The notify url parameter submitted by the 'Create Payout'. If the link cannot access, 
your merchant cannot receive the notification from the system.
```

{% endcode %}

## **Request Body**

| Name             | Type   | Description                                                                                                                                                                                                     | Description |
| ---------------- | ------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------- |
| app\_id          | string | Application                                                                                                                                                                                                     |             |
| mch\_id          | string | Merchant                                                                                                                                                                                                        |             |
| create\_time     | time   | Notification time                                                                                                                                                                                               |             |
| resource\_type   | string | The resource data type of the notification. Payment success notification is encrypt-resource                                                                                                                    |             |
| event\_type      | string | Notification type. The type of payment success notification is PAYPAYOUT.SUCCESS.                                                                                                                               |             |
| resource         | object | Notification resource data                                                                                                                                                                                      |             |
| » original\_type | string | The original callback type is payout                                                                                                                                                                            |             |
| » algorithm      | string | Currently, only AES-256-ECB is supported for the encryption algorithm that encrypts the result data                                                                                                             |             |
| » ciphertext     | string | Base64 encoded on/off result data ciphertext. If enabled, the encrypted content is returned. After decryption, it is a json string of [PayoutTransactionDetail.](/description/data-structure#payanother-detial) |             |
| » nonce          | string | Encrypt using random strings                                                                                                                                                                                    |             |

## **Request example**

```json
{
	"app_id": "xxxxx",
	"mch_id": "zzzzzz",
	"create_time": "2023-06-26T17:21:17.754429+08:00",
	"resource_type": "encrypt-resource",
	"event_type": "PAYPAYOUT.SUCCESS",
	"resource": {
		"original_type": "payout",
		"algorithm": "AEAD_AES_256_GCM",
		"ciphertext": "I/psKgdkVwxbkEIWtwRxfxLzViuRS+gJTQSdLf+lmK7awoqUcIJisTAJx0Qbv4K6wV8WgyMRFYHD5CCLKmFNU2OnmEm2f2vGhaoS2h28A9BEGx1CWEUw3tfldf/+VWlBAnIBylFjHzbSo7fgn7S3fFEAZHTxoy+9jNIoynqHZbn4Y6eucj1YCw0ZmuKHPpPPrvclbhHmaZHfau+SKyag3C0/cj7zu4mBkRZ39zuk9B7DAADzaRENOZ/ZyibU+zs3gibnCbI2NWEnQWIiCi7vK0jq/FCBWytHihQM364zlVrPPCBDbv2MSqk4fyAM7IDeT6h/z/2kmDOQ6aFPYlLojIkgCCOIevQITS9E+BS1rgmmH+DRKsJNiD257aLhX2/F53VEnjfqqKdDs2lqfX0dCMLqselGUT981fFKceXg+r6hQqcUzLlF28XL5NrfVPreRDo6jI2K0tCy9cOx+cxH3yoDzOFBzM0RlxWqvUhRsMv9ZGfpgCZ0o9HxNObqLjVCQzE5SWPXvmkw+QpWk0oNUvpCEDhj9Vfq6XCV8j3tT3tZTYCa5UQy9VCdmval/2vb50QaAgDYXU6PH/9Xv7AXg6kg29iK+Ec0euxZxosRoVczzRg+0Arl/zvBcphWNIUTdx5IcA12WtP+krk9NNGtj7igk21DhcseJrKBpG7ll9O/Wmq1L8BwW+ypuJS+kHV61jRNYMFJY48Pt11Zoukgqu94kzrhz+KET8q463zlyu/Kp2z5yWI8xwvOtuyjosszfm6/YFQTFdhcmHY3X1yz44NaVG9FPev1QPoPmI7K3Jqa0Q8Q5kQTbe/KrB0eyRpXtyAaShOEeiS2ypmFAC81/m4mjuTd24yAjBcTIfBYzjxwjPbKfv+OYKahDwJP1b7EhsM+Sgu48wQ+pp6wc8TYCOkiRR1pKeb3kaxpQGzlq7VNbWHFPw9TDiyCIEnr8T5eiJtzJJ0U0iIfqN5WHk7iHiNK4Y4TvmdF4f6UyeMTHvaprvzUZI8il5wvoCgIiRUY7qvv5V/KL4ZWHN6Y3EEvQmP4WDo3Wx5IFW8C1gkyFv8lQ1COSNYMPog6RLAI0rNvKZjvc4baWwcHmk/fM92X19F2Y0DArqLFFUTJVE5bUQXQexiUO1e8IL07wqY=",
		"nonce": "d8816e8d6dca4409b790a4bcaa25c621"
	}
}
```

## **Return example**

```
success
```

Please return `success` to notify the notification server after successfully receives the callback request. After the notification server receiving `success`, the notification stops. Otherwise, the notification will be sent 10 times at the frequency of 0s/15s/30s/3m/10m/20m/30m/60m/3h/6h.


# Cancel Payout

{% hint style="info" %}
TIP

For users to manually cancel payout or merchants to cancel payout.
{% endhint %}

## **Interface address**

```
POST https://api.tokenpay.me/v1/payanother/close
```

## **Interface parameters**

| Name       | location | Type   | Required | Description                                                       |
| ---------- | -------- | ------ | -------- | ----------------------------------------------------------------- |
| app\_id    | header   | string | Yes      | App ID, example value: `8e4b8c2e7cxxxxxxxx1a1cbd3d59e0bd`         |
| mch\_id    | body     | string | Yes      | Merchant ID, example value: `12345678`                            |
| payout\_id | body     | string | No       | Platform order, example value: `2a1cfa6568xxxxxxxx3050957024c559` |

**Parameters example**

```
{
  "app_id": "8e4b8c2e7cxxxxxxxx1a1cbd3d59e0bd",
  "mch_id": "12345678",
  "payout_id": "2a1cfa6568xxxxxxxx3050957024c559"
}
```

## **Interface return**

| Name        | Type    | Description                                                                  | Description |
| ----------- | ------- | ---------------------------------------------------------------------------- | ----------- |
| code        | integer | [Status code](https://ttpay.gitbook.io/api/v/english/error-code/status-code) | none        |
| msg         | string  | Status description                                                           | none        |
| request\_id | string  | Request ID                                                                   | none        |

## **Return example**

```
{
  "code": 0,
  "msg": "success",
  "request_id": "f23ade4a-e5ca-48f4-a4bb-59114ac360ba",
}
```

## **Example code**

{% tabs %}
{% tab title="Shell" %}

```sh
curl --location --request POST 'https://api.tokenpay.me/v1/payout/close' \
--header 'Authorization: <Authorization>' \
--header 'User-Agent: tokenpay API (https://tokenpay.me)' \
--header 'Content-Type: application/json' \
--data-raw '<body data here>'
```

{% endtab %}

{% tab title="Go" %}

```go
package main

import (
   "fmt"
   "strings"
   "net/http"
   "io/ioutil"
)

func main() {

   url := "https://api.tokenpay.me/v1/payout/close"
   method := "POST"

   payload := strings.NewReader(`<body data here>`)

   client := &http.Client {
   }
   req, err := http.NewRequest(method, url, payload)

   if err != nil {
      fmt.Println(err)
      return
   }
   req.Header.Add("Authorization", "<Authorization>")
   req.Header.Add("User-Agent", "tokenpay API (https://tokenpay.me)")
   req.Header.Add("Content-Type", "application/json")

   res, err := client.Do(req)
   if err != nil {
      fmt.Println(err)
      return
   }
   defer res.Body.Close()

   body, err := ioutil.ReadAll(res.Body)
   if err != nil {
      fmt.Println(err)
      return
   }
   fmt.Println(string(body))
}
```

{% endtab %}

{% tab title="PHP" %}

```php
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
   CURLOPT_URL => 'https://api.tokenpay.me/v1/payout/close',
   CURLOPT_RETURNTRANSFER => true,
   CURLOPT_ENCODING => '',
   CURLOPT_MAXREDIRS => 10,
   CURLOPT_TIMEOUT => 0,
   CURLOPT_FOLLOWLOCATION => true,
   CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
   CURLOPT_CUSTOMREQUEST => 'POST',
   CURLOPT_POSTFIELDS =>'<body data here>',
   CURLOPT_HTTPHEADER => array(
      'Authorization: <Authorization>',
      'User-Agent: tokenpay API (https://tokenpay.me)',
      'Content-Type: application/json'
   ),
));

$response = curl_exec($curl);

curl_close($curl);
echo $response;
```

{% endtab %}

{% tab title="Python" %}

```python
import http.client
import json

conn = http.client.HTTPSConnection("https://api.tokenpay.me")
payload = "<body data here>"
headers = {
   'Authorization': '<Authorization>',
   'User-Agent': 'tokenpay API (https://tokenpay.me)',
   'Content-Type': 'application/json'
}
conn.request("POST", "/v1/payout/close", payload, headers)
res = conn.getresponse()
data = res.read()
print(data.decode("utf-8"))
```

{% endtab %}

{% tab title="Java" %}

```java
OkHttpClient client = new OkHttpClient().newBuilder()
   .build();
MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "<body data here>");
Request request = new Request.Builder()
   .url("https://api.tokenpay.me/v1/payout/close")
   .method("POST", body)
   .addHeader("Authorization", "<Authorization>")
   .addHeader("User-Agent", "tokenpay API (https://tokenpay.me)")
   .addHeader("Content-Type", "application/json")
   .build();
Response response = client.newCall(request).execute();
```

{% endtab %}
{% endtabs %}


# Wallet


# Wallet addition

{% hint style="info" %}
TIP

Add the wallet in [monitor mode](/description/payment-method).
{% endhint %}

### Interface address <a href="#interface-address" id="interface-address"></a>

```
POST https://api.tokenpay.me/v1/wallet/insert
```

### Interface parameters <a href="#interface-parameters" id="interface-parameters"></a>

| Name            | Location | Type   | Required | Description                                                                                                                                                 |
| --------------- | -------- | ------ | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- |
| app\_id         | header   | string | Yes      | Application ID, example value: `8e4b8c2e7cxxxxxxxx1a1cbd3d59e0bd`.                                                                                          |
| mch\_id         | body     | string | Yes      | Merchant ID, example value: `1234567890`.                                                                                                                   |
| name            | body     | string | No       | Wallet note. In [monitor wallet mode](/description/payment-method), it can be used to identify `one user one wallet` unique information, such as `user ID`. |
| wallet\_address | body     | string | Yes      | Wallet address, example value: `TQjxEW2Z3pxxxxxxxxxxxxgJUrWXVAC92T`.                                                                                        |
| chain           | body     | string | Yes      | Owned public chain, example value:`TRON`、`ETHEREUM`、`BSC`. [View supported public chains](/currency/currency-information).                                  |

#### Parameters example <a href="#parameters-example" id="parameters-example"></a>

```json
{
  "mch_id": "1234567890",
  "app_id": "8e4b8c2e7cxxxxxxxx1a1cbd3d59e0bd",
  "wallet_address": "TQjxEW2Z3pxxxxxxxxxxxxgJUrWXVAC92T",
  "chain": "TRON",
  "name": "28713"
}
```

### Interface return <a href="#interface-return" id="interface-return"></a>

| Name        | Type                                                      | Required | Description                            |
| ----------- | --------------------------------------------------------- | -------- | -------------------------------------- |
| code        | integer                                                   | true     | [Status code](/error-code/status-code) |
| msg         | string                                                    | true     | Statements                             |
| request\_id | string                                                    | true     |                                        |
| data        | [WalletDetail](/description/data-structure#wallet-detial) | false    |                                        |

### Return example <a href="#return-example" id="return-example"></a>

```json
{
    "code": 0,
    "msg": "ok",
    "request_id": "60eeeab2-7896-4f80-8088-4251d262dea6",
    "data": {
        "app_id": "8e4b8c2e7cxxxxxxxx1a1cbd3d59e0bd",
        "mch_id": "1234567890",
        "name": "28713",
        "chain": "TRON",
        "wallet_address": "TQjxEW2Z3pxxxxxxxxxxxxgJUrWXVAC92T",
        "create_time": 1675236993,
        "last_time": 0
    }
}
```

### Example code <a href="#example-code" id="example-code"></a>

{% tabs %}
{% tab title="Shell" %}

```sh
curl --location --request POST 'https://api.tokenpay.me/v1/wallet/insert' \
--header 'Authorization: <Authorization>' \
--header 'User-Agent: tokenpay API (https://tokenpay.me)' \
--header 'Content-Type: application/json' \
--data-raw '<body data here>'
```

{% endtab %}

{% tab title="Go" %}

```go
package main

import (
   "fmt"
   "strings"
   "net/http"
   "io/ioutil"
)

func main() {

   url := "https://api.tokenpay.me/v1/wallet/insert"
   method := "POST"

   payload := strings.NewReader(`<body data here>`)

   client := &http.Client {
   }
   req, err := http.NewRequest(method, url, payload)

   if err != nil {
      fmt.Println(err)
      return
   }
   req.Header.Add("Authorization", "<Authorization>")
   req.Header.Add("User-Agent", "tokenpay API (https://tokenpay.me)")
   req.Header.Add("Content-Type", "application/json")

   res, err := client.Do(req)
   if err != nil {
      fmt.Println(err)
      return
   }
   defer res.Body.Close()

   body, err := ioutil.ReadAll(res.Body)
   if err != nil {
      fmt.Println(err)
      return
   }
   fmt.Println(string(body))
}
```

{% endtab %}

{% tab title="PHP" %}

```php
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
   CURLOPT_URL => 'https://api.tokenpay.me/v1/wallet/insert',
   CURLOPT_RETURNTRANSFER => true,
   CURLOPT_ENCODING => '',
   CURLOPT_MAXREDIRS => 10,
   CURLOPT_TIMEOUT => 0,
   CURLOPT_FOLLOWLOCATION => true,
   CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
   CURLOPT_CUSTOMREQUEST => 'POST',
   CURLOPT_POSTFIELDS =>'<body data here>',
   CURLOPT_HTTPHEADER => array(
      'Authorization: <Authorization>',
      'User-Agent: tokenpay API (https://tokenpay.me)',
      'Content-Type: application/json'
   ),
));

$response = curl_exec($curl);

curl_close($curl);
echo $response;
```

<br>
{% endtab %}

{% tab title="Python" %}

```python
import http.client
import json

conn = http.client.HTTPSConnection("https://api.tokenpay.me")
payload = "<body data here>"
headers = {
   'Authorization': '<Authorization>',
   'User-Agent': 'tokenpay API (https://tokenpay.me)',
   'Content-Type': 'application/json'
}
conn.request("POST", "/v1/wallet/insert", payload, headers)
res = conn.getresponse()
data = res.read()
print(data.decode("utf-8"))
```

{% endtab %}

{% tab title="Java" %}

```java
OkHttpClient client = new OkHttpClient().newBuilder()
   .build();
MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "<body data here>");
Request request = new Request.Builder()
   .url("https://api.tokenpay.me/v1/wallet/insert")
   .method("POST", body)
   .addHeader("Authorization", "<Authorization>")
   .addHeader("User-Agent", "tokenpay API (https://tokenpay.me)")
   .addHeader("Content-Type", "application/json")
   .build();
Response response = client.newCall(request).execute();
```

{% endtab %}
{% endtabs %}


# Wallet update

{% hint style="info" %}
TIP

Update the wallet in [monitor mode](/description/payment-method).
{% endhint %}

### Interface address <a href="#interface-address" id="interface-address"></a>

```
POST https://api.tokenpay.me/v1/wallet/update
```

### Interface parameters <a href="#interface-parameters" id="interface-parameters"></a>

| Name            | Location | Type   | Required | Description                                                                                                                                                 |
| --------------- | -------- | ------ | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- |
| app\_id         | header   | string | Yes      | Application ID, example value: `8e4b8c2e7cxxxxxxxx1a1cbd3d59e0bd`.                                                                                          |
| mch\_id         | body     | string | Yes      | Merchant ID, example value: `1234567890`.                                                                                                                   |
| name            | body     | string | No       | Wallet note. In [monitor wallet mode](/description/payment-method), it can be used to identify `one user one wallet` unique information, such as `user ID`. |
| wallet\_address | body     | string | Yes      | Wallet address, example value: `TQjxEW2Z3pxxxxxxxxxxxxgJUrWXVAC92T`.                                                                                        |
| chain           | body     | string | Yes      | Owned public chain, example value: `TRON`、`ETHEREUM`、`BSC`. [View supported public chains](/currency/currency-information).                                 |

#### Parameters example <a href="#parameters-example" id="parameters-example"></a>

```json
{
  "mch_id": "1234567890",
  "app_id": "8e4b8c2e7cxxxxxxxx1a1cbd3d59e0bd",
  "wallet_address": "TQjxEW2Z3pxxxxxxxxxxxxgJUrWXVAC92T",
  "chain": "TRON",
  "name": "28713"
}
```

### Interface return <a href="#interface-return" id="interface-return"></a>

| Name        | Type                                                           | Required | Description                            |
| ----------- | -------------------------------------------------------------- | -------- | -------------------------------------- |
| code        | integer                                                        | true     | [Status code](/error-code/status-code) |
| msg         | string                                                         | true     | Statements                             |
| request\_id | string                                                         | true     |                                        |
| data        | [WalletDetail](/description/data-structure#transaction-detail) | false    |                                        |

### Return example <a href="#return-example" id="return-example"></a>

```json
{
    "code": 0,
    "msg": "ok",
    "request_id": "60eeeab2-7896-4f80-8088-4251d262dea6",
    "data": {
        "app_id": "8e4b8c2e7cxxxxxxxx1a1cbd3d59e0bd",
        "mch_id": "1234567890",
        "name": "28713",
        "chain": "TRON",
        "wallet_address": "TQjxEW2Z3pxxxxxxxxxxxxgJUrWXVAC92T",
        "create_time": 1675236993,
        "last_time": 0
    }
}
```

### Example code <a href="#example-code" id="example-code"></a>

{% tabs %}
{% tab title="Shell" %}

```sh
curl --location --request POST 'https://api.tokenpay.me/v1/wallet/update' \
--header 'Authorization: <Authorization>' \
--header 'User-Agent: tokenpay API (https://tokenpay.me)' \
--header 'Content-Type: application/json' \
--data-raw '<body data here>'
```

{% endtab %}

{% tab title="Go" %}

```go
package main

import (
   "fmt"
   "strings"
   "net/http"
   "io/ioutil"
)

func main() {

   url := "https://api.tokenpay.me/v1/wallet/update"
   method := "POST"

   payload := strings.NewReader(`<body data here>`)

   client := &http.Client {
   }
   req, err := http.NewRequest(method, url, payload)

   if err != nil {
      fmt.Println(err)
      return
   }
   req.Header.Add("Authorization", "<Authorization>")
   req.Header.Add("User-Agent", "tokenpay API (https://tokenpay.me)")
   req.Header.Add("Content-Type", "application/json")

   res, err := client.Do(req)
   if err != nil {
      fmt.Println(err)
      return
   }
   defer res.Body.Close()

   body, err := ioutil.ReadAll(res.Body)
   if err != nil {
      fmt.Println(err)
      return
   }
   fmt.Println(string(body))
}
```

{% endtab %}

{% tab title="PHP" %}

```php
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
   CURLOPT_URL => 'https://api.tokenpay.me/v1/wallet/update',
   CURLOPT_RETURNTRANSFER => true,
   CURLOPT_ENCODING => '',
   CURLOPT_MAXREDIRS => 10,
   CURLOPT_TIMEOUT => 0,
   CURLOPT_FOLLOWLOCATION => true,
   CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
   CURLOPT_CUSTOMREQUEST => 'POST',
   CURLOPT_POSTFIELDS =>'<body data here>',
   CURLOPT_HTTPHEADER => array(
      'Authorization: <Authorization>',
      'User-Agent: tokenpay API (https://tokenpay.me)',
      'Content-Type: application/json'
   ),
));

$response = curl_exec($curl);

curl_close($curl);
echo $response;
```

<br>
{% endtab %}

{% tab title="Python" %}

```python
import http.client
import json

conn = http.client.HTTPSConnection("https://api.tokenpay.me")
payload = "<body data here>"
headers = {
   'Authorization': '<Authorization>',
   'User-Agent': 'tokenpay API (https://tokenpay.me)',
   'Content-Type': 'application/json'
}
conn.request("POST", "/v1/wallet/update", payload, headers)
res = conn.getresponse()
data = res.read()
print(data.decode("utf-8"))
```

{% endtab %}

{% tab title="Java" %}

```java
OkHttpClient client = new OkHttpClient().newBuilder()
   .build();
MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "<body data here>");
Request request = new Request.Builder()
   .url("https://api.tokenpay.me/v1/wallet/update")
   .method("POST", body)
   .addHeader("Authorization", "<Authorization>")
   .addHeader("User-Agent", "tokenpay API (https://tokenpay.me)")
   .addHeader("Content-Type", "application/json")
   .build();
Response response = client.newCall(request).execute();
```

{% endtab %}
{% endtabs %}


# Wallet deletion

{% hint style="info" %}
TIP

Delete the wallet in [monitor mode](/description/payment-method).
{% endhint %}

### Interface address <a href="#interface-address" id="interface-address"></a>

```
POST https://api.tokenpay.me/v1/wallet/delete
```

### Interface parameters <a href="#interface-parameters" id="interface-parameters"></a>

| Name            | Location | Type   | Required | Description                                                          |
| --------------- | -------- | ------ | -------- | -------------------------------------------------------------------- |
| app\_id         | header   | string | Yes      | Application ID, example value: `8e4b8c2e7cxxxxxxxx1a1cbd3d59e0bd`.   |
| mch\_id         | body     | string | Yes      | Merchant ID, example value: `1234567890`.                            |
| wallet\_address | body     | string | No       | Wallet address, example value: `TQjxEW2Z3pxxxxxxxxxxxxgJUrWXVAC92T`. |
| chain           | body     | string | Yes      | Chain, example value:`TRON`                                          |

#### Parameters example <a href="#parameters-example" id="parameters-example"></a>

```json
{
  "mch_id": "1234567890",
  "app_id": "8e4b8c2e7cxxxxxxxx1a1cbd3d59e0bd",
  "wallet_address": "TQjxEW2Z3pxxxxxxxxxxxxgJUrWXVAC92T",
  "chain": "TRON",
}
```

### Interface return <a href="#interface-return" id="interface-return"></a>

| Name        | Type    | Description                            | Description |
| ----------- | ------- | -------------------------------------- | ----------- |
| code        | integer | [Status code](/error-code/status-code) |             |
| msg         | string  | State description                      |             |
| request\_id | string  | Request ID                             |             |

### Return example <a href="#return-example" id="return-example"></a>

```json
{
    "code": 0,
    "msg": "success",
    "request_id": "b5506db8-fe9b-4ea6-bbc9-4497e70c03b6",
}
```

### Example code <a href="#example-code" id="example-code"></a>

{% tabs %}
{% tab title="Shell" %}

```sh
curl --location --request POST 'https://api.tokenpay.me/v1/wallet/delete' \
--header 'Authorization: <Authorization>' \
--header 'User-Agent: tokenpay API (https://tokenpay.me)' \
--header 'Content-Type: application/json' \
--data-raw '<body data here>'
```

{% endtab %}

{% tab title="Go" %}

```go
package main

import (
   "fmt"
   "strings"
   "net/http"
   "io/ioutil"
)

func main() {

   url := "https://api.tokenpay.me/v1/wallet/delete"
   method := "POST"

   payload := strings.NewReader(`<body data here>`)

   client := &http.Client {
   }
   req, err := http.NewRequest(method, url, payload)

   if err != nil {
      fmt.Println(err)
      return
   }
   req.Header.Add("Authorization", "<Authorization>")
   req.Header.Add("User-Agent", "tokenpay API (https://tokenpay.me)")
   req.Header.Add("Content-Type", "application/json")

   res, err := client.Do(req)
   if err != nil {
      fmt.Println(err)
      return
   }
   defer res.Body.Close()

   body, err := ioutil.ReadAll(res.Body)
   if err != nil {
      fmt.Println(err)
      return
   }
   fmt.Println(string(body))
}
```

{% endtab %}

{% tab title="PHP" %}

```php
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
   CURLOPT_URL => 'https://api.tokenpay.me/v1/wallet/delete',
   CURLOPT_RETURNTRANSFER => true,
   CURLOPT_ENCODING => '',
   CURLOPT_MAXREDIRS => 10,
   CURLOPT_TIMEOUT => 0,
   CURLOPT_FOLLOWLOCATION => true,
   CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
   CURLOPT_CUSTOMREQUEST => 'POST',
   CURLOPT_POSTFIELDS =>'<body data here>',
   CURLOPT_HTTPHEADER => array(
      'Authorization: <Authorization>',
      'User-Agent: tokenpay API (https://tokenpay.me)',
      'Content-Type: application/json'
   ),
));

$response = curl_exec($curl);

curl_close($curl);
echo $response;
```

<br>
{% endtab %}

{% tab title="Python" %}

```python
import http.client
import json

conn = http.client.HTTPSConnection("https://api.tokenpay.me")
payload = "<body data here>"
headers = {
   'Authorization': '<Authorization>',
   'User-Agent': 'tokenpay API (https://tokenpay.me)',
   'Content-Type': 'application/json'
}
conn.request("POST", "/v1/wallet/delete", payload, headers)
res = conn.getresponse()
data = res.read()
print(data.decode("utf-8"))
```

{% endtab %}

{% tab title="Java" %}

```java
OkHttpClient client = new OkHttpClient().newBuilder()
   .build();
MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "<body data here>");
Request request = new Request.Builder()
   .url("https://api.tokenpay.me/v1/wallet/delete")
   .method("POST", body)
   .addHeader("Authorization", "<Authorization>")
   .addHeader("User-Agent", "tokenpay API (https://tokenpay.me")
   .addHeader("Content-Type", "application/json")
   .build();
Response response = client.newCall(request).execute();
```

{% endtab %}
{% endtabs %}


# Wallet inquiry

{% hint style="info" %}
TIP

Query the wallet in [monitor mode](/description/payment-method).
{% endhint %}

### Interface address <a href="#interface-address" id="interface-address"></a>

```
GET https://api.tokenpay.me/v1/wallet/query
```

### Interface parameters <a href="#interface-parameters" id="interface-parameters"></a>

| Name            | Location | Type   | Required | Description                                                          |
| --------------- | -------- | ------ | -------- | -------------------------------------------------------------------- |
| app\_id         | header   | string | Yes      | Application ID, example value: `8e4b8c2e7cxxxxxxxx1a1cbd3d59e0bd`.   |
| mch\_id         | body     | string | Yes      | Merchant ID, example value: `1234567890`.                            |
| wallet\_address | query    | string | No       | Wallet address, example value: `TQjxEW2Z3pxxxxxxxxxxxxgJUrWXVAC92T`. |

### Interface return <a href="#interface-return" id="interface-return"></a>

| Name        | Type                                                      | Required | Description                            |
| ----------- | --------------------------------------------------------- | -------- | -------------------------------------- |
| code        | integer                                                   | true     | [Status code](/error-code/status-code) |
| msg         | string                                                    | true     | Statements                             |
| request\_id | string                                                    | true     |                                        |
| data        | [WalletDetail](/description/data-structure#wallet-detial) | false    |                                        |

### Return example <a href="#return-example" id="return-example"></a>

```json
{
    "code": 0,
    "msg": "ok",
    "request_id": "ac054f57-22bf-45aa-b2b7-2275a6daae6f",
    "data": {
        "app_id": "8e4b8c2e7cxxxxxxxx1a1cbd3d59e0bd",
        "mch_id": "1234567890",
        "name": "28713",
        "chain": "TRON",
        "wallet_address": "TQjxEW2Z3pxxxxxxxxxxxxgJUrWXVAC92T",
        "create_time": 1673333676,
        "last_time": 0
    }
}
```

### Example code <a href="#example-code" id="example-code"></a>

{% tabs %}
{% tab title="Shell" %}

```sh
curl --location --request GET 'https://api.tokenpay.me/v1/wallet/query' \
--header 'Authorization: <Authorization>' \
--header 'User-Agent: tokenpay API (https://tokenpay.me)' \
--header 'Content-Type: application/json' \
--data-raw '<body data here>'
```

{% endtab %}

{% tab title="Go" %}

```go
package main

import (
   "fmt"
   "strings"
   "net/http"
   "io/ioutil"
)

func main() {

   url := "https://api.tokenpay.me/v1/wallet/query"
   method := "GET"

   payload := strings.NewReader(`<body data here>`)

   client := &http.Client {
   }
   req, err := http.NewRequest(method, url, payload)

   if err != nil {
      fmt.Println(err)
      return
   }
   req.Header.Add("Authorization", "<Authorization>")
   req.Header.Add("User-Agent", "tokenpay API (https://tokenpay.me)")
   req.Header.Add("Content-Type", "application/json")

   res, err := client.Do(req)
   if err != nil {
      fmt.Println(err)
      return
   }
   defer res.Body.Close()

   body, err := ioutil.ReadAll(res.Body)
   if err != nil {
      fmt.Println(err)
      return
   }
   fmt.Println(string(body))
}
```

{% endtab %}

{% tab title="PHP" %}

```php
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
   CURLOPT_URL => 'https://api.tokenpay.me/v1/wallet/query',
   CURLOPT_RETURNTRANSFER => true,
   CURLOPT_ENCODING => '',
   CURLOPT_MAXREDIRS => 10,
   CURLOPT_TIMEOUT => 0,
   CURLOPT_FOLLOWLOCATION => true,
   CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
   CURLOPT_CUSTOMREQUEST => 'GET',
   CURLOPT_POSTFIELDS =>'<body data here>',
   CURLOPT_HTTPHEADER => array(
      'Authorization: <Authorization>',
      'User-Agent: tokenpay API (https://tokenpay.me)',
      'Content-Type: application/json'
   ),
));

$response = curl_exec($curl);

curl_close($curl);
echo $response;
```

<br>
{% endtab %}

{% tab title="Python" %}

```python
import http.client
import json

conn = http.client.HTTPSConnection("https://api.tokenpay.me")
payload = "<body data here>"
headers = {
   'Authorization': '<Authorization>',
   'User-Agent': 'tokenpay API (https://tokenpay.me)',
   'Content-Type': 'application/json'
}
conn.request("GET", "/v1/wallet/query", payload, headers)
res = conn.getresponse()
data = res.read()
print(data.decode("utf-8"))
```

{% endtab %}

{% tab title="Java" %}

```java
OkHttpClient client = new OkHttpClient().newBuilder()
   .build();
MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "<body data here>");
Request request = new Request.Builder()
   .url("https://api.tokenpay.me/v1/wallet/query")
   .method("GET", body)
   .addHeader("Authorization", "<Authorization>")
   .addHeader("User-Agent", "tokenpay API (https://tokenpay.me)")
   .addHeader("Content-Type", "application/json")
   .build();
Response response = client.newCall(request).execute();
```

{% endtab %}
{% endtabs %}


# Callback notification

{% hint style="info" %}
TIP

After the payment is completed, the payment center will send the relevant payment results and relevant information to the merchant, and the merchant needs to receive processing and return the response. When interacting with background notifications, if the payment center receives a merchant response that is not successful or times out, the payment Center considers the notification to have failed. The notification will be re-initiated periodically according to a certain policy to maximize the success rate of the notification, but there is no guarantee that the notification will be successful. （The notification frequency is 0s/15s/30s/3m/10m/20m/30m/60m/3h/6h）
{% endhint %}

{% hint style="warning" %}
WARNING

Note: The same notification may be sent multiple times to the merchant system. And the merchant system must be able to handle correctly the same notification. Recommended practices are as follows. When processing a notification, firstly checking the status of the corresponding service data to determine whether the notification has been processed. If no, process it again. If yes, direct return a success result. Before state checking and processing of business data, concurrency control is performed using data locks to avoid data chaos caused by function reentrant.
{% endhint %}

{% hint style="danger" %}
DANGER

Attention: The merchant system must do signature verification for the content of the order callback, and verify whether the returned order amount is consistent with the order amount. The reason for doing these to prevent data leakage resulting in "false notice" resulting in loss of funds.
{% endhint %}

### Interface address <a href="#interface-address" id="interface-address"></a>

```
The notify url parameter submitted by the POST unified order interface is set. If you cannot access the link, your service system cannot receive the notification from the payment center.
```

### Request Body <a href="#request-body" id="request-body"></a>

| Name             | Type   | Description                                                                                                                                                                                                      | Description |
| ---------------- | ------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------- |
| app\_id          | string | Application                                                                                                                                                                                                      |             |
| mch\_id          | string | Merchant                                                                                                                                                                                                         |             |
| create\_time     | time   | Notification time                                                                                                                                                                                                |             |
| resource\_type   | string | The resource data type of the notification. Payment success notification is encrypt-resource                                                                                                                     |             |
| event\_type      | string | Notification type. The type of payment success notification is SUCCESS.                                                                                                                                          |             |
| resource         | object | Notification resource data                                                                                                                                                                                       |             |
| » original\_type | string | The original callback type is transaction                                                                                                                                                                        |             |
| » algorithm      | string | Currently, only AES-256-ECB is supported for the encryption algorithm that encrypts the result data                                                                                                              |             |
| » ciphertext     | string | Base64 encoded on/off result data ciphertext. If enabled, the encrypted content is returned. After decryption, it is a json string of [TransactionNotifyDetail](/description/data-structure#transaction-detail). |             |
| » nonce          | string | Encrypt using random strings                                                                                                                                                                                     |             |

### Request example <a href="#request-example" id="request-example"></a>

```json
{
	"app_id": "xxxxx",
	"mch_id": "zzzzzz",
	"create_time": "2023-06-26T17:21:17.754429+08:00",
	"resource_type": "encrypt-resource",
	"event_type": "TRANSACTION.SUCCESS",
	"resource": {
		"original_type": "transaction",
		"algorithm": "AEAD_AES_256_GCM",
		"ciphertext": "I/psKgdkVwxbkEIWtwRxfxLzViuRS+gJTQSdLf+lmK7awoqUcIJisTAJx0Qbv4K6wV8WgyMRFYHD5CCLKmFNU2OnmEm2f2vGhaoS2h28A9BEGx1CWEUw3tfldf/+VWlBAnIBylFjHzbSo7fgn7S3fFEAZHTxoy+9jNIoynqHZbn4Y6eucj1YCw0ZmuKHPpPPrvclbhHmaZHfau+SKyag3C0/cj7zu4mBkRZ39zuk9B7DAADzaRENOZ/ZyibU+zs3gibnCbI2NWEnQWIiCi7vK0jq/FCBWytHihQM364zlVrPPCBDbv2MSqk4fyAM7IDeT6h/z/2kmDOQ6aFPYlLojIkgCCOIevQITS9E+BS1rgmmH+DRKsJNiD257aLhX2/F53VEnjfqqKdDs2lqfX0dCMLqselGUT981fFKceXg+r6hQqcUzLlF28XL5NrfVPreRDo6jI2K0tCy9cOx+cxH3yoDzOFBzM0RlxWqvUhRsMv9ZGfpgCZ0o9HxNObqLjVCQzE5SWPXvmkw+QpWk0oNUvpCEDhj9Vfq6XCV8j3tT3tZTYCa5UQy9VCdmval/2vb50QaAgDYXU6PH/9Xv7AXg6kg29iK+Ec0euxZxosRoVczzRg+0Arl/zvBcphWNIUTdx5IcA12WtP+krk9NNGtj7igk21DhcseJrKBpG7ll9O/Wmq1L8BwW+ypuJS+kHV61jRNYMFJY48Pt11Zoukgqu94kzrhz+KET8q463zlyu/Kp2z5yWI8xwvOtuyjosszfm6/YFQTFdhcmHY3X1yz44NaVG9FPev1QPoPmI7K3Jqa0Q8Q5kQTbe/KrB0eyRpXtyAaShOEeiS2ypmFAC81/m4mjuTd24yAjBcTIfBYzjxwjPbKfv+OYKahDwJP1b7EhsM+Sgu48wQ+pp6wc8TYCOkiRR1pKeb3kaxpQGzlq7VNbWHFPw9TDiyCIEnr8T5eiJtzJJ0U0iIfqN5WHk7iHiNK4Y4TvmdF4f6UyeMTHvaprvzUZI8il5wvoCgIiRUY7qvv5V/KL4ZWHN6Y3EEvQmP4WDo3Wx5IFW8C1gkyFv8lQ1COSNYMPog6RLAI0rNvKZjvc4baWwcHmk/fM92X19F2Y0DArqLFFUTJVE5bUQXQexiUO1e8IL07wqY=",
		"nonce": "d8816e8d6dca4409b790a4bcaa25c621"
	}
}
```

### Return example <a href="#return-example" id="return-example"></a>

```
success
```

Please return `success` to notify the notification server after successfully receives the callback request. After the notification server receiving `success`, the notification stops. Otherwise, the notification will be sent 10 times at the frequency of 0s/15s/30s/3m/10m/20m/30m/60m/3h/6h.


# Error code


# Status code

| Code  | Description                                     | Suggestion                                                                                                             |
| ----- | ----------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------- |
| 0     | Success                                         |                                                                                                                        |
| 100   | Request parameter error                         | It usually appears on a `POST` request. Please check that the json structure whether correct.                          |
| 103   | Invalid signature                               | Please check [signature generation](/description/signature-generation).                                                |
| 104   | Signature expired                               | Please sign again or check the server time.                                                                            |
| 11000 | Operation failed, please try again later.       | Usually, the service changes or becomes inoperable. You can give up or try again. Adjust according to `msg` prompts.   |
| 11001 | Operate too frequently, please try again later. | Limit `5` requests per second for `app id`. Place reduce the request frequency or add new applications.                |
| 11003 | Miss required parameter                         | Please carefully check document and the parameter type and value of the actual request whether rational and effective. |
| 12001 | Data is existed                                 |                                                                                                                        |
| 12002 | Data is absence                                 |                                                                                                                        |
| 12003 | Data is empty                                   |                                                                                                                        |
| 20000 | Application is absence                          |                                                                                                                        |
| 20001 | Application is disable                          |                                                                                                                        |
| 20002 | Under balance                                   | Please go to the user center to [recharge](https://ttpay.io/console/pages/recharge?lang=en).                           |
| 20003 | Under quota                                     |                                                                                                                        |
| 20004 | Request frequency limitation                    |                                                                                                                        |
| 20005 | Invalid parameter                               | Adjust according to `msg` prompts.                                                                                     |


