MPC定制化有限授权开源代码框架
CipherBC 正式推出定制化有限授权开源(Source-Available)MPC 框架,这是一项经过筛选的开源计划,旨在在保护核心知识产权的前提下,为审计机构与合作伙伴提供透明性。不同于传统的开源模式,该框架采用 非商业许可证,允许经过授权的机构、合规团队及学术研究者在签署保密协议(NDA)的前提下,审阅、分析并验证我们的 MPC-HSM 密钥架构(Key Architecture)。
凭借 累计 USD 11.7 亿+ 的交易量与 USD 150 亿+ 的托管资产规模,该有限授权开源 MPC 框架为企业提供了真正可落地的优势:
灵活性与透明度: 采用定制化开源模式,可根据不同企业合作方的安全需求与隐私预期进行配置。可访问范围、代码模块、技术洞察深度皆可按需定制,确保所有协作均在安全、私密、可控、互信的环境中进行,加速技术集成。
安全性与合规性: 仅向认证的第三方审计机构、安全团队及受监管合作伙伴开放访问权限,使 CipherBC 可借助独立验证进一步提升代码的可靠性与稳健性。这为银行级审计、机构尽调与监管评估奠定基础。
协作式知识产权保护: 在非商业用途前提下,我们会选择性向学术机构开放,用于密码学研究与理论验证,促进知识交流与技术演进;同时,通过定制化授权与法律保护机制,确保 CipherBC 的核心知识产权与商业价值得到完整保留。
技术架构
项目基于专业的 Omnibus Wallet(综合托管钱包)架构设计,具有清晰、模块化的代码结构,让合作伙伴能够轻松开展系统化、全面且高效的安全审计。
更多说明与信息
请注意,本项目并不遵循 Open Source Initiative(OSI)的传统开源定义。 它是一项 有限授权开源(Source-Available)项目,旨在与可信合作伙伴进行受控的知识共享和技术协作,而非开放给任何人自由参与。
访问本项目源码需提交申请。 请准备好您的 GitHub 账户,并联系:support@cipherbc.com 获取授权。
如需全面了解此框架,请访问: https://github.com/cipherbc1024/OpenSource
欢迎使用 CipherBC API
接入准备
1 申请APP_ID
联系客服人员申请APP_ID,需要提供相关资质信息。 例如:公司名称,域名,IP, 第一负责人及其他商务需要信息。
2 提供需要支持的主链与合约币种清单
合约币需要合约地址、所属主链、精度、名称等基本信息给到业务对接人。
3 接口测试环境调试
接口测试环境对接,联调,演练。 接口采用 RSA2048位 双向签名验签形式确保通信可信性。 商户需要提前将公钥给到平台,用于平台对商户请求参数验签。 商户需要提前获取平台公钥,用于对平台响应结果验签。
支持公链
签名规则
<?php
$obj = new obj();
$obj->coin_list();
class obj
{
public $baseUrl = 'http://api.xxxxx.com/shopapi';
public $priKey = "-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC8d6RGCeQkrobx
+4xO1jXnHwiMU48UyOaRaNW2FMQrN9DcK/T2h58FyuA7kYN0CVNFEnaZQS9S8Nur
Tl0lOVJcbwKfCSnu9nmFYDvPWqlCTqQW3F83sKNi9IWrMFFny3CX35eUHpeJahE2
R9wma2oJIFJv3ux/I3+w8fQQ6zMPIqpDx4Tcu9sCVpot+/siWJDpyiQBlbXfcxuH
YOePUGx+tJ5HLXtJOUtPcgyhFTXRmW9r17DnnsjrT5Vc50IbN//JXbvr96eexQ/e
/IXHZP6MZWdthjuv9y2TaxS+JMnpKLrXfgazoQEsKmchAsTLEyX6tHG5tHq+3MaK
BSTFCoHHAgMBAAECggEAYodR1GPbZ+nuFpfhlF2ctIWe3G3awYz+LUrXX2ef3tBB
WrmISVJBqq+TZtD+Hi254MR0SE6xxPSygu5m98zt5/EJN8d8qrckdLwIyLCnCElA
s8rl5KFt6Y/YSdTq2g6bgGqePgt4QZi4At6yk0tYlgjV0DKFBTqzyPfVFvs/KEuZ
o8le0XjgJA+Rnti35Gi5UDL1Tn9LcmCU/JcdpksFgPvU/wPmlNb8azM68ougXcrf
hBebSRWbS0F2OXRJd7+hrTq+pwTNIH+IyzsUZHQCcH0tFe2Q304oDuVuwX5VxB3S
tYG8+LoECW1nKalJbolkmdRqVxZRXG/Ho8/aRCHBcQKBgQDBmoZzUaKU2F4Sa6P+
5vCQ5RAAiAATWao/WYfL9BBVnLzbkbzget3BNdJcJZKp1Avh6F/jeB0xUOD0aFgm
rJAZjVAFu77damKWwiEPxKfdgSbBedV/KWCMASzr4m4cdYKOcmlLFsh+Du2+oZW5
3Mn35hyfbTf1OyYxrvOVrhSu+wKBgQD5NVfxWTBsugAE++d4CCy8TUL7QCqb1I1v
EQ0FNdZsmXslPbCFlJ5UCFJXAF6s2x0MDKCl7y2ixlDo31H7DI6xlOP5kjYon7wr
mB0U2bclGtlJ3FvCwDBFkfZykYZqPyey8A3D+kf4pnvZvn/0BgKfWCVSYnqEB4mp
BI5WhywOpQKBgH4Mio8YTn8UZCMgG/UBDQ15ZbLC2THABj0aoHRkoiHrW3ala1DI
DgsWbLB78gJKQbZCofOqp28NVnkqWoJLhcJtI/Wnp/vmoOvA1t+6TQTFaqM7HIqf
OPHObh3iHYi/5VGzIeS2n7CbLaUY9S++lWymUGpoJK+wZAyi+IqyfVrzAoGAPKmI
g75zNDQ+pvfuy2AqC5g/Esv200H1P7EF21vUm1DtEg6nNo0L0WbJLFZxtWAM/Q7h
2CKVmEbwEQ+zdAoFfiLBL9Iwjsj7VB1ODvJES6ryc7FJQOnpljXGqPLVpm1DK6KV
pzv4YwWbplBh8zO3VbRuOVSxgAwZrWPnhhaXWeUCgYEAwVHYXN1qGTBS1uyrldDr
OMuXyfvE7lbfJlg2EfG2A7PtTooPkh1IbRjlJ8ACbiadM0pYhnGGPk0D1WSKvRxU
SmSc6PgW2weANQ8QCemo2V/zZ0DlWFZDdCV+7jMbAFBhQHcVh0qUr+uNyntjLTjj
OPdMSnhKLoKtleu+NiMIogc=
-----END PRIVATE KEY-----";
public $pubKey = "-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAk7K9s+r82lofBFaj3KWp
o/5E1ryDPDlLGZ4Rv68DcoCxV/bv0IvYX3cleC0WvTpwbdTpGtLjS6RHj89JREhi
svv5qmk5YTfjEqd3RmtYDmOVz2Ry6E76wLh9qi1pqpneMGr3shvEzZC6gkieXRCA
MOlEYbE7TSzxxDJxmovdeElowdRZcvwwPLvh/BLmCn+H1MXfdx01c/eFpTvu8BZG
1m7AqDOqnaPcR1ru/ekJoIwotF1jCPM2E5kAbQQutNaeSXhLbkfom4bxqF2/ni6k
Cwnz3fbBYcXP3Ww3/AdI1dn0iLr6450qn72yBpDtQY8OZ7+Krff4Fa5jOBY7OHEN
FwIDAQAB
-----END PUBLIC KEY-----";
public function coin_list()
{
$data = $this->get_public_data();
$data["chain"] = "eth";
$data["coin"] = "eth";
$data['sign'] = Signature::encryption($data, $this->priKey);
$res = self::curlByPost($this->baseUrl . '/coin/list', $data);
print_r($res);
// 验签
$resp = json_decode($res, true);
if (Signature::checkSignature($resp["sign"], $resp, $this->pubKey)) {
print_r("验签通过");
} else {
print_r("验签失败");
}
}
public static function curlByPost($url, $data = null, $timeout = 60)
{
$SSL = substr($url, 0, 8) == "https://" ? TRUE : FALSE;
$ch = curl_init();
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_URL, $url);
if ($SSL) {
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
}
$data = json_encode($data);
$headers = [
'Content-Type: application/json; charset=utf-8',
'Content-Length:' . strlen($data)
];
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_POST, TRUE);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$output = curl_exec($ch);
return $output;
}
public function get_public_data()
{
$data['app_id'] = "xxxxxx";
$data['version'] = '1.0';
$data['key_version'] = 'admin';
$data['time'] = time();
return $data;
}
}
class Signature
{
/**
* 私钥签名
*
* @param $data
* @param $private_key
*/
public static function encryption($data, $private_key)
{
if (is_array($data))
$signString = self::getSignString($data);
else
$signString = $data;
$privKeyId = openssl_pkey_get_private($private_key);
$signature = '';
openssl_sign($signString, $signature, $privKeyId, OPENSSL_ALGO_MD5);
openssl_free_key($privKeyId);
return base64_encode($signature);
}
/**
* 使用对方的公钥验签,并且判断签名是否匹配
*
* @param $sign
* @param $data
* @param $public_key
* @return bool
*/
public static function checkSignature($sign, $data, $public_key)
{
$toSign = self::getSignString($data);
$publicKeyId = openssl_pkey_get_public($public_key);
$result = openssl_verify($toSign, base64_decode($sign), $publicKeyId, OPENSSL_ALGO_MD5);
openssl_free_key($publicKeyId);
return $result === 1 ? true : false;
}
public static function getSignString($data)
{
unset($data['sign']);
ksort($data);
reset($data);
$pairs = array();
foreach ($data as $k => $v) {
if (is_array($v)) $v = self::arrayToString($v);
$pairs[] = "$k=$v";
}
return implode('&', $pairs);
}
private static function arrayToString($data)
{
$str = '';
foreach ($data as $list) {
if (is_array($list)) {
$str .= self::arrayToString($list);
} else {
$str .= $list;
}
}
return $str;
}
}
package main
import (
"crypto"
"crypto/md5"
"crypto/rand"
"crypto/rsa"
"crypto/x509"
"encoding/base64"
"encoding/json"
"encoding/pem"
"errors"
"fmt"
"github.com/imroc/req"
"github.com/tidwall/gjson"
"sort"
"time"
)
var (
BaseUrl = "http://api.xxxxx.com/shopapi"
signPrivateKey = `-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC8d6RGCeQkrobx
+4xO1jXnHwiMU48UyOaRaNW2FMQrN9DcK/T2h58FyuA7kYN0CVNFEnaZQS9S8Nur
Tl0lOVJcbwKfCSnu9nmFYDvPWqlCTqQW3F83sKNi9IWrMFFny3CX35eUHpeJahE2
R9wma2oJIFJv3ux/I3+w8fQQ6zMPIqpDx4Tcu9sCVpot+/siWJDpyiQBlbXfcxuH
YOePUGx+tJ5HLXtJOUtPcgyhFTXRmW9r17DnnsjrT5Vc50IbN//JXbvr96eexQ/e
/IXHZP6MZWdthjuv9y2TaxS+JMnpKLrXfgazoQEsKmchAsTLEyX6tHG5tHq+3MaK
BSTFCoHHAgMBAAECggEAYodR1GPbZ+nuFpfhlF2ctIWe3G3awYz+LUrXX2ef3tBB
WrmISVJBqq+TZtD+Hi254MR0SE6xxPSygu5m98zt5/EJN8d8qrckdLwIyLCnCElA
s8rl5KFt6Y/YSdTq2g6bgGqePgt4QZi4At6yk0tYlgjV0DKFBTqzyPfVFvs/KEuZ
o8le0XjgJA+Rnti35Gi5UDL1Tn9LcmCU/JcdpksFgPvU/wPmlNb8azM68ougXcrf
hBebSRWbS0F2OXRJd7+hrTq+pwTNIH+IyzsUZHQCcH0tFe2Q304oDuVuwX5VxB3S
tYG8+LoECW1nKalJbolkmdRqVxZRXG/Ho8/aRCHBcQKBgQDBmoZzUaKU2F4Sa6P+
5vCQ5RAAiAATWao/WYfL9BBVnLzbkbzget3BNdJcJZKp1Avh6F/jeB0xUOD0aFgm
rJAZjVAFu77damKWwiEPxKfdgSbBedV/KWCMASzr4m4cdYKOcmlLFsh+Du2+oZW5
3Mn35hyfbTf1OyYxrvOVrhSu+wKBgQD5NVfxWTBsugAE++d4CCy8TUL7QCqb1I1v
EQ0FNdZsmXslPbCFlJ5UCFJXAF6s2x0MDKCl7y2ixlDo31H7DI6xlOP5kjYon7wr
mB0U2bclGtlJ3FvCwDBFkfZykYZqPyey8A3D+kf4pnvZvn/0BgKfWCVSYnqEB4mp
BI5WhywOpQKBgH4Mio8YTn8UZCMgG/UBDQ15ZbLC2THABj0aoHRkoiHrW3ala1DI
DgsWbLB78gJKQbZCofOqp28NVnkqWoJLhcJtI/Wnp/vmoOvA1t+6TQTFaqM7HIqf
OPHObh3iHYi/5VGzIeS2n7CbLaUY9S++lWymUGpoJK+wZAyi+IqyfVrzAoGAPKmI
g75zNDQ+pvfuy2AqC5g/Esv200H1P7EF21vUm1DtEg6nNo0L0WbJLFZxtWAM/Q7h
2CKVmEbwEQ+zdAoFfiLBL9Iwjsj7VB1ODvJES6ryc7FJQOnpljXGqPLVpm1DK6KV
pzv4YwWbplBh8zO3VbRuOVSxgAwZrWPnhhaXWeUCgYEAwVHYXN1qGTBS1uyrldDr
OMuXyfvE7lbfJlg2EfG2A7PtTooPkh1IbRjlJ8ACbiadM0pYhnGGPk0D1WSKvRxU
SmSc6PgW2weANQ8QCemo2V/zZ0DlWFZDdCV+7jMbAFBhQHcVh0qUr+uNyntjLTjj
OPdMSnhKLoKtleu+NiMIogc=
-----END PRIVATE KEY-----
`
signPublicKey = `-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAk7K9s+r82lofBFaj3KWp
o/5E1ryDPDlLGZ4Rv68DcoCxV/bv0IvYX3cleC0WvTpwbdTpGtLjS6RHj89JREhi
svv5qmk5YTfjEqd3RmtYDmOVz2Ry6E76wLh9qi1pqpneMGr3shvEzZC6gkieXRCA
MOlEYbE7TSzxxDJxmovdeElowdRZcvwwPLvh/BLmCn+H1MXfdx01c/eFpTvu8BZG
1m7AqDOqnaPcR1ru/ekJoIwotF1jCPM2E5kAbQQutNaeSXhLbkfom4bxqF2/ni6k
Cwnz3fbBYcXP3Ww3/AdI1dn0iLr6450qn72yBpDtQY8OZ7+Krff4Fa5jOBY7OHEN
FwIDAQAB
-----END PUBLIC KEY-----
`
)
func main() {
pub := make(map[string]string)
// 公共参数
pub["app_id"] = "xxxxxxxxx"
pub["version"] = "1.0"
pub["key_version"] = "admin"
pub["time"] = fmt.Sprintf("%d", time.Now().Unix())
// 业务参数
pub["chain"] = "eth"
pub["coin"] = "eth"
pub["sign"] = getSign(pub)
url := fmt.Sprintf("%s/coin/list", BaseUrl)
r := req.New()
r.EnableInsecureTLS(true)
post, err := r.Post(url, req.BodyJSON(&pub))
if err != nil {
panic(err)
}
fmt.Println("返回", post.String())
// 验签
checkSign(post.String())
}
// 获取签名串
func getSign(data map[string]string) string {
err, signStr := ApiSign(data, signPrivateKey)
if err != nil {
panic(err)
}
fmt.Println("签名串:", signStr)
return signStr
}
// 验证签名
func checkSign(resp string) {
var res map[string]interface{}
err := json.Unmarshal([]byte(resp), &res)
if err != nil {
panic(err)
}
sign := res["sign"].(string)
data := ParseJsonToClassMap(resp)
err = ApiVerifySign(data, signPublicKey, sign)
if err != nil {
fmt.Println("验签失败")
return
}
fmt.Println("验签通过")
}
/**
* 本地私钥签名
* @param data 参数
* @param priKey 本地私钥
* @return error
* @return string
*/
func ApiSign(data map[string]string, priKey string) (error, string) {
hashed := getSignString(data)
// rsa
block, _ := pem.Decode([]byte(priKey))
if block == nil {
return errors.New("private key error"), ""
}
privateKey, err := x509.ParsePKCS8PrivateKey(block.Bytes)
if err != nil {
return err, ""
}
signature, err := rsa.SignPKCS1v15(rand.Reader, privateKey.(*rsa.PrivateKey), crypto.MD5, hashed)
if err != nil {
return err, ""
}
ciphertext := base64.StdEncoding.EncodeToString(signature)
return nil, ciphertext
}
/**
* 使用对方的公钥验签,并且判断签名是否匹配
* @param data 参数
* @param signed 签名体
* @param pubKey 公钥
* @return error
*/
func ApiVerifySign(data map[string]string, pubKey string, signed string) error {
hashed := getSignString(data)
block, _ := pem.Decode([]byte(pubKey))
if block == nil {
return errors.New("public key error")
}
// 解析公钥
pubInterface, err := x509.ParsePKIXPublicKey(block.Bytes)
if err != nil {
return err
}
pub := pubInterface.(*rsa.PublicKey)
decodeString, err := base64.StdEncoding.DecodeString(signed)
if err != nil {
return err
}
err = rsa.VerifyPKCS1v15(pub, crypto.MD5, hashed, decodeString)
if err != nil {
return err
}
return nil
}
// 拼接参数
func getSignString(data map[string]string) []byte {
delete(data, "sign")
var keys []string
for k := range data {
keys = append(keys, k)
}
sort.Strings(keys)
var signStr string
for _, k := range keys {
if signStr != "" {
signStr = signStr + "&" + k + "=" + data[k]
} else {
signStr = k + "=" + data[k]
}
}
hashMd5 := md5.Sum([]byte(signStr))
hashed := hashMd5[:]
return hashed
}
func ParseJsonToClassMap(jsonStr string) (m map[string]string) {
m = make(map[string]string)
result := gjson.Parse(jsonStr)
result.ForEach(func(key, value gjson.Result) bool {
if value.Type == gjson.JSON && gjson.Valid(value.String()) {
m[key.String()] = JsonToString(value.String())
} else {
m[key.String()] = value.String()
}
return true
})
return
}
func JsonToString(jsonStr string) string {
str := ""
r := gjson.Parse(jsonStr)
r.ForEach(func(key, value gjson.Result) bool {
if value.Type == gjson.JSON && gjson.Valid(value.String()) {
str += JsonToString(value.String())
} else {
str += value.String()
}
return true
})
return str
}
var crypto = require('crypto');
var priKey = `-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC8d6RGCeQkrobx
+4xO1jXnHwiMU48UyOaRaNW2FMQrN9DcK/T2h58FyuA7kYN0CVNFEnaZQS9S8Nur
Tl0lOVJcbwKfCSnu9nmFYDvPWqlCTqQW3F83sKNi9IWrMFFny3CX35eUHpeJahE2
R9wma2oJIFJv3ux/I3+w8fQQ6zMPIqpDx4Tcu9sCVpot+/siWJDpyiQBlbXfcxuH
YOePUGx+tJ5HLXtJOUtPcgyhFTXRmW9r17DnnsjrT5Vc50IbN//JXbvr96eexQ/e
/IXHZP6MZWdthjuv9y2TaxS+JMnpKLrXfgazoQEsKmchAsTLEyX6tHG5tHq+3MaK
BSTFCoHHAgMBAAECggEAYodR1GPbZ+nuFpfhlF2ctIWe3G3awYz+LUrXX2ef3tBB
WrmISVJBqq+TZtD+Hi254MR0SE6xxPSygu5m98zt5/EJN8d8qrckdLwIyLCnCElA
s8rl5KFt6Y/YSdTq2g6bgGqePgt4QZi4At6yk0tYlgjV0DKFBTqzyPfVFvs/KEuZ
o8le0XjgJA+Rnti35Gi5UDL1Tn9LcmCU/JcdpksFgPvU/wPmlNb8azM68ougXcrf
hBebSRWbS0F2OXRJd7+hrTq+pwTNIH+IyzsUZHQCcH0tFe2Q304oDuVuwX5VxB3S
tYG8+LoECW1nKalJbolkmdRqVxZRXG/Ho8/aRCHBcQKBgQDBmoZzUaKU2F4Sa6P+
5vCQ5RAAiAATWao/WYfL9BBVnLzbkbzget3BNdJcJZKp1Avh6F/jeB0xUOD0aFgm
rJAZjVAFu77damKWwiEPxKfdgSbBedV/KWCMASzr4m4cdYKOcmlLFsh+Du2+oZW5
3Mn35hyfbTf1OyYxrvOVrhSu+wKBgQD5NVfxWTBsugAE++d4CCy8TUL7QCqb1I1v
EQ0FNdZsmXslPbCFlJ5UCFJXAF6s2x0MDKCl7y2ixlDo31H7DI6xlOP5kjYon7wr
mB0U2bclGtlJ3FvCwDBFkfZykYZqPyey8A3D+kf4pnvZvn/0BgKfWCVSYnqEB4mp
BI5WhywOpQKBgH4Mio8YTn8UZCMgG/UBDQ15ZbLC2THABj0aoHRkoiHrW3ala1DI
DgsWbLB78gJKQbZCofOqp28NVnkqWoJLhcJtI/Wnp/vmoOvA1t+6TQTFaqM7HIqf
OPHObh3iHYi/5VGzIeS2n7CbLaUY9S++lWymUGpoJK+wZAyi+IqyfVrzAoGAPKmI
g75zNDQ+pvfuy2AqC5g/Esv200H1P7EF21vUm1DtEg6nNo0L0WbJLFZxtWAM/Q7h
2CKVmEbwEQ+zdAoFfiLBL9Iwjsj7VB1ODvJES6ryc7FJQOnpljXGqPLVpm1DK6KV
pzv4YwWbplBh8zO3VbRuOVSxgAwZrWPnhhaXWeUCgYEAwVHYXN1qGTBS1uyrldDr
OMuXyfvE7lbfJlg2EfG2A7PtTooPkh1IbRjlJ8ACbiadM0pYhnGGPk0D1WSKvRxU
SmSc6PgW2weANQ8QCemo2V/zZ0DlWFZDdCV+7jMbAFBhQHcVh0qUr+uNyntjLTjj
OPdMSnhKLoKtleu+NiMIogc=
-----END PRIVATE KEY-----
`
var pubKey = `-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAk7K9s+r82lofBFaj3KWp
o/5E1ryDPDlLGZ4Rv68DcoCxV/bv0IvYX3cleC0WvTpwbdTpGtLjS6RHj89JREhi
svv5qmk5YTfjEqd3RmtYDmOVz2Ry6E76wLh9qi1pqpneMGr3shvEzZC6gkieXRCA
MOlEYbE7TSzxxDJxmovdeElowdRZcvwwPLvh/BLmCn+H1MXfdx01c/eFpTvu8BZG
1m7AqDOqnaPcR1ru/ekJoIwotF1jCPM2E5kAbQQutNaeSXhLbkfom4bxqF2/ni6k
Cwnz3fbBYcXP3Ww3/AdI1dn0iLr6450qn72yBpDtQY8OZ7+Krff4Fa5jOBY7OHEN
FwIDAQAB
-----END PUBLIC KEY-----
`
/**
* 私钥签名
*/
function encryption(data) {
let signString = getSignString(data)
let sign = crypto.createSign('md5WithRSAEncryption');
sign.update(signString, 'utf8');
sign.end();
let signature = sign.sign(priKey, 'base64');
return signature
}
/**
* 使用对方的公钥验签,并且判断签名是否匹配
* @param sign
* @param data
* @return bool
*/
function checkSignature(sign, data) {
let signString = getSignString(data)
let verify = crypto.createVerify('md5WithRSAEncryption');
verify.update(signString, 'utf8');
verify.end();
return verify.verify(pubKey, sign, 'base64');
}
// 拼接参数
function getSignString(data) {
delete(data["sign"])
var keys = Object.keys(data)
keys = keys.sort()
let signStr = ""
for(let k in keys) {
if(typeof(data[keys[k]]) == "object") {
signStr = keys[k] + "=" + arrayToString(data[keys[k]])
}else {
if (signStr != "") {
signStr = signStr + "&" + keys[k] + "=" + data[keys[k]]
} else {
signStr = keys[k] + "=" + data[keys[k]]
}
}
}
return signStr
}
function arrayToString(data) {
let str = '';
for(let list in data) {
if (typeof (data[list]) == "object") {
str += arrayToString(data[list]);
} else {
str += data[list];
}
}
return str;
}
//发送请求
function httpByPost(data) {
let HTTP = require('http')
let POST_OPTIONS = {
port: 8888,
host: "http://api.xxxxx.com/shopapi",
path: "/coin/list",
method: 'POST',
headers: {
"Content-Type": "application/json"
}
};
// 创建 http 连接
const REQUEST = HTTP.request(POST_OPTIONS, requestOnResponse)
// 设置超时
REQUEST.setTimeout(6000)
// 通过连接发送数据
REQUEST.write(JSON.stringify(data), 'utf8')
REQUEST.end()
}
// 接受返回的数据验签
function requestOnResponse(incomingMessage){
let data = []
incomingMessage.on('data', chunk => {
data.push(...chunk)
})
incomingMessage.on('end', () => {
let _date = JSON.parse( new TextDecoder().decode(new Uint8Array(data)))
let res = checkSignature(_date["sign"], _date)
console.log(res)
})
}
/*****测试********/
let data = {
'app_id' : 'xxxxxxxxx',
'version' : '1.0',
'key_version' : 'admin',
'time' : Math.floor(Date.now()/1000),
'chain' :'eth',
'coin' : 'eth',
}
data['sign'] = encryption(data)
httpByPost(data);
package com.junior.common;
import com.google.gson.*;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.security.*;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.*;
import java.util.stream.Collectors;
public class rsaSigner {
public static void main(String[] args) {
String baseUrl = "http://api.xxxxx.com/shopapi";
String priKey = "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCtdgvcfozY7fe/x6UlXR/Fff8+wX++CiG05YVRafDe90O8y5KJAMZ156TgajEUXSRyKZqASz7iVoMAcu5FqfK1KuOOdjTAg0LFe/twIZvKmAqHcCSS2pjUXk0fTpZEgQ5lmDCK12Mg07YXvr+BeHjF+kBpwRJMPMG/+DGBDYNFNeRSJqWyopt6yyF528soAykHIUQ7TTultJV5IPCrvjRQQrGdJ/QtCdE0vZg+tA09nFN7AqgraU99kIvzyS0sqysj+pP1SJRmTRSGtlVAO3mILfkXOekZl1KD60G7CF+7BIaaW83FPD55tZhAGhnbLMYyiq7OiIyU61LTRcNSaJ0tAgMBAAECggEBAIGgGKcSzxCBbMYdXLV6TPbZ/HeaRGrwyVWUu7cmc0E8CJu6iWvmb2jGzbiCwuCT5luF6ZZ8JKchvU4FlTfsE5r9TQY2IZ/Ht4s65qBaDUEts5iY3kv8HX9+ZSXDJZpV0ztqqsPmx4ZNj+NYwWXwcFiKdb5R8OmV8bgSsnPddD6wFhwewglUOBPRAjropHE4sqk1Vam6q1MlFq5kiekMn/CItyFYFFzST/ruqAtVTp7YIvazAMrfCKH+pvXWk6pYNHZmL/JZey0GglRyJ1nItiqL33X8Lji056FcbAclidq022h/KPLEJpZk6irWqYdqYZeF6YMLHtdZFDkTZ/hXY+UCgYEA5i794UTQ1Kd6K+iui/S8K5H8nGdiXb3+uZ5j5VKYfbRmzXhAdVYisYe8czeTECxhH+MeHgM4tLR4ifx9q60ylvZxl9Fav1p6EaE36YcvGVmpm7Gm3q6QDDBa4gB+X9u7CxCS4LpotV917YS1QvOIF9lnRonSj1zNzFtbXkywrN8CgYEAwOpx/mR40ZvgZxNCq9DsIdrSZYAFFKpw0xy0OtF1PpuwMaREoRabnlVw6Bb3Hofg50XA3JxemzAX6fB92ee+NfXfeL4UtC4vG1K9JyiXHtHq8p9Uw2W03ehIEeNa3xdoRRnLmD4VUpyfL19ViE2+7TM1Gd3TogjDT+AMOCSuq3MCgYBsurPH7gaq/LVT+mRAzgj4l8v4YUlwuGeTbIMJdvt7HXUWB4CDLH3U2CYnUpAQKrZyJok6ahEmIr1xiKggKP7lmmHL8eNo0icpHrtXfzi7Q8Q/PCpzs4dtioXTjaIkS5nNvzVyG/uL+RyuZmpsxrZ5dYM4KbAhchfwORMutxEZhwKBgQC5zpVw4jCEItBmNuTWO+nTScGvxTgfiXIVw+XLaQa2AJoZlhAL34yPWdffko79tv3lgweY9HsimZXO2rU8dbp8mo5c6ydhy8HPXUeWOcAkDSdv/ApWENW9jgYsRIC3swHY3Fl+Dv3Wjce8huQI3mjwaYvRmBhIToxfmHnscVhTBQKBgB9uciEHfz8hMI7ePrPo2PkyK/RbJDm3HnuWE2lFBp7MOUMlh53MXwv4dIRaYMbRrFuN1UIKEFxuKhWwTHSzZJufk/UENrha/81fpj2BoFsAKkEunKeETvaIh6fZSjec16h2+zxbzwkdS6b+yIYkSlaoAxmDYrMtae0C8G4e0YS9";
String pubKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2RZZISModRzproL3eTxRtvVK/nToDbeLmAVdmaVtHgNCwjXMeNCZvHySZKO7+t7XySzBd2PhhQjvAkDd8HRKB5Y0uvP6TFwvhxOMkMydTeBFcUobQWNeAI7ttRms1txSNrmyrZr0WpWfk79VIsO+yI/jFN/Pj2gxD+vh5UUKU1LD2IQq/VxgtEpf8Vs6w7SvafPwYkpdPGCKUFkRvN1FrY2+tq0j1MRVJbB2rIunWDnT8cDUh2sWLXf4yNaJVOaaTFB0zbAk/qcoicGQyW7bVG7dVW8WywKmOAPeQCCQa+SJ4BhfI1k8eEAwFVRuxz/f9Ecfog9hZJ+RgELkpS8qhQIDAQAB";
rsaSigner signer = new rsaSigner();
Map<String, Object> params = new HashMap<>();
params.put("app_id", "hxgmau9imt86qky9");
params.put("version", "1.0");
params.put("key_version", "admin");
params.put("time", Long.toString(System.currentTimeMillis() / 1000));
params.put("coin", "trx");
try {
params.put("sign", signer.genSign(params, priKey));
Gson gson = new GsonBuilder().create();
System.out.println("params = " + gson.toJson(params));
String res = doPost(baseUrl + "/address/getBatch", gson.toJson(params));
if (null == res) {
throw new RuntimeException("http error");
}
System.out.println("response = " + res);
JsonParser jp = new JsonParser();
JsonObject resEle = jp.parse(res).getAsJsonObject();
boolean retSignOK = signer.verifySign(resEle, resEle.get("sign").getAsString(), pubKey);
if (!retSignOK) {
throw new RuntimeException("verify response sign fail");
}
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("OK");
}
public String genSign(Map<String, Object> data, String priKey) throws NoSuchAlgorithmException, InvalidKeySpecException, SignatureException, InvalidKeyException {
Map<String, String> stringMap = toStringMap(new GsonBuilder().create().toJson(data));
return this.sign(this.genSignString(stringMap), priKey);
}
public String genSignString(Map<String, String> params) {
if (null == params || params.size() == 0) {
return "";
}
List<String> sortedKeys = new ArrayList<>(params.keySet());
sortedKeys.remove("sign");
sortedKeys.sort(null);
String sb = sortedKeys.stream().map(s -> s + "=" + params.get(s)).collect(Collectors.joining("&"));
System.out.println("genSignString = " + sb);
return sb;
}
public String sign(String str, String priKey) throws NoSuchAlgorithmException, InvalidKeySpecException, InvalidKeyException, SignatureException {
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
byte[] decodedKey = Base64.getDecoder().decode(priKey.getBytes(StandardCharsets.UTF_8));
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(decodedKey);
PrivateKey pk = keyFactory.generatePrivate(keySpec);
Signature signature = Signature.getInstance("MD5withRSA");
signature.initSign(pk);
signature.update(str.getBytes(StandardCharsets.UTF_8));
return new String(Base64.getEncoder().encode(signature.sign()), StandardCharsets.UTF_8);
}
public boolean verifySign(JsonElement data, String sign, String pubKey) throws NoSuchAlgorithmException, InvalidKeySpecException, InvalidKeyException, SignatureException {
Map<String, String> resMap = toStringMap(data);
String signString = this.genSignString(resMap);
byte[] keyBytes = Base64.getDecoder().decode(pubKey.getBytes(StandardCharsets.UTF_8));
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PublicKey key = keyFactory.generatePublic(keySpec);
Signature signature = Signature.getInstance("MD5withRSA");
signature.initVerify(key);
signature.update(signString.getBytes(StandardCharsets.UTF_8));
return signature.verify(Base64.getDecoder().decode(sign.getBytes(StandardCharsets.UTF_8)));
}
public static Map<String, String> toStringMap(String str) {
JsonParser jp = new JsonParser();
JsonElement jEle = jp.parse(str);
return toStringMap(jEle);
}
public static Map<String, String> toStringMap(JsonElement jEle) {
Map<String, String> resMap = new HashMap<>();
if (null != jEle && jEle.isJsonObject()) {
for (Map.Entry<String, JsonElement> entry : jEle.getAsJsonObject().entrySet()) {
resMap.put(entry.getKey(), valueAsString(entry.getValue()));
}
}
return resMap;
}
public static String valueAsString(JsonElement element) {
if (element.isJsonNull()) {
return "";
} else if (element.isJsonPrimitive()) {
return element.getAsJsonPrimitive().getAsString();
} else if (element.isJsonObject()) {
StringBuilder sb = new StringBuilder();
for (Map.Entry<String, JsonElement> entry : element.getAsJsonObject().entrySet()) {
sb.append(valueAsString(entry.getValue()));
}
return sb.toString();
} else if (element.isJsonArray()) {
StringBuilder sb = new StringBuilder();
for (JsonElement vv : element.getAsJsonArray()) {
sb.append(valueAsString(vv));
}
return sb.toString();
}
return "";
}
public static String doPost(String httpUrl, String param) {
//send http post request
}
}
创建私钥
openssl genrsa -out rsa_private_key.pem 2048
根据私钥创建公钥
openssl rsa -in rsa_private_key.pem -out rsa_public_key.pem -pubout
签名算法详解
- 1. 获取请求参数并进行格式化获得一个新的参数格式化后的字符串:
- 2. 对第一步data进行用RSA私钥签名并把签名结果保存到一个变量中:
生成签名字符串, 对于如下的参数数组:
user_id = 1
coin = eth
address = 0x038B8E7406dED2Be112B6c7E4681Df5316957cad
amount = 10.001
trade_id = 20220131012030274786
对数组里的每一个键从a到z的顺序排序,若遇到相同首字母,则看第二个字母,以此类推。排序完成之后,再把所有数组值以“&”字符连接起来,如$dataString:
address=0x038B8E7406dED2Be112B6c7E4681Df5316957cad&amount=10.001&coin=eth&trade_id=20220131012030274786&user_id=1
这串字符串便是拼接好的字符串。
公共信息说明
以下信息对所有接口均通用、后面每个接口不重复描述
生产环境
API接口地址请联系客服获得
测试环境
API接口地址请联系客服获得
请求公共参数
| 参数名 | 必选 | 类型 | 约束 | 案列 | 说明 |
|---|---|---|---|---|---|
| app_id | 是 | string | 系统生成 | A6vZLiqyRYxu | 商户号具体对接时候系统分配 |
| version | 是 | string | 固定 | 1.0 | 接口版本号-根据接入时候约定为准固定不变 |
| sign | 是 | string | 长度344位 | Dr7MnhPYh… | RSA-2048 位秘钥模式 |
| time | 是 | string | 长度 10 位 | 1578829811 | 时间戳-忽略时区以秒为单位的timestamp |
| key_version | 否 | string | 动态枚举型 | 默认:admin | 秘钥版本号:admin / read / arbitrary-可以针对任意1-n个接口授权 |
公共信息须知
| 名称 | 类型 | 案列 | 描述 |
|---|---|---|---|
| 时间1 | timeStamp | 1578829811 | UTC 时间统一时间不带时区 |
| 时间2 | DateTime | 2020-01-09 15:48:42 | 全局系统如果出现这种格式默认为北京时间 |
| 请求方式 | POST | — | 所有请求均为POST |
| 编码 | UTF-8 | — | 其他编码可能会产生乱码和错误 |
| 通信协议 | HTTPS | https | 目前仅支持HTTPS |
| 签名类型 | RSA-2048位 | Dr7MnhPYh… | 点击查看规则详情 |
| 请求与返回 | JSON | — | 所有请求和响应参数都是JSON格式 |
| 金额参数注意 | string | — | 小数点后超8位,小数点前超12位无法通过,最后无效0要删除 |
地址
地址获取
$url = "http://api.xxxx.com/shopapi/address/getBatch";
$header = [
'Content-Type:application/json',
];
$params = [
"coin" => "hc",
"app_id" => "hxgmau9imt86qky9",
"version" => "1.0",
"time" => 1578997143,
"sign" => "IUtWA3HEkK+wvTGaSBYwIrdx+ANyoOPl2/1LQTDevCSTxf4/lDXPrg6/ph+skNXIbZTR8Qs2yGGkqTUHEW/vbiTPzWkYZ874rRgplp06vhOBM/Pkw289K7PVCKy1ksOtLjwj1dUfDD/2AEqTgxRDjGyn+yDWRa7HLL/28bjU3pZoFwPPjbPyRxMK9BVL/li9IQ6hb8lyOyQNHNxS3C82sDVaQKqrB0dOqtP61OH0hBonrxMhBAMD8dUmaqO6Ef+bhHzbBm3BCC5VapkOkdthb+UWXKCiBoCipg3gqrwnBdOUGXqx/1mYicNZ+oHeVpBwnJlXudff6FT+HySszr5ISw=="
];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
$return = curl_exec($ch);
print_r($return);
var url = "http://api.xxxx.com/shopapi/address/getBatch"
data := map[string]string{
"coin" : "hc",
"app_id" : "hxgmau9imt86qky9",
"version" : "1.0",
"time" : "1578997143",
"sign": "IUtWA3HEkK+wvTGaSBYwIrdx+ANyoOPl2/1LQTDevCSTxf4/lDXPrg6/ph+skNXIbZTR8Qs2yGGkqTUHEW/vbiTPzWkYZ874rRgplp06vhOBM/Pkw289K7PVCKy1ksOtLjwj1dUfDD/2AEqTgxRDjGyn+yDWRa7HLL/28bjU3pZoFwPPjbPyRxMK9BVL/li9IQ6hb8lyOyQNHNxS3C82sDVaQKqrB0dOqtP61OH0hBonrxMhBAMD8dUmaqO6Ef+bhHzbBm3BCC5VapkOkdthb+UWXKCiBoCipg3gqrwnBdOUGXqx/1mYicNZ+oHeVpBwnJlXudff6FT+HySszr5ISw==",
}
dataType, _ := json.Marshal(data)
resp, err := http.Post(url, "application/json", strings.NewReader(string(dataType)))
if err != nil {
fmt.Println(err)
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Println(err)
}
fmt.Println(string(body))
let HTTP = require('http')
let postData = {
"coin" : "hc",
"app_id" : "hxgmau9imt86qky9",
"version" : "1.0",
"time" : "1578997143",
"sign": "IUtWA3HEkK+wvTGaSBYwIrdx+ANyoOPl2/1LQTDevCSTxf4/lDXPrg6/ph+skNXIbZTR8Qs2yGGkqTUHEW/vbiTPzWkYZ874rRgplp06vhOBM/Pkw289K7PVCKy1ksOtLjwj1dUfDD/2AEqTgxRDjGyn+yDWRa7HLL/28bjU3pZoFwPPjbPyRxMK9BVL/li9IQ6hb8lyOyQNHNxS3C82sDVaQKqrB0dOqtP61OH0hBonrxMhBAMD8dUmaqO6Ef+bhHzbBm3BCC5VapkOkdthb+UWXKCiBoCipg3gqrwnBdOUGXqx/1mYicNZ+oHeVpBwnJlXudff6FT+HySszr5ISw==",
};
let POST_OPTIONS = {
port: 80,
host: "api.xxxx.com",
path: "/shopapi/address/getBatch",
method: 'POST',
headers: {
"Content-Type": "application/json; charset=utf-8"
}
};
const REQUEST = HTTP.request(POST_OPTIONS,function (res) {
let data = []
res.on('data', chunk => {
data.push(...chunk)
})
res.on('end', () => {
let _date = JSON.parse( new TextDecoder().decode(new Uint8Array(data)))
console.log(_date)
})
});
REQUEST.setTimeout(6000)
REQUEST.write(JSON.stringify(postData), 'utf8')
REQUEST.end()
public static void main(String[] args) {
// 完整实例请查看"签名规则"中的Java示例代码
String baseUrl = "http://api.xxxx.com/shopapi";
String priKey = "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCtdgvcfozY7fe/x6UlXR/Fff8+wX++CiG05YVRafDe90O8y5KJAMZ156TgajEUXSRyKZqASz7iVoMAcu5FqfK1KuOOdjTAg0LFe/twIZvKmAqHcCSS2pjUXk0fTpZEgQ5lmDCK12Mg07YXvr+BeHjF+kBpwRJMPMG/+DGBDYNFNeRSJqWyopt6yyF528soAykHIUQ7TTultJV5IPCrvjRQQrGdJ/QtCdE0vZg+tA09nFN7AqgraU99kIvzyS0sqysj+pP1SJRmTRSGtlVAO3mILfkXOekZl1KD60G7CF+7BIaaW83FPD55tZhAGhnbLMYyiq7OiIyU61LTRcNSaJ0tAgMBAAECggEBAIGgGKcSzxCBbMYdXLV6TPbZ/HeaRGrwyVWUu7cmc0E8CJu6iWvmb2jGzbiCwuCT5luF6ZZ8JKchvU4FlTfsE5r9TQY2IZ/Ht4s65qBaDUEts5iY3kv8HX9+ZSXDJZpV0ztqqsPmx4ZNj+NYwWXwcFiKdb5R8OmV8bgSsnPddD6wFhwewglUOBPRAjropHE4sqk1Vam6q1MlFq5kiekMn/CItyFYFFzST/ruqAtVTp7YIvazAMrfCKH+pvXWk6pYNHZmL/JZey0GglRyJ1nItiqL33X8Lji056FcbAclidq022h/KPLEJpZk6irWqYdqYZeF6YMLHtdZFDkTZ/hXY+UCgYEA5i794UTQ1Kd6K+iui/S8K5H8nGdiXb3+uZ5j5VKYfbRmzXhAdVYisYe8czeTECxhH+MeHgM4tLR4ifx9q60ylvZxl9Fav1p6EaE36YcvGVmpm7Gm3q6QDDBa4gB+X9u7CxCS4LpotV917YS1QvOIF9lnRonSj1zNzFtbXkywrN8CgYEAwOpx/mR40ZvgZxNCq9DsIdrSZYAFFKpw0xy0OtF1PpuwMaREoRabnlVw6Bb3Hofg50XA3JxemzAX6fB92ee+NfXfeL4UtC4vG1K9JyiXHtHq8p9Uw2W03ehIEeNa3xdoRRnLmD4VUpyfL19ViE2+7TM1Gd3TogjDT+AMOCSuq3MCgYBsurPH7gaq/LVT+mRAzgj4l8v4YUlwuGeTbIMJdvt7HXUWB4CDLH3U2CYnUpAQKrZyJok6ahEmIr1xiKggKP7lmmHL8eNo0icpHrtXfzi7Q8Q/PCpzs4dtioXTjaIkS5nNvzVyG/uL+RyuZmpsxrZ5dYM4KbAhchfwORMutxEZhwKBgQC5zpVw4jCEItBmNuTWO+nTScGvxTgfiXIVw+XLaQa2AJoZlhAL34yPWdffko79tv3lgweY9HsimZXO2rU8dbp8mo5c6ydhy8HPXUeWOcAkDSdv/ApWENW9jgYsRIC3swHY3Fl+Dv3Wjce8huQI3mjwaYvRmBhIToxfmHnscVhTBQKBgB9uciEHfz8hMI7ePrPo2PkyK/RbJDm3HnuWE2lFBp7MOUMlh53MXwv4dIRaYMbRrFuN1UIKEFxuKhWwTHSzZJufk/UENrha/81fpj2BoFsAKkEunKeETvaIh6fZSjec16h2+zxbzwkdS6b+yIYkSlaoAxmDYrMtae0C8G4e0YS9";
String pubKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2RZZISModRzproL3eTxRtvVK/nToDbeLmAVdmaVtHgNCwjXMeNCZvHySZKO7+t7XySzBd2PhhQjvAkDd8HRKB5Y0uvP6TFwvhxOMkMydTeBFcUobQWNeAI7ttRms1txSNrmyrZr0WpWfk79VIsO+yI/jFN/Pj2gxD+vh5UUKU1LD2IQq/VxgtEpf8Vs6w7SvafPwYkpdPGCKUFkRvN1FrY2+tq0j1MRVJbB2rIunWDnT8cDUh2sWLXf4yNaJVOaaTFB0zbAk/qcoicGQyW7bVG7dVW8WywKmOAPeQCCQa+SJ4BhfI1k8eEAwFVRuxz/f9Ecfog9hZJ+RgELkpS8qhQIDAQAB";
rsaSigner signer = new rsaSigner();
Map<String, Object> params = new HashMap<>();
params.put("app_id", "hxgmau9imt86qky9");
params.put("version", "1.0");
params.put("key_version", "admin");
params.put("time", Long.toString(System.currentTimeMillis() / 1000));
params.put("coin", "trx");
try {
params.put("sign", signer.genSign(params, priKey));
Gson gson = new GsonBuilder().create();
System.out.println("params = " + gson.toJson(params));
String res = doPost(baseUrl + "/address/getBatch", gson.toJson(params));
if (null == res) {
throw new RuntimeException("http error");
}
System.out.println("response = " + res);
JsonParser jp = new JsonParser();
JsonObject resEle = jp.parse(res).getAsJsonObject();
boolean retSignOK = signer.verifySign(resEle, resEle.get("sign").getAsString(), pubKey);
if (!retSignOK) {
throw new RuntimeException("verify response sign fail");
}
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("OK");
}
返回结果示例:
{
"status":200,
"msg":"请求成功",
"data":[
"HsZWVPmCS92hXJ4mUpTwCs3DX74MK1ihEBn",
"HsCt7eYaJJkn331ZkprcbvGFDrRuqMYcAHx"
],
"date_time":"2020-06-29 14:43:17",
"time_stamp":1593412997,
"sign":"lwxzuuGuZN1Z/j4hTombrcict1wom1+D6+k2URGIxL/L4sezn6Sh1IDawPixO2nEC2VZ9O0JVpBP+CH8QfjYY8Q0A+DTwLMjLRneB3iV/++c+ODcT8rUwHU+jAZmETccI2Knln5ND9MbrQpcWSW3wwPmJtNTeh6sYcwK2vJR18IAE26j47LQZV5RMfmWzHnIO2O1oftZuOT40H2aXfU3Zk6xybsMFi3uzYaK7/Zz5porGe6GG3IVELsFoHGtVl7mFGRl1sLUtT9iUuwa8F8alKozMjuK9IyW44ExHv0OyDS2PZewhwRRLnvUTTTM5+8bgAeM5w0bRetfL22coHnSHw=="
}
{
"status": 500,
"msg": "地址不足",
"data": null,
"date_time": "2020-01-09 15:46:14",
"sign": "rzbmkcf0Vr1AEZAo0Lsnlmk1s6HGONYZkpQxWKhGwIFxyN/fkaYzA6UxhIm9C8Drlfa8oZxpyrH89POuoaVfToxPhC9p8w10rfb4G/kNaZBE/gIo2H8e4/CTvEsiX5lz/ASNLiSe6BtHStUwMDCsl+ub7TF79uybb0RDy5mOegM="
}
{
"status":551,
"msg":"有 6 个已分配未使用地址,请使用完再请求新的地址",
"data":"6",
"date_time":"2020-03-05 10:46:24",
"time_stamp":1583376384,
"sign":"e57nRfbDNvVIZuwvbXOsJaBnj9D+2hiP90SC8Q9ZCpdyTSbhB3WEpmotvZg11n3sW2Kzzle+ZSLPJH10iHqou3NgYzqEWD3EAThCzP0H8rhsj14NZ909JFAveRTe7XeP8xUcJINsY9HOliU2M5pt/qSnOx2CvdpFtxmVNLpIK+1VHdYuX6NRGc9TQ/Ptgwc6c9K7NNqqXY1y0e46LK8EBvXoEwbWa6L46f14Sx+/hN94Ymc6OKBUNFnbMGh31aeBp7E5YV/5fV2ZWKfNaNOxTyQVsPhpRt5NU9qCIzcgHKsqbroU72adWlBjyNrNWcXayilmwNHPAVJ1QKoqS6zoEQ=="
}
- 功能: 返回新地址给商户
- 单次获取地址数量为N个(默认200,测试环境每次返回2个),商户可根据实际需要请求多次。
- 针对EOS这类账户+memo模式的,这个接口只返回memo,配合接口:/address/coinAccount
- 注意:平台 eth、bnb_bsc(bsc主链)、ht_heco(heco主链)等共用 eth 地址,在请求地址相关api接口时使用 coin=eth。所有共用eth地址的主链网络: eth, bnb_bsc, ht_heco, pol, okt, avax_c, movr, eth_aurora, rei, smartbch, ftm, eth_optimism, eth_arbitrum, cmp, ethw, mbe, core, wemix, ethg, eth_zksync, gdcc, main_hec, cvn, nrk, eth_base, tfuel_theta, alyx, btc_merlin, etc, zeta, main_taiko
HTTP Request
POST : /address/getBatch
请求参数
| 参数名 | 必选 | 类型 | 说明 |
|---|---|---|---|
| 公共参数 | 是 | JSON | 公参指:签名(sign)、版本(version)、商户ID(app_id)、时间(time) |
| coin | 是 | string | 12个字符内主链币名,币名平台提供为准(若是bnb_bsc请传eth)。可查询/coin/list接口查看币名 |
返回参数说明
| 参数名 | 必选 | 类型 | 说明 |
|---|---|---|---|
| status | 是 | int | 状态码 |
| msg | 否 | string | 100字内 状态描述 |
| data | 否 | jsonObject | 状态200返回地址数组,500地址不足返回null,551已分配未使用地址,返回未使用数字 |
| date_time | 否 | DateTime | 北京时间:2020-06-29 14:28:14 |
| time_stamp | 否 | string | 响应时间,单位秒:1593412094 |
| sign | 是 | string | 返回签名,对以上所有参与参数签名 |
合约币和主链币共享同一个地址,请只用主链币名进行申请即可,不支持用合约币名申请地址,对于商户同一个用户的一个或多个合约币及同属于一个主链的主链币,仅分配一个主链币地址即可。 案列:user_coin表
| 用户ID | 币名 | 地址 |
|---|---|---|
| 1688 | eth | 0xa6f8745c56a7c4fcb094678a2fbdcbd9ee9228f7 |
| 1688 | usdt_erc20 | 0xa6f8745c56a7c4fcb094678a2fbdcbd9ee9228f7 |
| 1688 | leek | 0xa6f8745c56a7c4fcb094678a2fbdcbd9ee9228f7 |
- 注意:上面地址都属于ETH主链地址,同时也可以接收ETH合约币
地址列表
$url = "http://api.xxxx.com/shopapi/address/list";
$header = [
'Content-Type:application/json',
];
$params = [
"app_id" => "hxgmau9imt86qky9",
"version" => "1.0",
"time" => 1578997143,
"sign" => "IUtWA3HEkK+wvTGaSBYwIrdx+ANyoOPl2/1LQTDevCSTxf4/lDXPrg6/ph+skNXIbZTR8Qs2yGGkqTUHEW/vbiTPzWkYZ874rRgplp06vhOBM/Pkw289K7PVCKy1ksOtLjwj1dUfDD/2AEqTgxRDjGyn+yDWRa7HLL/28bjU3pZoFwPPjbPyRxMK9BVL/li9IQ6hb8lyOyQNHNxS3C82sDVaQKqrB0dOqtP61OH0hBonrxMhBAMD8dUmaqO6Ef+bhHzbBm3BCC5VapkOkdthb+UWXKCiBoCipg3gqrwnBdOUGXqx/1mYicNZ+oHeVpBwnJlXudff6FT+HySszr5ISw==",
"coin" => "hc",
"address" => "HsHGWeEMmx5QLds9UiWfjxarM4RbLAc3xrD",
"is_used" => "1",
"page" => "1"
];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
$return = curl_exec($ch);
print_r($return);
var url = "http://api.xxxx.com/shopapi/address/list"
data := map[string]string{
"app_id":"hxgmau9imt86qky9",
"version":"1.0",
"time":"1578997143",
"sign":"IUtWA3HEkK+wvTGaSBYwIrdx+ANyoOPl2/1LQTDevCSTxf4/lDXPrg6/ph+skNXIbZTR8Qs2yGGkqTUHEW/vbiTPzWkYZ874rRgplp06vhOBM/Pkw289K7PVCKy1ksOtLjwj1dUfDD/2AEqTgxRDjGyn+yDWRa7HLL/28bjU3pZoFwPPjbPyRxMK9BVL/li9IQ6hb8lyOyQNHNxS3C82sDVaQKqrB0dOqtP61OH0hBonrxMhBAMD8dUmaqO6Ef+bhHzbBm3BCC5VapkOkdthb+UWXKCiBoCipg3gqrwnBdOUGXqx/1mYicNZ+oHeVpBwnJlXudff6FT+HySszr5ISw==",
"coin":"hc",
"address":"HsHGWeEMmx5QLds9UiWfjxarM4RbLAc3xrD",
"is_used":"1",
"page":"1",
}
dataType, _ := json.Marshal(data)
resp, err := http.Post(url, "application/json", strings.NewReader(string(dataType)))
if err != nil {
fmt.Println(err)
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Println(err)
}
fmt.Println(string(body))
let HTTP = require('http')
let postData = {
"app_id":"hxgmau9imt86qky9",
"version":"1.0",
"time":"1578997143",
"sign":"IUtWA3HEkK+wvTGaSBYwIrdx+ANyoOPl2/1LQTDevCSTxf4/lDXPrg6/ph+skNXIbZTR8Qs2yGGkqTUHEW/vbiTPzWkYZ874rRgplp06vhOBM/Pkw289K7PVCKy1ksOtLjwj1dUfDD/2AEqTgxRDjGyn+yDWRa7HLL/28bjU3pZoFwPPjbPyRxMK9BVL/li9IQ6hb8lyOyQNHNxS3C82sDVaQKqrB0dOqtP61OH0hBonrxMhBAMD8dUmaqO6Ef+bhHzbBm3BCC5VapkOkdthb+UWXKCiBoCipg3gqrwnBdOUGXqx/1mYicNZ+oHeVpBwnJlXudff6FT+HySszr5ISw==",
"coin":"hc",
"address":"HsHGWeEMmx5QLds9UiWfjxarM4RbLAc3xrD",
"is_used":"1",
"page":"1",
};
let POST_OPTIONS = {
port: 80,
host: "api.xxxx.com",
path: "/shopapi/address/list",
method: 'POST',
headers: {
"Content-Type": "application/json; charset=utf-8"
}
};
const REQUEST = HTTP.request(POST_OPTIONS,function (res) {
let data = []
res.on('data', chunk => {
data.push(...chunk)
})
res.on('end', () => {
let _date = JSON.parse( new TextDecoder().decode(new Uint8Array(data)))
console.log(_date)
})
});
REQUEST.setTimeout(6000)
REQUEST.write(JSON.stringify(postData), 'utf8')
REQUEST.end()
public static void main(String[] args) {
// 完整实例请查看"签名规则"中的Java示例代码
String baseUrl = "http://api.xxxx.com/shopapi";
String priKey = "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCtdgvcfozY7fe/x6UlXR/Fff8+wX++CiG05YVRafDe90O8y5KJAMZ156TgajEUXSRyKZqASz7iVoMAcu5FqfK1KuOOdjTAg0LFe/twIZvKmAqHcCSS2pjUXk0fTpZEgQ5lmDCK12Mg07YXvr+BeHjF+kBpwRJMPMG/+DGBDYNFNeRSJqWyopt6yyF528soAykHIUQ7TTultJV5IPCrvjRQQrGdJ/QtCdE0vZg+tA09nFN7AqgraU99kIvzyS0sqysj+pP1SJRmTRSGtlVAO3mILfkXOekZl1KD60G7CF+7BIaaW83FPD55tZhAGhnbLMYyiq7OiIyU61LTRcNSaJ0tAgMBAAECggEBAIGgGKcSzxCBbMYdXLV6TPbZ/HeaRGrwyVWUu7cmc0E8CJu6iWvmb2jGzbiCwuCT5luF6ZZ8JKchvU4FlTfsE5r9TQY2IZ/Ht4s65qBaDUEts5iY3kv8HX9+ZSXDJZpV0ztqqsPmx4ZNj+NYwWXwcFiKdb5R8OmV8bgSsnPddD6wFhwewglUOBPRAjropHE4sqk1Vam6q1MlFq5kiekMn/CItyFYFFzST/ruqAtVTp7YIvazAMrfCKH+pvXWk6pYNHZmL/JZey0GglRyJ1nItiqL33X8Lji056FcbAclidq022h/KPLEJpZk6irWqYdqYZeF6YMLHtdZFDkTZ/hXY+UCgYEA5i794UTQ1Kd6K+iui/S8K5H8nGdiXb3+uZ5j5VKYfbRmzXhAdVYisYe8czeTECxhH+MeHgM4tLR4ifx9q60ylvZxl9Fav1p6EaE36YcvGVmpm7Gm3q6QDDBa4gB+X9u7CxCS4LpotV917YS1QvOIF9lnRonSj1zNzFtbXkywrN8CgYEAwOpx/mR40ZvgZxNCq9DsIdrSZYAFFKpw0xy0OtF1PpuwMaREoRabnlVw6Bb3Hofg50XA3JxemzAX6fB92ee+NfXfeL4UtC4vG1K9JyiXHtHq8p9Uw2W03ehIEeNa3xdoRRnLmD4VUpyfL19ViE2+7TM1Gd3TogjDT+AMOCSuq3MCgYBsurPH7gaq/LVT+mRAzgj4l8v4YUlwuGeTbIMJdvt7HXUWB4CDLH3U2CYnUpAQKrZyJok6ahEmIr1xiKggKP7lmmHL8eNo0icpHrtXfzi7Q8Q/PCpzs4dtioXTjaIkS5nNvzVyG/uL+RyuZmpsxrZ5dYM4KbAhchfwORMutxEZhwKBgQC5zpVw4jCEItBmNuTWO+nTScGvxTgfiXIVw+XLaQa2AJoZlhAL34yPWdffko79tv3lgweY9HsimZXO2rU8dbp8mo5c6ydhy8HPXUeWOcAkDSdv/ApWENW9jgYsRIC3swHY3Fl+Dv3Wjce8huQI3mjwaYvRmBhIToxfmHnscVhTBQKBgB9uciEHfz8hMI7ePrPo2PkyK/RbJDm3HnuWE2lFBp7MOUMlh53MXwv4dIRaYMbRrFuN1UIKEFxuKhWwTHSzZJufk/UENrha/81fpj2BoFsAKkEunKeETvaIh6fZSjec16h2+zxbzwkdS6b+yIYkSlaoAxmDYrMtae0C8G4e0YS9";
String pubKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2RZZISModRzproL3eTxRtvVK/nToDbeLmAVdmaVtHgNCwjXMeNCZvHySZKO7+t7XySzBd2PhhQjvAkDd8HRKB5Y0uvP6TFwvhxOMkMydTeBFcUobQWNeAI7ttRms1txSNrmyrZr0WpWfk79VIsO+yI/jFN/Pj2gxD+vh5UUKU1LD2IQq/VxgtEpf8Vs6w7SvafPwYkpdPGCKUFkRvN1FrY2+tq0j1MRVJbB2rIunWDnT8cDUh2sWLXf4yNaJVOaaTFB0zbAk/qcoicGQyW7bVG7dVW8WywKmOAPeQCCQa+SJ4BhfI1k8eEAwFVRuxz/f9Ecfog9hZJ+RgELkpS8qhQIDAQAB";
rsaSigner signer = new rsaSigner();
Map<String, Object> params = new HashMap<>();
params.put("app_id", "hxgmau9imt86qky9");
params.put("version", "1.0");
params.put("key_version", "admin");
params.put("time", Long.toString(System.currentTimeMillis() / 1000));
params.put("coin", "trx");
params.put("address", "HsHGWeEMmx5QLds9UiWfjxarM4RbLAc3xrD");
params.put("page", "1");
params.put("is_used", "1");
try {
params.put("sign", signer.genSign(params, priKey));
Gson gson = new GsonBuilder().create();
System.out.println("params = " + gson.toJson(params));
String res = doPost(baseUrl + "/address/list", gson.toJson(params));
if (null == res) {
throw new RuntimeException("http error");
}
System.out.println("response = " + res);
JsonParser jp = new JsonParser();
JsonObject resEle = jp.parse(res).getAsJsonObject();
boolean retSignOK = signer.verifySign(resEle, resEle.get("sign").getAsString(), pubKey);
if (!retSignOK) {
throw new RuntimeException("verify response sign fail");
}
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("OK");
}
返回结果示例:
{
"status":200,
"msg":"处理成功",
"data":{
"page":1,
"max_page":1,
"count":4,
"list":[
{
"address":"HsHGWeEMmx5QLds9UiWfjxarM4RbLAc3xrD",
"user_id":""
},
{
"address":"HsDZKWmgusF7fYbJ1Xw6FJJWx5Bkykdcfq9",
"user_id":""
}
]
},
"date_time":"2020-04-26 17:26:09",
"time_stamp":1587893169,
"sign":"LNnLd4tIHwNqRHgcd1d0E46u5rU0Jbm/fO5yZL8IIzt6cdfAwEBmtQ9kBczZhttp+KoP/rN7jZkex55SCZ5+9ILc276XOIalO6qF8L36GpwSJEizWYI1w6WjXTjdo9sCp2D6+ZUlV27mwkRtlwsIbF5gMmEnb2wmeyFoFctuDSHnPNLrs9WHHXvZ2q0lXU6L2LT1V8Ugfow3cZ7cCSbC9Vx9l8gMSGR/z7LRz8YB5iaM4rL9L2WpZy3SLoEd5d+Zu38de3z5TC2Cjnf3xkYxqKarPKy6mHe/RgIVFkYov8awveIYdaL2KZ+2bWmLeIXQLxUv7zVPaWytB82NPRz9Xg=="
}
- 通过此接口查询地址使用状态,地址所属关系等。
HTTP Request
POST : /address/list
请求参数
| 参数名 | 必选 | 类型 | 说明 |
|---|---|---|---|
| 公共参数 | 是 | JSON | 公参指:签名(sign)、版本(version)、商户ID(app_id)、时间(time) |
| coin | 是 | string | 主链币名-见支持公链公共信息说明(若是bnb_bsc请传eth) |
| address | 否 | string | 地址 |
| page | 否 | int | 1<= N <=Max, 超过Max的取Max,小于1返回1 |
| is_used | 否 | int | 1=使用 , 2=未使用 |
返回参数说明
| 参数名 | 类型 | 说明 |
|---|---|---|
| status | int | 状态码 |
| msg | string | 状态描述 |
| data | jsonObject | **具体见下面** “data细节说明”。 |
| data.page | int | 当前第几页 |
| data.max_page | int | 一共多少页 |
| data.count | int | 本页记录数 |
| data.list | jsonArray | 具体每条记录 |
| date_time | string | 响应时间 |
| time_stamp | int | 时间戳,单位秒 |
| sign | string | 签名 |
类EOS的地址+memo模式
$url = "http://api.xxxx.com/shopapi/address/coinAccount";
$header = [
'Content-Type:application/json',
];
$params = [
"app_id" => "hxgmau9imt86qky9",
"version" => "1.0",
"time" => 1578997143,
"sign" => "IUtWA3HEkK+wvTGaSBYwIrdx+ANyoOPl2/1LQTDevCSTxf4/lDXPrg6/ph+skNXIbZTR8Qs2yGGkqTUHEW/vbiTPzWkYZ874rRgplp06vhOBM/Pkw289K7PVCKy1ksOtLjwj1dUfDD/2AEqTgxRDjGyn+yDWRa7HLL/28bjU3pZoFwPPjbPyRxMK9BVL/li9IQ6hb8lyOyQNHNxS3C82sDVaQKqrB0dOqtP61OH0hBonrxMhBAMD8dUmaqO6Ef+bhHzbBm3BCC5VapkOkdthb+UWXKCiBoCipg3gqrwnBdOUGXqx/1mYicNZ+oHeVpBwnJlXudff6FT+HySszr5ISw==",
"coin" => "eos"
];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
$return = curl_exec($ch);
print_r($return);
var url = "http://api.xxxx.com/shopapi/address/coinAccount"
data := map[string]string{
"app_id":"hxgmau9imt86qky9",
"version":"1.0",
"time":"1578997143",
"sign":"IUtWA3HEkK+wvTGaSBYwIrdx+ANyoOPl2/1LQTDevCSTxf4/lDXPrg6/ph+skNXIbZTR8Qs2yGGkqTUHEW/vbiTPzWkYZ874rRgplp06vhOBM/Pkw289K7PVCKy1ksOtLjwj1dUfDD/2AEqTgxRDjGyn+yDWRa7HLL/28bjU3pZoFwPPjbPyRxMK9BVL/li9IQ6hb8lyOyQNHNxS3C82sDVaQKqrB0dOqtP61OH0hBonrxMhBAMD8dUmaqO6Ef+bhHzbBm3BCC5VapkOkdthb+UWXKCiBoCipg3gqrwnBdOUGXqx/1mYicNZ+oHeVpBwnJlXudff6FT+HySszr5ISw==",
"coin":"eos",
}
dataType, _ := json.Marshal(data)
resp, err := http.Post(url, "application/json", strings.NewReader(string(dataType)))
if err != nil {
fmt.Println(err)
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Println(err)
}
fmt.Println(string(body))
let HTTP = require('http')
let postData = {
"app_id":"hxgmau9imt86qky9",
"version":"1.0",
"time":"1578997143",
"sign":"IUtWA3HEkK+wvTGaSBYwIrdx+ANyoOPl2/1LQTDevCSTxf4/lDXPrg6/ph+skNXIbZTR8Qs2yGGkqTUHEW/vbiTPzWkYZ874rRgplp06vhOBM/Pkw289K7PVCKy1ksOtLjwj1dUfDD/2AEqTgxRDjGyn+yDWRa7HLL/28bjU3pZoFwPPjbPyRxMK9BVL/li9IQ6hb8lyOyQNHNxS3C82sDVaQKqrB0dOqtP61OH0hBonrxMhBAMD8dUmaqO6Ef+bhHzbBm3BCC5VapkOkdthb+UWXKCiBoCipg3gqrwnBdOUGXqx/1mYicNZ+oHeVpBwnJlXudff6FT+HySszr5ISw==",
"coin":"eos",
};
let POST_OPTIONS = {
port: 80,
host: "api.xxxx.com",
path: "/shopapi/address/coinAccount",
method: 'POST',
headers: {
"Content-Type": "application/json; charset=utf-8"
}
};
const REQUEST = HTTP.request(POST_OPTIONS,function (res) {
let data = []
res.on('data', chunk => {
data.push(...chunk)
})
res.on('end', () => {
let _date = JSON.parse( new TextDecoder().decode(new Uint8Array(data)))
console.log(_date)
})
});
REQUEST.setTimeout(6000)
REQUEST.write(JSON.stringify(postData), 'utf8')
REQUEST.end()
public static void main(String[] args) {
// 完整实例请查看"签名规则"中的Java示例代码
String baseUrl = "http://api.xxxx.com/shopapi";
String priKey = "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCtdgvcfozY7fe/x6UlXR/Fff8+wX++CiG05YVRafDe90O8y5KJAMZ156TgajEUXSRyKZqASz7iVoMAcu5FqfK1KuOOdjTAg0LFe/twIZvKmAqHcCSS2pjUXk0fTpZEgQ5lmDCK12Mg07YXvr+BeHjF+kBpwRJMPMG/+DGBDYNFNeRSJqWyopt6yyF528soAykHIUQ7TTultJV5IPCrvjRQQrGdJ/QtCdE0vZg+tA09nFN7AqgraU99kIvzyS0sqysj+pP1SJRmTRSGtlVAO3mILfkXOekZl1KD60G7CF+7BIaaW83FPD55tZhAGhnbLMYyiq7OiIyU61LTRcNSaJ0tAgMBAAECggEBAIGgGKcSzxCBbMYdXLV6TPbZ/HeaRGrwyVWUu7cmc0E8CJu6iWvmb2jGzbiCwuCT5luF6ZZ8JKchvU4FlTfsE5r9TQY2IZ/Ht4s65qBaDUEts5iY3kv8HX9+ZSXDJZpV0ztqqsPmx4ZNj+NYwWXwcFiKdb5R8OmV8bgSsnPddD6wFhwewglUOBPRAjropHE4sqk1Vam6q1MlFq5kiekMn/CItyFYFFzST/ruqAtVTp7YIvazAMrfCKH+pvXWk6pYNHZmL/JZey0GglRyJ1nItiqL33X8Lji056FcbAclidq022h/KPLEJpZk6irWqYdqYZeF6YMLHtdZFDkTZ/hXY+UCgYEA5i794UTQ1Kd6K+iui/S8K5H8nGdiXb3+uZ5j5VKYfbRmzXhAdVYisYe8czeTECxhH+MeHgM4tLR4ifx9q60ylvZxl9Fav1p6EaE36YcvGVmpm7Gm3q6QDDBa4gB+X9u7CxCS4LpotV917YS1QvOIF9lnRonSj1zNzFtbXkywrN8CgYEAwOpx/mR40ZvgZxNCq9DsIdrSZYAFFKpw0xy0OtF1PpuwMaREoRabnlVw6Bb3Hofg50XA3JxemzAX6fB92ee+NfXfeL4UtC4vG1K9JyiXHtHq8p9Uw2W03ehIEeNa3xdoRRnLmD4VUpyfL19ViE2+7TM1Gd3TogjDT+AMOCSuq3MCgYBsurPH7gaq/LVT+mRAzgj4l8v4YUlwuGeTbIMJdvt7HXUWB4CDLH3U2CYnUpAQKrZyJok6ahEmIr1xiKggKP7lmmHL8eNo0icpHrtXfzi7Q8Q/PCpzs4dtioXTjaIkS5nNvzVyG/uL+RyuZmpsxrZ5dYM4KbAhchfwORMutxEZhwKBgQC5zpVw4jCEItBmNuTWO+nTScGvxTgfiXIVw+XLaQa2AJoZlhAL34yPWdffko79tv3lgweY9HsimZXO2rU8dbp8mo5c6ydhy8HPXUeWOcAkDSdv/ApWENW9jgYsRIC3swHY3Fl+Dv3Wjce8huQI3mjwaYvRmBhIToxfmHnscVhTBQKBgB9uciEHfz8hMI7ePrPo2PkyK/RbJDm3HnuWE2lFBp7MOUMlh53MXwv4dIRaYMbRrFuN1UIKEFxuKhWwTHSzZJufk/UENrha/81fpj2BoFsAKkEunKeETvaIh6fZSjec16h2+zxbzwkdS6b+yIYkSlaoAxmDYrMtae0C8G4e0YS9";
String pubKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2RZZISModRzproL3eTxRtvVK/nToDbeLmAVdmaVtHgNCwjXMeNCZvHySZKO7+t7XySzBd2PhhQjvAkDd8HRKB5Y0uvP6TFwvhxOMkMydTeBFcUobQWNeAI7ttRms1txSNrmyrZr0WpWfk79VIsO+yI/jFN/Pj2gxD+vh5UUKU1LD2IQq/VxgtEpf8Vs6w7SvafPwYkpdPGCKUFkRvN1FrY2+tq0j1MRVJbB2rIunWDnT8cDUh2sWLXf4yNaJVOaaTFB0zbAk/qcoicGQyW7bVG7dVW8WywKmOAPeQCCQa+SJ4BhfI1k8eEAwFVRuxz/f9Ecfog9hZJ+RgELkpS8qhQIDAQAB";
rsaSigner signer = new rsaSigner();
Map<String, Object> params = new HashMap<>();
params.put("app_id", "hxgmau9imt86qky9");
params.put("version", "1.0");
params.put("key_version", "admin");
params.put("time", Long.toString(System.currentTimeMillis() / 1000));
params.put("coin", "trx");
try {
params.put("sign", signer.genSign(params, priKey));
Gson gson = new GsonBuilder().create();
System.out.println("params = " + gson.toJson(params));
String res = doPost(baseUrl + "/address/coinAccount", gson.toJson(params));
if (null == res) {
throw new RuntimeException("http error");
}
System.out.println("response = " + res);
JsonParser jp = new JsonParser();
JsonObject resEle = jp.parse(res).getAsJsonObject();
boolean retSignOK = signer.verifySign(resEle, resEle.get("sign").getAsString(), pubKey);
if (!retSignOK) {
throw new RuntimeException("verify response sign fail");
}
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("OK");
}
返回结果示例:
{
"status":200,
"msg":"请求成功",
"data":"hyperpayeos1",
"date_time":"2020-04-08 18:20:33",
"time_stamp":1586341233,
"sign":"r+AWadjxa5L9CY5gWNMy5+4n9gtmHGUIsxgsTVOhs5mHPe2/jmm1jYOXS+KW/TLZLBnN1AMLeAgnHCQ6UxztsldMJg71ef3MTgV1GikCDXO+RQwQXYVHjjq1Cn6z/dGYikl7pht+avjnlmvGHUQjZBmhkKCpWVyG7Hl+h1cJKyMAZhJNqKemmSpbmTxe5GEDDR/NSrqKNsd0gt0QXMJu4VwURr6piRqc3euNqbtY94xelXcie75ZE0SKKHSikk6H/k1RQCfbTmfqhwp+vDZfrZ6kBucvaenczgFgX4S7k9Akb1B/xJ1n5NjLUilzn1GO2STUwhY4ATE5IbXJ819QVQ=="
}
- 对于类似EOS加Memo模式币种特殊处理
- 方案1、 直接通知客服提供好即可,在商家后台能看到。
- 方案2、通过接口获取
HTTP Request
POST : /address/coinAccount
请求参数
| 参数名 | 必选 | 类型 | 说明 |
|---|---|---|---|
| 公共参数 | 是 | JSON | 公参指:签名(sign)、版本(version)、商户ID(app_id)、时间(time) |
| coin | 是 | string | 主链币名-见支持公链公共信息说明(若是bnb_bsc请传eth) |
返回参数说明
| 参数名 | 类型 | 说明 |
|---|---|---|
| status | int | 状态码 |
| msg | string | 状态描述 |
| data | jsonObject | |
| date_time | string | 响应时间 |
| time_stamp | int | 时间戳,单位秒 |
| sign | string | 签名 |
地址状态同步
$url = "http://api.xxxx.com/shopapi/address/syncStatus";
$header = [
'Content-Type:application/json',
];
$params = [
"app_id" => "hxgmau9imt86qky9",
"version" => "1.0",
"time" => 1578997143,
"sign" => "IUtWA3HEkK+wvTGaSBYwIrdx+ANyoOPl2/1LQTDevCSTxf4/lDXPrg6/ph+skNXIbZTR8Qs2yGGkqTUHEW/vbiTPzWkYZ874rRgplp06vhOBM/Pkw289K7PVCKy1ksOtLjwj1dUfDD/2AEqTgxRDjGyn+yDWRa7HLL/28bjU3pZoFwPPjbPyRxMK9BVL/li9IQ6hb8lyOyQNHNxS3C82sDVaQKqrB0dOqtP61OH0hBonrxMhBAMD8dUmaqO6Ef+bhHzbBm3BCC5VapkOkdthb+UWXKCiBoCipg3gqrwnBdOUGXqx/1mYicNZ+oHeVpBwnJlXudff6FT+HySszr5ISw==",
"coin" => "eth",
"address" => "0xb930c8149bc0bbb0214ae4207164d3b1cb41f395",
"user_id" => "28"
];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
$return = curl_exec($ch);
print_r($return);
var url = "http://api.xxxx.com/shopapi/address/syncStatus"
data := map[string]string{
"app_id":"hxgmau9imt86qky9",
"version":"1.0",
"time":"1578997143",
"sign":"IUtWA3HEkK+wvTGaSBYwIrdx+ANyoOPl2/1LQTDevCSTxf4/lDXPrg6/ph+skNXIbZTR8Qs2yGGkqTUHEW/vbiTPzWkYZ874rRgplp06vhOBM/Pkw289K7PVCKy1ksOtLjwj1dUfDD/2AEqTgxRDjGyn+yDWRa7HLL/28bjU3pZoFwPPjbPyRxMK9BVL/li9IQ6hb8lyOyQNHNxS3C82sDVaQKqrB0dOqtP61OH0hBonrxMhBAMD8dUmaqO6Ef+bhHzbBm3BCC5VapkOkdthb+UWXKCiBoCipg3gqrwnBdOUGXqx/1mYicNZ+oHeVpBwnJlXudff6FT+HySszr5ISw==",
"coin":"eth",
"address":"0xb930c8149bc0bbb0214ae4207164d3b1cb41f395",
"user_id":"28",
}
dataType, _ := json.Marshal(data)
resp, err := http.Post(url, "application/json", strings.NewReader(string(dataType)))
if err != nil {
fmt.Println(err)
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Println(err)
}
fmt.Println(string(body))
let HTTP = require('http')
let postData = {
"app_id":"hxgmau9imt86qky9",
"version":"1.0",
"time":"1578997143",
"sign":"IUtWA3HEkK+wvTGaSBYwIrdx+ANyoOPl2/1LQTDevCSTxf4/lDXPrg6/ph+skNXIbZTR8Qs2yGGkqTUHEW/vbiTPzWkYZ874rRgplp06vhOBM/Pkw289K7PVCKy1ksOtLjwj1dUfDD/2AEqTgxRDjGyn+yDWRa7HLL/28bjU3pZoFwPPjbPyRxMK9BVL/li9IQ6hb8lyOyQNHNxS3C82sDVaQKqrB0dOqtP61OH0hBonrxMhBAMD8dUmaqO6Ef+bhHzbBm3BCC5VapkOkdthb+UWXKCiBoCipg3gqrwnBdOUGXqx/1mYicNZ+oHeVpBwnJlXudff6FT+HySszr5ISw==",
"coin":"eth",
"address":"0xb930c8149bc0bbb0214ae4207164d3b1cb41f395",
"user_id":"28",
};
let POST_OPTIONS = {
port: 80,
host: "api.xxxx.com",
path: "/shopapi/address/syncStatus",
method: 'POST',
headers: {
"Content-Type": "application/json; charset=utf-8"
}
};
const REQUEST = HTTP.request(POST_OPTIONS,function (res) {
let data = []
res.on('data', chunk => {
data.push(...chunk)
})
res.on('end', () => {
let _date = JSON.parse( new TextDecoder().decode(new Uint8Array(data)))
console.log(_date)
})
});
REQUEST.setTimeout(6000)
REQUEST.write(JSON.stringify(postData), 'utf8')
REQUEST.end()
public static void main(String[] args) {
// 完整实例请查看"签名规则"中的Java示例代码
String baseUrl = "http://api.xxxx.com/shopapi";
String priKey = "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCtdgvcfozY7fe/x6UlXR/Fff8+wX++CiG05YVRafDe90O8y5KJAMZ156TgajEUXSRyKZqASz7iVoMAcu5FqfK1KuOOdjTAg0LFe/twIZvKmAqHcCSS2pjUXk0fTpZEgQ5lmDCK12Mg07YXvr+BeHjF+kBpwRJMPMG/+DGBDYNFNeRSJqWyopt6yyF528soAykHIUQ7TTultJV5IPCrvjRQQrGdJ/QtCdE0vZg+tA09nFN7AqgraU99kIvzyS0sqysj+pP1SJRmTRSGtlVAO3mILfkXOekZl1KD60G7CF+7BIaaW83FPD55tZhAGhnbLMYyiq7OiIyU61LTRcNSaJ0tAgMBAAECggEBAIGgGKcSzxCBbMYdXLV6TPbZ/HeaRGrwyVWUu7cmc0E8CJu6iWvmb2jGzbiCwuCT5luF6ZZ8JKchvU4FlTfsE5r9TQY2IZ/Ht4s65qBaDUEts5iY3kv8HX9+ZSXDJZpV0ztqqsPmx4ZNj+NYwWXwcFiKdb5R8OmV8bgSsnPddD6wFhwewglUOBPRAjropHE4sqk1Vam6q1MlFq5kiekMn/CItyFYFFzST/ruqAtVTp7YIvazAMrfCKH+pvXWk6pYNHZmL/JZey0GglRyJ1nItiqL33X8Lji056FcbAclidq022h/KPLEJpZk6irWqYdqYZeF6YMLHtdZFDkTZ/hXY+UCgYEA5i794UTQ1Kd6K+iui/S8K5H8nGdiXb3+uZ5j5VKYfbRmzXhAdVYisYe8czeTECxhH+MeHgM4tLR4ifx9q60ylvZxl9Fav1p6EaE36YcvGVmpm7Gm3q6QDDBa4gB+X9u7CxCS4LpotV917YS1QvOIF9lnRonSj1zNzFtbXkywrN8CgYEAwOpx/mR40ZvgZxNCq9DsIdrSZYAFFKpw0xy0OtF1PpuwMaREoRabnlVw6Bb3Hofg50XA3JxemzAX6fB92ee+NfXfeL4UtC4vG1K9JyiXHtHq8p9Uw2W03ehIEeNa3xdoRRnLmD4VUpyfL19ViE2+7TM1Gd3TogjDT+AMOCSuq3MCgYBsurPH7gaq/LVT+mRAzgj4l8v4YUlwuGeTbIMJdvt7HXUWB4CDLH3U2CYnUpAQKrZyJok6ahEmIr1xiKggKP7lmmHL8eNo0icpHrtXfzi7Q8Q/PCpzs4dtioXTjaIkS5nNvzVyG/uL+RyuZmpsxrZ5dYM4KbAhchfwORMutxEZhwKBgQC5zpVw4jCEItBmNuTWO+nTScGvxTgfiXIVw+XLaQa2AJoZlhAL34yPWdffko79tv3lgweY9HsimZXO2rU8dbp8mo5c6ydhy8HPXUeWOcAkDSdv/ApWENW9jgYsRIC3swHY3Fl+Dv3Wjce8huQI3mjwaYvRmBhIToxfmHnscVhTBQKBgB9uciEHfz8hMI7ePrPo2PkyK/RbJDm3HnuWE2lFBp7MOUMlh53MXwv4dIRaYMbRrFuN1UIKEFxuKhWwTHSzZJufk/UENrha/81fpj2BoFsAKkEunKeETvaIh6fZSjec16h2+zxbzwkdS6b+yIYkSlaoAxmDYrMtae0C8G4e0YS9";
String pubKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2RZZISModRzproL3eTxRtvVK/nToDbeLmAVdmaVtHgNCwjXMeNCZvHySZKO7+t7XySzBd2PhhQjvAkDd8HRKB5Y0uvP6TFwvhxOMkMydTeBFcUobQWNeAI7ttRms1txSNrmyrZr0WpWfk79VIsO+yI/jFN/Pj2gxD+vh5UUKU1LD2IQq/VxgtEpf8Vs6w7SvafPwYkpdPGCKUFkRvN1FrY2+tq0j1MRVJbB2rIunWDnT8cDUh2sWLXf4yNaJVOaaTFB0zbAk/qcoicGQyW7bVG7dVW8WywKmOAPeQCCQa+SJ4BhfI1k8eEAwFVRuxz/f9Ecfog9hZJ+RgELkpS8qhQIDAQAB";
rsaSigner signer = new rsaSigner();
Map<String, Object> params = new HashMap<>();
params.put("app_id", "hxgmau9imt86qky9");
params.put("version", "1.0");
params.put("key_version", "admin");
params.put("time", Long.toString(System.currentTimeMillis() / 1000));
params.put("coin", "trx");
params.put("address", "HsHGWeEMmx5QLds9UiWfjxarM4RbLAc3xrD");
params.put("user_id", "111");
try {
params.put("sign", signer.genSign(params, priKey));
Gson gson = new GsonBuilder().create();
System.out.println("params = " + gson.toJson(params));
String res = doPost(baseUrl + "/address/syncStatus", gson.toJson(params));
if (null == res) {
throw new RuntimeException("http error");
}
System.out.println("response = " + res);
JsonParser jp = new JsonParser();
JsonObject resEle = jp.parse(res).getAsJsonObject();
boolean retSignOK = signer.verifySign(resEle, resEle.get("sign").getAsString(), pubKey);
if (!retSignOK) {
throw new RuntimeException("verify response sign fail");
}
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("OK");
}
返回结果示例:
{
"status":200,
"msg":"同步成功",
"data":{
"address":"0x0603b5a606e6ae28e729d145f4d5a99bd8769950",
"coin":"eth"
},
"date_time":"2020-01-14 00:33:58",
"sign":"KVZrYNjK9xwZvqJHMSRxxK4PjbirEtS1vyI220BzK/rF7bp+iU+ClQU5BSERcaujFz0EqRtZW5LSojjgRPeGbh4Wyqmlpk/Qz7ulTC0lqkik3torj3xL4SP2MKvUMXyPRRn8MKh586c8XLF1APRR48mdlDVQgxdUmr9mtB8ssLI="
}
- 商户将地址分配给用户后,一定要通过“状态同步接口”通知平台进行地址使用状态更新。
HTTP Request
POST : /address/syncStatus
请求参数
| 参数名 | 必选 | 类型 | 说明 |
|---|---|---|---|
| 公共参数 | 是 | JSON | 公参指:签名(sign)、版本(version)、商户ID(app_id)、时间(time) |
| coin | 是 | string | 12个字符以内,地址所属主链币种 (若是bnb_bsc请传eth) |
| address | 是 | string | 地址,128个字符以内 |
| user_id | 是 | string | 关联到地址的用户ID,由字母、数字和下划线组成,长度40以内。 |
返回参数说明
| 参数名 | 必选 | 类型 | 说明 |
|---|---|---|---|
| status | 是 | int | 返回状态码 |
| msg | 是 | string | 状态码描述 |
| date_time | 是 | string | 接口返回时间 |
| time_stamp | 是 | string | 无时区时间单位秒 |
| data | 是 | null或JSONObjectString | 返回数据 |
| sign | 是 | string | 后端签名 |
注意:商户把地址分配给自己的用户后,一定要请求该接口回传使用状态信息,并获取到 200正确状态码返回值后再开启用户的充提现功能。
*1、如果不同步会影响地址获取接口的使用(已分配未使用的地址数量 超过一定量时,平台不再分配新的地址给商家)。
*2、如果状态同步没有收到正确返回结果,而是报错提示,请人工排查错误。
设计规则:相同币种或合约币,相同商家,相同用户ID 只能分配一个地址。
如果违法上面规则会报错。
地址状态批量同步
$url = "http://api.xxxx.com/shopapi/address/syncBatchStatus";
$header = [
'Content-Type:application/json',
];
$params = [
"app_id" => "hxgmau9imt86qky9",
"version" => "1.0",
"time" => 1578997143,
"sign" => "IUtWA3HEkK+wvTGaSBYwIrdx+ANyoOPl2/1LQTDevCSTxf4/lDXPrg6/ph+skNXIbZTR8Qs2yGGkqTUHEW/vbiTPzWkYZ874rRgplp06vhOBM/Pkw289K7PVCKy1ksOtLjwj1dUfDD/2AEqTgxRDjGyn+yDWRa7HLL/28bjU3pZoFwPPjbPyRxMK9BVL/li9IQ6hb8lyOyQNHNxS3C82sDVaQKqrB0dOqtP61OH0hBonrxMhBAMD8dUmaqO6Ef+bhHzbBm3BCC5VapkOkdthb+UWXKCiBoCipg3gqrwnBdOUGXqx/1mYicNZ+oHeVpBwnJlXudff6FT+HySszr5ISw==",
"address_list" => [
[
"address" => "0x038B8E7406dED2Be112B6c7E4681Df5316957cad",
"coin" => "eth",
"user_id" => "123sa"
],
[
"address" => "0xf854AC319A546ae11e367ef80a203AaC923ca6A3",
"coin" => "eth",
"user_id" => "123sb"
]
]
];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
$return = curl_exec($ch);
print_r($return);
var url = "http://api.xxxx.com/shopapi/address/syncBatchStatus"
data := map[string]interface{}{
"app_id": "hxgmau9imt86qky9",
"version": "1.0",
"time": "1578997143",
"sign": "IUtWA3HEkK+wvTGaSBYwIrdx+ANyoOPl2/1LQTDevCSTxf4/lDXPrg6/ph+skNXIbZTR8Qs2yGGkqTUHEW/vbiTPzWkYZ874rRgplp06vhOBM/Pkw289K7PVCKy1ksOtLjwj1dUfDD/2AEqTgxRDjGyn+yDWRa7HLL/28bjU3pZoFwPPjbPyRxMK9BVL/li9IQ6hb8lyOyQNHNxS3C82sDVaQKqrB0dOqtP61OH0hBonrxMhBAMD8dUmaqO6Ef+bhHzbBm3BCC5VapkOkdthb+UWXKCiBoCipg3gqrwnBdOUGXqx/1mYicNZ+oHeVpBwnJlXudff6FT+HySszr5ISw==",
"address_list": []interface{}{
map[string]interface{}{
"address": "0x038B8E7406dED2Be112B6c7E4681Df5316957cad",
"coin": "eth",
"user_id": "123sa",
},
map[string]interface{}{
"address": "0xf854AC319A546ae11e367ef80a203AaC923ca6A3",
"coin": "eth",
"user_id": "123sb",
},
},
}
dataType, _ := json.Marshal(data)
resp, err := http.Post(url, "application/json", strings.NewReader(string(dataType)))
if err != nil {
fmt.Println(err)
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Println(err)
}
fmt.Println(string(body))
let HTTP = require('http')
let postData = {
"app_id": "hxgmau9imt86qky9",
"version": "1.0",
"time": "1578997143",
"sign": "IUtWA3HEkK+wvTGaSBYwIrdx+ANyoOPl2/1LQTDevCSTxf4/lDXPrg6/ph+skNXIbZTR8Qs2yGGkqTUHEW/vbiTPzWkYZ874rRgplp06vhOBM/Pkw289K7PVCKy1ksOtLjwj1dUfDD/2AEqTgxRDjGyn+yDWRa7HLL/28bjU3pZoFwPPjbPyRxMK9BVL/li9IQ6hb8lyOyQNHNxS3C82sDVaQKqrB0dOqtP61OH0hBonrxMhBAMD8dUmaqO6Ef+bhHzbBm3BCC5VapkOkdthb+UWXKCiBoCipg3gqrwnBdOUGXqx/1mYicNZ+oHeVpBwnJlXudff6FT+HySszr5ISw==",
"address_list": [
{
"address": "0x038B8E7406dED2Be112B6c7E4681Df5316957cad",
"coin": "eth",
"user_id": "123sa",
},
{
"address": "0xf854AC319A546ae11e367ef80a203AaC923ca6A3",
"coin": "eth",
"user_id": "123sb",
},
],
};
let POST_OPTIONS = {
port: 80,
host: "api.xxxx.com",
path: "/shopapi/address/syncBatchStatus",
method: 'POST',
headers: {
"Content-Type": "application/json; charset=utf-8"
}
};
const REQUEST = HTTP.request(POST_OPTIONS,function (res) {
let data = []
res.on('data', chunk => {
data.push(...chunk)
})
res.on('end', () => {
let _date = JSON.parse( new TextDecoder().decode(new Uint8Array(data)))
console.log(_date)
})
});
REQUEST.setTimeout(6000)
REQUEST.write(JSON.stringify(postData), 'utf8')
REQUEST.end()
public static void main(String[] args) {
// 完整实例请查看"签名规则"中的Java示例代码
String baseUrl = "http://api.xxxx.com/shopapi";
String priKey = "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCtdgvcfozY7fe/x6UlXR/Fff8+wX++CiG05YVRafDe90O8y5KJAMZ156TgajEUXSRyKZqASz7iVoMAcu5FqfK1KuOOdjTAg0LFe/twIZvKmAqHcCSS2pjUXk0fTpZEgQ5lmDCK12Mg07YXvr+BeHjF+kBpwRJMPMG/+DGBDYNFNeRSJqWyopt6yyF528soAykHIUQ7TTultJV5IPCrvjRQQrGdJ/QtCdE0vZg+tA09nFN7AqgraU99kIvzyS0sqysj+pP1SJRmTRSGtlVAO3mILfkXOekZl1KD60G7CF+7BIaaW83FPD55tZhAGhnbLMYyiq7OiIyU61LTRcNSaJ0tAgMBAAECggEBAIGgGKcSzxCBbMYdXLV6TPbZ/HeaRGrwyVWUu7cmc0E8CJu6iWvmb2jGzbiCwuCT5luF6ZZ8JKchvU4FlTfsE5r9TQY2IZ/Ht4s65qBaDUEts5iY3kv8HX9+ZSXDJZpV0ztqqsPmx4ZNj+NYwWXwcFiKdb5R8OmV8bgSsnPddD6wFhwewglUOBPRAjropHE4sqk1Vam6q1MlFq5kiekMn/CItyFYFFzST/ruqAtVTp7YIvazAMrfCKH+pvXWk6pYNHZmL/JZey0GglRyJ1nItiqL33X8Lji056FcbAclidq022h/KPLEJpZk6irWqYdqYZeF6YMLHtdZFDkTZ/hXY+UCgYEA5i794UTQ1Kd6K+iui/S8K5H8nGdiXb3+uZ5j5VKYfbRmzXhAdVYisYe8czeTECxhH+MeHgM4tLR4ifx9q60ylvZxl9Fav1p6EaE36YcvGVmpm7Gm3q6QDDBa4gB+X9u7CxCS4LpotV917YS1QvOIF9lnRonSj1zNzFtbXkywrN8CgYEAwOpx/mR40ZvgZxNCq9DsIdrSZYAFFKpw0xy0OtF1PpuwMaREoRabnlVw6Bb3Hofg50XA3JxemzAX6fB92ee+NfXfeL4UtC4vG1K9JyiXHtHq8p9Uw2W03ehIEeNa3xdoRRnLmD4VUpyfL19ViE2+7TM1Gd3TogjDT+AMOCSuq3MCgYBsurPH7gaq/LVT+mRAzgj4l8v4YUlwuGeTbIMJdvt7HXUWB4CDLH3U2CYnUpAQKrZyJok6ahEmIr1xiKggKP7lmmHL8eNo0icpHrtXfzi7Q8Q/PCpzs4dtioXTjaIkS5nNvzVyG/uL+RyuZmpsxrZ5dYM4KbAhchfwORMutxEZhwKBgQC5zpVw4jCEItBmNuTWO+nTScGvxTgfiXIVw+XLaQa2AJoZlhAL34yPWdffko79tv3lgweY9HsimZXO2rU8dbp8mo5c6ydhy8HPXUeWOcAkDSdv/ApWENW9jgYsRIC3swHY3Fl+Dv3Wjce8huQI3mjwaYvRmBhIToxfmHnscVhTBQKBgB9uciEHfz8hMI7ePrPo2PkyK/RbJDm3HnuWE2lFBp7MOUMlh53MXwv4dIRaYMbRrFuN1UIKEFxuKhWwTHSzZJufk/UENrha/81fpj2BoFsAKkEunKeETvaIh6fZSjec16h2+zxbzwkdS6b+yIYkSlaoAxmDYrMtae0C8G4e0YS9";
String pubKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2RZZISModRzproL3eTxRtvVK/nToDbeLmAVdmaVtHgNCwjXMeNCZvHySZKO7+t7XySzBd2PhhQjvAkDd8HRKB5Y0uvP6TFwvhxOMkMydTeBFcUobQWNeAI7ttRms1txSNrmyrZr0WpWfk79VIsO+yI/jFN/Pj2gxD+vh5UUKU1LD2IQq/VxgtEpf8Vs6w7SvafPwYkpdPGCKUFkRvN1FrY2+tq0j1MRVJbB2rIunWDnT8cDUh2sWLXf4yNaJVOaaTFB0zbAk/qcoicGQyW7bVG7dVW8WywKmOAPeQCCQa+SJ4BhfI1k8eEAwFVRuxz/f9Ecfog9hZJ+RgELkpS8qhQIDAQAB";
rsaSigner signer = new rsaSigner();
Map<String, Object> params = new HashMap<>();
params.put("app_id", "hxgmau9imt86qky9");
params.put("version", "1.0");
params.put("key_version", "admin");
params.put("time", Long.toString(System.currentTimeMillis() / 1000));
List<addressObj> addressList = new ArrayList<addressObj>();
addressList.add(new addressObj("trx", "TFf9pAefXqKMekvizwiFi1YgdXH4fRjNYS", "111"));
addressList.add(new addressObj("trx", "TNsym9u9o2LGNMJ9pkXQ9EkubrKanCV1HJ", "222"));
params.put("address_list", addressList);
try {
params.put("sign", signer.genSign(params, priKey));
Gson gson = new GsonBuilder().create();
System.out.println("params = " + gson.toJson(params));
String res = doPost(baseUrl + "/address/syncBatchStatus", gson.toJson(params));
if (null == res) {
throw new RuntimeException("http error");
}
System.out.println("response = " + res);
JsonParser jp = new JsonParser();
JsonObject resEle = jp.parse(res).getAsJsonObject();
boolean retSignOK = signer.verifySign(resEle, resEle.get("sign").getAsString(), pubKey);
if (!retSignOK) {
throw new RuntimeException("verify response sign fail");
}
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("OK");
}
public class addressObj {
public String coin;
public String address;
@SerializedName("user_id")
public String userId;
addressObj(String coin, String address, String user_id) {
this.coin = coin;
this.address = address;
this.userId = user_id;
}
public String getAddress() {
return address;
}
public String getCoin() {
return coin;
}
public String getUserId() {
return userId;
}
}
返回结果示例:
{
"status":200,
"msg":"请求成功",
"data":{
"success_data":[
{
"address":"0x038B8E7406dED2Be112B6c7E4681Df5316957cad",
"user_id":"123sa",
"coin":"eth"
}
],
"fail_data":[
{
"address":"0xf854AC319A546ae11e367ef80a203AaC923ca6A3",
"user_id":"123sb",
"coin":"eth",
"msg":"该地址已分配给其他用户不能重复分配",
"status":524,
"owner_user_id":"345ad"
}
]
},
"date_time":"2021-03-22 10:55:58",
"time_stamp":1616381758,
"sign":"NTQg0pwGcHoIBTDzUAx635olXJDzCVy3OWCvu7LWdcZ3/2uYGjpflNXgXDtO8lMoK57GYZqG8p4v+0zd2ggBIk+XVhGAjPId8YLEsRFjWWXFxCWKpZALT54vH5zH5RdBsoZPW2lR/YQbZNhCbVED1QGB+QxFSx8wkf1Qi+R9WC4/bKhYZmmJXi9aoJCR9+BcdVVf0D+GBg3VqRWDPAosOHiCDRPsOw5+X8DijEkS7n8GFf9w5AT/lajWinlVU5fN2nra7sunYoJqUrk4tm3yTvF6k0GxcW6byFUZcddMJts9rE/uG3F+G/xW2MMG/F0N8scYKjyD4r85oMNl/pxBeQ=="
}
- 商户将地址分配给用户后,一定要通过“状态同步接口”通知平台进行地址使用状态更新,该接口支持批量同步(建议每次最多 100个以内)。
HTTP Request
POST : /address/syncBatchStatus
请求参数
| 参数名 | 必选 | 类型 | 长度 | 说明 |
|---|---|---|---|---|
| 公共参数 | 是 | JSON | 公参指:签名(sign)、版本(version)、商户ID(app_id)、时间(time) | |
| address_list | 是 | array | ||
| address_list.address | 是 | string | 128个字符以内 | 地址 |
| address_list.coin | 是 | string | 12个字符以内 | 地址所属主链币种 (若是bnb_bsc请传eth) |
| address_list.user_id | 是 | string | 40以内字符串 | 关联到地址的用户ID,由字母、数字和下划线组成。 |
返回参数说明
| 参数名 | 类型 | 说明 |
|---|---|---|
| status | 是 | int |
| msg | 是 | string |
| date_time | 是 | string |
| time_stamp | 是 | string |
| success_data | 是 | null或JSONObjectString |
| success_data.address | 是 | string |
| success_data.coin | 是 | string |
| success_data.user_id | 是 | string |
| fail_data | 是 | null或JSONObjectString |
| fail_data.address | 是 | string |
| fail_data.coin | 是 | string |
| fail_data.user_id | 是 | string |
| fail_data.status | 是 | string |
| fail_data.msg | 是 | string |
| fail_data.old_address | 是 | string |
| fail_data.owner_user_id | 是 | string |
| sign | 是 | string |
注意:商户把地址分配给自己的用户后,一定要请求该接口回传使用状态信息,并获取到 200正确状态码返回值后再开启用户的充提现功能。
1、如果不同步会影响地址获取接口的使用(已分配未使用的地址数量 超过一定量时,平台不再分配新的地址给商家)。
2、如果状态同步没有收到正确返回结果,而是报错提示,请人工排查错误。
设计规则:相同币种或合约币,相同商家,相同用户ID 只能分配一个地址。
如果违法上面规则会报错。
地址验证
$url = "http://api.xxxx.com/shopapi/address/verifyAddress";
$header = [
'Content-Type:application/json',
];
$params = [
"app_id" => "hxgmau9imt86qky9",
"version" => "1.0",
"time" => 1578997143,
"sign" => "IUtWA3HEkK+wvTGaSBYwIrdx+ANyoOPl2/1LQTDevCSTxf4/lDXPrg6/ph+skNXIbZTR8Qs2yGGkqTUHEW/vbiTPzWkYZ874rRgplp06vhOBM/Pkw289K7PVCKy1ksOtLjwj1dUfDD/2AEqTgxRDjGyn+yDWRa7HLL/28bjU3pZoFwPPjbPyRxMK9BVL/li9IQ6hb8lyOyQNHNxS3C82sDVaQKqrB0dOqtP61OH0hBonrxMhBAMD8dUmaqO6Ef+bhHzbBm3BCC5VapkOkdthb+UWXKCiBoCipg3gqrwnBdOUGXqx/1mYicNZ+oHeVpBwnJlXudff6FT+HySszr5ISw==",
"coin" => "trx",
"address" => "TUEgUZh24tA48EXiAQjA6Qf6rSS7bJKQ6g"
];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
$return = curl_exec($ch);
print_r($return);
var url = "http://api.xxxx.com/shopapi/address/verifyAddress"
data := map[string]string{
"app_id":"hxgmau9imt86qky9",
"version":"1.0",
"time":"1578997143",
"sign":"IUtWA3HEkK+wvTGaSBYwIrdx+ANyoOPl2/1LQTDevCSTxf4/lDXPrg6/ph+skNXIbZTR8Qs2yGGkqTUHEW/vbiTPzWkYZ874rRgplp06vhOBM/Pkw289K7PVCKy1ksOtLjwj1dUfDD/2AEqTgxRDjGyn+yDWRa7HLL/28bjU3pZoFwPPjbPyRxMK9BVL/li9IQ6hb8lyOyQNHNxS3C82sDVaQKqrB0dOqtP61OH0hBonrxMhBAMD8dUmaqO6Ef+bhHzbBm3BCC5VapkOkdthb+UWXKCiBoCipg3gqrwnBdOUGXqx/1mYicNZ+oHeVpBwnJlXudff6FT+HySszr5ISw==",
"coin":"trx",
"address":"TUEgUZh24tA48EXiAQjA6Qf6rSS7bJKQ6g",
}
dataType, _ := json.Marshal(data)
resp, err := http.Post(url, "application/json", strings.NewReader(string(dataType)))
if err != nil {
fmt.Println(err)
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Println(err)
}
fmt.Println(string(body))
let HTTP = require('http')
let postData = {
"app_id":"hxgmau9imt86qky9",
"version":"1.0",
"time":"1578997143",
"sign":"IUtWA3HEkK+wvTGaSBYwIrdx+ANyoOPl2/1LQTDevCSTxf4/lDXPrg6/ph+skNXIbZTR8Qs2yGGkqTUHEW/vbiTPzWkYZ874rRgplp06vhOBM/Pkw289K7PVCKy1ksOtLjwj1dUfDD/2AEqTgxRDjGyn+yDWRa7HLL/28bjU3pZoFwPPjbPyRxMK9BVL/li9IQ6hb8lyOyQNHNxS3C82sDVaQKqrB0dOqtP61OH0hBonrxMhBAMD8dUmaqO6Ef+bhHzbBm3BCC5VapkOkdthb+UWXKCiBoCipg3gqrwnBdOUGXqx/1mYicNZ+oHeVpBwnJlXudff6FT+HySszr5ISw==",
"coin":"trx",
"address":"TUEgUZh24tA48EXiAQjA6Qf6rSS7bJKQ6g",
};
let POST_OPTIONS = {
port: 80,
host: "api.xxxx.com",
path: "/shopapi/address/verifyAddress",
method: 'POST',
headers: {
"Content-Type": "application/json; charset=utf-8"
}
};
const REQUEST = HTTP.request(POST_OPTIONS,function (res) {
let data = []
res.on('data', chunk => {
data.push(...chunk)
})
res.on('end', () => {
let _date = JSON.parse( new TextDecoder().decode(new Uint8Array(data)))
console.log(_date)
})
});
REQUEST.setTimeout(6000)
REQUEST.write(JSON.stringify(postData), 'utf8')
REQUEST.end()
public static void main(String[] args) {
// 完整实例请查看"签名规则"中的Java示例代码
String baseUrl = "http://api.xxxx.com/shopapi";
String priKey = "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCtdgvcfozY7fe/x6UlXR/Fff8+wX++CiG05YVRafDe90O8y5KJAMZ156TgajEUXSRyKZqASz7iVoMAcu5FqfK1KuOOdjTAg0LFe/twIZvKmAqHcCSS2pjUXk0fTpZEgQ5lmDCK12Mg07YXvr+BeHjF+kBpwRJMPMG/+DGBDYNFNeRSJqWyopt6yyF528soAykHIUQ7TTultJV5IPCrvjRQQrGdJ/QtCdE0vZg+tA09nFN7AqgraU99kIvzyS0sqysj+pP1SJRmTRSGtlVAO3mILfkXOekZl1KD60G7CF+7BIaaW83FPD55tZhAGhnbLMYyiq7OiIyU61LTRcNSaJ0tAgMBAAECggEBAIGgGKcSzxCBbMYdXLV6TPbZ/HeaRGrwyVWUu7cmc0E8CJu6iWvmb2jGzbiCwuCT5luF6ZZ8JKchvU4FlTfsE5r9TQY2IZ/Ht4s65qBaDUEts5iY3kv8HX9+ZSXDJZpV0ztqqsPmx4ZNj+NYwWXwcFiKdb5R8OmV8bgSsnPddD6wFhwewglUOBPRAjropHE4sqk1Vam6q1MlFq5kiekMn/CItyFYFFzST/ruqAtVTp7YIvazAMrfCKH+pvXWk6pYNHZmL/JZey0GglRyJ1nItiqL33X8Lji056FcbAclidq022h/KPLEJpZk6irWqYdqYZeF6YMLHtdZFDkTZ/hXY+UCgYEA5i794UTQ1Kd6K+iui/S8K5H8nGdiXb3+uZ5j5VKYfbRmzXhAdVYisYe8czeTECxhH+MeHgM4tLR4ifx9q60ylvZxl9Fav1p6EaE36YcvGVmpm7Gm3q6QDDBa4gB+X9u7CxCS4LpotV917YS1QvOIF9lnRonSj1zNzFtbXkywrN8CgYEAwOpx/mR40ZvgZxNCq9DsIdrSZYAFFKpw0xy0OtF1PpuwMaREoRabnlVw6Bb3Hofg50XA3JxemzAX6fB92ee+NfXfeL4UtC4vG1K9JyiXHtHq8p9Uw2W03ehIEeNa3xdoRRnLmD4VUpyfL19ViE2+7TM1Gd3TogjDT+AMOCSuq3MCgYBsurPH7gaq/LVT+mRAzgj4l8v4YUlwuGeTbIMJdvt7HXUWB4CDLH3U2CYnUpAQKrZyJok6ahEmIr1xiKggKP7lmmHL8eNo0icpHrtXfzi7Q8Q/PCpzs4dtioXTjaIkS5nNvzVyG/uL+RyuZmpsxrZ5dYM4KbAhchfwORMutxEZhwKBgQC5zpVw4jCEItBmNuTWO+nTScGvxTgfiXIVw+XLaQa2AJoZlhAL34yPWdffko79tv3lgweY9HsimZXO2rU8dbp8mo5c6ydhy8HPXUeWOcAkDSdv/ApWENW9jgYsRIC3swHY3Fl+Dv3Wjce8huQI3mjwaYvRmBhIToxfmHnscVhTBQKBgB9uciEHfz8hMI7ePrPo2PkyK/RbJDm3HnuWE2lFBp7MOUMlh53MXwv4dIRaYMbRrFuN1UIKEFxuKhWwTHSzZJufk/UENrha/81fpj2BoFsAKkEunKeETvaIh6fZSjec16h2+zxbzwkdS6b+yIYkSlaoAxmDYrMtae0C8G4e0YS9";
String pubKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2RZZISModRzproL3eTxRtvVK/nToDbeLmAVdmaVtHgNCwjXMeNCZvHySZKO7+t7XySzBd2PhhQjvAkDd8HRKB5Y0uvP6TFwvhxOMkMydTeBFcUobQWNeAI7ttRms1txSNrmyrZr0WpWfk79VIsO+yI/jFN/Pj2gxD+vh5UUKU1LD2IQq/VxgtEpf8Vs6w7SvafPwYkpdPGCKUFkRvN1FrY2+tq0j1MRVJbB2rIunWDnT8cDUh2sWLXf4yNaJVOaaTFB0zbAk/qcoicGQyW7bVG7dVW8WywKmOAPeQCCQa+SJ4BhfI1k8eEAwFVRuxz/f9Ecfog9hZJ+RgELkpS8qhQIDAQAB";
rsaSigner signer = new rsaSigner();
Map<String, Object> params = new HashMap<>();
params.put("app_id", "hxgmau9imt86qky9");
params.put("version", "1.0");
params.put("key_version", "admin");
params.put("time", Long.toString(System.currentTimeMillis() / 1000));
params.put("coin", "trx");
params.put("address", "HsHGWeEMmx5QLds9UiWfjxarM4RbLAc3xrD");
try {
params.put("sign", signer.genSign(params, priKey));
Gson gson = new GsonBuilder().create();
System.out.println("params = " + gson.toJson(params));
String res = doPost(baseUrl + "/address/verifyAddress", gson.toJson(params));
if (null == res) {
throw new RuntimeException("http error");
}
System.out.println("response = " + res);
JsonParser jp = new JsonParser();
JsonObject resEle = jp.parse(res).getAsJsonObject();
boolean retSignOK = signer.verifySign(resEle, resEle.get("sign").getAsString(), pubKey);
if (!retSignOK) {
throw new RuntimeException("verify response sign fail");
}
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("OK");
}
返回结果示例:
{
"status":200,
"msg":"验证成功",
"data":null,
"date_time":"2020-10-20 15:32:16",
"time_stamp":1603179136,
"sign":"isaqtnmKOJca5+QpHHeigqmAXh4Gquv3akniwzF0YEdIiz5prc0lMZ2+PWYsYkkqX66JedddyofD/7pgIjurh8qNaE9PWvVkupBgunzevlfwNUrIvsCUpUx8m1Iv8WPqUqdszoRbCDed3PqM2mcMe0Ol28QIRPeoMc8qRdSh4Bph9EfVtWS4x+8gqcax4SmSsbGGhCpe1LB4uS8OGaMbS18wz50asjz9HRnElwYiHbnz4R5TqHcnVqdFFXNWBlPM5QJjDqh+aArZneNwnmU4VCM82R4teLELZ/ldXOpUuCUzrI77iE8Of2qLaIIplKc3vZ6VqqoguD8M1QEyLAmk8A=="
}
- 地址有效性验证,目前仅支持 eth 、trx 、btc 主链地址验证,后续持续扩充其他主链地址验证
HTTP Request
POST : /address/verifyAddress
请求参数
| 参数名 | 必选 | 类型 | 说明 |
|---|---|---|---|
| 公共参数 | 是 | string | 公参指:签名(sign)、版本(version)、商户ID(app_id)、时间(time) |
| coin | 是 | string | 12个字符内主链币名, 币名平台提供为准 |
| address | 是 | string | 地址 |
返回参数说明
| 参数名 | 必选 | 类型 | 说明 |
|---|---|---|---|
| status | 是 | int | 返回值:200 验证成功;543 验证失败;565 币种不支持 |
| msg | 否 | string | 100字内, 状态描述 |
| data | 是 | jsonObject | — |
| date_time | 否 | DateTime | 北京时间:2020-06-29 14:28:14 |
| time_stamp | 否 | string | 响应时间,单位秒:1593412094 |
| sign | 是 | string | 返回签名,对以上所有参与参数签名 |
- 注意:注意:上面地址都属于ETH主链地址,同时也可以接收ETH合约币
地址AML反洗钱风险验证
$url = "http://api.xxxx.com/shopapi/address/verifyAml";
$header = [
'Content-Type:application/json',
];
$params = [
"app_id" => "hxgmau9imt86qky9",
"version" => "1.0",
"time" => 1578997143,
"sign" => "IUtWA3HEkK+wvTGaSBYwIrdx+ANyoOPl2/1LQTDevCSTxf4/lDXPrg6/ph+skNXIbZTR8Qs2yGGkqTUHEW/vbiTPzWkYZ874rRgplp06vhOBM/Pkw289K7PVCKy1ksOtLjwj1dUfDD/2AEqTgxRDjGyn+yDWRa7HLL/28bjU3pZoFwPPjbPyRxMK9BVL/li9IQ6hb8lyOyQNHNxS3C82sDVaQKqrB0dOqtP61OH0hBonrxMhBAMD8dUmaqO6Ef+bhHzbBm3BCC5VapkOkdthb+UWXKCiBoCipg3gqrwnBdOUGXqx/1mYicNZ+oHeVpBwnJlXudff6FT+HySszr5ISw==",
"chain" => "trx",
"address" => "TUEgUZh24tA48EXiAQjA6Qf6rSS7bJKQ6g",
"skip_api_source" => "OK_LINK"
];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
$return = curl_exec($ch);
print_r($return);
var url = "http://api.xxxx.com/shopapi/address/verifyAml"
data := map[string]string{
"app_id":"hxgmau9imt86qky9",
"version":"1.0",
"time":"1578997143",
"sign":"IUtWA3HEkK+wvTGaSBYwIrdx+ANyoOPl2/1LQTDevCSTxf4/lDXPrg6/ph+skNXIbZTR8Qs2yGGkqTUHEW/vbiTPzWkYZ874rRgplp06vhOBM/Pkw289K7PVCKy1ksOtLjwj1dUfDD/2AEqTgxRDjGyn+yDWRa7HLL/28bjU3pZoFwPPjbPyRxMK9BVL/li9IQ6hb8lyOyQNHNxS3C82sDVaQKqrB0dOqtP61OH0hBonrxMhBAMD8dUmaqO6Ef+bhHzbBm3BCC5VapkOkdthb+UWXKCiBoCipg3gqrwnBdOUGXqx/1mYicNZ+oHeVpBwnJlXudff6FT+HySszr5ISw==",
"chain":"trx",
"address":"TUEgUZh24tA48EXiAQjA6Qf6rSS7bJKQ6g",
"skip_api_source": "OK_LINK",
}
dataType, _ := json.Marshal(data)
resp, err := http.Post(url, "application/json", strings.NewReader(string(dataType)))
if err != nil {
fmt.Println(err)
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Println(err)
}
fmt.Println(string(body))
let HTTP = require('http')
let postData = {
"app_id":"hxgmau9imt86qky9",
"version":"1.0",
"time":"1578997143",
"sign":"IUtWA3HEkK+wvTGaSBYwIrdx+ANyoOPl2/1LQTDevCSTxf4/lDXPrg6/ph+skNXIbZTR8Qs2yGGkqTUHEW/vbiTPzWkYZ874rRgplp06vhOBM/Pkw289K7PVCKy1ksOtLjwj1dUfDD/2AEqTgxRDjGyn+yDWRa7HLL/28bjU3pZoFwPPjbPyRxMK9BVL/li9IQ6hb8lyOyQNHNxS3C82sDVaQKqrB0dOqtP61OH0hBonrxMhBAMD8dUmaqO6Ef+bhHzbBm3BCC5VapkOkdthb+UWXKCiBoCipg3gqrwnBdOUGXqx/1mYicNZ+oHeVpBwnJlXudff6FT+HySszr5ISw==",
"chain":"trx",
"address":"TUEgUZh24tA48EXiAQjA6Qf6rSS7bJKQ6g",
"skip_api_source": "OK_LINK",
};
let POST_OPTIONS = {
port: 80,
host: "api.xxxx.com",
path: "/shopapi/address/verifyAml",
method: 'POST',
headers: {
"Content-Type": "application/json; charset=utf-8"
}
};
const REQUEST = HTTP.request(POST_OPTIONS,function (res) {
let data = []
res.on('data', chunk => {
data.push(...chunk)
})
res.on('end', () => {
let _date = JSON.parse( new TextDecoder().decode(new Uint8Array(data)))
console.log(_date)
})
});
REQUEST.setTimeout(6000)
REQUEST.write(JSON.stringify(postData), 'utf8')
REQUEST.end()
public static void main(String[] args) {
// 完整实例请查看"签名规则"中的Java示例代码
String baseUrl = "http://api.xxxx.com/shopapi";
String priKey = "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCtdgvcfozY7fe/x6UlXR/Fff8+wX++CiG05YVRafDe90O8y5KJAMZ156TgajEUXSRyKZqASz7iVoMAcu5FqfK1KuOOdjTAg0LFe/twIZvKmAqHcCSS2pjUXk0fTpZEgQ5lmDCK12Mg07YXvr+BeHjF+kBpwRJMPMG/+DGBDYNFNeRSJqWyopt6yyF528soAykHIUQ7TTultJV5IPCrvjRQQrGdJ/QtCdE0vZg+tA09nFN7AqgraU99kIvzyS0sqysj+pP1SJRmTRSGtlVAO3mILfkXOekZl1KD60G7CF+7BIaaW83FPD55tZhAGhnbLMYyiq7OiIyU61LTRcNSaJ0tAgMBAAECggEBAIGgGKcSzxCBbMYdXLV6TPbZ/HeaRGrwyVWUu7cmc0E8CJu6iWvmb2jGzbiCwuCT5luF6ZZ8JKchvU4FlTfsE5r9TQY2IZ/Ht4s65qBaDUEts5iY3kv8HX9+ZSXDJZpV0ztqqsPmx4ZNj+NYwWXwcFiKdb5R8OmV8bgSsnPddD6wFhwewglUOBPRAjropHE4sqk1Vam6q1MlFq5kiekMn/CItyFYFFzST/ruqAtVTp7YIvazAMrfCKH+pvXWk6pYNHZmL/JZey0GglRyJ1nItiqL33X8Lji056FcbAclidq022h/KPLEJpZk6irWqYdqYZeF6YMLHtdZFDkTZ/hXY+UCgYEA5i794UTQ1Kd6K+iui/S8K5H8nGdiXb3+uZ5j5VKYfbRmzXhAdVYisYe8czeTECxhH+MeHgM4tLR4ifx9q60ylvZxl9Fav1p6EaE36YcvGVmpm7Gm3q6QDDBa4gB+X9u7CxCS4LpotV917YS1QvOIF9lnRonSj1zNzFtbXkywrN8CgYEAwOpx/mR40ZvgZxNCq9DsIdrSZYAFFKpw0xy0OtF1PpuwMaREoRabnlVw6Bb3Hofg50XA3JxemzAX6fB92ee+NfXfeL4UtC4vG1K9JyiXHtHq8p9Uw2W03ehIEeNa3xdoRRnLmD4VUpyfL19ViE2+7TM1Gd3TogjDT+AMOCSuq3MCgYBsurPH7gaq/LVT+mRAzgj4l8v4YUlwuGeTbIMJdvt7HXUWB4CDLH3U2CYnUpAQKrZyJok6ahEmIr1xiKggKP7lmmHL8eNo0icpHrtXfzi7Q8Q/PCpzs4dtioXTjaIkS5nNvzVyG/uL+RyuZmpsxrZ5dYM4KbAhchfwORMutxEZhwKBgQC5zpVw4jCEItBmNuTWO+nTScGvxTgfiXIVw+XLaQa2AJoZlhAL34yPWdffko79tv3lgweY9HsimZXO2rU8dbp8mo5c6ydhy8HPXUeWOcAkDSdv/ApWENW9jgYsRIC3swHY3Fl+Dv3Wjce8huQI3mjwaYvRmBhIToxfmHnscVhTBQKBgB9uciEHfz8hMI7ePrPo2PkyK/RbJDm3HnuWE2lFBp7MOUMlh53MXwv4dIRaYMbRrFuN1UIKEFxuKhWwTHSzZJufk/UENrha/81fpj2BoFsAKkEunKeETvaIh6fZSjec16h2+zxbzwkdS6b+yIYkSlaoAxmDYrMtae0C8G4e0YS9";
String pubKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2RZZISModRzproL3eTxRtvVK/nToDbeLmAVdmaVtHgNCwjXMeNCZvHySZKO7+t7XySzBd2PhhQjvAkDd8HRKB5Y0uvP6TFwvhxOMkMydTeBFcUobQWNeAI7ttRms1txSNrmyrZr0WpWfk79VIsO+yI/jFN/Pj2gxD+vh5UUKU1LD2IQq/VxgtEpf8Vs6w7SvafPwYkpdPGCKUFkRvN1FrY2+tq0j1MRVJbB2rIunWDnT8cDUh2sWLXf4yNaJVOaaTFB0zbAk/qcoicGQyW7bVG7dVW8WywKmOAPeQCCQa+SJ4BhfI1k8eEAwFVRuxz/f9Ecfog9hZJ+RgELkpS8qhQIDAQAB";
rsaSigner signer = new rsaSigner();
Map<String, Object> params = new HashMap<>();
params.put("app_id", "hxgmau9imt86qky9");
params.put("version", "1.0");
params.put("key_version", "admin");
params.put("time", Long.toString(System.currentTimeMillis() / 1000));
params.put("chain", "trx");
params.put("address", "HsHGWeEMmx5QLds9UiWfjxarM4RbLAc3xrD");
params.put("skip_api_source", "OK_LINK");
try {
params.put("sign", signer.genSign(params, priKey));
Gson gson = new GsonBuilder().create();
System.out.println("params = " + gson.toJson(params));
String res = doPost(baseUrl + "/address/verifyAml", gson.toJson(params));
if (null == res) {
throw new RuntimeException("http error");
}
System.out.println("response = " + res);
JsonParser jp = new JsonParser();
JsonObject resEle = jp.parse(res).getAsJsonObject();
boolean retSignOK = signer.verifySign(resEle, resEle.get("sign").getAsString(), pubKey);
if (!retSignOK) {
throw new RuntimeException("verify response sign fail");
}
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("OK");
}
返回结果示例:
{
"data": {
"address": "0x8e609ac80f4324e499a6efd24f221a2caa868224",
"chain": "eth",
"detail": "{\"可疑交易\":[\"大额交易比例较高\",\"存在高频交易行为\",\"交易的集中程度高\"],\"黑地址关联方\":[\"黑客关联方\"]}",
"level": "MEDIUM",
"risk_code": 5103,
"risk_score": "62",
"source": "OK_LINK",
"tag": "风险中等:黑地址关联方;可疑交易"
},
"date_time": "2023-11-22 18:19:54",
"msg": "SUCCESS",
"sign": "PSkdliG8jomX+ojV9jJ6Vv19/uTw6WqYnNCedm1dySNi4AqFbhW/gQVYmuXhcff51uJvsHKsJXGkAtATi5iqMsHKVZDNdNbsmUFV8pdUKIEHrLCHpIq5G7SYSdU0O5t1BYLVAmCIZa7YLF9vnPKc0gF1Y2so8HmznuFToO5jlHqS0hsLvc8HAjEDuKkl1Zpgykciftc7MvXC4hE14PwLssHmKc8J97oh+ab1BG+AnjxiI1fcArNAZbwj+YUK9l2RqD0C9wh+13qRTC7Aj0rZHGFBwFoTOqpcpxruarSlEcdi98ueZgrLd0amb7/l5tKPTbpasBv0yjzezfrsP2/NIg==",
"status": 200,
"time_stamp": 1700648394
}
- 地址AML反洗钱风险验证,目前仅支持 btc,eos,etc,eth,trx,usdt,xrp 主链地址验证,后续持续扩充其他主链地址验证。需要开通支持请联系客服。
HTTP Request
POST : /address/verifyAml
请求参数
| 参数名 | 必选 | 类型 | 说明 |
|---|---|---|---|
| 公共参数 | 是 | string | 公参指:签名(sign)、版本(version)、商户ID(app_id)、时间(time) |
| chain | 是 | string | 主链币名, 以平台提供为准 |
| address | 是 | string | 地址 |
| skip_api_source | 否 | string | 指定跳过远程接口查询的aml源,可填写来源 OK_LINK 或 BEOSIN,多个逗号分隔。前提是已通过客服开通来相应来源。 |
返回参数说明
| 参数名 | 必选 | 类型 | 说明 |
|---|---|---|---|
| status | 是 | int | 返回值:200 成功 |
| msg | 否 | string | 100字内, 状态描述 |
| data | 是 | jsonObject | — |
| data.chain | 是 | string | 主链币名 |
| data.address | 是 | string | 地址 |
| data.risk_code | 是 | int | 风险标识码,默认0:无风险。非0就是有风险,后续可能增加更多标识码。 |
| data.source | 是 | string | AML数据来源,OK_LINK,SLOW_MIST,BEOSIN |
| data.tag | 否 | string | 风险描述标签 |
| data.detail | 否 | string | 附带描述 |
| data.risk_score | 否 | string | OK_LINK风险分值,满分100无风险。分值越低风险越高。 |
| data.level | 否 | string | OK_LINK风险等级,SEVERE,HIGH,MEDIUM,LOW,NONE |
| date_time | 否 | DateTime | 北京时间:2020-06-29 14:28:14 |
| time_stamp | 否 | string | 响应时间,单位秒:1593412094 |
| sign | 是 | string | 返回签名,对以上所有参与参数签名 |
risk_code错误码说明
| risk_code | 说明 |
|---|---|
| 0 | 无风险 |
| 5001 | 实施勒索活动,涉及恶意挖矿活动 |
| 5002 | 实施盗币攻击 |
| 5003 | 实施钓鱼活动 |
| 5004 | 实施钓鱼活动,涉及网络犯罪 |
| 5101 | 风险极大(OK_LINK来源的) |
| 5102 | 风险高(OK_LINK来源的) |
| 5103 | 风险中等(OK_LINK来源的) |
| 5104 | 风险低(OK_LINK来源的) |
| 5201 | 风险极大(BEOSIN来源的) |
| 5202 | 风险高(BEOSIN来源的) |
| 5203 | 风险中等(BEOSIN来源的) |
| 5204 | 风险低(BEOSIN来源的) |
| xxxx | 后续可能增加更多标识码... |
充值
充值列表
$url = "http://api.xxxx.com/shopapi/receive/list";
$header = [
'Content-Type:application/json',
];
$params = [
"version" => "1.0",
"app_id" => "hxgmau9imt86qky9",
"time" => "1578736053",
"sign" => "OTA8utI8y8G93p7RPCyb4qIilFQ0B4Aq4iUjhaXWK9m2kgektqlHOASDKXT2VE7NPNysrGycYlVfjDR2WGZn1G66phHo3qa9CcCNpG9klOBEuBEMjiVbb/d8AXcxEzvQr9OCwNsikyxonyzLiY/lsNHeGm9cC5eRvlNLdUSVBipH+ajPd0lDHCayZPs1eCMfbm/xnf8e2lfy6z0UPOpHGfyX/0+hz99Ir5Xnx+0sBBzyZZJxKm4ROid5aDv/9m9guILpURae+Yw/IrkYF4uAKGX+/44cBvtTRQSdX76CAOBSiywZa6BAgDYBLRtkAPM+i+vwNzFBovqHUvI+4Ponaw==",
"page" => 1,
"coin" => "eth",
"order_id" => "20200803220112662436",
"status" => "1",
"start_time" => "1578736053",
"end_time" => "1578836053",
"page_size" => "20",
"sort_num" => 2
];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
$return = curl_exec($ch);
print_r($return);
var url = "http://api.xxxx.com/shopapi/receive/list"
data := map[string]string{
"version": "1.0",
"app_id": "hxgmau9imt86qky9",
"time": "1578736053",
"sign": "OTA8utI8y8G93p7RPCyb4qIilFQ0B4Aq4iUjhaXWK9m2kgektqlHOASDKXT2VE7NPNysrGycYlVfjDR2WGZn1G66phHo3qa9CcCNpG9klOBEuBEMjiVbb/d8AXcxEzvQr9OCwNsikyxonyzLiY/lsNHeGm9cC5eRvlNLdUSVBipH+ajPd0lDHCayZPs1eCMfbm/xnf8e2lfy6z0UPOpHGfyX/0+hz99Ir5Xnx+0sBBzyZZJxKm4ROid5aDv/9m9guILpURae+Yw/IrkYF4uAKGX+/44cBvtTRQSdX76CAOBSiywZa6BAgDYBLRtkAPM+i+vwNzFBovqHUvI+4Ponaw==",
"page": "1",
"coin" :"eth",
"order_id" :"20200803220112662436",
"status" :"1",
"start_time" :"1578736053",
"end_time" :"1578836053",
"page_size" :"20",
"sort_num" :"2",
}
dataType, _ := json.Marshal(data)
resp, err := http.Post(url, "application/json", strings.NewReader(string(dataType)))
if err != nil {
fmt.Println(err)
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Println(err)
}
fmt.Println(string(body))
let HTTP = require('http')
let postData = {
"version": "1.0",
"app_id": "hxgmau9imt86qky9",
"time": "1578736053",
"sign": "OTA8utI8y8G93p7RPCyb4qIilFQ0B4Aq4iUjhaXWK9m2kgektqlHOASDKXT2VE7NPNysrGycYlVfjDR2WGZn1G66phHo3qa9CcCNpG9klOBEuBEMjiVbb/d8AXcxEzvQr9OCwNsikyxonyzLiY/lsNHeGm9cC5eRvlNLdUSVBipH+ajPd0lDHCayZPs1eCMfbm/xnf8e2lfy6z0UPOpHGfyX/0+hz99Ir5Xnx+0sBBzyZZJxKm4ROid5aDv/9m9guILpURae+Yw/IrkYF4uAKGX+/44cBvtTRQSdX76CAOBSiywZa6BAgDYBLRtkAPM+i+vwNzFBovqHUvI+4Ponaw==",
"page": "1",
"coin" : "eth",
"order_id" : "20200803220112662436",
"status" : "1",
"start_time" : "1578736053",
"end_time" : "1578836053",
"page_size" : "20",
"sort_num" : "2",
};
let POST_OPTIONS = {
port: 80,
host: "api.xxxx.com",
path: "/shopapi/receive/list",
method: 'POST',
headers: {
"Content-Type": "application/json; charset=utf-8"
}
};
const REQUEST = HTTP.request(POST_OPTIONS,function (res) {
let data = []
res.on('data', chunk => {
data.push(...chunk)
})
res.on('end', () => {
let _date = JSON.parse( new TextDecoder().decode(new Uint8Array(data)))
console.log(_date)
})
});
REQUEST.setTimeout(6000)
REQUEST.write(JSON.stringify(postData), 'utf8')
REQUEST.end()
public static void main(String[] args) {
// 完整实例请查看"签名规则"中的Java示例代码
String baseUrl = "http://api.xxxx.com/shopapi";
String priKey = "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCtdgvcfozY7fe/x6UlXR/Fff8+wX++CiG05YVRafDe90O8y5KJAMZ156TgajEUXSRyKZqASz7iVoMAcu5FqfK1KuOOdjTAg0LFe/twIZvKmAqHcCSS2pjUXk0fTpZEgQ5lmDCK12Mg07YXvr+BeHjF+kBpwRJMPMG/+DGBDYNFNeRSJqWyopt6yyF528soAykHIUQ7TTultJV5IPCrvjRQQrGdJ/QtCdE0vZg+tA09nFN7AqgraU99kIvzyS0sqysj+pP1SJRmTRSGtlVAO3mILfkXOekZl1KD60G7CF+7BIaaW83FPD55tZhAGhnbLMYyiq7OiIyU61LTRcNSaJ0tAgMBAAECggEBAIGgGKcSzxCBbMYdXLV6TPbZ/HeaRGrwyVWUu7cmc0E8CJu6iWvmb2jGzbiCwuCT5luF6ZZ8JKchvU4FlTfsE5r9TQY2IZ/Ht4s65qBaDUEts5iY3kv8HX9+ZSXDJZpV0ztqqsPmx4ZNj+NYwWXwcFiKdb5R8OmV8bgSsnPddD6wFhwewglUOBPRAjropHE4sqk1Vam6q1MlFq5kiekMn/CItyFYFFzST/ruqAtVTp7YIvazAMrfCKH+pvXWk6pYNHZmL/JZey0GglRyJ1nItiqL33X8Lji056FcbAclidq022h/KPLEJpZk6irWqYdqYZeF6YMLHtdZFDkTZ/hXY+UCgYEA5i794UTQ1Kd6K+iui/S8K5H8nGdiXb3+uZ5j5VKYfbRmzXhAdVYisYe8czeTECxhH+MeHgM4tLR4ifx9q60ylvZxl9Fav1p6EaE36YcvGVmpm7Gm3q6QDDBa4gB+X9u7CxCS4LpotV917YS1QvOIF9lnRonSj1zNzFtbXkywrN8CgYEAwOpx/mR40ZvgZxNCq9DsIdrSZYAFFKpw0xy0OtF1PpuwMaREoRabnlVw6Bb3Hofg50XA3JxemzAX6fB92ee+NfXfeL4UtC4vG1K9JyiXHtHq8p9Uw2W03ehIEeNa3xdoRRnLmD4VUpyfL19ViE2+7TM1Gd3TogjDT+AMOCSuq3MCgYBsurPH7gaq/LVT+mRAzgj4l8v4YUlwuGeTbIMJdvt7HXUWB4CDLH3U2CYnUpAQKrZyJok6ahEmIr1xiKggKP7lmmHL8eNo0icpHrtXfzi7Q8Q/PCpzs4dtioXTjaIkS5nNvzVyG/uL+RyuZmpsxrZ5dYM4KbAhchfwORMutxEZhwKBgQC5zpVw4jCEItBmNuTWO+nTScGvxTgfiXIVw+XLaQa2AJoZlhAL34yPWdffko79tv3lgweY9HsimZXO2rU8dbp8mo5c6ydhy8HPXUeWOcAkDSdv/ApWENW9jgYsRIC3swHY3Fl+Dv3Wjce8huQI3mjwaYvRmBhIToxfmHnscVhTBQKBgB9uciEHfz8hMI7ePrPo2PkyK/RbJDm3HnuWE2lFBp7MOUMlh53MXwv4dIRaYMbRrFuN1UIKEFxuKhWwTHSzZJufk/UENrha/81fpj2BoFsAKkEunKeETvaIh6fZSjec16h2+zxbzwkdS6b+yIYkSlaoAxmDYrMtae0C8G4e0YS9";
String pubKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2RZZISModRzproL3eTxRtvVK/nToDbeLmAVdmaVtHgNCwjXMeNCZvHySZKO7+t7XySzBd2PhhQjvAkDd8HRKB5Y0uvP6TFwvhxOMkMydTeBFcUobQWNeAI7ttRms1txSNrmyrZr0WpWfk79VIsO+yI/jFN/Pj2gxD+vh5UUKU1LD2IQq/VxgtEpf8Vs6w7SvafPwYkpdPGCKUFkRvN1FrY2+tq0j1MRVJbB2rIunWDnT8cDUh2sWLXf4yNaJVOaaTFB0zbAk/qcoicGQyW7bVG7dVW8WywKmOAPeQCCQa+SJ4BhfI1k8eEAwFVRuxz/f9Ecfog9hZJ+RgELkpS8qhQIDAQAB";
rsaSigner signer = new rsaSigner();
Map<String, Object> params = new HashMap<>();
params.put("app_id", "hxgmau9imt86qky9");
params.put("version", "1.0");
params.put("key_version", "admin");
params.put("time", Long.toString(System.currentTimeMillis() / 1000));
params.put("page", "1");
params.put("coin", "eth");
params.put("order_id", "20200803220112662436");
params.put("status", "1");
params.put("start_time", "1578736053");
params.put("end_time", "1578836053");
params.put("page_size", "20");
params.put("sort_num", "2");
try {
params.put("sign", signer.genSign(params, priKey));
Gson gson = new GsonBuilder().create();
System.out.println("params = " + gson.toJson(params));
String res = doPost(baseUrl + "/receive/list", gson.toJson(params));
if (null == res) {
throw new RuntimeException("http error");
}
System.out.println("response = " + res);
JsonParser jp = new JsonParser();
JsonObject resEle = jp.parse(res).getAsJsonObject();
boolean retSignOK = signer.verifySign(resEle, resEle.get("sign").getAsString(), pubKey);
if (!retSignOK) {
throw new RuntimeException("verify response sign fail");
}
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("OK");
}
返回结果示例:
{
"status":200,
"msg":"处理成功",
"data":{
"page":1,
"count":9,
"list":[
{
"coin":"hc",
"txid":"b064a252228105d7be10fefabf02fcdfbb863a071304298f7c3c1c1ace471e2b",
"total":"0.30000000",
"chain":"hc",
"confirm_count":"6",
"order_id":"20200803220112662436",
"status":"0",
"address":"0", #入账地址,
"from_address":"0", #转出地址,
"time":"1583922327", #新增status=1的时间如果没有为status=0的时间
"type":"1"
}
]
},
"date_time":"2020-03-11 18:25:27",
"time_stamp":1583922327,
"sign":"ESIOqIfhKnYHFh3HPD1XewWYBraPz+MukYIFcMrMLv7zEKZEIY/ZsxOYTwQ1AtcfSPiVlOJtp9SqtAVxRxcwRNK9X0ZHjSo+eP8YRXYhDCTi0jFETy5hA2Cy8j3X0t7LFiO9feGE6qA/Xok4sngbTwbQ3MqZP+lN/P3dK2VZyiFKywx5/pPi4tUAOpCo4SJEtLkapS4rCHwNreo72Z7D8L9YiT4iCOkzYBL/2ryuwZrpM1sX6WvC4Zf3LRLTE+X4XFZ++AlbrAuSS+zis+bWEG/qEYAdTXOXhkQrgfuidpH/U2HGjA9zf/skYlisdAt4cMiMiQmgIHTuO2Ujobn2Ow=="
}
通过批量查询接口查询订单状态情况
HTTP Request
POST: /receive/list
请求参数
| 参数名 | 必选 | 类型 | 说明 |
|---|---|---|---|
| 公共参数 | 是 | string | 公参指:签名(sign)、版本(version)、商户ID(app_id)、时间(time) |
| page | 否 | int,默认值为1 | 1<= N <=Max, N>Max ? N=Max ; N<1 ? N=1 |
| coin | 否 | varchar | 币名(如:eth) |
| order_id | 否 | varchar | 平台 订单号 |
| status | 否 | int | 0 待审核 1 转入成功 |
| start_time | 否 | int | 开始时间(创建时间) 格式 :时间戳 |
| end_time | 否 | int | 结束时间(创建时间) 格式 :时间戳 |
| page_size | 否 | int | 每页数量 (20 ~100),默认 20 |
| sort_num | 否 | int | 列表排序规则 默认按入系统时间正序排列( 1 正序 ; 2 倒序) |
返回参数说明
| 参数名 | 类型 | 说明 |
|---|---|---|
| status | int | 状态码 |
| msg | string | 状态描述 |
| data | jsonObject | trade_id-由商户提供 |
| data.page | int | 第几页 |
| data.count | int | 本页记录数 |
| data.list | jsonArray | 具体每条记录 |
| data.list.coin | string | 币种 |
| data.list.txid | string | 链上txid |
| data.list.total | numberString | 总金额 |
| data.list.chain | string | 主链币名 |
| data.list.confirm_count | string | 确认数 |
| data.list.order_id | string | 订单号 |
| data.list.status | string | 0入账但未确认 1确认成功 5失败 8等待退款 10退款中 20已退款 |
| data.list.address | string | 转入地址 |
| data.list.from_address | string | 转出地址 |
| data.list.time | string | 默认为status=1的时间,如果status=0就是status=0的时间 |
| data.list.type | string | 1站内充值 2链上充值 |
| date_time | string | 响应时间 |
| time_stamp | int | 无时区的秒 |
| sign | string | 签名 |
账户余额查询
$url = "http://api.xxxx.com/shopapi/balance";
$header = [
'Content-Type:application/json',
];
$params = [
"version" => "1.0",
"app_id" => "hxgmau9imt86qky9",
"time" => "1578736053",
"sign" => "OTA8utI8y8G93p7RPCyb4qIilFQ0B4Aq4iUjhaXWK9m2kgektqlHOASDKXT2VE7NPNysrGycYlVfjDR2WGZn1G66phHo3qa9CcCNpG9klOBEuBEMjiVbb/d8AXcxEzvQr9OCwNsikyxonyzLiY/lsNHeGm9cC5eRvlNLdUSVBipH+ajPd0lDHCayZPs1eCMfbm/xnf8e2lfy6z0UPOpHGfyX/0+hz99Ir5Xnx+0sBBzyZZJxKm4ROid5aDv/9m9guILpURae+Yw/IrkYF4uAKGX+/44cBvtTRQSdX76CAOBSiywZa6BAgDYBLRtkAPM+i+vwNzFBovqHUvI+4Ponaw==",
"coin" => "etc"
];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
$return = curl_exec($ch);
print_r($return);
var url = "http://api.xxxx.com/shopapi/balance"
data := map[string]string{
"version": "1.0",
"app_id": "hxgmau9imt86qky9",
"time": "1578736053",
"sign": "OTA8utI8y8G93p7RPCyb4qIilFQ0B4Aq4iUjhaXWK9m2kgektqlHOASDKXT2VE7NPNysrGycYlVfjDR2WGZn1G66phHo3qa9CcCNpG9klOBEuBEMjiVbb/d8AXcxEzvQr9OCwNsikyxonyzLiY/lsNHeGm9cC5eRvlNLdUSVBipH+ajPd0lDHCayZPs1eCMfbm/xnf8e2lfy6z0UPOpHGfyX/0+hz99Ir5Xnx+0sBBzyZZJxKm4ROid5aDv/9m9guILpURae+Yw/IrkYF4uAKGX+/44cBvtTRQSdX76CAOBSiywZa6BAgDYBLRtkAPM+i+vwNzFBovqHUvI+4Ponaw==",
"coin": "etc",
}
dataType, _ := json.Marshal(data)
resp, err := http.Post(url, "application/json", strings.NewReader(string(dataType)))
if err != nil {
fmt.Println(err)
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Println(err)
}
fmt.Println(string(body))
let HTTP = require('http')
let postData = {
"version": "1.0",
"app_id": "hxgmau9imt86qky9",
"time": "1578736053",
"sign": "OTA8utI8y8G93p7RPCyb4qIilFQ0B4Aq4iUjhaXWK9m2kgektqlHOASDKXT2VE7NPNysrGycYlVfjDR2WGZn1G66phHo3qa9CcCNpG9klOBEuBEMjiVbb/d8AXcxEzvQr9OCwNsikyxonyzLiY/lsNHeGm9cC5eRvlNLdUSVBipH+ajPd0lDHCayZPs1eCMfbm/xnf8e2lfy6z0UPOpHGfyX/0+hz99Ir5Xnx+0sBBzyZZJxKm4ROid5aDv/9m9guILpURae+Yw/IrkYF4uAKGX+/44cBvtTRQSdX76CAOBSiywZa6BAgDYBLRtkAPM+i+vwNzFBovqHUvI+4Ponaw==",
"coin": "etc",
};
let POST_OPTIONS = {
port: 80,
host: "api.xxxx.com",
path: "/shopapi/balance",
method: 'POST',
headers: {
"Content-Type": "application/json; charset=utf-8"
}
};
const REQUEST = HTTP.request(POST_OPTIONS,function (res) {
let data = []
res.on('data', chunk => {
data.push(...chunk)
})
res.on('end', () => {
let _date = JSON.parse( new TextDecoder().decode(new Uint8Array(data)))
console.log(_date)
})
});
REQUEST.setTimeout(6000)
REQUEST.write(JSON.stringify(postData), 'utf8')
REQUEST.end()
public static void main(String[] args) {
// 完整实例请查看"签名规则"中的Java示例代码
String baseUrl = "http://api.xxxx.com/shopapi";
String priKey = "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCtdgvcfozY7fe/x6UlXR/Fff8+wX++CiG05YVRafDe90O8y5KJAMZ156TgajEUXSRyKZqASz7iVoMAcu5FqfK1KuOOdjTAg0LFe/twIZvKmAqHcCSS2pjUXk0fTpZEgQ5lmDCK12Mg07YXvr+BeHjF+kBpwRJMPMG/+DGBDYNFNeRSJqWyopt6yyF528soAykHIUQ7TTultJV5IPCrvjRQQrGdJ/QtCdE0vZg+tA09nFN7AqgraU99kIvzyS0sqysj+pP1SJRmTRSGtlVAO3mILfkXOekZl1KD60G7CF+7BIaaW83FPD55tZhAGhnbLMYyiq7OiIyU61LTRcNSaJ0tAgMBAAECggEBAIGgGKcSzxCBbMYdXLV6TPbZ/HeaRGrwyVWUu7cmc0E8CJu6iWvmb2jGzbiCwuCT5luF6ZZ8JKchvU4FlTfsE5r9TQY2IZ/Ht4s65qBaDUEts5iY3kv8HX9+ZSXDJZpV0ztqqsPmx4ZNj+NYwWXwcFiKdb5R8OmV8bgSsnPddD6wFhwewglUOBPRAjropHE4sqk1Vam6q1MlFq5kiekMn/CItyFYFFzST/ruqAtVTp7YIvazAMrfCKH+pvXWk6pYNHZmL/JZey0GglRyJ1nItiqL33X8Lji056FcbAclidq022h/KPLEJpZk6irWqYdqYZeF6YMLHtdZFDkTZ/hXY+UCgYEA5i794UTQ1Kd6K+iui/S8K5H8nGdiXb3+uZ5j5VKYfbRmzXhAdVYisYe8czeTECxhH+MeHgM4tLR4ifx9q60ylvZxl9Fav1p6EaE36YcvGVmpm7Gm3q6QDDBa4gB+X9u7CxCS4LpotV917YS1QvOIF9lnRonSj1zNzFtbXkywrN8CgYEAwOpx/mR40ZvgZxNCq9DsIdrSZYAFFKpw0xy0OtF1PpuwMaREoRabnlVw6Bb3Hofg50XA3JxemzAX6fB92ee+NfXfeL4UtC4vG1K9JyiXHtHq8p9Uw2W03ehIEeNa3xdoRRnLmD4VUpyfL19ViE2+7TM1Gd3TogjDT+AMOCSuq3MCgYBsurPH7gaq/LVT+mRAzgj4l8v4YUlwuGeTbIMJdvt7HXUWB4CDLH3U2CYnUpAQKrZyJok6ahEmIr1xiKggKP7lmmHL8eNo0icpHrtXfzi7Q8Q/PCpzs4dtioXTjaIkS5nNvzVyG/uL+RyuZmpsxrZ5dYM4KbAhchfwORMutxEZhwKBgQC5zpVw4jCEItBmNuTWO+nTScGvxTgfiXIVw+XLaQa2AJoZlhAL34yPWdffko79tv3lgweY9HsimZXO2rU8dbp8mo5c6ydhy8HPXUeWOcAkDSdv/ApWENW9jgYsRIC3swHY3Fl+Dv3Wjce8huQI3mjwaYvRmBhIToxfmHnscVhTBQKBgB9uciEHfz8hMI7ePrPo2PkyK/RbJDm3HnuWE2lFBp7MOUMlh53MXwv4dIRaYMbRrFuN1UIKEFxuKhWwTHSzZJufk/UENrha/81fpj2BoFsAKkEunKeETvaIh6fZSjec16h2+zxbzwkdS6b+yIYkSlaoAxmDYrMtae0C8G4e0YS9";
String pubKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2RZZISModRzproL3eTxRtvVK/nToDbeLmAVdmaVtHgNCwjXMeNCZvHySZKO7+t7XySzBd2PhhQjvAkDd8HRKB5Y0uvP6TFwvhxOMkMydTeBFcUobQWNeAI7ttRms1txSNrmyrZr0WpWfk79VIsO+yI/jFN/Pj2gxD+vh5UUKU1LD2IQq/VxgtEpf8Vs6w7SvafPwYkpdPGCKUFkRvN1FrY2+tq0j1MRVJbB2rIunWDnT8cDUh2sWLXf4yNaJVOaaTFB0zbAk/qcoicGQyW7bVG7dVW8WywKmOAPeQCCQa+SJ4BhfI1k8eEAwFVRuxz/f9Ecfog9hZJ+RgELkpS8qhQIDAQAB";
rsaSigner signer = new rsaSigner();
Map<String, Object> params = new HashMap<>();
params.put("app_id", "hxgmau9imt86qky9");
params.put("version", "1.0");
params.put("key_version", "admin");
params.put("time", Long.toString(System.currentTimeMillis() / 1000));
params.put("page", "1");
params.put("coin", "trx");
try {
params.put("sign", signer.genSign(params, priKey));
Gson gson = new GsonBuilder().create();
System.out.println("params = " + gson.toJson(params));
String res = doPost(baseUrl + "/balance", gson.toJson(params));
if (null == res) {
throw new RuntimeException("http error");
}
System.out.println("response = " + res);
JsonParser jp = new JsonParser();
JsonObject resEle = jp.parse(res).getAsJsonObject();
boolean retSignOK = signer.verifySign(resEle, resEle.get("sign").getAsString(), pubKey);
if (!retSignOK) {
throw new RuntimeException("verify response sign fail");
}
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("OK");
}
返回结果示例:
{
"status": 200,
"msg": "请求成功",
"data": {
"chain_hot_amount": "0",
"amount": "0",
"freeze_amount": "0",
"total": "0",
"waiting_collect_amount": "0"
},
"date_time": "2022-07-22 19:03:08",
"time_stamp": 1658487788,
"sign": "tA8F3+VBGqyA0hmPPGMSIGgCH6hRssZc6Ez+KPst+c28SoakNI0k6Xoqh6qbHXsaPNBuPuaQnpR3unxWsOs675podt8vQREhzInOH1iieceqRzdtzKifEcaekhWDblGUK+h6yJTYGY0ABRtDDfb7X/GByEdmzBeOGz8LFa3oRNkVc59r5CPfBBbqGyYVM5KJM5l2RHXezXC8z2OmL7XK23o/zxD2JAQHukXqrAj5WhUpClhw4WEVzBhswj/dELKq4jUI2Rp4PVDLMj+H4itPf7XLkV3F/cwc67rBlTXgR31vUqwCbFbdbDIjcbm+9ksrTH4QHkkdW4GlXCLO/aqvEA=="
}
币种余额查询接口,返回单个币种的链上充值剩余总余额。
HTTP Request
POST: /balance
请求参数
| 参数名 | 必选 | 类型 | 说明 |
|---|---|---|---|
| 公共参数 | 是 | JSON | 公参指:签名(sign)、版本(version)、商户ID(app_id)、时间(time) |
| coin | 是 | string | 20个字符内币名,币名平台提供为准 |
返回参数说明
| 参数名 | 类型 | 说明 |
|---|---|---|
| status | int | 状态码 |
| msg | string | 状态描述 |
| data | jsonObject | trade_id-由商户提供 |
| data.amount | string | — |
| data.freeze_amount | string | — |
| data.total | string | — |
| data.chain_hot_amount | string | — |
| date_time | string | 响应时间 |
| time_stamp | int | 无时区的秒 |
| sign | string | 签名 |
充值结果回调通知
$url = "具体回调地址,由商户提供给平台方";
$header = [
'Content-Type:application/json',
];
$params = [
"data" => [
"order_id" => "2020010211153423123456",
"coin" => "eth",
"chain" => "eth",
"address" => "this is test address",
"from_address" => "this is test address",
"txid" => "this is txid",
"total" => "5",
"amount" => "10.0089",
"fee" => "0",
"status" => "0",
"confirm_count" => "5",
"time" => "1650011196",
"type" => 1
],
"sign" => "OTA8utI8y8G93p7RPCyb4qIilFQ0B4Aq4iUjhaXWK9m2kgektqlHOASDKXT2VE7NPNysrGycYlVfjDR2WGZn1G66phHo3qa9CcCNpG9klOBEuBEMjiVbb/d8AXcxEzvQr9OCwNsikyxonyzLiY/lsNHeGm9cC5eRvlNLdUSVBipH+ajPd0lDHCayZPs1eCMfbm/xnf8e2lfy6z0UPOpHGfyX/0+hz99Ir5Xnx+0sBBzyZZJxKm4ROid5aDv/9m9guILpURae+Yw/IrkYF4uAKGX+/44cBvtTRQSdX76CAOBSiywZa6BAgDYBLRtkAPM+i+vwNzFBovqHUvI+4Ponaw==",
];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
$return = curl_exec($ch);
print_r($return);
var url = "具体回调地址,由商户提供给平台方"
data := map[string]interface{}{
"data": map[string]string{
"order_id": "2020010211153423123456",
"coin": "eth",
"chain": "eth",
"address": "this is test address",
"from_address": "this is test address",
"txid": "this is txid",
"total": "5",
"amount": "10.0089",
"fee": "0",
"status": "0",
"confirm_count": "5",
"time": "1650011196",
"type": "1",
},
"sign": "OTA8utI8y8G93p7RPCyb4qIilFQ0B4Aq4iUjhaXWK9m2kgektqlHOASDKXT2VE7NPNysrGycYlVfjDR2WGZn1G66phHo3qa9CcCNpG9klOBEuBEMjiVbb/d8AXcxEzvQr9OCwNsikyxonyzLiY/lsNHeGm9cC5eRvlNLdUSVBipH+ajPd0lDHCayZPs1eCMfbm/xnf8e2lfy6z0UPOpHGfyX/0+hz99Ir5Xnx+0sBBzyZZJxKm4ROid5aDv/9m9guILpURae+Yw/IrkYF4uAKGX+/44cBvtTRQSdX76CAOBSiywZa6BAgDYBLRtkAPM+i+vwNzFBovqHUvI+4Ponaw==",
}
dataType, _ := json.Marshal(data)
resp, err := http.Post(url, "application/json", strings.NewReader(string(dataType)))
if err != nil {
fmt.Println(err)
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Println(err)
}
fmt.Println(string(body))
let HTTP = require('http')
let postData = {
"data": {
"order_id": "2020010211153423123456",
"coin": "eth",
"chain": "eth",
"address": "this is test address",
"from_address": "this is test address",
"txid": "this is txid",
"total": "5",
"amount": "10.0089",
"fee": "0",
"status": "0",
"confirm_count": "5",
"time": "1650011196",
"type": "1",
},
"sign": "OTA8utI8y8G93p7RPCyb4qIilFQ0B4Aq4iUjhaXWK9m2kgektqlHOASDKXT2VE7NPNysrGycYlVfjDR2WGZn1G66phHo3qa9CcCNpG9klOBEuBEMjiVbb/d8AXcxEzvQr9OCwNsikyxonyzLiY/lsNHeGm9cC5eRvlNLdUSVBipH+ajPd0lDHCayZPs1eCMfbm/xnf8e2lfy6z0UPOpHGfyX/0+hz99Ir5Xnx+0sBBzyZZJxKm4ROid5aDv/9m9guILpURae+Yw/IrkYF4uAKGX+/44cBvtTRQSdX76CAOBSiywZa6BAgDYBLRtkAPM+i+vwNzFBovqHUvI+4Ponaw==",
};
let POST_OPTIONS = {
port: 80,
host: "具体回调地址,由商户提供给平台方",
path: "",
method: 'POST',
headers: {
"Content-Type": "application/json; charset=utf-8"
}
};
const REQUEST = HTTP.request(POST_OPTIONS,function (res) {
let data = []
res.on('data', chunk => {
data.push(...chunk)
})
res.on('end', () => {
let _date = JSON.parse( new TextDecoder().decode(new Uint8Array(data)))
console.log(_date)
})
});
REQUEST.setTimeout(6000)
REQUEST.write(JSON.stringify(postData), 'utf8')
REQUEST.end()
public static void main() {
String priKey = "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCtdgvcfozY7fe/x6UlXR/Fff8+wX++CiG05YVRafDe90O8y5KJAMZ156TgajEUXSRyKZqASz7iVoMAcu5FqfK1KuOOdjTAg0LFe/twIZvKmAqHcCSS2pjUXk0fTpZEgQ5lmDCK12Mg07YXvr+BeHjF+kBpwRJMPMG/+DGBDYNFNeRSJqWyopt6yyF528soAykHIUQ7TTultJV5IPCrvjRQQrGdJ/QtCdE0vZg+tA09nFN7AqgraU99kIvzyS0sqysj+pP1SJRmTRSGtlVAO3mILfkXOekZl1KD60G7CF+7BIaaW83FPD55tZhAGhnbLMYyiq7OiIyU61LTRcNSaJ0tAgMBAAECggEBAIGgGKcSzxCBbMYdXLV6TPbZ/HeaRGrwyVWUu7cmc0E8CJu6iWvmb2jGzbiCwuCT5luF6ZZ8JKchvU4FlTfsE5r9TQY2IZ/Ht4s65qBaDUEts5iY3kv8HX9+ZSXDJZpV0ztqqsPmx4ZNj+NYwWXwcFiKdb5R8OmV8bgSsnPddD6wFhwewglUOBPRAjropHE4sqk1Vam6q1MlFq5kiekMn/CItyFYFFzST/ruqAtVTp7YIvazAMrfCKH+pvXWk6pYNHZmL/JZey0GglRyJ1nItiqL33X8Lji056FcbAclidq022h/KPLEJpZk6irWqYdqYZeF6YMLHtdZFDkTZ/hXY+UCgYEA5i794UTQ1Kd6K+iui/S8K5H8nGdiXb3+uZ5j5VKYfbRmzXhAdVYisYe8czeTECxhH+MeHgM4tLR4ifx9q60ylvZxl9Fav1p6EaE36YcvGVmpm7Gm3q6QDDBa4gB+X9u7CxCS4LpotV917YS1QvOIF9lnRonSj1zNzFtbXkywrN8CgYEAwOpx/mR40ZvgZxNCq9DsIdrSZYAFFKpw0xy0OtF1PpuwMaREoRabnlVw6Bb3Hofg50XA3JxemzAX6fB92ee+NfXfeL4UtC4vG1K9JyiXHtHq8p9Uw2W03ehIEeNa3xdoRRnLmD4VUpyfL19ViE2+7TM1Gd3TogjDT+AMOCSuq3MCgYBsurPH7gaq/LVT+mRAzgj4l8v4YUlwuGeTbIMJdvt7HXUWB4CDLH3U2CYnUpAQKrZyJok6ahEmIr1xiKggKP7lmmHL8eNo0icpHrtXfzi7Q8Q/PCpzs4dtioXTjaIkS5nNvzVyG/uL+RyuZmpsxrZ5dYM4KbAhchfwORMutxEZhwKBgQC5zpVw4jCEItBmNuTWO+nTScGvxTgfiXIVw+XLaQa2AJoZlhAL34yPWdffko79tv3lgweY9HsimZXO2rU8dbp8mo5c6ydhy8HPXUeWOcAkDSdv/ApWENW9jgYsRIC3swHY3Fl+Dv3Wjce8huQI3mjwaYvRmBhIToxfmHnscVhTBQKBgB9uciEHfz8hMI7ePrPo2PkyK/RbJDm3HnuWE2lFBp7MOUMlh53MXwv4dIRaYMbRrFuN1UIKEFxuKhWwTHSzZJufk/UENrha/81fpj2BoFsAKkEunKeETvaIh6fZSjec16h2+zxbzwkdS6b+yIYkSlaoAxmDYrMtae0C8G4e0YS9";
String pubKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArXYL3H6M2O33v8elJV0fxX3/PsF/vgohtOWFUWnw3vdDvMuSiQDGdeek4GoxFF0kcimagEs+4laDAHLuRanytSrjjnY0wINCxXv7cCGbypgKh3AkktqY1F5NH06WRIEOZZgwitdjINO2F76/gXh4xfpAacESTDzBv/gxgQ2DRTXkUialsqKbesshedvLKAMpByFEO007pbSVeSDwq740UEKxnSf0LQnRNL2YPrQNPZxTewKoK2lPfZCL88ktLKsrI/qT9UiUZk0UhrZVQDt5iC35FznpGZdSg+tBuwhfuwSGmlvNxTw+ebWYQBoZ2yzGMoquzoiMlOtS00XDUmidLQIDAQAB";
rsaSigner signer = new rsaSigner();
Map<String, Object> data = new HashMap<>();
data.put("order_id", "2020010211153423123456");
data.put("coin", "eth");
data.put("chain", "eth");
data.put("address", "this is test address");
data.put("from_address", "this is test address");
data.put("txid", "this is txid");
data.put("amount", "1");
data.put("fee", "0");
data.put("total", "1");
data.put("status", "1");
data.put("confirm_count", "3");
data.put("time", "1650011196");
data.put("type", "1");
try {
Map<String, Object> params = new HashMap<>();
params.put("data", data);
params.put("sign", signer.genSign(data, priKey));
Gson gson = new GsonBuilder().create();
System.out.println("params = " + gson.toJson(params));
String res;
// platform request shop callback API
// res = doPost("http://api.shophost.com/deposit/callback", gson.toJson(params));
// if (null == res) {
// throw new RuntimeException("http error");
// }
// mock response from shop callback API
{
res = """
{
"status":200,
"sign": "A3wCWwcw1w7Ee/xDDWBpf80i2Wc1oqpcqChznv9mr7dgLcKPQAECtemvmRTPwAxsZm6SJeGSN7P3ssB8/wmyZcJiVykr1HWbcQNL/YNYb6MCJqBXpbpnOwaBSWGr+aOh/1ql1ciW04W/rhF8rHch13Se+ZQ1TmJ5/JooEssCxaIRI4EiwGM47cpFSpuMv1e0UMsozCNvudAZDhwh/fDU4eIk2n3qikFEN6uAkG2gN2Y0dseG1/ua1RLYn97lb6oU4cYTpmrlGYZCMzc+cvhDkBL83UsU1hiVYMQtTJ5jtrUe5sumkYuVqkT0VjZklszvKtDDblK/KYXtZ2kRkWn2kg==",
"data":{
"success_data":"success"
}
}
""";
}
System.out.println("response = " + res);
JsonParser jp = new JsonParser();
JsonObject resEle = jp.parse(res).getAsJsonObject();
boolean retSignOK = signer.verifySign(resEle.get("data"), resEle.get("sign").getAsString(), pubKey);
if (!retSignOK) {
throw new RuntimeException("verify response sign fail");
}
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("OK");
}
返回结果示例:
{
"status":200,
"sign": "OTA8utI8y8G93p7RPCyb4qIilFQ0B4Aq4iUjhaXWK9m2kgektqlHOASDKXT2VE7NPNysrGycYlVfjDR2WGZn1G66phHo3qa9CcCNpG9klOBEuBEMjiVbb/d8AXcxEzvQr9OCwNsikyxonyzLiY/lsNHeGm9cC5eRvlNLdUSVBipH+ajPd0lDHCayZPs1eCMfbm/xnf8e2lfy6z0UPOpHGfyX/0+hz99Ir5Xnx+0sBBzyZZJxKm4ROid5aDv/9m9guILpURae+Yw/IrkYF4uAKGX+/44cBvtTRQSdX76CAOBSiywZa6BAgDYBLRtkAPM+i+vwNzFBovqHUvI+4Ponaw==",
"data":{
"success_data":"success"
}
}
用户充值到账通知回调,有平台发起请求,商户响应
HTTP Request
POST: 具体回调地址,由商户提供给平台方
请求参数
| 参数名 | 必选 | 类型 | 说明 |
|---|---|---|---|
| data | 否 | string | 回调通知携带数据结构 |
| data.order_id | 是 | string | 订单号 |
| data.coin | 是 | string | 币名 |
| data.chain | 是 | string | 主链币名 |
| data.address | 是 | string | 入账地址 |
| data.from_address | 是 | string | 转出地址,正式环境2023-05-05之后接入的商户才会返回该属性 |
| data.txid | 是 | string | 链上txid |
| data.total | 是 | string | 实际到账 total = amount - fee |
| data.fee | 是 | string | 平台手续费 |
| data.amount | 否 | string | 链上金额(本字段仅供参考) |
| data.status | 是 | int | 0入账但未确认 1确认成功 5失败 8等待退款 10退款中 20已退款 |
| data.confirm_count | 是 | int | 确认数仅供参考,以status=1为入账成功 |
| data.time | 是 | int | 订单确认时间 |
| data.type | 是 | int | 1站内充值 2链上充值 |
| data.reject_reason | 否 | string | 商户审核时选择的拒绝原因,值描述见后面的表格。默认不会有该参数,需要返回请联系商务人员。 |
| sign | 是 | string | 对data内数据签名 |
返回参数说明
| 参数名 | 必选 | 类型 | 说明 |
|---|---|---|---|
| status | 是 | int | 状态码 |
| data | 是 | jsonObject | 返回数据对象 |
| data.success_data | 是 | sring | success 接收成功 |
| sign | 是 | string | 签名 |
请求参数中data.reject_reason说明
| 值 | 描述说明 |
|---|---|
| no-shop-coin | 商户没有配置币种 |
| shop-coin-no-recharge | 币种没有开通充值功能 |
| aml-slow-mist | 慢雾检测:风险地址 |
| aml-ok-link | OKLink检测:风险地址 |
| other | 其他 |
提现
提现申请
$url = "http://api.xxxx.com/shopapi/transfer";
$header = [
'Content-Type:application/json',
];
$params = [
"app_id" => "hxgmau9imt86qky9",
"version" => "1.0",
"time" => 1579004943,
"user_id" => "0",
"coin" => "hc",
"address" => "HsRDEePh7WBCsdJPfo1UsjfurwLBU6HD5Vi",
"amount" => "0.02",
"trade_id" => "20200114202903274786",
"sign" => "dLtK+uiPcnxt2ACKMbBqQ6wI5ttAvesOHzK5ybVID1R6hqYPDTkagl7Tsjr5iLJafehcSLTZyJLtCRI8O2CtIWQUUroGXBneHZC486NUi/4FMOQs0FaAgm17pWlbhX5/96cWXXXMVeoe3IZFKaFNYSWaA14v3RcdDU6QDE/9ixGiSJ0DIxm9NKA0+RkbIFbyYeuFn8d63OcjmUhv7tsOE6rKCc3Q2yi7Qe9i6BNAQFYMFATztb18MsxsBHKUxNqklqyVnl0ofETAHmQhfOHLmungOJQnOqAAuwfmRtg50Qci5F+R2mXeqjmIXko/u3E+DLYW1ygDBp3afKZmU4PwmA=="
];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
$return = curl_exec($ch);
print_r($return);
var url = "http://api.xxxx.com/shopapi/transfer"
data := map[string]interface{}{
"app_id":"hxgmau9imt86qky9",
"version":"1.0",
"time":"1579004943",
"user_id":"0",
"coin":"hc",
"address":"HsRDEePh7WBCsdJPfo1UsjfurwLBU6HD5Vi",
"amount":"0.02",
"trade_id":"20200114202903274786",
"sign":"dLtK+uiPcnxt2ACKMbBqQ6wI5ttAvesOHzK5ybVID1R6hqYPDTkagl7Tsjr5iLJafehcSLTZyJLtCRI8O2CtIWQUUroGXBneHZC486NUi/4FMOQs0FaAgm17pWlbhX5/96cWXXXMVeoe3IZFKaFNYSWaA14v3RcdDU6QDE/9ixGiSJ0DIxm9NKA0+RkbIFbyYeuFn8d63OcjmUhv7tsOE6rKCc3Q2yi7Qe9i6BNAQFYMFATztb18MsxsBHKUxNqklqyVnl0ofETAHmQhfOHLmungOJQnOqAAuwfmRtg50Qci5F+R2mXeqjmIXko/u3E+DLYW1ygDBp3afKZmU4PwmA==",
}
dataType, _ := json.Marshal(data)
resp, err := http.Post(url, "application/json", strings.NewReader(string(dataType)))
if err != nil {
fmt.Println(err)
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Println(err)
}
fmt.Println(string(body))
let HTTP = require('http')
let postData = {
"app_id":"hxgmau9imt86qky9",
"version":"1.0",
"time":"1579004943",
"user_id":"0",
"coin":"hc",
"address":"HsRDEePh7WBCsdJPfo1UsjfurwLBU6HD5Vi",
"amount":"0.02",
"trade_id":"20200114202903274786",
"sign":"dLtK+uiPcnxt2ACKMbBqQ6wI5ttAvesOHzK5ybVID1R6hqYPDTkagl7Tsjr5iLJafehcSLTZyJLtCRI8O2CtIWQUUroGXBneHZC486NUi/4FMOQs0FaAgm17pWlbhX5/96cWXXXMVeoe3IZFKaFNYSWaA14v3RcdDU6QDE/9ixGiSJ0DIxm9NKA0+RkbIFbyYeuFn8d63OcjmUhv7tsOE6rKCc3Q2yi7Qe9i6BNAQFYMFATztb18MsxsBHKUxNqklqyVnl0ofETAHmQhfOHLmungOJQnOqAAuwfmRtg50Qci5F+R2mXeqjmIXko/u3E+DLYW1ygDBp3afKZmU4PwmA==",
};
let POST_OPTIONS = {
port: 80,
host: "api.xxxx.com",
path: "/shopapi/transfer",
method: 'POST',
headers: {
"Content-Type": "application/json; charset=utf-8"
}
};
const REQUEST = HTTP.request(POST_OPTIONS,function (res) {
let data = []
res.on('data', chunk => {
data.push(...chunk)
})
res.on('end', () => {
let _date = JSON.parse( new TextDecoder().decode(new Uint8Array(data)))
console.log(_date)
})
});
REQUEST.setTimeout(6000)
REQUEST.write(JSON.stringify(postData), 'utf8')
REQUEST.end()
public static void main(String[] args) {
// 完整实例请查看"签名规则"中的Java示例代码
String baseUrl = "http://api.xxxx.com/shopapi";
String priKey = "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCtdgvcfozY7fe/x6UlXR/Fff8+wX++CiG05YVRafDe90O8y5KJAMZ156TgajEUXSRyKZqASz7iVoMAcu5FqfK1KuOOdjTAg0LFe/twIZvKmAqHcCSS2pjUXk0fTpZEgQ5lmDCK12Mg07YXvr+BeHjF+kBpwRJMPMG/+DGBDYNFNeRSJqWyopt6yyF528soAykHIUQ7TTultJV5IPCrvjRQQrGdJ/QtCdE0vZg+tA09nFN7AqgraU99kIvzyS0sqysj+pP1SJRmTRSGtlVAO3mILfkXOekZl1KD60G7CF+7BIaaW83FPD55tZhAGhnbLMYyiq7OiIyU61LTRcNSaJ0tAgMBAAECggEBAIGgGKcSzxCBbMYdXLV6TPbZ/HeaRGrwyVWUu7cmc0E8CJu6iWvmb2jGzbiCwuCT5luF6ZZ8JKchvU4FlTfsE5r9TQY2IZ/Ht4s65qBaDUEts5iY3kv8HX9+ZSXDJZpV0ztqqsPmx4ZNj+NYwWXwcFiKdb5R8OmV8bgSsnPddD6wFhwewglUOBPRAjropHE4sqk1Vam6q1MlFq5kiekMn/CItyFYFFzST/ruqAtVTp7YIvazAMrfCKH+pvXWk6pYNHZmL/JZey0GglRyJ1nItiqL33X8Lji056FcbAclidq022h/KPLEJpZk6irWqYdqYZeF6YMLHtdZFDkTZ/hXY+UCgYEA5i794UTQ1Kd6K+iui/S8K5H8nGdiXb3+uZ5j5VKYfbRmzXhAdVYisYe8czeTECxhH+MeHgM4tLR4ifx9q60ylvZxl9Fav1p6EaE36YcvGVmpm7Gm3q6QDDBa4gB+X9u7CxCS4LpotV917YS1QvOIF9lnRonSj1zNzFtbXkywrN8CgYEAwOpx/mR40ZvgZxNCq9DsIdrSZYAFFKpw0xy0OtF1PpuwMaREoRabnlVw6Bb3Hofg50XA3JxemzAX6fB92ee+NfXfeL4UtC4vG1K9JyiXHtHq8p9Uw2W03ehIEeNa3xdoRRnLmD4VUpyfL19ViE2+7TM1Gd3TogjDT+AMOCSuq3MCgYBsurPH7gaq/LVT+mRAzgj4l8v4YUlwuGeTbIMJdvt7HXUWB4CDLH3U2CYnUpAQKrZyJok6ahEmIr1xiKggKP7lmmHL8eNo0icpHrtXfzi7Q8Q/PCpzs4dtioXTjaIkS5nNvzVyG/uL+RyuZmpsxrZ5dYM4KbAhchfwORMutxEZhwKBgQC5zpVw4jCEItBmNuTWO+nTScGvxTgfiXIVw+XLaQa2AJoZlhAL34yPWdffko79tv3lgweY9HsimZXO2rU8dbp8mo5c6ydhy8HPXUeWOcAkDSdv/ApWENW9jgYsRIC3swHY3Fl+Dv3Wjce8huQI3mjwaYvRmBhIToxfmHnscVhTBQKBgB9uciEHfz8hMI7ePrPo2PkyK/RbJDm3HnuWE2lFBp7MOUMlh53MXwv4dIRaYMbRrFuN1UIKEFxuKhWwTHSzZJufk/UENrha/81fpj2BoFsAKkEunKeETvaIh6fZSjec16h2+zxbzwkdS6b+yIYkSlaoAxmDYrMtae0C8G4e0YS9";
String pubKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2RZZISModRzproL3eTxRtvVK/nToDbeLmAVdmaVtHgNCwjXMeNCZvHySZKO7+t7XySzBd2PhhQjvAkDd8HRKB5Y0uvP6TFwvhxOMkMydTeBFcUobQWNeAI7ttRms1txSNrmyrZr0WpWfk79VIsO+yI/jFN/Pj2gxD+vh5UUKU1LD2IQq/VxgtEpf8Vs6w7SvafPwYkpdPGCKUFkRvN1FrY2+tq0j1MRVJbB2rIunWDnT8cDUh2sWLXf4yNaJVOaaTFB0zbAk/qcoicGQyW7bVG7dVW8WywKmOAPeQCCQa+SJ4BhfI1k8eEAwFVRuxz/f9Ecfog9hZJ+RgELkpS8qhQIDAQAB";
rsaSigner signer = new rsaSigner();
Map<String, Object> params = new HashMap<>();
params.put("app_id", "hxgmau9imt86qky9");
params.put("version", "1.0");
params.put("key_version", "admin");
params.put("time", Long.toString(System.currentTimeMillis() / 1000));
params.put("user_id", "1");
params.put("coin", "hc");
params.put("address", "HsRDEePh7WBCsdJPfo1UsjfurwLBU6HD5Vi");
params.put("amount", "0.02");
params.put("trade_id", "20200114202903274786");
try {
params.put("sign", signer.genSign(params, priKey));
Gson gson = new GsonBuilder().create();
System.out.println("params = " + gson.toJson(params));
String res = doPost(baseUrl + "/transfer", gson.toJson(params));
if (null == res) {
throw new RuntimeException("http error");
}
System.out.println("response = " + res);
JsonParser jp = new JsonParser();
JsonObject resEle = jp.parse(res).getAsJsonObject();
boolean retSignOK = signer.verifySign(resEle, resEle.get("sign").getAsString(), pubKey);
if (!retSignOK) {
throw new RuntimeException("verify response sign fail");
}
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("OK");
}
返回结果示例:
{
"status":200,
"msg":"请求成功",
"data":{
"trade_id":"20200114005026028784"
},
"date_time":"2020-01-14 00:50:27",
"sign":"ib1gqr0E0gJ02yo3InXKcKGaPqIp+r1izMego+KMRvE0B4ZdkFGrLmOtxGStUBibGVMzJRGWppKyU4PzcK877AOEvQlSFiUI+hDL1z8WaZsWD3r3ykbPzU0uWo4U+6WQTpOEo1gJ/N2zJsdTRcMVgJMSC7LEAg7oib4se2NPFlw="
}
商户发起链上提币,请求此接口 开通提现功能时 ,同时需要提供 风控接口(见:风控回调api -> 商户提现订单二次复核)
HTTP Request
POST: /transfer
请求参数
| 参数名 | 必选 | 类型 | 说明 |
|---|---|---|---|
| 公共参数 | 是 | string | 公参指:签名(sign)、版本(version)、商户ID(app_id)、时间(time) |
| user_id | 否 | string | 用户ID,字母、数字和下划线组成,长度40以内 |
| coin | 是 | string | 币种简称-平台约定为准 |
| amount | 是 | string | 提现数量,超范围会出错 |
| address | 是 | string | 收款地址,超范围会出错 |
| memo | 否 | string | memo/tag 当前币为 eos及其代币时需要填写 |
| trade_id | 是 | string | 商户端交易唯一ID(建议格式:年月日时分秒+6位随机数案列:20200311202903000001) |
返回参数说明
| 参数名 | 类型 | 说明 |
|---|---|---|
| status | int | 状态码 |
| msg | string | 状态描述 |
| data | jsonObject | trade_id-由商户提供 |
| data.trade_id | string | 商户端交易唯一ID |
| date_time | string | 响应时间 |
| time_stamp | int | 无时区的秒 |
| sign | string | 签名 |
- 备注: 该接口返回成功只是接收成功,不代表转账处理成功,处理结果以通知接口返回数据为准 更多返回错误代码请看首页的错误代码描述
提现列表
$url = "http://api.xxxx.com/shopapi/transfer/list";
$header = [
'Content-Type:application/json',
];
$params = [
"version" => "1.0",
"app_id" => "hxgmau9imt86qky9",
"time" => "1578736053",
"page" => 1,
"sign" => "dLtK+uiPcnxt2ACKMbBqQ6wI5ttAvesOHzK5ybVID1R6hqYPDTkagl7Tsjr5iLJafehcSLTZyJLtCRI8O2CtIWQUUroGXBneHZC486NUi/4FMOQs0FaAgm17pWlbhX5/96cWXXXMVeoe3IZFKaFNYSWaA14v3RcdDU6QDE/9ixGiSJ0DIxm9NKA0+RkbIFbyYeuFn8d63OcjmUhv7tsOE6rKCc3Q2yi7Qe9i6BNAQFYMFATztb18MsxsBHKUxNqklqyVnl0ofETAHmQhfOHLmungOJQnOqAAuwfmRtg50Qci5F+R2mXeqjmIXko/u3E+DLYW1ygDBp3afKZmU4PwmA=="
];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
$return = curl_exec($ch);
print_r($return);
var url = "http://api.xxxx.com/shopapi/transfer/list"
data := map[string]string{
"version": "1.0",
"app_id": "hxgmau9imt86qky9",
"time": "1578736053",
"page": "1",
"sign": "OTA8utI8y8G93p7RPCyb4qIilFQ0B4Aq4iUjhaXWK9m2kgektqlHOASDKXT2VE7NPNysrGycYlVfjDR2WGZn1G66phHo3qa9CcCNpG9klOBEuBEMjiVbb/d8AXcxEzvQr9OCwNsikyxonyzLiY/lsNHeGm9cC5eRvlNLdUSVBipH+ajPd0lDHCayZPs1eCMfbm/xnf8e2lfy6z0UPOpHGfyX/0+hz99Ir5Xnx+0sBBzyZZJxKm4ROid5aDv/9m9guILpURae+Yw/IrkYF4uAKGX+/44cBvtTRQSdX76CAOBSiywZa6BAgDYBLRtkAPM+i+vwNzFBovqHUvI+4Ponaw==",
}
dataType, _ := json.Marshal(data)
resp, err := http.Post(url, "application/json", strings.NewReader(string(dataType)))
if err != nil {
fmt.Println(err)
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Println(err)
}
fmt.Println(string(body))
let HTTP = require('http')
let postData = {
"version": "1.0",
"app_id": "hxgmau9imt86qky9",
"time": "1578736053",
"page": "1",
"sign": "OTA8utI8y8G93p7RPCyb4qIilFQ0B4Aq4iUjhaXWK9m2kgektqlHOASDKXT2VE7NPNysrGycYlVfjDR2WGZn1G66phHo3qa9CcCNpG9klOBEuBEMjiVbb/d8AXcxEzvQr9OCwNsikyxonyzLiY/lsNHeGm9cC5eRvlNLdUSVBipH+ajPd0lDHCayZPs1eCMfbm/xnf8e2lfy6z0UPOpHGfyX/0+hz99Ir5Xnx+0sBBzyZZJxKm4ROid5aDv/9m9guILpURae+Yw/IrkYF4uAKGX+/44cBvtTRQSdX76CAOBSiywZa6BAgDYBLRtkAPM+i+vwNzFBovqHUvI+4Ponaw==",
};
let POST_OPTIONS = {
port: 80,
host: "api.xxxx.com",
path: "/shopapi/transfer/list",
method: 'POST',
headers: {
"Content-Type": "application/json; charset=utf-8"
}
};
const REQUEST = HTTP.request(POST_OPTIONS,function (res) {
let data = []
res.on('data', chunk => {
data.push(...chunk)
})
res.on('end', () => {
let _date = JSON.parse( new TextDecoder().decode(new Uint8Array(data)))
console.log(_date)
})
});
REQUEST.setTimeout(6000)
REQUEST.write(JSON.stringify(postData), 'utf8')
REQUEST.end()
public static void main(String[] args) {
// 完整实例请查看"签名规则"中的Java示例代码
String baseUrl = "http://api.xxxx.com/shopapi";
String priKey = "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCtdgvcfozY7fe/x6UlXR/Fff8+wX++CiG05YVRafDe90O8y5KJAMZ156TgajEUXSRyKZqASz7iVoMAcu5FqfK1KuOOdjTAg0LFe/twIZvKmAqHcCSS2pjUXk0fTpZEgQ5lmDCK12Mg07YXvr+BeHjF+kBpwRJMPMG/+DGBDYNFNeRSJqWyopt6yyF528soAykHIUQ7TTultJV5IPCrvjRQQrGdJ/QtCdE0vZg+tA09nFN7AqgraU99kIvzyS0sqysj+pP1SJRmTRSGtlVAO3mILfkXOekZl1KD60G7CF+7BIaaW83FPD55tZhAGhnbLMYyiq7OiIyU61LTRcNSaJ0tAgMBAAECggEBAIGgGKcSzxCBbMYdXLV6TPbZ/HeaRGrwyVWUu7cmc0E8CJu6iWvmb2jGzbiCwuCT5luF6ZZ8JKchvU4FlTfsE5r9TQY2IZ/Ht4s65qBaDUEts5iY3kv8HX9+ZSXDJZpV0ztqqsPmx4ZNj+NYwWXwcFiKdb5R8OmV8bgSsnPddD6wFhwewglUOBPRAjropHE4sqk1Vam6q1MlFq5kiekMn/CItyFYFFzST/ruqAtVTp7YIvazAMrfCKH+pvXWk6pYNHZmL/JZey0GglRyJ1nItiqL33X8Lji056FcbAclidq022h/KPLEJpZk6irWqYdqYZeF6YMLHtdZFDkTZ/hXY+UCgYEA5i794UTQ1Kd6K+iui/S8K5H8nGdiXb3+uZ5j5VKYfbRmzXhAdVYisYe8czeTECxhH+MeHgM4tLR4ifx9q60ylvZxl9Fav1p6EaE36YcvGVmpm7Gm3q6QDDBa4gB+X9u7CxCS4LpotV917YS1QvOIF9lnRonSj1zNzFtbXkywrN8CgYEAwOpx/mR40ZvgZxNCq9DsIdrSZYAFFKpw0xy0OtF1PpuwMaREoRabnlVw6Bb3Hofg50XA3JxemzAX6fB92ee+NfXfeL4UtC4vG1K9JyiXHtHq8p9Uw2W03ehIEeNa3xdoRRnLmD4VUpyfL19ViE2+7TM1Gd3TogjDT+AMOCSuq3MCgYBsurPH7gaq/LVT+mRAzgj4l8v4YUlwuGeTbIMJdvt7HXUWB4CDLH3U2CYnUpAQKrZyJok6ahEmIr1xiKggKP7lmmHL8eNo0icpHrtXfzi7Q8Q/PCpzs4dtioXTjaIkS5nNvzVyG/uL+RyuZmpsxrZ5dYM4KbAhchfwORMutxEZhwKBgQC5zpVw4jCEItBmNuTWO+nTScGvxTgfiXIVw+XLaQa2AJoZlhAL34yPWdffko79tv3lgweY9HsimZXO2rU8dbp8mo5c6ydhy8HPXUeWOcAkDSdv/ApWENW9jgYsRIC3swHY3Fl+Dv3Wjce8huQI3mjwaYvRmBhIToxfmHnscVhTBQKBgB9uciEHfz8hMI7ePrPo2PkyK/RbJDm3HnuWE2lFBp7MOUMlh53MXwv4dIRaYMbRrFuN1UIKEFxuKhWwTHSzZJufk/UENrha/81fpj2BoFsAKkEunKeETvaIh6fZSjec16h2+zxbzwkdS6b+yIYkSlaoAxmDYrMtae0C8G4e0YS9";
String pubKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2RZZISModRzproL3eTxRtvVK/nToDbeLmAVdmaVtHgNCwjXMeNCZvHySZKO7+t7XySzBd2PhhQjvAkDd8HRKB5Y0uvP6TFwvhxOMkMydTeBFcUobQWNeAI7ttRms1txSNrmyrZr0WpWfk79VIsO+yI/jFN/Pj2gxD+vh5UUKU1LD2IQq/VxgtEpf8Vs6w7SvafPwYkpdPGCKUFkRvN1FrY2+tq0j1MRVJbB2rIunWDnT8cDUh2sWLXf4yNaJVOaaTFB0zbAk/qcoicGQyW7bVG7dVW8WywKmOAPeQCCQa+SJ4BhfI1k8eEAwFVRuxz/f9Ecfog9hZJ+RgELkpS8qhQIDAQAB";
rsaSigner signer = new rsaSigner();
Map<String, Object> params = new HashMap<>();
params.put("app_id", "hxgmau9imt86qky9");
params.put("version", "1.0");
params.put("key_version", "admin");
params.put("time", Long.toString(System.currentTimeMillis() / 1000));
params.put("page", "1");
try {
params.put("sign", signer.genSign(params, priKey));
Gson gson = new GsonBuilder().create();
System.out.println("params = " + gson.toJson(params));
String res = doPost(baseUrl + "/transfer/list", gson.toJson(params));
if (null == res) {
throw new RuntimeException("http error");
}
System.out.println("response = " + res);
JsonParser jp = new JsonParser();
JsonObject resEle = jp.parse(res).getAsJsonObject();
boolean retSignOK = signer.verifySign(resEle, resEle.get("sign").getAsString(), pubKey);
if (!retSignOK) {
throw new RuntimeException("verify response sign fail");
}
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("OK");
}
返回结果示例:
{
"status": 200,
"msg": "处理成功",
"data": {
"page": 1,
"max_page": 1,
"count": 1,
"list": [{
"trade_id": "20200114202903274786",
"coin": "hc",
"chain": "hc",
"txid": "",
"amount": "0.02",
"fee": "0",
"total": "0.02",
"address": "HsRDEePh7WBCsdJPfo1UsjfurwLBU6HD5Vi",
"from_address": "the transaction from address",
"status": "2",
"time": "1658482253",
"type": "2",
"gas_fee": "0.1"
}]
},
"date_time": "2022-07-22 18:36:36",
"time_stamp": 1658486196,
"sign": "uuYWvmoMqM5xh7aTcxspJmW78y8op5BBjYXp0XoqcqFXe+HrSGzxN2Ls6LA7SlfsNndCtS4AX1/J+2o1MWZw/HFVfRqtxu02AEfWhM5ZSiJfEtO8f47H2/EGcsKw/eK8nxOnYAyAKwG6Ia6L4KgYIXLwsGt6Dt0VYWADu+vEQEes83/c6+Tc8QdqpdnLbs2XXXkYkl5eijoja+QEMaENbx+DHxnsVZV0iRK5FcSQH9PdOIpWmC944BA2v0tnPQWb6WDnOTsw5xoVKiL57WGIeOaxepvjo6poi1a/+HYrowT4IcejZZHi9YW0iM4eNm8MPK0tloAQ8GWY7kVs9uEwOA=="
}
通过此接口查询查询订单状态情况,可以只查一个,也可以模糊查询多个。
HTTP Request
POST: /transfer/list
请求参数
| 参数名 | 必选 | 类型 | 说明 |
|---|---|---|---|
| 公共参数 | 是 | string | 公参指:签名(sign)、版本(version)、商户ID(app_id)、时间(time) |
| trade_id | 否 | string | 如果传trade_id为精准查找,下面参数失效 |
| page | 否 | int | 1<= N <=Max,对于超过Max的取Max,小于1或没有传参数的返回1 |
| status | 否 | int | 0 待审核 1 提现成功、2 等待风控处理中、5 等待出币、10 审核不通过、20 转账失败 |
| start_time | 否 | int | 开始时间(创建时间) 格式 :时间戳 |
| end_time | 否 | int | 结束时间(创建时间) 格式 :时间戳 |
| page_size | 否 | int | 每页数量 (20 ~100),默认 20 |
| sort_num | 否 | int | 列表排序规则 默认按入系统时间正序排列( 1 正序 ; 2 倒序) |
返回参数说明
| 参数名 | 类型 | 说明 |
|---|---|---|
| status | int | 状态码 |
| msg | string | 状态描述 |
| data | jsonObject | trade_id-由商户提供 |
| data.page | int | 第几页 |
| data.count | int | 本页记录数 |
| data.list | jsonArray | 具体每条记录 |
| data.list.trade_id | string | 交易id |
| data.list.coin | string | 币种 |
| data.list.txid | string | 链上txid |
| data.list.amount | string | 总金额 |
| data.list.fee | string | 手续费 (业务规则fee不是链上gasfee),外扣模式 |
| data.list.total | string | 提现总金额 total = amount+fee |
| data.list.address | string | 提现收款地址 |
| data.list.from_address | string | 提现出款地址,正式环境2025-01-22之后接入的商户才会返回该属性 |
| data.list.chain | string | 主链币名 |
| data.list.memo | string | memo/tag 当前为 eos 及其代币 时 会回传该字段 |
| data.list.status | enum | 0 待审核、1 提现成功、2 等待风控处理中、5 等待出币、10 审核不通过、20 转账失败 |
| data.list.time | time_stamp | 状态时间,最终固定在status=1时候的时间 |
| data.list.type | string | 1站内交易 2链上交易 5中心化提现 |
| data.list.gas_fee | string | 链上消耗Gas费,正式环境2024-08-14接入的商户才会返回该属性,精度统一8位 |
| date_time | string | 响应时间 |
| time_stamp | int | 无时区的秒 |
| sign | string | 签名 |
提现结果回调通知
$url = "商家后台配置的提现回调URL";
$header = [
'Content-Type:application/json',
];
$params = [
"data" => [
"trade_id" => "this is trade_id",
"coin" => "eth",
"txid" => "this is txid",
"address" => "this is to address",
"from_address" => "this is from address"
"time" => "1591779242",
"amount" => "10.1",
"fee" => "0",
"total" => "10.1",
"status" => "1",
"msg" => "提示信息",
"type" => 1,
"gas_fee" => "0.1",
],
"sign" => "dLtK+uiPcnxt2ACKMbBqQ6wI5ttAvesOHzK5ybVID1R6hqYPDTkagl7Tsjr5iLJafehcSLTZyJLtCRI8O2CtIWQUUroGXBneHZC486NUi/4FMOQs0FaAgm17pWlbhX5/96cWXXXMVeoe3IZFKaFNYSWaA14v3RcdDU6QDE/9ixGiSJ0DIxm9NKA0+RkbIFbyYeuFn8d63OcjmUhv7tsOE6rKCc3Q2yi7Qe9i6BNAQFYMFATztb18MsxsBHKUxNqklqyVnl0ofETAHmQhfOHLmungOJQnOqAAuwfmRtg50Qci5F+R2mXeqjmIXko/u3E+DLYW1ygDBp3afKZmU4PwmA=="
];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
$return = curl_exec($ch);
print_r($return);
var url = "商家后台配置的提现回调URL"
data := map[string]interface{}{
"data": map[string]string{
"trade_id":"this is trade_id",
"coin":"eth",
"txid":"this is txid",
"address":"this is to address",
"from_address":"this is from address",
"time":"1591779242",
"amount":"10.1",
"fee":"0",
"total":"10.1",
"status":"1",
"msg":"提示信息",
"type":"1",
"gas_fee":"0.1",
},
"sign": "OTA8utI8y8G93p7RPCyb4qIilFQ0B4Aq4iUjhaXWK9m2kgektqlHOASDKXT2VE7NPNysrGycYlVfjDR2WGZn1G66phHo3qa9CcCNpG9klOBEuBEMjiVbb/d8AXcxEzvQr9OCwNsikyxonyzLiY/lsNHeGm9cC5eRvlNLdUSVBipH+ajPd0lDHCayZPs1eCMfbm/xnf8e2lfy6z0UPOpHGfyX/0+hz99Ir5Xnx+0sBBzyZZJxKm4ROid5aDv/9m9guILpURae+Yw/IrkYF4uAKGX+/44cBvtTRQSdX76CAOBSiywZa6BAgDYBLRtkAPM+i+vwNzFBovqHUvI+4Ponaw==",
}
dataType, _ := json.Marshal(data)
resp, err := http.Post(url, "application/json", strings.NewReader(string(dataType)))
if err != nil {
fmt.Println(err)
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Println(err)
}
fmt.Println(string(body))
let HTTP = require('http')
let postData = {
"data": {
"trade_id":"this is trade_id",
"coin":"eth",
"txid":"this is txid",
"address":"this is from address",
"from_address":"this is from address",
"time":"1591779242",
"amount": "10.1",
"fee":"0",
"total":"10.1",
"status":"1",
"msg":"Prompt information",
"type":"1",
"gas_fee":"0.1",
},
"sign": "OTA8utI8y8G93p7RPCyb4qIilFQ0B4Aq4iUjhaXWK9m2kgektqlHOASDKXT2VE7NPNysrGycYlVfjDR2WGZn1G66phHo3qa9CcCNpG9klOBEuBEMjiVbb/d8AXcxEzvQr9OCwNsikyxonyzLiY/lsNHeGm9cC5eRvlNLdUSVBipH+ajPd0lDHCayZPs1eCMfbm/xnf8e2lfy6z0UPOpHGfyX/0+hz99Ir5Xnx+0sBBzyZZJxKm4ROid5aDv/9m9guILpURae+Yw/IrkYF4uAKGX+/44cBvtTRQSdX76CAOBSiywZa6BAgDYBLRtkAPM+i+vwNzFBovqHUvI+4Ponaw==",
};
let POST_OPTIONS = {
port: 80,
host: "商家后台配置的提现回调URL",
path: "",
method: 'POST',
headers: {
"Content-Type": "application/json; charset=utf-8"
}
};
const REQUEST = HTTP.request(POST_OPTIONS,function (res) {
let data = []
res.on('data', chunk => {
data.push(...chunk)
})
res.on('end', () => {
let _date = JSON.parse( new TextDecoder().decode(new Uint8Array(data)))
console.log(_date)
})
});
REQUEST.setTimeout(6000)
REQUEST.write(JSON.stringify(postData), 'utf8')
REQUEST.end()
public static void main() {
String priKey = "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCtdgvcfozY7fe/x6UlXR/Fff8+wX++CiG05YVRafDe90O8y5KJAMZ156TgajEUXSRyKZqASz7iVoMAcu5FqfK1KuOOdjTAg0LFe/twIZvKmAqHcCSS2pjUXk0fTpZEgQ5lmDCK12Mg07YXvr+BeHjF+kBpwRJMPMG/+DGBDYNFNeRSJqWyopt6yyF528soAykHIUQ7TTultJV5IPCrvjRQQrGdJ/QtCdE0vZg+tA09nFN7AqgraU99kIvzyS0sqysj+pP1SJRmTRSGtlVAO3mILfkXOekZl1KD60G7CF+7BIaaW83FPD55tZhAGhnbLMYyiq7OiIyU61LTRcNSaJ0tAgMBAAECggEBAIGgGKcSzxCBbMYdXLV6TPbZ/HeaRGrwyVWUu7cmc0E8CJu6iWvmb2jGzbiCwuCT5luF6ZZ8JKchvU4FlTfsE5r9TQY2IZ/Ht4s65qBaDUEts5iY3kv8HX9+ZSXDJZpV0ztqqsPmx4ZNj+NYwWXwcFiKdb5R8OmV8bgSsnPddD6wFhwewglUOBPRAjropHE4sqk1Vam6q1MlFq5kiekMn/CItyFYFFzST/ruqAtVTp7YIvazAMrfCKH+pvXWk6pYNHZmL/JZey0GglRyJ1nItiqL33X8Lji056FcbAclidq022h/KPLEJpZk6irWqYdqYZeF6YMLHtdZFDkTZ/hXY+UCgYEA5i794UTQ1Kd6K+iui/S8K5H8nGdiXb3+uZ5j5VKYfbRmzXhAdVYisYe8czeTECxhH+MeHgM4tLR4ifx9q60ylvZxl9Fav1p6EaE36YcvGVmpm7Gm3q6QDDBa4gB+X9u7CxCS4LpotV917YS1QvOIF9lnRonSj1zNzFtbXkywrN8CgYEAwOpx/mR40ZvgZxNCq9DsIdrSZYAFFKpw0xy0OtF1PpuwMaREoRabnlVw6Bb3Hofg50XA3JxemzAX6fB92ee+NfXfeL4UtC4vG1K9JyiXHtHq8p9Uw2W03ehIEeNa3xdoRRnLmD4VUpyfL19ViE2+7TM1Gd3TogjDT+AMOCSuq3MCgYBsurPH7gaq/LVT+mRAzgj4l8v4YUlwuGeTbIMJdvt7HXUWB4CDLH3U2CYnUpAQKrZyJok6ahEmIr1xiKggKP7lmmHL8eNo0icpHrtXfzi7Q8Q/PCpzs4dtioXTjaIkS5nNvzVyG/uL+RyuZmpsxrZ5dYM4KbAhchfwORMutxEZhwKBgQC5zpVw4jCEItBmNuTWO+nTScGvxTgfiXIVw+XLaQa2AJoZlhAL34yPWdffko79tv3lgweY9HsimZXO2rU8dbp8mo5c6ydhy8HPXUeWOcAkDSdv/ApWENW9jgYsRIC3swHY3Fl+Dv3Wjce8huQI3mjwaYvRmBhIToxfmHnscVhTBQKBgB9uciEHfz8hMI7ePrPo2PkyK/RbJDm3HnuWE2lFBp7MOUMlh53MXwv4dIRaYMbRrFuN1UIKEFxuKhWwTHSzZJufk/UENrha/81fpj2BoFsAKkEunKeETvaIh6fZSjec16h2+zxbzwkdS6b+yIYkSlaoAxmDYrMtae0C8G4e0YS9";
String pubKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArXYL3H6M2O33v8elJV0fxX3/PsF/vgohtOWFUWnw3vdDvMuSiQDGdeek4GoxFF0kcimagEs+4laDAHLuRanytSrjjnY0wINCxXv7cCGbypgKh3AkktqY1F5NH06WRIEOZZgwitdjINO2F76/gXh4xfpAacESTDzBv/gxgQ2DRTXkUialsqKbesshedvLKAMpByFEO007pbSVeSDwq740UEKxnSf0LQnRNL2YPrQNPZxTewKoK2lPfZCL88ktLKsrI/qT9UiUZk0UhrZVQDt5iC35FznpGZdSg+tBuwhfuwSGmlvNxTw+ebWYQBoZ2yzGMoquzoiMlOtS00XDUmidLQIDAQAB";
rsaSigner signer = new rsaSigner();
Map<String, Object> data = new HashMap<>();
data.put("trade_id","this is trade_id");
data.put("coin","eth");
data.put("txid","this is txid");
data.put("address","this is to address");
data.put("from_address","this is from address");
data.put("time","1591779242");
data.put("amount", "10.1");
data.put("fee","0");
data.put("total","10.1");
data.put("status","1");
data.put("msg","Prompt information");
data.put("type","1");
data.put("gas_fee","0.1");
try {
Map<String, Object> params = new HashMap<>();
params.put("data", data);
params.put("sign", signer.genSign(data, priKey));
Gson gson = new GsonBuilder().create();
System.out.println("params = " + gson.toJson(params));
String res;
// platform request shop callback API
// res = doPost("http://api.shophost.com/withdraw/callback", gson.toJson(params));
// if (null == res) {
// throw new RuntimeException("http error");
// }
// mock response from shop callback API
{
res = """
{
"status":200,
"sign": "A3wCWwcw1w7Ee/xDDWBpf80i2Wc1oqpcqChznv9mr7dgLcKPQAECtemvmRTPwAxsZm6SJeGSN7P3ssB8/wmyZcJiVykr1HWbcQNL/YNYb6MCJqBXpbpnOwaBSWGr+aOh/1ql1ciW04W/rhF8rHch13Se+ZQ1TmJ5/JooEssCxaIRI4EiwGM47cpFSpuMv1e0UMsozCNvudAZDhwh/fDU4eIk2n3qikFEN6uAkG2gN2Y0dseG1/ua1RLYn97lb6oU4cYTpmrlGYZCMzc+cvhDkBL83UsU1hiVYMQtTJ5jtrUe5sumkYuVqkT0VjZklszvKtDDblK/KYXtZ2kRkWn2kg==",
"data":{
"success_data":"success"
}
}
""";
}
System.out.println("response = " + res);
JsonParser jp = new JsonParser();
JsonObject resEle = jp.parse(res).getAsJsonObject();
boolean retSignOK = signer.verifySign(resEle.get("data"), resEle.get("sign").getAsString(), pubKey);
if (!retSignOK) {
throw new RuntimeException("verify response sign fail");
}
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("OK");
}
返回结果示例:
{
"status":200,
"sign": "OTA8utI8y8G93p7RPCyb4qIilFQ0B4Aq4iUjhaXWK9m2kgektqlHOASDKXT2VE7NPNysrGycYlVfjDR2WGZn1G66phHo3qa9CcCNpG9klOBEuBEMjiVbb/d8AXcxEzvQr9OCwNsikyxonyzLiY/lsNHeGm9cC5eRvlNLdUSVBipH+ajPd0lDHCayZPs1eCMfbm/xnf8e2lfy6z0UPOpHGfyX/0+hz99Ir5Xnx+0sBBzyZZJxKm4ROid5aDv/9m9guILpURae+Yw/IrkYF4uAKGX+/44cBvtTRQSdX76CAOBSiywZa6BAgDYBLRtkAPM+i+vwNzFBovqHUvI+4Ponaw==",
"data":{
"success_data":"success"
}
}
- 异步用户提现结果通知功能,提现最终确定成功或失败均通知商户方。
- 其中因商户方原因导致的提现失败,有商户方进行处理,反之有平台方处理。
HTTP Request
POST: 具体回调地址,由商户提供给平台方
请求参数
| 参数名 | 必选 | 类型 | 说明 |
|---|---|---|---|
| data | 否 | string | 如下 |
| data.trade_id | 是 | string | 交易ID |
| data.coin | 是 | string | 币名 |
| data.chain | 是 | string | 主链币名 |
| data.txid | 是 | string | txid |
| data.address | 是 | string | 提现收款地址 |
| data.from_address | 是 | string | 交易出款地址,正式环境2025-01-22之后接入的商户才会返回该属性 |
| data.time | 是 | string | 订单最后更新时间 |
| data.amount | 是 | string | 提现数额,精度统一8位 |
| data.fee | 是 | string | 手续费,精度统一8位 |
| data.total | 是 | string | 提现总额 total=amount+fee,精度统一8位 |
| data.status | 是 | string | 提现状态 : 1 成功;5 出币处理中(此时会推送 txid,但是txid值以最终确认时为准。主要考虑前端展示对用户友好,像btc 类等链交易确认较慢);10 审核不通过;20 转账失败 ;其他错误码(参考错误码说明) |
| data.msg | 是 | string | 状态描述 |
| data.type | 是 | int | 1站内充值 2链上充值 |
| data.gas_fee | 否 | string | 链上消耗Gas费,正式环境2024-08-14接入的商户才会返回该属性,精度统一8位 |
| sign | 是 | string | 对data内数据签名 |
返回参数说明
| 参数名 | 必选 | 类型 | 说明 |
|---|---|---|---|
| status | 是 | int | 状态码 |
| sign | 是 | string | RSA对返回数据的签名 |
| data | 是 | JSONObject | 返回数据对象 |
| data.success_data | 是 | string | success 接收成功 |
- 对于转账失败的情况和处理办法
| 类型 | 内容 | 商户处理办法 |
|---|---|---|
| 成功 | 对应trade_id的status=1 | 商户端可以认为一定成功 |
| 成功后变1 | 因链故障回滚,txid变化。trade_id和状态不变 | 商户端可以认为一定成功,只需更新txid |
| 成功后变2 | 平台广播失败,平台处理 | 商户端可以认为一定成功,只需更新txid |
| 失败1 | 因商户给错地址,把btc地址给了eth | 平台不扣款,这种需要商户端重新请求 |
| 失败2 | 因用户余额不足 | 平台不扣款,这种需要商户端重新请求 |
简单来说:商户端错误导致失败,都有商户端重新请求处理。平台端错误由平台处理。对平台处理来说订单是绝对唯一的。txid是可能会变化的。
* 异步通知时间点
平台端执行发现客户端错误,或平台端确定成功后或成功后变。
兑换
兑换申请
$url = "http://api.xxxx.com/shopapi/exchange/index";
$header = [
'Content-Type:application/json',
];
$params = [
"version" => "1.0",
"app_id" => "hxgmau9imt86qky9",
"time" => 1578736053,
"user_id" => "28",
"source_coin" => "eth",
"target_coin" => "usdt",
"amount" => "0.011",
"trade_id" => "20200114202903274786",
"limit_price" => "5",
"type" => 1,
"max_time" => 5,
"sign" => "dLtK+uiPcnxt2ACKMbBqQ6wI5ttAvesOHzK5ybVID1R6hqYPDTkagl7Tsjr5iLJafehcSLTZyJLtCRI8O2CtIWQUUroGXBneHZC486NUi/4FMOQs0FaAgm17pWlbhX5/96cWXXXMVeoe3IZFKaFNYSWaA14v3RcdDU6QDE/9ixGiSJ0DIxm9NKA0+RkbIFbyYeuFn8d63OcjmUhv7tsOE6rKCc3Q2yi7Qe9i6BNAQFYMFATztb18MsxsBHKUxNqklqyVnl0ofETAHmQhfOHLmungOJQnOqAAuwfmRtg50Qci5F+R2mXeqjmIXko/u3E+DLYW1ygDBp3afKZmU4PwmA=="
];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
$return = curl_exec($ch);
print_r($return);
var url = "http://api.xxxx.com/shopapi/exchange/index"
data := map[string]string{
"version": "1.0",
"app_id": "hxgmau9imt86qky9",
"time": "1578736053",
"sign": "OTA8utI8y8G93p7RPCyb4qIilFQ0B4Aq4iUjhaXWK9m2kgektqlHOASDKXT2VE7NPNysrGycYlVfjDR2WGZn1G66phHo3qa9CcCNpG9klOBEuBEMjiVbb/d8AXcxEzvQr9OCwNsikyxonyzLiY/lsNHeGm9cC5eRvlNLdUSVBipH+ajPd0lDHCayZPs1eCMfbm/xnf8e2lfy6z0UPOpHGfyX/0+hz99Ir5Xnx+0sBBzyZZJxKm4ROid5aDv/9m9guILpURae+Yw/IrkYF4uAKGX+/44cBvtTRQSdX76CAOBSiywZa6BAgDYBLRtkAPM+i+vwNzFBovqHUvI+4Ponaw==",
"user_id":"28",
"source_coin":"eth",
"target_coin":"usdt",
"amount":"0.011",
"trade_id":"20200114202903274786",
"limit_price":"5",
"type":"1",
"max_time":"5",
}
dataType, _ := json.Marshal(data)
resp, err := http.Post(url, "application/json", strings.NewReader(string(dataType)))
if err != nil {
fmt.Println(err)
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Println(err)
}
fmt.Println(string(body))
let HTTP = require('http')
let postData = {
"version": "1.0",
"app_id": "hxgmau9imt86qky9",
"time": "1578736053",
"sign": "OTA8utI8y8G93p7RPCyb4qIilFQ0B4Aq4iUjhaXWK9m2kgektqlHOASDKXT2VE7NPNysrGycYlVfjDR2WGZn1G66phHo3qa9CcCNpG9klOBEuBEMjiVbb/d8AXcxEzvQr9OCwNsikyxonyzLiY/lsNHeGm9cC5eRvlNLdUSVBipH+ajPd0lDHCayZPs1eCMfbm/xnf8e2lfy6z0UPOpHGfyX/0+hz99Ir5Xnx+0sBBzyZZJxKm4ROid5aDv/9m9guILpURae+Yw/IrkYF4uAKGX+/44cBvtTRQSdX76CAOBSiywZa6BAgDYBLRtkAPM+i+vwNzFBovqHUvI+4Ponaw==",
"user_id":"28",
"source_coin":"eth",
"target_coin":"usdt",
"amount":"0.011",
"trade_id":"20200114202903274786",
"limit_price":"5",
"type":"1",
"max_time":"5",
};
let POST_OPTIONS = {
port: 80,
host: "api.xxxx.com",
path: "/shopapi/exchange/index",
method: 'POST',
headers: {
"Content-Type": "application/json; charset=utf-8"
}
};
const REQUEST = HTTP.request(POST_OPTIONS,function (res) {
let data = []
res.on('data', chunk => {
data.push(...chunk)
})
res.on('end', () => {
let _date = JSON.parse( new TextDecoder().decode(new Uint8Array(data)))
console.log(_date)
})
});
REQUEST.setTimeout(6000)
REQUEST.write(JSON.stringify(postData), 'utf8')
REQUEST.end()
public static void main(String[] args) {
// 完整实例请查看"签名规则"中的Java示例代码
String baseUrl = "http://api.xxxx.com/shopapi";
String priKey = "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCtdgvcfozY7fe/x6UlXR/Fff8+wX++CiG05YVRafDe90O8y5KJAMZ156TgajEUXSRyKZqASz7iVoMAcu5FqfK1KuOOdjTAg0LFe/twIZvKmAqHcCSS2pjUXk0fTpZEgQ5lmDCK12Mg07YXvr+BeHjF+kBpwRJMPMG/+DGBDYNFNeRSJqWyopt6yyF528soAykHIUQ7TTultJV5IPCrvjRQQrGdJ/QtCdE0vZg+tA09nFN7AqgraU99kIvzyS0sqysj+pP1SJRmTRSGtlVAO3mILfkXOekZl1KD60G7CF+7BIaaW83FPD55tZhAGhnbLMYyiq7OiIyU61LTRcNSaJ0tAgMBAAECggEBAIGgGKcSzxCBbMYdXLV6TPbZ/HeaRGrwyVWUu7cmc0E8CJu6iWvmb2jGzbiCwuCT5luF6ZZ8JKchvU4FlTfsE5r9TQY2IZ/Ht4s65qBaDUEts5iY3kv8HX9+ZSXDJZpV0ztqqsPmx4ZNj+NYwWXwcFiKdb5R8OmV8bgSsnPddD6wFhwewglUOBPRAjropHE4sqk1Vam6q1MlFq5kiekMn/CItyFYFFzST/ruqAtVTp7YIvazAMrfCKH+pvXWk6pYNHZmL/JZey0GglRyJ1nItiqL33X8Lji056FcbAclidq022h/KPLEJpZk6irWqYdqYZeF6YMLHtdZFDkTZ/hXY+UCgYEA5i794UTQ1Kd6K+iui/S8K5H8nGdiXb3+uZ5j5VKYfbRmzXhAdVYisYe8czeTECxhH+MeHgM4tLR4ifx9q60ylvZxl9Fav1p6EaE36YcvGVmpm7Gm3q6QDDBa4gB+X9u7CxCS4LpotV917YS1QvOIF9lnRonSj1zNzFtbXkywrN8CgYEAwOpx/mR40ZvgZxNCq9DsIdrSZYAFFKpw0xy0OtF1PpuwMaREoRabnlVw6Bb3Hofg50XA3JxemzAX6fB92ee+NfXfeL4UtC4vG1K9JyiXHtHq8p9Uw2W03ehIEeNa3xdoRRnLmD4VUpyfL19ViE2+7TM1Gd3TogjDT+AMOCSuq3MCgYBsurPH7gaq/LVT+mRAzgj4l8v4YUlwuGeTbIMJdvt7HXUWB4CDLH3U2CYnUpAQKrZyJok6ahEmIr1xiKggKP7lmmHL8eNo0icpHrtXfzi7Q8Q/PCpzs4dtioXTjaIkS5nNvzVyG/uL+RyuZmpsxrZ5dYM4KbAhchfwORMutxEZhwKBgQC5zpVw4jCEItBmNuTWO+nTScGvxTgfiXIVw+XLaQa2AJoZlhAL34yPWdffko79tv3lgweY9HsimZXO2rU8dbp8mo5c6ydhy8HPXUeWOcAkDSdv/ApWENW9jgYsRIC3swHY3Fl+Dv3Wjce8huQI3mjwaYvRmBhIToxfmHnscVhTBQKBgB9uciEHfz8hMI7ePrPo2PkyK/RbJDm3HnuWE2lFBp7MOUMlh53MXwv4dIRaYMbRrFuN1UIKEFxuKhWwTHSzZJufk/UENrha/81fpj2BoFsAKkEunKeETvaIh6fZSjec16h2+zxbzwkdS6b+yIYkSlaoAxmDYrMtae0C8G4e0YS9";
String pubKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2RZZISModRzproL3eTxRtvVK/nToDbeLmAVdmaVtHgNCwjXMeNCZvHySZKO7+t7XySzBd2PhhQjvAkDd8HRKB5Y0uvP6TFwvhxOMkMydTeBFcUobQWNeAI7ttRms1txSNrmyrZr0WpWfk79VIsO+yI/jFN/Pj2gxD+vh5UUKU1LD2IQq/VxgtEpf8Vs6w7SvafPwYkpdPGCKUFkRvN1FrY2+tq0j1MRVJbB2rIunWDnT8cDUh2sWLXf4yNaJVOaaTFB0zbAk/qcoicGQyW7bVG7dVW8WywKmOAPeQCCQa+SJ4BhfI1k8eEAwFVRuxz/f9Ecfog9hZJ+RgELkpS8qhQIDAQAB";
rsaSigner signer = new rsaSigner();
Map<String, Object> params = new HashMap<>();
params.put("app_id", "hxgmau9imt86qky9");
params.put("version", "1.0");
params.put("key_version", "admin");
params.put("time", Long.toString(System.currentTimeMillis() / 1000));
params.put("user_id", "28");
params.put("source_coin", "eth");
params.put("target_coin", "usdt");
params.put("amount", "0.011");
params.put("trade_id", "20200114202903274786");
params.put("limit_price", "5");
params.put("type", "1");
params.put("max_time", "5");
try {
params.put("sign", signer.genSign(params, priKey));
Gson gson = new GsonBuilder().create();
System.out.println("params = " + gson.toJson(params));
String res = doPost(baseUrl + "/exchange/index", gson.toJson(params));
if (null == res) {
throw new RuntimeException("http error");
}
System.out.println("response = " + res);
JsonParser jp = new JsonParser();
JsonObject resEle = jp.parse(res).getAsJsonObject();
boolean retSignOK = signer.verifySign(resEle, resEle.get("sign").getAsString(), pubKey);
if (!retSignOK) {
throw new RuntimeException("verify response sign fail");
}
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("OK");
}
返回结果示例:
{
"status":200,
"msg":"请求成功",
"data":{
"trade_id":"2424sfshdrsfsf210"
},
"date_time":"2020-12-29 09:14:10",
"time_stamp":1609204450,
"sign":"folFicr8IuNfZVJe/RO3qbP4nCvmVrQS1+hq8MyK9eVE63KRVe8CNdKjlBzt89buN/weu9fLBtdRk1YgAEUB0ZBd8KcMuzvbuk0WZtW3YKjlPidoQWE9ooSU7HmUJ3larBK4iMGpkXcC+t4ucDy8vnc2s8sQWBBOxuXG22cx3LnXXm9KDXRWkV0T4DnaA65/G7UKPATvwNuQCilwLdyej94CAQnHRoVaSjm27i4EWvr2HcM8q38ceswFNwzQ/UYm54A7OidSwRIkDjs9dC0bFMfJvE8vgsUVX0UYDN9Vs276qC6XkbhBWr3B8HN65lJw7OhxqbnGG1QkNM1AGCso0Q=="
}
商户发起兑换,请求此接口。
HTTP Request
POST: /exchange/index
请求参数
| 参数名 | 必选 | 类型 | 说明 |
|---|---|---|---|
| 公共参数 | 是 | JSON | 公参指:签名(sign)、版本(version)、商户ID(app_id)、时间(time) |
| user_id | 否 | string | 商家用户id (开启风控的商家,为必填项) |
| source_coin | 是 | string | 兑换币 |
| target_coin | 是 | string | 兑换目标币 |
| amount | 是 | string | 兑换币兑换数量 |
| trade_id | 是 | string | 商户端交易唯一ID(长度最多支持 32个字符长度。建议格式:年月日时分秒+6位随机数案列:20200311202903000001) |
| limit_price | 否 | string | 限价(如果type=0,此字段必传)。兑换稳定币时的最低兑换价,或兑换虚拟币时的最高兑换价。 |
| type | 是 | int | 兑换模式(1平仓模式/0一般兑换),默认1。一般兑换在满足最低价格情况下进行挂单,可能会存在部分成功部分失败的情况,在一定时间内未兑换成功,会做撤单处理。平仓模式是一定会挂单成功,不考虑滑点影响,会持续尝试在交易所挂单,不考虑价格。 |
| max_time | 否 | int | 单位秒-最大兑换时间-超过会完成的兑换会停止兑换(一般模式才生效) |
返回参数说明
| 参数名 | 类型 | 说明 |
|---|---|---|
| status | int | 状态码 |
| msg | string | 状态描述 |
| data | jsonObject | |
| data.trade_id | string | trade_id-商户给的 |
| date_time | string | 北京时间 |
| time_stamp | string | 响应时间单位秒 |
| sign | string | 签名-对以上所有参与参数的签名 |
- 该接口返回成功只是接收成功,不代表兑换成功,处理结果以通知接口返回数据为准
兑换账户充值
$url = "http://api.xxxx.com/shopapi/exchange/transfer";
$header = [
'Content-Type:application/json',
];
$params = [
"version" => "1.0",
"app_id" => "hxgmau9imt86qky9",
"time" => "1578736053",
"coin" => "usdt_erc20",
"exchange_coin" => "usdt",
"amount" => "10",
"sign" => "dLtK+uiPcnxt2ACKMbBqQ6wI5ttAvesOHzK5ybVID1R6hqYPDTkagl7Tsjr5iLJafehcSLTZyJLtCRI8O2CtIWQUUroGXBneHZC486NUi/4FMOQs0FaAgm17pWlbhX5/96cWXXXMVeoe3IZFKaFNYSWaA14v3RcdDU6QDE/9ixGiSJ0DIxm9NKA0+RkbIFbyYeuFn8d63OcjmUhv7tsOE6rKCc3Q2yi7Qe9i6BNAQFYMFATztb18MsxsBHKUxNqklqyVnl0ofETAHmQhfOHLmungOJQnOqAAuwfmRtg50Qci5F+R2mXeqjmIXko/u3E+DLYW1ygDBp3afKZmU4PwmA=="
];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
$return = curl_exec($ch);
print_r($return);
var url = "http://api.xxxx.com/shopapi/exchange/transfer"
data := map[string]string{
"version": "1.0",
"app_id": "hxgmau9imt86qky9",
"time": "1578736053",
"sign": "OTA8utI8y8G93p7RPCyb4qIilFQ0B4Aq4iUjhaXWK9m2kgektqlHOASDKXT2VE7NPNysrGycYlVfjDR2WGZn1G66phHo3qa9CcCNpG9klOBEuBEMjiVbb/d8AXcxEzvQr9OCwNsikyxonyzLiY/lsNHeGm9cC5eRvlNLdUSVBipH+ajPd0lDHCayZPs1eCMfbm/xnf8e2lfy6z0UPOpHGfyX/0+hz99Ir5Xnx+0sBBzyZZJxKm4ROid5aDv/9m9guILpURae+Yw/IrkYF4uAKGX+/44cBvtTRQSdX76CAOBSiywZa6BAgDYBLRtkAPM+i+vwNzFBovqHUvI+4Ponaw==",
"coin" : "usdt_erc20",
"exchange_coin" : "usdt",
"amount":"10",
}
dataType, _ := json.Marshal(data)
resp, err := http.Post(url, "application/json", strings.NewReader(string(dataType)))
if err != nil {
fmt.Println(err)
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Println(err)
}
fmt.Println(string(body))
let HTTP = require('http')
let postData = {
"version": "1.0",
"app_id": "hxgmau9imt86qky9",
"time": "1578736053",
"sign": "OTA8utI8y8G93p7RPCyb4qIilFQ0B4Aq4iUjhaXWK9m2kgektqlHOASDKXT2VE7NPNysrGycYlVfjDR2WGZn1G66phHo3qa9CcCNpG9klOBEuBEMjiVbb/d8AXcxEzvQr9OCwNsikyxonyzLiY/lsNHeGm9cC5eRvlNLdUSVBipH+ajPd0lDHCayZPs1eCMfbm/xnf8e2lfy6z0UPOpHGfyX/0+hz99Ir5Xnx+0sBBzyZZJxKm4ROid5aDv/9m9guILpURae+Yw/IrkYF4uAKGX+/44cBvtTRQSdX76CAOBSiywZa6BAgDYBLRtkAPM+i+vwNzFBovqHUvI+4Ponaw==",
"coin":"usdt_erc20",
"exchange_coin":"usdt",
"amount":"10",
};
let POST_OPTIONS = {
port: 80,
host: "api.xxxx.com",
path: "/shopapi/exchange/transfer",
method: 'POST',
headers: {
"Content-Type": "application/json; charset=utf-8"
}
};
const REQUEST = HTTP.request(POST_OPTIONS,function (res) {
let data = []
res.on('data', chunk => {
data.push(...chunk)
})
res.on('end', () => {
let _date = JSON.parse( new TextDecoder().decode(new Uint8Array(data)))
console.log(_date)
})
});
REQUEST.setTimeout(6000)
REQUEST.write(JSON.stringify(postData), 'utf8')
REQUEST.end()
public static void main(String[] args) {
// 完整实例请查看"签名规则"中的Java示例代码
String baseUrl = "http://api.xxxx.com/shopapi";
String priKey = "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCtdgvcfozY7fe/x6UlXR/Fff8+wX++CiG05YVRafDe90O8y5KJAMZ156TgajEUXSRyKZqASz7iVoMAcu5FqfK1KuOOdjTAg0LFe/twIZvKmAqHcCSS2pjUXk0fTpZEgQ5lmDCK12Mg07YXvr+BeHjF+kBpwRJMPMG/+DGBDYNFNeRSJqWyopt6yyF528soAykHIUQ7TTultJV5IPCrvjRQQrGdJ/QtCdE0vZg+tA09nFN7AqgraU99kIvzyS0sqysj+pP1SJRmTRSGtlVAO3mILfkXOekZl1KD60G7CF+7BIaaW83FPD55tZhAGhnbLMYyiq7OiIyU61LTRcNSaJ0tAgMBAAECggEBAIGgGKcSzxCBbMYdXLV6TPbZ/HeaRGrwyVWUu7cmc0E8CJu6iWvmb2jGzbiCwuCT5luF6ZZ8JKchvU4FlTfsE5r9TQY2IZ/Ht4s65qBaDUEts5iY3kv8HX9+ZSXDJZpV0ztqqsPmx4ZNj+NYwWXwcFiKdb5R8OmV8bgSsnPddD6wFhwewglUOBPRAjropHE4sqk1Vam6q1MlFq5kiekMn/CItyFYFFzST/ruqAtVTp7YIvazAMrfCKH+pvXWk6pYNHZmL/JZey0GglRyJ1nItiqL33X8Lji056FcbAclidq022h/KPLEJpZk6irWqYdqYZeF6YMLHtdZFDkTZ/hXY+UCgYEA5i794UTQ1Kd6K+iui/S8K5H8nGdiXb3+uZ5j5VKYfbRmzXhAdVYisYe8czeTECxhH+MeHgM4tLR4ifx9q60ylvZxl9Fav1p6EaE36YcvGVmpm7Gm3q6QDDBa4gB+X9u7CxCS4LpotV917YS1QvOIF9lnRonSj1zNzFtbXkywrN8CgYEAwOpx/mR40ZvgZxNCq9DsIdrSZYAFFKpw0xy0OtF1PpuwMaREoRabnlVw6Bb3Hofg50XA3JxemzAX6fB92ee+NfXfeL4UtC4vG1K9JyiXHtHq8p9Uw2W03ehIEeNa3xdoRRnLmD4VUpyfL19ViE2+7TM1Gd3TogjDT+AMOCSuq3MCgYBsurPH7gaq/LVT+mRAzgj4l8v4YUlwuGeTbIMJdvt7HXUWB4CDLH3U2CYnUpAQKrZyJok6ahEmIr1xiKggKP7lmmHL8eNo0icpHrtXfzi7Q8Q/PCpzs4dtioXTjaIkS5nNvzVyG/uL+RyuZmpsxrZ5dYM4KbAhchfwORMutxEZhwKBgQC5zpVw4jCEItBmNuTWO+nTScGvxTgfiXIVw+XLaQa2AJoZlhAL34yPWdffko79tv3lgweY9HsimZXO2rU8dbp8mo5c6ydhy8HPXUeWOcAkDSdv/ApWENW9jgYsRIC3swHY3Fl+Dv3Wjce8huQI3mjwaYvRmBhIToxfmHnscVhTBQKBgB9uciEHfz8hMI7ePrPo2PkyK/RbJDm3HnuWE2lFBp7MOUMlh53MXwv4dIRaYMbRrFuN1UIKEFxuKhWwTHSzZJufk/UENrha/81fpj2BoFsAKkEunKeETvaIh6fZSjec16h2+zxbzwkdS6b+yIYkSlaoAxmDYrMtae0C8G4e0YS9";
String pubKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2RZZISModRzproL3eTxRtvVK/nToDbeLmAVdmaVtHgNCwjXMeNCZvHySZKO7+t7XySzBd2PhhQjvAkDd8HRKB5Y0uvP6TFwvhxOMkMydTeBFcUobQWNeAI7ttRms1txSNrmyrZr0WpWfk79VIsO+yI/jFN/Pj2gxD+vh5UUKU1LD2IQq/VxgtEpf8Vs6w7SvafPwYkpdPGCKUFkRvN1FrY2+tq0j1MRVJbB2rIunWDnT8cDUh2sWLXf4yNaJVOaaTFB0zbAk/qcoicGQyW7bVG7dVW8WywKmOAPeQCCQa+SJ4BhfI1k8eEAwFVRuxz/f9Ecfog9hZJ+RgELkpS8qhQIDAQAB";
rsaSigner signer = new rsaSigner();
Map<String, Object> params = new HashMap<>();
params.put("app_id", "hxgmau9imt86qky9");
params.put("version", "1.0");
params.put("key_version", "admin");
params.put("time", Long.toString(System.currentTimeMillis() / 1000));
params.put("coin", "usdt_erc20");
params.put("exchange_coin", "usdt");
params.put("amount", "10");
try {
params.put("sign", signer.genSign(params, priKey));
Gson gson = new GsonBuilder().create();
System.out.println("params = " + gson.toJson(params));
String res = doPost(baseUrl + "/exchange/transfer", gson.toJson(params));
if (null == res) {
throw new RuntimeException("http error");
}
System.out.println("response = " + res);
JsonParser jp = new JsonParser();
JsonObject resEle = jp.parse(res).getAsJsonObject();
boolean retSignOK = signer.verifySign(resEle, resEle.get("sign").getAsString(), pubKey);
if (!retSignOK) {
throw new RuntimeException("verify response sign fail");
}
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("OK");
}
返回结果示例:
{
"status": 200,
"msg": "请求成功",
"data": [],
"date_time": "2021-08-20 15:44:25",
"time_stamp": 1629445465,
"sign": "lRQQoEIc5B9ZwYoTCW3B58M+3GB17wUwTX+SmaOQ9iofK3Vs9RIb4TWzwtpOLZyGls2Ixe6s6MDSZZufjjqiqnSrgx1vqd5k3BkVLeHKJJmPWb8aXBT55qjlqifF7tRWCJJ8ToboBOWaJldWnvJgyQxwgdcGKUR/G2IVlIBddLdUkRlIf+hDqZAqboMU8b9k5tra3iIgIF0AMFrjYas4MeKxHDrnTZr9dJkKqJqWHOdn3cYkkxK9I27s+ZEOHVNhezS/tpwKm9pOJeNdIUPzumnUT7rkd2dSrimlokR85cC48qrqZehoz3lj6Rua4ravWmz0nr8mPLodnkKOerF3qA=="
}
兑换账户充值的资金是由热钱包地址转出到兑换账户
HTTP Request
POST: /exchange/transfer
请求参数
| 参数名 | 必选 | 类型 | 说明 |
|---|---|---|---|
| 公共参数 | 是 | JSON | 公参指:签名(sign)、版本(version)、商户ID(app_id)、时间(time) |
| coin | 是 | string | 热钱包币种,如:usdt_erc20、usdt_trc20 |
| exchange_coin | 是 | string | 兑换账户币种,如:usdt |
| amount | 是 | string | 充值金额 |
返回参数说明
| 参数名 | 类型 | 说明 |
|---|---|---|
| status | int | 状态码 |
| msg | string | 状态描述 |
| data | jsonObject | |
| date_time | string | 北京时间 |
| time_stamp | string | 响应时间单位秒 |
| sign | string | 签名-对以上所有参与参数的签名 |
兑换汇率
$url = "http://api.xxxx.com/shopapi/rate/exchange";
$header = [
'Content-Type:application/json',
];
$params = [
"version" => "1.0",
"app_id" => "hxgmau9imt86qky9",
"time" => "1578736053",
"source_coin" => "eth",
"target_coin" => "usdt",
"amount" => "10",
"sign" => "dLtK+uiPcnxt2ACKMbBqQ6wI5ttAvesOHzK5ybVID1R6hqYPDTkagl7Tsjr5iLJafehcSLTZyJLtCRI8O2CtIWQUUroGXBneHZC486NUi/4FMOQs0FaAgm17pWlbhX5/96cWXXXMVeoe3IZFKaFNYSWaA14v3RcdDU6QDE/9ixGiSJ0DIxm9NKA0+RkbIFbyYeuFn8d63OcjmUhv7tsOE6rKCc3Q2yi7Qe9i6BNAQFYMFATztb18MsxsBHKUxNqklqyVnl0ofETAHmQhfOHLmungOJQnOqAAuwfmRtg50Qci5F+R2mXeqjmIXko/u3E+DLYW1ygDBp3afKZmU4PwmA=="
];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
$return = curl_exec($ch);
print_r($return);
var url = "http://api.xxxx.com/shopapi/rate/exchange"
data := map[string]string{
"version": "1.0",
"app_id": "hxgmau9imt86qky9",
"time": "1578736053",
"sign": "OTA8utI8y8G93p7RPCyb4qIilFQ0B4Aq4iUjhaXWK9m2kgektqlHOASDKXT2VE7NPNysrGycYlVfjDR2WGZn1G66phHo3qa9CcCNpG9klOBEuBEMjiVbb/d8AXcxEzvQr9OCwNsikyxonyzLiY/lsNHeGm9cC5eRvlNLdUSVBipH+ajPd0lDHCayZPs1eCMfbm/xnf8e2lfy6z0UPOpHGfyX/0+hz99Ir5Xnx+0sBBzyZZJxKm4ROid5aDv/9m9guILpURae+Yw/IrkYF4uAKGX+/44cBvtTRQSdX76CAOBSiywZa6BAgDYBLRtkAPM+i+vwNzFBovqHUvI+4Ponaw==",
"source_coin":"eth",
"target_coin":"usdt",
"amount":"10",
}
dataType, _ := json.Marshal(data)
resp, err := http.Post(url, "application/json", strings.NewReader(string(dataType)))
if err != nil {
fmt.Println(err)
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Println(err)
}
fmt.Println(string(body))
let HTTP = require('http')
let postData = {
"version": "1.0",
"app_id": "hxgmau9imt86qky9",
"time": "1578736053",
"sign": "OTA8utI8y8G93p7RPCyb4qIilFQ0B4Aq4iUjhaXWK9m2kgektqlHOASDKXT2VE7NPNysrGycYlVfjDR2WGZn1G66phHo3qa9CcCNpG9klOBEuBEMjiVbb/d8AXcxEzvQr9OCwNsikyxonyzLiY/lsNHeGm9cC5eRvlNLdUSVBipH+ajPd0lDHCayZPs1eCMfbm/xnf8e2lfy6z0UPOpHGfyX/0+hz99Ir5Xnx+0sBBzyZZJxKm4ROid5aDv/9m9guILpURae+Yw/IrkYF4uAKGX+/44cBvtTRQSdX76CAOBSiywZa6BAgDYBLRtkAPM+i+vwNzFBovqHUvI+4Ponaw==",
"source_coin":"eth",
"target_coin":"usdt",
"amount":"10",
};
let POST_OPTIONS = {
port: 80,
host: "api.xxxx.com",
path: "/shopapi/rate/exchange",
method: 'POST',
headers: {
"Content-Type": "application/json; charset=utf-8"
}
};
const REQUEST = HTTP.request(POST_OPTIONS,function (res) {
let data = []
res.on('data', chunk => {
data.push(...chunk)
})
res.on('end', () => {
let _date = JSON.parse( new TextDecoder().decode(new Uint8Array(data)))
console.log(_date)
})
});
REQUEST.setTimeout(6000)
REQUEST.write(JSON.stringify(postData), 'utf8')
REQUEST.end()
public static void main(String[] args) {
// 完整实例请查看"签名规则"中的Java示例代码
String baseUrl = "http://api.xxxx.com/shopapi";
String priKey = "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCtdgvcfozY7fe/x6UlXR/Fff8+wX++CiG05YVRafDe90O8y5KJAMZ156TgajEUXSRyKZqASz7iVoMAcu5FqfK1KuOOdjTAg0LFe/twIZvKmAqHcCSS2pjUXk0fTpZEgQ5lmDCK12Mg07YXvr+BeHjF+kBpwRJMPMG/+DGBDYNFNeRSJqWyopt6yyF528soAykHIUQ7TTultJV5IPCrvjRQQrGdJ/QtCdE0vZg+tA09nFN7AqgraU99kIvzyS0sqysj+pP1SJRmTRSGtlVAO3mILfkXOekZl1KD60G7CF+7BIaaW83FPD55tZhAGhnbLMYyiq7OiIyU61LTRcNSaJ0tAgMBAAECggEBAIGgGKcSzxCBbMYdXLV6TPbZ/HeaRGrwyVWUu7cmc0E8CJu6iWvmb2jGzbiCwuCT5luF6ZZ8JKchvU4FlTfsE5r9TQY2IZ/Ht4s65qBaDUEts5iY3kv8HX9+ZSXDJZpV0ztqqsPmx4ZNj+NYwWXwcFiKdb5R8OmV8bgSsnPddD6wFhwewglUOBPRAjropHE4sqk1Vam6q1MlFq5kiekMn/CItyFYFFzST/ruqAtVTp7YIvazAMrfCKH+pvXWk6pYNHZmL/JZey0GglRyJ1nItiqL33X8Lji056FcbAclidq022h/KPLEJpZk6irWqYdqYZeF6YMLHtdZFDkTZ/hXY+UCgYEA5i794UTQ1Kd6K+iui/S8K5H8nGdiXb3+uZ5j5VKYfbRmzXhAdVYisYe8czeTECxhH+MeHgM4tLR4ifx9q60ylvZxl9Fav1p6EaE36YcvGVmpm7Gm3q6QDDBa4gB+X9u7CxCS4LpotV917YS1QvOIF9lnRonSj1zNzFtbXkywrN8CgYEAwOpx/mR40ZvgZxNCq9DsIdrSZYAFFKpw0xy0OtF1PpuwMaREoRabnlVw6Bb3Hofg50XA3JxemzAX6fB92ee+NfXfeL4UtC4vG1K9JyiXHtHq8p9Uw2W03ehIEeNa3xdoRRnLmD4VUpyfL19ViE2+7TM1Gd3TogjDT+AMOCSuq3MCgYBsurPH7gaq/LVT+mRAzgj4l8v4YUlwuGeTbIMJdvt7HXUWB4CDLH3U2CYnUpAQKrZyJok6ahEmIr1xiKggKP7lmmHL8eNo0icpHrtXfzi7Q8Q/PCpzs4dtioXTjaIkS5nNvzVyG/uL+RyuZmpsxrZ5dYM4KbAhchfwORMutxEZhwKBgQC5zpVw4jCEItBmNuTWO+nTScGvxTgfiXIVw+XLaQa2AJoZlhAL34yPWdffko79tv3lgweY9HsimZXO2rU8dbp8mo5c6ydhy8HPXUeWOcAkDSdv/ApWENW9jgYsRIC3swHY3Fl+Dv3Wjce8huQI3mjwaYvRmBhIToxfmHnscVhTBQKBgB9uciEHfz8hMI7ePrPo2PkyK/RbJDm3HnuWE2lFBp7MOUMlh53MXwv4dIRaYMbRrFuN1UIKEFxuKhWwTHSzZJufk/UENrha/81fpj2BoFsAKkEunKeETvaIh6fZSjec16h2+zxbzwkdS6b+yIYkSlaoAxmDYrMtae0C8G4e0YS9";
String pubKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2RZZISModRzproL3eTxRtvVK/nToDbeLmAVdmaVtHgNCwjXMeNCZvHySZKO7+t7XySzBd2PhhQjvAkDd8HRKB5Y0uvP6TFwvhxOMkMydTeBFcUobQWNeAI7ttRms1txSNrmyrZr0WpWfk79VIsO+yI/jFN/Pj2gxD+vh5UUKU1LD2IQq/VxgtEpf8Vs6w7SvafPwYkpdPGCKUFkRvN1FrY2+tq0j1MRVJbB2rIunWDnT8cDUh2sWLXf4yNaJVOaaTFB0zbAk/qcoicGQyW7bVG7dVW8WywKmOAPeQCCQa+SJ4BhfI1k8eEAwFVRuxz/f9Ecfog9hZJ+RgELkpS8qhQIDAQAB";
rsaSigner signer = new rsaSigner();
Map<String, Object> params = new HashMap<>();
params.put("app_id", "hxgmau9imt86qky9");
params.put("version", "1.0");
params.put("key_version", "admin");
params.put("time", Long.toString(System.currentTimeMillis() / 1000));
params.put("source_coin", "eth");
params.put("target_coin", "usdt");
params.put("amount", "0.011");
try {
params.put("sign", signer.genSign(params, priKey));
Gson gson = new GsonBuilder().create();
System.out.println("params = " + gson.toJson(params));
String res = doPost(baseUrl + "/rate/exchange", gson.toJson(params));
if (null == res) {
throw new RuntimeException("http error");
}
System.out.println("response = " + res);
JsonParser jp = new JsonParser();
JsonObject resEle = jp.parse(res).getAsJsonObject();
boolean retSignOK = signer.verifySign(resEle, resEle.get("sign").getAsString(), pubKey);
if (!retSignOK) {
throw new RuntimeException("verify response sign fail");
}
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("OK");
}
返回结果示例:
{
"status": 200,
"msg": "请求成功",
"data": {
"rate": "3233.688",
"max": "20",
"min": "15",
"source_unit": "4",
"base_coin": "usdt"
},
"date_time": "2021-08-20 15:44:25",
"time_stamp": 1629445465,
"sign": "lRQQoEIc5B9ZwYoTCW3B58M+3GB17wUwTX+SmaOQ9iofK3Vs9RIb4TWzwtpOLZyGls2Ixe6s6MDSZZufjjqiqnSrgx1vqd5k3BkVLeHKJJmPWb8aXBT55qjlqifF7tRWCJJ8ToboBOWaJldWnvJgyQxwgdcGKUR/G2IVlIBddLdUkRlIf+hDqZAqboMU8b9k5tra3iIgIF0AMFrjYas4MeKxHDrnTZr9dJkKqJqWHOdn3cYkkxK9I27s+ZEOHVNhezS/tpwKm9pOJeNdIUPzumnUT7rkd2dSrimlokR85cC48qrqZehoz3lj6Rua4ravWmz0nr8mPLodnkKOerF3qA=="
}
兑换前 ,查询兑换汇率。
HTTP Request
POST: /rate/exchange
请求参数
| 参数名 | 必选 | 类型 | 说明 |
|---|---|---|---|
| 公共参数 | 是 | JSON | 公参指:签名(sign)、版本(version)、商户ID(app_id)、时间(time) |
| source_coin | 是 | string | 兑换币 |
| target_coin | 是 | string | 兑换目标币 |
| amount | 是 | string | 兑换币兑换数量 |
返回参数说明
| 参数名 | 类型 | 说明 |
|---|---|---|
| status | int | 状态码 |
| msg | string | 状态描述 |
| data | jsonObject | |
| data.rate | string | 其他币对应usdt的兑换汇率 |
| data.max | string | 兑换币最大支持单笔兑换数量 |
| data.min | string | 兑换币最小支持单笔兑换数量 |
| data.source_unit | int | 支持兑换币小数位长度(值如4, 表示最多支持4个小数位) |
| data.base_coin | string | 基准币种,交易区支持公链作为交易价格的基准币种 |
| date_time | string | 北京时间 |
| time_stamp | string | 响应时间单位秒 |
| sign | string | 签名-对以上所有参与参数的签名 |
批量查询兑换汇率
$url = "http://api.xxxx.com/shopapi/rate/exchange_batch";
$header = [
'Content-Type:application/json',
];
$params = [
"version" => "1.0",
"app_id" => "hxgmau9imt86qky9",
"time" => "1578736053",
"source_coin" => "eth",
"target_coin" => "usdt",
"amount" => "10",
"sign" => "dLtK+uiPcnxt2ACKMbBqQ6wI5ttAvesOHzK5ybVID1R6hqYPDTkagl7Tsjr5iLJafehcSLTZyJLtCRI8O2CtIWQUUroGXBneHZC486NUi/4FMOQs0FaAgm17pWlbhX5/96cWXXXMVeoe3IZFKaFNYSWaA14v3RcdDU6QDE/9ixGiSJ0DIxm9NKA0+RkbIFbyYeuFn8d63OcjmUhv7tsOE6rKCc3Q2yi7Qe9i6BNAQFYMFATztb18MsxsBHKUxNqklqyVnl0ofETAHmQhfOHLmungOJQnOqAAuwfmRtg50Qci5F+R2mXeqjmIXko/u3E+DLYW1ygDBp3afKZmU4PwmA=="
];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
$return = curl_exec($ch);
print_r($return);
var url = "http://api.xxxx.com/shopapi/rate/exchange_batch"
data := map[string]string{
"version": "1.0",
"app_id": "hxgmau9imt86qky9",
"time": "1578736053",
"sign": "OTA8utI8y8G93p7RPCyb4qIilFQ0B4Aq4iUjhaXWK9m2kgektqlHOASDKXT2VE7NPNysrGycYlVfjDR2WGZn1G66phHo3qa9CcCNpG9klOBEuBEMjiVbb/d8AXcxEzvQr9OCwNsikyxonyzLiY/lsNHeGm9cC5eRvlNLdUSVBipH+ajPd0lDHCayZPs1eCMfbm/xnf8e2lfy6z0UPOpHGfyX/0+hz99Ir5Xnx+0sBBzyZZJxKm4ROid5aDv/9m9guILpURae+Yw/IrkYF4uAKGX+/44cBvtTRQSdX76CAOBSiywZa6BAgDYBLRtkAPM+i+vwNzFBovqHUvI+4Ponaw==",
"source_coin":"eth",
"target_coin":"usdt",
"amount":"10",
}
dataType, _ := json.Marshal(data)
resp, err := http.Post(url, "application/json", strings.NewReader(string(dataType)))
if err != nil {
fmt.Println(err)
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Println(err)
}
fmt.Println(string(body))
let HTTP = require('http')
let postData = {
"version": "1.0",
"app_id": "hxgmau9imt86qky9",
"time": "1578736053",
"sign": "OTA8utI8y8G93p7RPCyb4qIilFQ0B4Aq4iUjhaXWK9m2kgektqlHOASDKXT2VE7NPNysrGycYlVfjDR2WGZn1G66phHo3qa9CcCNpG9klOBEuBEMjiVbb/d8AXcxEzvQr9OCwNsikyxonyzLiY/lsNHeGm9cC5eRvlNLdUSVBipH+ajPd0lDHCayZPs1eCMfbm/xnf8e2lfy6z0UPOpHGfyX/0+hz99Ir5Xnx+0sBBzyZZJxKm4ROid5aDv/9m9guILpURae+Yw/IrkYF4uAKGX+/44cBvtTRQSdX76CAOBSiywZa6BAgDYBLRtkAPM+i+vwNzFBovqHUvI+4Ponaw==",
"source_coin":"eth",
"target_coin":"usdt",
"amount":"10",
};
let POST_OPTIONS = {
port: 80,
host: "api.xxxx.com",
path: "/shopapi/rate/exchange_batch",
method: 'POST',
headers: {
"Content-Type": "application/json; charset=utf-8"
}
};
const REQUEST = HTTP.request(POST_OPTIONS,function (res) {
let data = []
res.on('data', chunk => {
data.push(...chunk)
})
res.on('end', () => {
let _date = JSON.parse( new TextDecoder().decode(new Uint8Array(data)))
console.log(_date)
})
});
REQUEST.setTimeout(6000)
REQUEST.write(JSON.stringify(postData), 'utf8')
REQUEST.end()
public static void main(String[] args) {
// 完整实例请查看"签名规则"中的Java示例代码
String baseUrl = "http://api.xxxx.com/shopapi";
String priKey = "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCtdgvcfozY7fe/x6UlXR/Fff8+wX++CiG05YVRafDe90O8y5KJAMZ156TgajEUXSRyKZqASz7iVoMAcu5FqfK1KuOOdjTAg0LFe/twIZvKmAqHcCSS2pjUXk0fTpZEgQ5lmDCK12Mg07YXvr+BeHjF+kBpwRJMPMG/+DGBDYNFNeRSJqWyopt6yyF528soAykHIUQ7TTultJV5IPCrvjRQQrGdJ/QtCdE0vZg+tA09nFN7AqgraU99kIvzyS0sqysj+pP1SJRmTRSGtlVAO3mILfkXOekZl1KD60G7CF+7BIaaW83FPD55tZhAGhnbLMYyiq7OiIyU61LTRcNSaJ0tAgMBAAECggEBAIGgGKcSzxCBbMYdXLV6TPbZ/HeaRGrwyVWUu7cmc0E8CJu6iWvmb2jGzbiCwuCT5luF6ZZ8JKchvU4FlTfsE5r9TQY2IZ/Ht4s65qBaDUEts5iY3kv8HX9+ZSXDJZpV0ztqqsPmx4ZNj+NYwWXwcFiKdb5R8OmV8bgSsnPddD6wFhwewglUOBPRAjropHE4sqk1Vam6q1MlFq5kiekMn/CItyFYFFzST/ruqAtVTp7YIvazAMrfCKH+pvXWk6pYNHZmL/JZey0GglRyJ1nItiqL33X8Lji056FcbAclidq022h/KPLEJpZk6irWqYdqYZeF6YMLHtdZFDkTZ/hXY+UCgYEA5i794UTQ1Kd6K+iui/S8K5H8nGdiXb3+uZ5j5VKYfbRmzXhAdVYisYe8czeTECxhH+MeHgM4tLR4ifx9q60ylvZxl9Fav1p6EaE36YcvGVmpm7Gm3q6QDDBa4gB+X9u7CxCS4LpotV917YS1QvOIF9lnRonSj1zNzFtbXkywrN8CgYEAwOpx/mR40ZvgZxNCq9DsIdrSZYAFFKpw0xy0OtF1PpuwMaREoRabnlVw6Bb3Hofg50XA3JxemzAX6fB92ee+NfXfeL4UtC4vG1K9JyiXHtHq8p9Uw2W03ehIEeNa3xdoRRnLmD4VUpyfL19ViE2+7TM1Gd3TogjDT+AMOCSuq3MCgYBsurPH7gaq/LVT+mRAzgj4l8v4YUlwuGeTbIMJdvt7HXUWB4CDLH3U2CYnUpAQKrZyJok6ahEmIr1xiKggKP7lmmHL8eNo0icpHrtXfzi7Q8Q/PCpzs4dtioXTjaIkS5nNvzVyG/uL+RyuZmpsxrZ5dYM4KbAhchfwORMutxEZhwKBgQC5zpVw4jCEItBmNuTWO+nTScGvxTgfiXIVw+XLaQa2AJoZlhAL34yPWdffko79tv3lgweY9HsimZXO2rU8dbp8mo5c6ydhy8HPXUeWOcAkDSdv/ApWENW9jgYsRIC3swHY3Fl+Dv3Wjce8huQI3mjwaYvRmBhIToxfmHnscVhTBQKBgB9uciEHfz8hMI7ePrPo2PkyK/RbJDm3HnuWE2lFBp7MOUMlh53MXwv4dIRaYMbRrFuN1UIKEFxuKhWwTHSzZJufk/UENrha/81fpj2BoFsAKkEunKeETvaIh6fZSjec16h2+zxbzwkdS6b+yIYkSlaoAxmDYrMtae0C8G4e0YS9";
String pubKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2RZZISModRzproL3eTxRtvVK/nToDbeLmAVdmaVtHgNCwjXMeNCZvHySZKO7+t7XySzBd2PhhQjvAkDd8HRKB5Y0uvP6TFwvhxOMkMydTeBFcUobQWNeAI7ttRms1txSNrmyrZr0WpWfk79VIsO+yI/jFN/Pj2gxD+vh5UUKU1LD2IQq/VxgtEpf8Vs6w7SvafPwYkpdPGCKUFkRvN1FrY2+tq0j1MRVJbB2rIunWDnT8cDUh2sWLXf4yNaJVOaaTFB0zbAk/qcoicGQyW7bVG7dVW8WywKmOAPeQCCQa+SJ4BhfI1k8eEAwFVRuxz/f9Ecfog9hZJ+RgELkpS8qhQIDAQAB";
rsaSigner signer = new rsaSigner();
Map<String, Object> params = new HashMap<>();
params.put("app_id", "hxgmau9imt86qky9");
params.put("version", "1.0");
params.put("key_version", "admin");
params.put("time", Long.toString(System.currentTimeMillis() / 1000));
try {
params.put("sign", signer.genSign(params, priKey));
Gson gson = new GsonBuilder().create();
System.out.println("params = " + gson.toJson(params));
String res = doPost(baseUrl + "/rate/exchange_batch", gson.toJson(params));
if (null == res) {
throw new RuntimeException("http error");
}
System.out.println("response = " + res);
JsonParser jp = new JsonParser();
JsonObject resEle = jp.parse(res).getAsJsonObject();
boolean retSignOK = signer.verifySign(resEle, resEle.get("sign").getAsString(), pubKey);
if (!retSignOK) {
throw new RuntimeException("verify response sign fail");
}
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("OK");
}
返回结果示例:
{
"status": 200,
"msg": "请求成功",
"data": [
{
"source_coin": "eth",
"target_coin": "usdt",
"rate": 3198.707676,
"max": 0,
"min": 0,
"source_unit": 4,
"base_coin": "usdt"
},
{
"source_coin": "usdt",
"target_coin": "eth",
"rate": 3231.075,
"max": 20,
"min": 15,
"source_unit": 4,
"base_coin": "usdt"
}
],
"date_time": "2021-08-20 15:47:52",
"time_stamp": 1629445672,
"sign": "Jjkpqtjw6oITCvxpIcEDC0EQfhKjDfWQKcnxRqDYOHqCB3oXl7GDHFEQ3g7JFc3g8tW2XQRaQldCnNXd1jw9gddZRUWimULPSiOrdaCYn5wxLBLGTf4bHX//P34ZBrNa45APCURqk26U68ZzQmnmcpzH8te1WOiey2WnCkSABVkBEeMwLjsM8pO3kmiWx5ZQ+hVQqHO6wONRsIToMisDKgr/4YzcxB3fAuY+7J5Ns3ZTrBTKPxg6Idy41sIi0sSjssXFD/mVBt6sIRaD/JknOwCdwCE5a8rVMWT7wPbQdaCDSgNMnjit14x1665a6tNG8S6IC+o/pn4dgVk9rCqVHA=="
}
HTTP Request
POST: /rate/exchange_batch
请求参数
| 参数名 | 必选 | 类型 | 说明 |
|---|---|---|---|
| 公共参数 | 是 | JSON | 公参指:签名(sign)、版本(version)、商户ID(app_id)、时间(time) |
返回参数说明
| 参数名 | 类型 | 说明 |
|---|---|---|
| status | int | 状态码 |
| msg | string | 状态描述 |
| data | jsonObject | |
| data.rate | string | 其他币对应usdt的兑换汇率 |
| data.max | string | 兑换币最大支持单笔兑换数量 |
| data.min | string | 兑换币最小支持单笔兑换数量 |
| data.source_unit | int | 支持兑换币小数位长度(值如4, 表示最多支持4个小数位) |
| data.base_coin | string | 基准币种,交易区支持公链作为交易价格的基准币种 |
| data.source_coin | string | 兑换币 |
| data.target_coin | string | 目标币 |
| date_time | string | 北京时间 |
| time_stamp | string | 响应时间单位秒 |
| sign | string | 签名-对以上所有参与参数的签名 |
兑换余额查询
$url = "http://api.xxxx.com/shopapi/balance/exchange";
$header = [
'Content-Type:application/json',
];
$params = [
"version" => "1.0",
"app_id" => "hxgmau9imt86qky9",
"time" => "1578736053",
"coin" =>"eth",
"sign" => "dLtK+uiPcnxt2ACKMbBqQ6wI5ttAvesOHzK5ybVID1R6hqYPDTkagl7Tsjr5iLJafehcSLTZyJLtCRI8O2CtIWQUUroGXBneHZC486NUi/4FMOQs0FaAgm17pWlbhX5/96cWXXXMVeoe3IZFKaFNYSWaA14v3RcdDU6QDE/9ixGiSJ0DIxm9NKA0+RkbIFbyYeuFn8d63OcjmUhv7tsOE6rKCc3Q2yi7Qe9i6BNAQFYMFATztb18MsxsBHKUxNqklqyVnl0ofETAHmQhfOHLmungOJQnOqAAuwfmRtg50Qci5F+R2mXeqjmIXko/u3E+DLYW1ygDBp3afKZmU4PwmA=="
];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
$return = curl_exec($ch);
print_r($return);
var url = "http://api.xxxx.com/shopapi/balance/exchange"
data := map[string]string{
"version": "1.0",
"app_id": "hxgmau9imt86qky9",
"time": "1578736053",
"sign": "OTA8utI8y8G93p7RPCyb4qIilFQ0B4Aq4iUjhaXWK9m2kgektqlHOASDKXT2VE7NPNysrGycYlVfjDR2WGZn1G66phHo3qa9CcCNpG9klOBEuBEMjiVbb/d8AXcxEzvQr9OCwNsikyxonyzLiY/lsNHeGm9cC5eRvlNLdUSVBipH+ajPd0lDHCayZPs1eCMfbm/xnf8e2lfy6z0UPOpHGfyX/0+hz99Ir5Xnx+0sBBzyZZJxKm4ROid5aDv/9m9guILpURae+Yw/IrkYF4uAKGX+/44cBvtTRQSdX76CAOBSiywZa6BAgDYBLRtkAPM+i+vwNzFBovqHUvI+4Ponaw==",
"coin":"eth",
}
dataType, _ := json.Marshal(data)
resp, err := http.Post(url, "application/json", strings.NewReader(string(dataType)))
if err != nil {
fmt.Println(err)
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Println(err)
}
fmt.Println(string(body))
let HTTP = require('http')
let postData = {
"version": "1.0",
"app_id": "hxgmau9imt86qky9",
"time": "1578736053",
"sign": "OTA8utI8y8G93p7RPCyb4qIilFQ0B4Aq4iUjhaXWK9m2kgektqlHOASDKXT2VE7NPNysrGycYlVfjDR2WGZn1G66phHo3qa9CcCNpG9klOBEuBEMjiVbb/d8AXcxEzvQr9OCwNsikyxonyzLiY/lsNHeGm9cC5eRvlNLdUSVBipH+ajPd0lDHCayZPs1eCMfbm/xnf8e2lfy6z0UPOpHGfyX/0+hz99Ir5Xnx+0sBBzyZZJxKm4ROid5aDv/9m9guILpURae+Yw/IrkYF4uAKGX+/44cBvtTRQSdX76CAOBSiywZa6BAgDYBLRtkAPM+i+vwNzFBovqHUvI+4Ponaw==",
"coin":"eth",
};
let POST_OPTIONS = {
port: 80,
host: "api.xxxx.com",
path: "/shopapi/balance/exchange",
method: 'POST',
headers: {
"Content-Type": "application/json; charset=utf-8"
}
};
const REQUEST = HTTP.request(POST_OPTIONS,function (res) {
let data = []
res.on('data', chunk => {
data.push(...chunk)
})
res.on('end', () => {
let _date = JSON.parse( new TextDecoder().decode(new Uint8Array(data)))
console.log(_date)
})
});
REQUEST.setTimeout(6000)
REQUEST.write(JSON.stringify(postData), 'utf8')
REQUEST.end()
public static void main(String[] args) {
// 完整实例请查看"签名规则"中的Java示例代码
String baseUrl = "http://api.xxxx.com/shopapi";
String priKey = "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCtdgvcfozY7fe/x6UlXR/Fff8+wX++CiG05YVRafDe90O8y5KJAMZ156TgajEUXSRyKZqASz7iVoMAcu5FqfK1KuOOdjTAg0LFe/twIZvKmAqHcCSS2pjUXk0fTpZEgQ5lmDCK12Mg07YXvr+BeHjF+kBpwRJMPMG/+DGBDYNFNeRSJqWyopt6yyF528soAykHIUQ7TTultJV5IPCrvjRQQrGdJ/QtCdE0vZg+tA09nFN7AqgraU99kIvzyS0sqysj+pP1SJRmTRSGtlVAO3mILfkXOekZl1KD60G7CF+7BIaaW83FPD55tZhAGhnbLMYyiq7OiIyU61LTRcNSaJ0tAgMBAAECggEBAIGgGKcSzxCBbMYdXLV6TPbZ/HeaRGrwyVWUu7cmc0E8CJu6iWvmb2jGzbiCwuCT5luF6ZZ8JKchvU4FlTfsE5r9TQY2IZ/Ht4s65qBaDUEts5iY3kv8HX9+ZSXDJZpV0ztqqsPmx4ZNj+NYwWXwcFiKdb5R8OmV8bgSsnPddD6wFhwewglUOBPRAjropHE4sqk1Vam6q1MlFq5kiekMn/CItyFYFFzST/ruqAtVTp7YIvazAMrfCKH+pvXWk6pYNHZmL/JZey0GglRyJ1nItiqL33X8Lji056FcbAclidq022h/KPLEJpZk6irWqYdqYZeF6YMLHtdZFDkTZ/hXY+UCgYEA5i794UTQ1Kd6K+iui/S8K5H8nGdiXb3+uZ5j5VKYfbRmzXhAdVYisYe8czeTECxhH+MeHgM4tLR4ifx9q60ylvZxl9Fav1p6EaE36YcvGVmpm7Gm3q6QDDBa4gB+X9u7CxCS4LpotV917YS1QvOIF9lnRonSj1zNzFtbXkywrN8CgYEAwOpx/mR40ZvgZxNCq9DsIdrSZYAFFKpw0xy0OtF1PpuwMaREoRabnlVw6Bb3Hofg50XA3JxemzAX6fB92ee+NfXfeL4UtC4vG1K9JyiXHtHq8p9Uw2W03ehIEeNa3xdoRRnLmD4VUpyfL19ViE2+7TM1Gd3TogjDT+AMOCSuq3MCgYBsurPH7gaq/LVT+mRAzgj4l8v4YUlwuGeTbIMJdvt7HXUWB4CDLH3U2CYnUpAQKrZyJok6ahEmIr1xiKggKP7lmmHL8eNo0icpHrtXfzi7Q8Q/PCpzs4dtioXTjaIkS5nNvzVyG/uL+RyuZmpsxrZ5dYM4KbAhchfwORMutxEZhwKBgQC5zpVw4jCEItBmNuTWO+nTScGvxTgfiXIVw+XLaQa2AJoZlhAL34yPWdffko79tv3lgweY9HsimZXO2rU8dbp8mo5c6ydhy8HPXUeWOcAkDSdv/ApWENW9jgYsRIC3swHY3Fl+Dv3Wjce8huQI3mjwaYvRmBhIToxfmHnscVhTBQKBgB9uciEHfz8hMI7ePrPo2PkyK/RbJDm3HnuWE2lFBp7MOUMlh53MXwv4dIRaYMbRrFuN1UIKEFxuKhWwTHSzZJufk/UENrha/81fpj2BoFsAKkEunKeETvaIh6fZSjec16h2+zxbzwkdS6b+yIYkSlaoAxmDYrMtae0C8G4e0YS9";
String pubKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2RZZISModRzproL3eTxRtvVK/nToDbeLmAVdmaVtHgNCwjXMeNCZvHySZKO7+t7XySzBd2PhhQjvAkDd8HRKB5Y0uvP6TFwvhxOMkMydTeBFcUobQWNeAI7ttRms1txSNrmyrZr0WpWfk79VIsO+yI/jFN/Pj2gxD+vh5UUKU1LD2IQq/VxgtEpf8Vs6w7SvafPwYkpdPGCKUFkRvN1FrY2+tq0j1MRVJbB2rIunWDnT8cDUh2sWLXf4yNaJVOaaTFB0zbAk/qcoicGQyW7bVG7dVW8WywKmOAPeQCCQa+SJ4BhfI1k8eEAwFVRuxz/f9Ecfog9hZJ+RgELkpS8qhQIDAQAB";
rsaSigner signer = new rsaSigner();
Map<String, Object> params = new HashMap<>();
params.put("app_id", "hxgmau9imt86qky9");
params.put("version", "1.0");
params.put("key_version", "admin");
params.put("time", Long.toString(System.currentTimeMillis() / 1000));
params.put("coin", "eth");
try {
params.put("sign", signer.genSign(params, priKey));
Gson gson = new GsonBuilder().create();
System.out.println("params = " + gson.toJson(params));
String res = doPost(baseUrl + "/balance/exchange", gson.toJson(params));
if (null == res) {
throw new RuntimeException("http error");
}
System.out.println("response = " + res);
JsonParser jp = new JsonParser();
JsonObject resEle = jp.parse(res).getAsJsonObject();
boolean retSignOK = signer.verifySign(resEle, resEle.get("sign").getAsString(), pubKey);
if (!retSignOK) {
throw new RuntimeException("verify response sign fail");
}
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("OK");
}
返回结果示例:
{
"status": 200,
"msg": "请求成功",
"data": [{
"coin": "eth",
"amount": 0,
"freeze_amount": 0,
"total": 0
}],
"date_time": "2022-07-22 20:18:01",
"time_stamp": 1658492281,
"sign": "xqLyFst5Xv2mqargS2couk7anmeWMZ+1wVEBUYQHlnfJAHdmeXh3eev/bqK5CnfEHGN/A1q+z/vFmMdXfgmzY5S+3iGRz+qGLwqBOFjC4S7J6+fgHu/ciaQedR9jss4KmonxxYrGHoNgsXe/H3toDGe/z/EO956nhZW3K3g9bh/CzZJc/OfNKT0TfgXuOy+B3MvZ5oxZi2mygaXk2aWEjcrZoUEiZfJkx/AzLpolCTrqDt5+1l/U5pQpCptGaR6lOIjTmbd3ycUYRGOxuhoK4OzO3euQIEVxbaf5aRnJU9r48QU2lPUC0PGd3i4+hAHy9gg1S2pNVuWA9PGJvpFhpg=="
}
兑换账户余额查询接口,返回单个币种的兑换账户余额
HTTP Request
POST: /balance/exchange
请求参数
| 参数名 | 必选 | 类型 | 说明 |
|---|---|---|---|
| 公共参数 | 是 | JSON | 公参指:签名(sign)、版本(version)、商户ID(app_id)、时间(time) |
| coin | 否 | string | 20个字符内币名,币名平台提供为准,若该参数为空则返回所有币种 |
返回参数说明
| 参数名 | 类型 | 说明 |
|---|---|---|
| status | int | 状态码 |
| msg | string | 状态描述 |
| data | jsonObject | |
| data.amount | float | 可用余额 |
| data.freeze_amount | float | 冻结余额 |
| data.total | float | 冻结+可用余额 |
| date_time | string | 北京时间 |
| time_stamp | string | 响应时间单位秒 |
| sign | string | 签名-对以上所有参与参数的签名 |
兑换交易对查询
$url = "http://api.xxxx.com/shopapi/exchange/coin";
$header = [
'Content-Type:application/json',
];
$params = [
"version"=> "1.0",
"app_id"=> "hxgmau9imt86qky9",
"time"=> "1578736053",
"sign" => "dLtK+uiPcnxt2ACKMbBqQ6wI5ttAvesOHzK5ybVID1R6hqYPDTkagl7Tsjr5iLJafehcSLTZyJLtCRI8O2CtIWQUUroGXBneHZC486NUi/4FMOQs0FaAgm17pWlbhX5/96cWXXXMVeoe3IZFKaFNYSWaA14v3RcdDU6QDE/9ixGiSJ0DIxm9NKA0+RkbIFbyYeuFn8d63OcjmUhv7tsOE6rKCc3Q2yi7Qe9i6BNAQFYMFATztb18MsxsBHKUxNqklqyVnl0ofETAHmQhfOHLmungOJQnOqAAuwfmRtg50Qci5F+R2mXeqjmIXko/u3E+DLYW1ygDBp3afKZmU4PwmA=="
];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
$return = curl_exec($ch);
print_r($return);
var url = "http://api.xxxx.com/shopapi/exchange/coin"
data := map[string]string{
"version": "1.0",
"app_id": "hxgmau9imt86qky9",
"time": "1578736053",
"sign": "OTA8utI8y8G93p7RPCyb4qIilFQ0B4Aq4iUjhaXWK9m2kgektqlHOASDKXT2VE7NPNysrGycYlVfjDR2WGZn1G66phHo3qa9CcCNpG9klOBEuBEMjiVbb/d8AXcxEzvQr9OCwNsikyxonyzLiY/lsNHeGm9cC5eRvlNLdUSVBipH+ajPd0lDHCayZPs1eCMfbm/xnf8e2lfy6z0UPOpHGfyX/0+hz99Ir5Xnx+0sBBzyZZJxKm4ROid5aDv/9m9guILpURae+Yw/IrkYF4uAKGX+/44cBvtTRQSdX76CAOBSiywZa6BAgDYBLRtkAPM+i+vwNzFBovqHUvI+4Ponaw==",
}
dataType, _ := json.Marshal(data)
resp, err := http.Post(url, "application/json", strings.NewReader(string(dataType)))
if err != nil {
fmt.Println(err)
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Println(err)
}
fmt.Println(string(body))
let HTTP = require('http')
let postData = {
"version": "1.0",
"app_id": "hxgmau9imt86qky9",
"time": "1578736053",
"sign": "OTA8utI8y8G93p7RPCyb4qIilFQ0B4Aq4iUjhaXWK9m2kgektqlHOASDKXT2VE7NPNysrGycYlVfjDR2WGZn1G66phHo3qa9CcCNpG9klOBEuBEMjiVbb/d8AXcxEzvQr9OCwNsikyxonyzLiY/lsNHeGm9cC5eRvlNLdUSVBipH+ajPd0lDHCayZPs1eCMfbm/xnf8e2lfy6z0UPOpHGfyX/0+hz99Ir5Xnx+0sBBzyZZJxKm4ROid5aDv/9m9guILpURae+Yw/IrkYF4uAKGX+/44cBvtTRQSdX76CAOBSiywZa6BAgDYBLRtkAPM+i+vwNzFBovqHUvI+4Ponaw==",
};
let POST_OPTIONS = {
port: 80,
host: "api.xxxx.com",
path: "/shopapi/exchange/coin",
method: 'POST',
headers: {
"Content-Type": "application/json; charset=utf-8"
}
};
const REQUEST = HTTP.request(POST_OPTIONS,function (res) {
let data = []
res.on('data', chunk => {
data.push(...chunk)
})
res.on('end', () => {
let _date = JSON.parse( new TextDecoder().decode(new Uint8Array(data)))
console.log(_date)
})
});
REQUEST.setTimeout(6000)
REQUEST.write(JSON.stringify(postData), 'utf8')
REQUEST.end()
public static void main(String[] args) {
// 完整实例请查看"签名规则"中的Java示例代码
String baseUrl = "http://api.xxxx.com/shopapi";
String priKey = "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCtdgvcfozY7fe/x6UlXR/Fff8+wX++CiG05YVRafDe90O8y5KJAMZ156TgajEUXSRyKZqASz7iVoMAcu5FqfK1KuOOdjTAg0LFe/twIZvKmAqHcCSS2pjUXk0fTpZEgQ5lmDCK12Mg07YXvr+BeHjF+kBpwRJMPMG/+DGBDYNFNeRSJqWyopt6yyF528soAykHIUQ7TTultJV5IPCrvjRQQrGdJ/QtCdE0vZg+tA09nFN7AqgraU99kIvzyS0sqysj+pP1SJRmTRSGtlVAO3mILfkXOekZl1KD60G7CF+7BIaaW83FPD55tZhAGhnbLMYyiq7OiIyU61LTRcNSaJ0tAgMBAAECggEBAIGgGKcSzxCBbMYdXLV6TPbZ/HeaRGrwyVWUu7cmc0E8CJu6iWvmb2jGzbiCwuCT5luF6ZZ8JKchvU4FlTfsE5r9TQY2IZ/Ht4s65qBaDUEts5iY3kv8HX9+ZSXDJZpV0ztqqsPmx4ZNj+NYwWXwcFiKdb5R8OmV8bgSsnPddD6wFhwewglUOBPRAjropHE4sqk1Vam6q1MlFq5kiekMn/CItyFYFFzST/ruqAtVTp7YIvazAMrfCKH+pvXWk6pYNHZmL/JZey0GglRyJ1nItiqL33X8Lji056FcbAclidq022h/KPLEJpZk6irWqYdqYZeF6YMLHtdZFDkTZ/hXY+UCgYEA5i794UTQ1Kd6K+iui/S8K5H8nGdiXb3+uZ5j5VKYfbRmzXhAdVYisYe8czeTECxhH+MeHgM4tLR4ifx9q60ylvZxl9Fav1p6EaE36YcvGVmpm7Gm3q6QDDBa4gB+X9u7CxCS4LpotV917YS1QvOIF9lnRonSj1zNzFtbXkywrN8CgYEAwOpx/mR40ZvgZxNCq9DsIdrSZYAFFKpw0xy0OtF1PpuwMaREoRabnlVw6Bb3Hofg50XA3JxemzAX6fB92ee+NfXfeL4UtC4vG1K9JyiXHtHq8p9Uw2W03ehIEeNa3xdoRRnLmD4VUpyfL19ViE2+7TM1Gd3TogjDT+AMOCSuq3MCgYBsurPH7gaq/LVT+mRAzgj4l8v4YUlwuGeTbIMJdvt7HXUWB4CDLH3U2CYnUpAQKrZyJok6ahEmIr1xiKggKP7lmmHL8eNo0icpHrtXfzi7Q8Q/PCpzs4dtioXTjaIkS5nNvzVyG/uL+RyuZmpsxrZ5dYM4KbAhchfwORMutxEZhwKBgQC5zpVw4jCEItBmNuTWO+nTScGvxTgfiXIVw+XLaQa2AJoZlhAL34yPWdffko79tv3lgweY9HsimZXO2rU8dbp8mo5c6ydhy8HPXUeWOcAkDSdv/ApWENW9jgYsRIC3swHY3Fl+Dv3Wjce8huQI3mjwaYvRmBhIToxfmHnscVhTBQKBgB9uciEHfz8hMI7ePrPo2PkyK/RbJDm3HnuWE2lFBp7MOUMlh53MXwv4dIRaYMbRrFuN1UIKEFxuKhWwTHSzZJufk/UENrha/81fpj2BoFsAKkEunKeETvaIh6fZSjec16h2+zxbzwkdS6b+yIYkSlaoAxmDYrMtae0C8G4e0YS9";
String pubKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2RZZISModRzproL3eTxRtvVK/nToDbeLmAVdmaVtHgNCwjXMeNCZvHySZKO7+t7XySzBd2PhhQjvAkDd8HRKB5Y0uvP6TFwvhxOMkMydTeBFcUobQWNeAI7ttRms1txSNrmyrZr0WpWfk79VIsO+yI/jFN/Pj2gxD+vh5UUKU1LD2IQq/VxgtEpf8Vs6w7SvafPwYkpdPGCKUFkRvN1FrY2+tq0j1MRVJbB2rIunWDnT8cDUh2sWLXf4yNaJVOaaTFB0zbAk/qcoicGQyW7bVG7dVW8WywKmOAPeQCCQa+SJ4BhfI1k8eEAwFVRuxz/f9Ecfog9hZJ+RgELkpS8qhQIDAQAB";
rsaSigner signer = new rsaSigner();
Map<String, Object> params = new HashMap<>();
params.put("app_id", "hxgmau9imt86qky9");
params.put("version", "1.0");
params.put("key_version", "admin");
params.put("time", Long.toString(System.currentTimeMillis() / 1000));
try {
params.put("sign", signer.genSign(params, priKey));
Gson gson = new GsonBuilder().create();
System.out.println("params = " + gson.toJson(params));
String res = doPost(baseUrl + "/exchange/coin", gson.toJson(params));
if (null == res) {
throw new RuntimeException("http error");
}
System.out.println("response = " + res);
JsonParser jp = new JsonParser();
JsonObject resEle = jp.parse(res).getAsJsonObject();
boolean retSignOK = signer.verifySign(resEle, resEle.get("sign").getAsString(), pubKey);
if (!retSignOK) {
throw new RuntimeException("verify response sign fail");
}
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("OK");
}
返回结果示例:
{
"status": 200,
"msg": "处理成功",
"data": [
{
"source_coin": "eth",
"target_coin": "usdt",
"source_min_amount": "0",
"source_max_amount": "0",
"source_unit": "4",
"target_unit": "2"
},
{
"source_coin": "usdt_trc20",
"target_coin": "usdt",
"source_min_amount": "0",
"source_max_amount": "0",
"source_unit": "2",
"target_unit": "6"
}
],
"date_time": "2021-08-10 09:32:26",
"time_stamp": 1628559146,
"sign": "uqhR4gE6jZ1cK0pz3QoUjJIHMBwaK2dYTBVEgjhsq4bbk12rDLJ4VKq99BT510POmouF0o5ZsK2Y9/MlUdumb90rLam2PFwVqcwuBHEIJ7RTMwzcrF4G1z3oCQS4/sPkmOlX8pTK7StcNGzJfbqQB3Gr+4x1chxZR8MZSvXnkKtElco75K/4LyuoYbOUTtGSYgUgYsa5Yh8EnZeKfekR3yclet8WThtqJJ187RdXZMkMUWNU+27N3PbDf0bI8Vxiz26tFg2Y1FIUTJbmOnG2zTNuUUtdgu5H3USRsCMGHUq8YZeyFAZW54odZGrqc5njO2GkRdoyS7f1JGEXwMfdEA=="
}
查询支持的兑换币种
HTTP Request
POST: /exchange/coin
请求参数
| 参数名 | 必选 | 类型 | 说明 |
|---|---|---|---|
| 公共参数 | 是 | JSON | 公参指:签名(sign)、版本(version)、商户ID(app_id)、时间(time) |
返回参数说明
| 参数名 | 类型 | 说明 |
|---|---|---|
| status | int | 状态码 |
| msg | string | 状态描述 |
| data | jsonObject | |
| data.source_coin | string | 源币种 |
| data.target_coin | string | 目标币种 |
| data.source_min_amount | string | 兑换币最小支持单笔兑换数量 |
| data.source_max_amount | string | 兑换币最大支持单笔兑换数量 |
| data.source_unit | string | 支持兑换币小数位长度(值如4, 表示最多支持4个小数位) |
| data.target_unit | string | 支持目标币小数位长度(值如4, 表示最多支持4个小数位) |
| date_time | string | 北京时间 |
| time_stamp | string | 响应时间单位秒 |
| sign | string | 签名-对以上所有参与参数的签名 |
兑换列表查询
$url = "http://api.xxxx.com/shopapi/exchange/list";
$header = [
'Content-Type:application/json',
];
$params = [
"version" => "1.0",
"app_id" => "hxgmau9imt86qky9",
"time" => "1578736053",
"trade_id" => "",
"source_coin" => "eth",
"target_coin" => "usdt",
"start_time" => "1587004987",
"end_time" => "1599616679",
"status" => "1",
"page" => "1",
"page_size" => "20",
"sign" => "dLtK+uiPcnxt2ACKMbBqQ6wI5ttAvesOHzK5ybVID1R6hqYPDTkagl7Tsjr5iLJafehcSLTZyJLtCRI8O2CtIWQUUroGXBneHZC486NUi/4FMOQs0FaAgm17pWlbhX5/96cWXXXMVeoe3IZFKaFNYSWaA14v3RcdDU6QDE/9ixGiSJ0DIxm9NKA0+RkbIFbyYeuFn8d63OcjmUhv7tsOE6rKCc3Q2yi7Qe9i6BNAQFYMFATztb18MsxsBHKUxNqklqyVnl0ofETAHmQhfOHLmungOJQnOqAAuwfmRtg50Qci5F+R2mXeqjmIXko/u3E+DLYW1ygDBp3afKZmU4PwmA=="
];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
$return = curl_exec($ch);
print_r($return);
var url = "http://api.xxxx.com/shopapi/exchange/list"
data := map[string]string{
"version": "1.0",
"app_id": "hxgmau9imt86qky9",
"time": "1578736053",
"sign": "OTA8utI8y8G93p7RPCyb4qIilFQ0B4Aq4iUjhaXWK9m2kgektqlHOASDKXT2VE7NPNysrGycYlVfjDR2WGZn1G66phHo3qa9CcCNpG9klOBEuBEMjiVbb/d8AXcxEzvQr9OCwNsikyxonyzLiY/lsNHeGm9cC5eRvlNLdUSVBipH+ajPd0lDHCayZPs1eCMfbm/xnf8e2lfy6z0UPOpHGfyX/0+hz99Ir5Xnx+0sBBzyZZJxKm4ROid5aDv/9m9guILpURae+Yw/IrkYF4uAKGX+/44cBvtTRQSdX76CAOBSiywZa6BAgDYBLRtkAPM+i+vwNzFBovqHUvI+4Ponaw==",
"trade_id":"",
"source_coin":"eth",
"target_coin":"usdt",
"start_time":"1587004987",
"end_time":"1599616679",
"status":"1",
"page":"1",
"page_size":"20",
}
dataType, _ := json.Marshal(data)
resp, err := http.Post(url, "application/json", strings.NewReader(string(dataType)))
if err != nil {
fmt.Println(err)
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Println(err)
}
fmt.Println(string(body))
let HTTP = require('http')
let postData = {
"version": "1.0",
"app_id": "hxgmau9imt86qky9",
"time": "1578736053",
"sign": "OTA8utI8y8G93p7RPCyb4qIilFQ0B4Aq4iUjhaXWK9m2kgektqlHOASDKXT2VE7NPNysrGycYlVfjDR2WGZn1G66phHo3qa9CcCNpG9klOBEuBEMjiVbb/d8AXcxEzvQr9OCwNsikyxonyzLiY/lsNHeGm9cC5eRvlNLdUSVBipH+ajPd0lDHCayZPs1eCMfbm/xnf8e2lfy6z0UPOpHGfyX/0+hz99Ir5Xnx+0sBBzyZZJxKm4ROid5aDv/9m9guILpURae+Yw/IrkYF4uAKGX+/44cBvtTRQSdX76CAOBSiywZa6BAgDYBLRtkAPM+i+vwNzFBovqHUvI+4Ponaw==",
"trade_id":"",
"source_coin":"eth",
"target_coin":"usdt",
"start_time":"1587004987",
"end_time":"1599616679",
"status":"1",
"page":"1",
"page_size":"20",
};
let POST_OPTIONS = {
port: 80,
host: "api.xxxx.com",
path: "/shopapi/exchange/list",
method: 'POST',
headers: {
"Content-Type": "application/json; charset=utf-8"
}
};
const REQUEST = HTTP.request(POST_OPTIONS,function (res) {
let data = []
res.on('data', chunk => {
data.push(...chunk)
})
res.on('end', () => {
let _date = JSON.parse( new TextDecoder().decode(new Uint8Array(data)))
console.log(_date)
})
});
REQUEST.setTimeout(6000)
REQUEST.write(JSON.stringify(postData), 'utf8')
REQUEST.end()
public static void main(String[] args) {
// 完整实例请查看"签名规则"中的Java示例代码
String baseUrl = "http://api.xxxx.com/shopapi";
String priKey = "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCtdgvcfozY7fe/x6UlXR/Fff8+wX++CiG05YVRafDe90O8y5KJAMZ156TgajEUXSRyKZqASz7iVoMAcu5FqfK1KuOOdjTAg0LFe/twIZvKmAqHcCSS2pjUXk0fTpZEgQ5lmDCK12Mg07YXvr+BeHjF+kBpwRJMPMG/+DGBDYNFNeRSJqWyopt6yyF528soAykHIUQ7TTultJV5IPCrvjRQQrGdJ/QtCdE0vZg+tA09nFN7AqgraU99kIvzyS0sqysj+pP1SJRmTRSGtlVAO3mILfkXOekZl1KD60G7CF+7BIaaW83FPD55tZhAGhnbLMYyiq7OiIyU61LTRcNSaJ0tAgMBAAECggEBAIGgGKcSzxCBbMYdXLV6TPbZ/HeaRGrwyVWUu7cmc0E8CJu6iWvmb2jGzbiCwuCT5luF6ZZ8JKchvU4FlTfsE5r9TQY2IZ/Ht4s65qBaDUEts5iY3kv8HX9+ZSXDJZpV0ztqqsPmx4ZNj+NYwWXwcFiKdb5R8OmV8bgSsnPddD6wFhwewglUOBPRAjropHE4sqk1Vam6q1MlFq5kiekMn/CItyFYFFzST/ruqAtVTp7YIvazAMrfCKH+pvXWk6pYNHZmL/JZey0GglRyJ1nItiqL33X8Lji056FcbAclidq022h/KPLEJpZk6irWqYdqYZeF6YMLHtdZFDkTZ/hXY+UCgYEA5i794UTQ1Kd6K+iui/S8K5H8nGdiXb3+uZ5j5VKYfbRmzXhAdVYisYe8czeTECxhH+MeHgM4tLR4ifx9q60ylvZxl9Fav1p6EaE36YcvGVmpm7Gm3q6QDDBa4gB+X9u7CxCS4LpotV917YS1QvOIF9lnRonSj1zNzFtbXkywrN8CgYEAwOpx/mR40ZvgZxNCq9DsIdrSZYAFFKpw0xy0OtF1PpuwMaREoRabnlVw6Bb3Hofg50XA3JxemzAX6fB92ee+NfXfeL4UtC4vG1K9JyiXHtHq8p9Uw2W03ehIEeNa3xdoRRnLmD4VUpyfL19ViE2+7TM1Gd3TogjDT+AMOCSuq3MCgYBsurPH7gaq/LVT+mRAzgj4l8v4YUlwuGeTbIMJdvt7HXUWB4CDLH3U2CYnUpAQKrZyJok6ahEmIr1xiKggKP7lmmHL8eNo0icpHrtXfzi7Q8Q/PCpzs4dtioXTjaIkS5nNvzVyG/uL+RyuZmpsxrZ5dYM4KbAhchfwORMutxEZhwKBgQC5zpVw4jCEItBmNuTWO+nTScGvxTgfiXIVw+XLaQa2AJoZlhAL34yPWdffko79tv3lgweY9HsimZXO2rU8dbp8mo5c6ydhy8HPXUeWOcAkDSdv/ApWENW9jgYsRIC3swHY3Fl+Dv3Wjce8huQI3mjwaYvRmBhIToxfmHnscVhTBQKBgB9uciEHfz8hMI7ePrPo2PkyK/RbJDm3HnuWE2lFBp7MOUMlh53MXwv4dIRaYMbRrFuN1UIKEFxuKhWwTHSzZJufk/UENrha/81fpj2BoFsAKkEunKeETvaIh6fZSjec16h2+zxbzwkdS6b+yIYkSlaoAxmDYrMtae0C8G4e0YS9";
String pubKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2RZZISModRzproL3eTxRtvVK/nToDbeLmAVdmaVtHgNCwjXMeNCZvHySZKO7+t7XySzBd2PhhQjvAkDd8HRKB5Y0uvP6TFwvhxOMkMydTeBFcUobQWNeAI7ttRms1txSNrmyrZr0WpWfk79VIsO+yI/jFN/Pj2gxD+vh5UUKU1LD2IQq/VxgtEpf8Vs6w7SvafPwYkpdPGCKUFkRvN1FrY2+tq0j1MRVJbB2rIunWDnT8cDUh2sWLXf4yNaJVOaaTFB0zbAk/qcoicGQyW7bVG7dVW8WywKmOAPeQCCQa+SJ4BhfI1k8eEAwFVRuxz/f9Ecfog9hZJ+RgELkpS8qhQIDAQAB";
rsaSigner signer = new rsaSigner();
Map<String, Object> params = new HashMap<>();
params.put("app_id", "hxgmau9imt86qky9");
params.put("version", "1.0");
params.put("key_version", "admin");
params.put("time", Long.toString(System.currentTimeMillis() / 1000));
params.put("trade_id","");
params.put("source_coin","eth");
params.put("target_coin","usdt");
params.put("start_time","1587004987");
params.put("end_time","1599616679");
params.put("status","1");
params.put("page","1");
params.put("page_size","20");
try {
params.put("sign", signer.genSign(params, priKey));
Gson gson = new GsonBuilder().create();
System.out.println("params = " + gson.toJson(params));
String res = doPost(baseUrl + "/exchange/list", gson.toJson(params));
if (null == res) {
throw new RuntimeException("http error");
}
System.out.println("response = " + res);
JsonParser jp = new JsonParser();
JsonObject resEle = jp.parse(res).getAsJsonObject();
boolean retSignOK = signer.verifySign(resEle, resEle.get("sign").getAsString(), pubKey);
if (!retSignOK) {
throw new RuntimeException("verify response sign fail");
}
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("OK");
}
返回结果示例:
{
"status": 200,
"msg": "处理成功",
"data": {
"page": 1,
"max_page": 1,
"count": 4,
"list": [
{
"order_id": "20210811162504870081",
"trade_id": "2424sfshdrsfsf211wqe11",
"user_id": "1001",
"source_coin": "eth",
"target_coin": "usdt",
"source_amount": "0.1234",
"source_success_amount": "0",
"source_failed_amount": "0",
"target_amount": "0",
"limit_price": "3.4",
"type": "1",
"exchange_fee": "0",
"exchange_rate": "0",
"status": "2",
"time": "1629252807"
},
{
"order_id": "20210811162442276466",
"trade_id": "2424sfshdrsfsf211wqe1",
"user_id": "1002",
"source_coin": "eth",
"target_coin": "usdt",
"source_amount": "0.1234",
"source_success_amount": "0",
"source_failed_amount": "0",
"target_amount": "0",
"limit_price": "3.4",
"type": "1",
"exchange_fee": "0",
"exchange_rate": "0",
"status": "2",
"time": "1628670282"
}
]
},
"date_time": "2021-08-18 17:11:54",
"time_stamp": 1629277914,
"sign": "EC2LAtl7T3h0Q93nsqf3QzJAAUDrxqRYPpEsClzg9S+SGk77wCxEkQvNAJEK3IYHBvkTtyrlggbBaH7YA7q4dJeFsuwMVlvuVQ9yHuzEe3XVA8CLDVn98QDvmSjprBHUrQKG4FCvD3YiOlaZj46xXaGD2Dm/A3gvxclDfafUMzKOqXbb2yhOraz71+VzhqszKkZQyghx4Et55GA0ZqSIu1Ui81qjVLvu1t2J90kzq/ffE6rUCz4ZidA+9ybnxTU8T9swzdSpudHiuxMOa5kNaJD0daqVbz3Ez17r0c7w78U9Hj5WWicNSQ8j4VLyQ2BK6hIKqj79ibqM84mxec7Ltw=="
}
兑换账号余额查询
查处兑换单状态接口,支持多维度查询
HTTP Request
POST: /exchange/list
请求参数
| 参数名 | 必选 | 类型 | 说明 |
|---|---|---|---|
| 公共参数 | 是 | JSON | 公参指:签名(sign)、版本(version)、商户ID(app_id)、时间(time) |
| trade_id | 否 | string | 如果传trade_id为精准查找,下面参数失效 |
| source_coin | 否 | string | 兑换币 |
| target_coin | 否 | string | 兑换目标币 |
| page | 否 | int | 1<= N <=Max,对于超过Max的取Max,小于1或没有传参数的返回1 |
| status | 否 | int | 0 待审核 1 兑换成功、5 审核通过、10 审核不通过、20 兑换失败 |
| start_time | 否 | int | 开始时间(创建时间) 格式 :时间戳 |
| end_time | 否 | int | 结束时间(创建时间) 格式 :时间戳 |
| page_size | 否 | int | 每页数量 (20 ~500),默认 20 |
返回参数说明
| 参数名 | 类型 | 说明 |
|---|---|---|
| status | int | 状态码 |
| msg | string | 状态描述 |
| data | jsonObject | |
| data.page | int | 第几页 |
| data.count | int | 本页记录数 |
| data.list | jsonArray | 具体每条记录 |
| data.list.trade_id | string | 交易id |
| data.list.source_coin | string | 兑换币 |
| data.list.target_coin | string | 兑换目标币 |
| data.list.source_amount | string | 兑换币数量 |
| data.list.target_amount | string | 兑换目标币数量 |
| data.list.limit_price | string | 限价 |
| data.list.type | string | 兑换模式(0一般兑换/1平仓模式) |
| data.list.exchange_fee | string | 兑换手续费(单位:目标币) |
| data.list.status | string | 订单状态:0 待审核、1 兑换完成、2 待处理、5 审核通过、10 审核不通过、20 转账失败 |
| data.list.time | string | 状态时间,最终固定在status=1时候的时间 |
| data.list.order_id | string | 订单id |
| data.list.exchange_rate | string | 兑换汇率(平均成交价) |
| data.list.source_success_amount | string | 兑换币实际兑换金额 (一般兑换模式存在部分兑换) |
| data.list.source_failed_amount | string | 兑换币兑换失败金额(系统会自动退回至兑换账户) |
| data.list.user_id | string | 用户ID |
| date_time | string | 北京时间 |
| time_stamp | string | 响应时间单位秒 |
| sign | string | 签名-对以上所有参与参数的签名 |
兑换回调通知
$url = "具体回调地址,由商户提供给平台方";
$header = [
'Content-Type:application/json',
];
$params = [
"data" => [
"trade_id"=> "20200114202903274786",
"order_id"=> "2020010211153423123456",
"source_coin"=> "eth",
"target_coin"=> "eth",
"source_amount"=> "10",
"target_amount"=> "100",
"exchange_rate"=> "5",
"exchange_fee"=> "1",
"limit_price"=> "100",
"type"=> "0",
"status"=> "1",
"time"=> "1650011196",
"source_success_amount"=> 10,
"source_failed_amount"=> 100,
"user_id"=> 1,
],
"sign" => "dLtK+uiPcnxt2ACKMbBqQ6wI5ttAvesOHzK5ybVID1R6hqYPDTkagl7Tsjr5iLJafehcSLTZyJLtCRI8O2CtIWQUUroGXBneHZC486NUi/4FMOQs0FaAgm17pWlbhX5/96cWXXXMVeoe3IZFKaFNYSWaA14v3RcdDU6QDE/9ixGiSJ0DIxm9NKA0+RkbIFbyYeuFn8d63OcjmUhv7tsOE6rKCc3Q2yi7Qe9i6BNAQFYMFATztb18MsxsBHKUxNqklqyVnl0ofETAHmQhfOHLmungOJQnOqAAuwfmRtg50Qci5F+R2mXeqjmIXko/u3E+DLYW1ygDBp3afKZmU4PwmA=="
];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
$return = curl_exec($ch);
print_r($return);
var url = "具体回调地址,由商户提供给平台方"
data := map[string]interface{}{
"data": map[string]string{
"trade_id":"20200114202903274786",
"order_id":"2020010211153423123456",
"source_coin":"eth",
"target_coin":"eth",
"source_amount":"10",
"target_amount":"100",
"exchange_rate":"5",
"exchange_fee":"1",
"limit_price":"100",
"type":"0",
"status":"1",
"time":"1650011196",
"source_success_amount":"10",
"source_failed_amount":"100",
"user_id":"1",
},
"sign": "OTA8utI8y8G93p7RPCyb4qIilFQ0B4Aq4iUjhaXWK9m2kgektqlHOASDKXT2VE7NPNysrGycYlVfjDR2WGZn1G66phHo3qa9CcCNpG9klOBEuBEMjiVbb/d8AXcxEzvQr9OCwNsikyxonyzLiY/lsNHeGm9cC5eRvlNLdUSVBipH+ajPd0lDHCayZPs1eCMfbm/xnf8e2lfy6z0UPOpHGfyX/0+hz99Ir5Xnx+0sBBzyZZJxKm4ROid5aDv/9m9guILpURae+Yw/IrkYF4uAKGX+/44cBvtTRQSdX76CAOBSiywZa6BAgDYBLRtkAPM+i+vwNzFBovqHUvI+4Ponaw==",
}
dataType, _ := json.Marshal(data)
resp, err := http.Post(url, "application/json", strings.NewReader(string(dataType)))
if err != nil {
fmt.Println(err)
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Println(err)
}
fmt.Println(string(body))
let HTTP = require('http')
let postData = {
"data": {
"trade_id":"20200114202903274786",
"order_id":"2020010211153423123456",
"source_coin":"eth",
"target_coin":"eth",
"source_amount":"10",
"target_amount":"100",
"exchange_rate":"5",
"exchange_fee":"1",
"limit_price":"100",
"type":"0",
"status":"1",
"time":"1650011196",
"source_success_amount":"10",
"source_failed_amount":"100",
"user_id":"1",
},
"sign": "OTA8utI8y8G93p7RPCyb4qIilFQ0B4Aq4iUjhaXWK9m2kgektqlHOASDKXT2VE7NPNysrGycYlVfjDR2WGZn1G66phHo3qa9CcCNpG9klOBEuBEMjiVbb/d8AXcxEzvQr9OCwNsikyxonyzLiY/lsNHeGm9cC5eRvlNLdUSVBipH+ajPd0lDHCayZPs1eCMfbm/xnf8e2lfy6z0UPOpHGfyX/0+hz99Ir5Xnx+0sBBzyZZJxKm4ROid5aDv/9m9guILpURae+Yw/IrkYF4uAKGX+/44cBvtTRQSdX76CAOBSiywZa6BAgDYBLRtkAPM+i+vwNzFBovqHUvI+4Ponaw==",
};
let POST_OPTIONS = {
port: 80,
host: "具体回调地址,由商户提供给平台方",
path: "",
method: 'POST',
headers: {
"Content-Type": "application/json; charset=utf-8"
}
};
const REQUEST = HTTP.request(POST_OPTIONS,function (res) {
let data = []
res.on('data', chunk => {
data.push(...chunk)
})
res.on('end', () => {
let _date = JSON.parse( new TextDecoder().decode(new Uint8Array(data)))
console.log(_date)
})
});
REQUEST.setTimeout(6000)
REQUEST.write(JSON.stringify(postData), 'utf8')
REQUEST.end()
返回结果示例:
{
"status":200,
"sign": "OTA8utI8y8G93p7RPCyb4qIilFQ0B4Aq4iUjhaXWK9m2kgektqlHOASDKXT2VE7NPNysrGycYlVfjDR2WGZn1G66phHo3qa9CcCNpG9klOBEuBEMjiVbb/d8AXcxEzvQr9OCwNsikyxonyzLiY/lsNHeGm9cC5eRvlNLdUSVBipH+ajPd0lDHCayZPs1eCMfbm/xnf8e2lfy6z0UPOpHGfyX/0+hz99Ir5Xnx+0sBBzyZZJxKm4ROid5aDv/9m9guILpURae+Yw/IrkYF4uAKGX+/44cBvtTRQSdX76CAOBSiywZa6BAgDYBLRtkAPM+i+vwNzFBovqHUvI+4Ponaw==",
"data":{
"success_data":"success"
}
}
兑换结果通知(成功/失败),有平台发起请求,商户响应
- 该接口使用单独的 rsa密钥对,商户和平台各生成一对rsa密钥
- 请求时,平台私钥签名生成sign,商户使用平台公钥解密验证签名
- 响应时,商户使用商户私钥加密签名,平台使用商户公钥解签
- 签名参数规则跟api接口签名规则一致
HTTP Request
POST: 具体回调地址,由商户提供给平台方
请求参数
| 参数名 | 必选 | 类型 | 说明 |
|---|---|---|---|
| data | 否 | string | 回调通知携带数据结构 |
| data.trade_id | 是 | string | 商家交易订单号 |
| data.order_id | 是 | string | 平台兑换订单号 |
| data.source_coin | 是 | string | 兑换币 |
| data.target_coin | 是 | string | 兑换目标币 |
| data.source_amount | 是 | string | 实际兑换币数量 |
| data.target_amount | 是 | string | 兑换获得目标币金额 |
| data.exchange_rate | 是 | string | 汇率(平均成交价) |
| data.exchange_fee | 是 | string | 兑换手续费(单位为目标币) |
| data.limit_price | 是 | string | 限价 |
| data.type | 是 | string | 兑换模式(0一般兑换/1平仓模式) |
| data.status | 是 | string | 订单状态:0 待审核、1 兑换完成、2 待处理、5 审核通过、10 审核不通过、20 转账失败 |
| data.time | 是 | int | 发生时间(时间戳) |
| data.source_success_amount | 是 | string | 兑换币实际兑换金额 (一般兑换模式存在部分兑换) |
| data.source_failed_amount | 是 | string | 兑换币兑换失败金额(系统会自动退回至兑换账户) |
| data.user_id | 是 | string | 用户ID |
| sign | 是 | string | 对data内数据签名 |
返回参数说明
| 参数名 | 必选 | 类型 | 说明 |
|---|---|---|---|
| status | 是 | int | 状态码 |
| data | 是 | jsonObject | 返回数据对象 |
| data.success_data | 是 | sring | success 接收成功 |
| sign | 是 | string | 签名 |
统计
商家财务结算总账
$url = "http://api.xxxx.com/shopapi/balance/generalAccount";
$header = [
'Content-Type:application/json',
];
$params = [
"app_id"=> "hxgmau9imt86qky9",
"version"=> "1.0",
"time"=> 1578997143,
"sign" => "dLtK+uiPcnxt2ACKMbBqQ6wI5ttAvesOHzK5ybVID1R6hqYPDTkagl7Tsjr5iLJafehcSLTZyJLtCRI8O2CtIWQUUroGXBneHZC486NUi/4FMOQs0FaAgm17pWlbhX5/96cWXXXMVeoe3IZFKaFNYSWaA14v3RcdDU6QDE/9ixGiSJ0DIxm9NKA0+RkbIFbyYeuFn8d63OcjmUhv7tsOE6rKCc3Q2yi7Qe9i6BNAQFYMFATztb18MsxsBHKUxNqklqyVnl0ofETAHmQhfOHLmungOJQnOqAAuwfmRtg50Qci5F+R2mXeqjmIXko/u3E+DLYW1ygDBp3afKZmU4PwmA=="
];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
$return = curl_exec($ch);
print_r($return);
var url = "http://api.xxxx.com/shopapi/balance/generalAccount"
data := map[string]string{
"app_id":"hxgmau9imt86qky9",
"version":"1.0",
"time":"1578997143",
"sign":"IUtWA3HEkK+wvTGaSBYwIrdx+ANyoOPl2/1LQTDevCSTxf4/lDXPrg6/ph+skNXIbZTR8Qs2yGGkqTUHEW/vbiTPzWkYZ874rRgplp06vhOBM/Pkw289K7PVCKy1ksOtLjwj1dUfDD/2AEqTgxRDjGyn+yDWRa7HLL/28bjU3pZoFwPPjbPyRxMK9BVL/li9IQ6hb8lyOyQNHNxS3C82sDVaQKqrB0dOqtP61OH0hBonrxMhBAMD8dUmaqO6Ef+bhHzbBm3BCC5VapkOkdthb+UWXKCiBoCipg3gqrwnBdOUGXqx/1mYicNZ+oHeVpBwnJlXudff6FT+HySszr5ISw==",
}
dataType, _ := json.Marshal(data)
resp, err := http.Post(url, "application/json", strings.NewReader(string(dataType)))
if err != nil {
fmt.Println(err)
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Println(err)
}
fmt.Println(string(body))
let HTTP = require('http')
let postData = {
"app_id":"hxgmau9imt86qky9",
"version":"1.0",
"time":"1578997143",
"sign":"IUtWA3HEkK+wvTGaSBYwIrdx+ANyoOPl2/1LQTDevCSTxf4/lDXPrg6/ph+skNXIbZTR8Qs2yGGkqTUHEW/vbiTPzWkYZ874rRgplp06vhOBM/Pkw289K7PVCKy1ksOtLjwj1dUfDD/2AEqTgxRDjGyn+yDWRa7HLL/28bjU3pZoFwPPjbPyRxMK9BVL/li9IQ6hb8lyOyQNHNxS3C82sDVaQKqrB0dOqtP61OH0hBonrxMhBAMD8dUmaqO6Ef+bhHzbBm3BCC5VapkOkdthb+UWXKCiBoCipg3gqrwnBdOUGXqx/1mYicNZ+oHeVpBwnJlXudff6FT+HySszr5ISw==",
};
let POST_OPTIONS = {
port: 80,
host: "api.xxxx.com",
path: "/shopapi/balance/generalAccount",
method: 'POST',
headers: {
"Content-Type": "application/json; charset=utf-8"
}
};
const REQUEST = HTTP.request(POST_OPTIONS,function (res) {
let data = []
res.on('data', chunk => {
data.push(...chunk)
})
res.on('end', () => {
let _date = JSON.parse( new TextDecoder().decode(new Uint8Array(data)))
console.log(_date)
})
});
REQUEST.setTimeout(6000)
REQUEST.write(JSON.stringify(postData), 'utf8')
REQUEST.end()
public static void main(String[] args) {
// 完整实例请查看"签名规则"中的Java示例代码
String baseUrl = "http://api.xxxx.com/shopapi";
String priKey = "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCtdgvcfozY7fe/x6UlXR/Fff8+wX++CiG05YVRafDe90O8y5KJAMZ156TgajEUXSRyKZqASz7iVoMAcu5FqfK1KuOOdjTAg0LFe/twIZvKmAqHcCSS2pjUXk0fTpZEgQ5lmDCK12Mg07YXvr+BeHjF+kBpwRJMPMG/+DGBDYNFNeRSJqWyopt6yyF528soAykHIUQ7TTultJV5IPCrvjRQQrGdJ/QtCdE0vZg+tA09nFN7AqgraU99kIvzyS0sqysj+pP1SJRmTRSGtlVAO3mILfkXOekZl1KD60G7CF+7BIaaW83FPD55tZhAGhnbLMYyiq7OiIyU61LTRcNSaJ0tAgMBAAECggEBAIGgGKcSzxCBbMYdXLV6TPbZ/HeaRGrwyVWUu7cmc0E8CJu6iWvmb2jGzbiCwuCT5luF6ZZ8JKchvU4FlTfsE5r9TQY2IZ/Ht4s65qBaDUEts5iY3kv8HX9+ZSXDJZpV0ztqqsPmx4ZNj+NYwWXwcFiKdb5R8OmV8bgSsnPddD6wFhwewglUOBPRAjropHE4sqk1Vam6q1MlFq5kiekMn/CItyFYFFzST/ruqAtVTp7YIvazAMrfCKH+pvXWk6pYNHZmL/JZey0GglRyJ1nItiqL33X8Lji056FcbAclidq022h/KPLEJpZk6irWqYdqYZeF6YMLHtdZFDkTZ/hXY+UCgYEA5i794UTQ1Kd6K+iui/S8K5H8nGdiXb3+uZ5j5VKYfbRmzXhAdVYisYe8czeTECxhH+MeHgM4tLR4ifx9q60ylvZxl9Fav1p6EaE36YcvGVmpm7Gm3q6QDDBa4gB+X9u7CxCS4LpotV917YS1QvOIF9lnRonSj1zNzFtbXkywrN8CgYEAwOpx/mR40ZvgZxNCq9DsIdrSZYAFFKpw0xy0OtF1PpuwMaREoRabnlVw6Bb3Hofg50XA3JxemzAX6fB92ee+NfXfeL4UtC4vG1K9JyiXHtHq8p9Uw2W03ehIEeNa3xdoRRnLmD4VUpyfL19ViE2+7TM1Gd3TogjDT+AMOCSuq3MCgYBsurPH7gaq/LVT+mRAzgj4l8v4YUlwuGeTbIMJdvt7HXUWB4CDLH3U2CYnUpAQKrZyJok6ahEmIr1xiKggKP7lmmHL8eNo0icpHrtXfzi7Q8Q/PCpzs4dtioXTjaIkS5nNvzVyG/uL+RyuZmpsxrZ5dYM4KbAhchfwORMutxEZhwKBgQC5zpVw4jCEItBmNuTWO+nTScGvxTgfiXIVw+XLaQa2AJoZlhAL34yPWdffko79tv3lgweY9HsimZXO2rU8dbp8mo5c6ydhy8HPXUeWOcAkDSdv/ApWENW9jgYsRIC3swHY3Fl+Dv3Wjce8huQI3mjwaYvRmBhIToxfmHnscVhTBQKBgB9uciEHfz8hMI7ePrPo2PkyK/RbJDm3HnuWE2lFBp7MOUMlh53MXwv4dIRaYMbRrFuN1UIKEFxuKhWwTHSzZJufk/UENrha/81fpj2BoFsAKkEunKeETvaIh6fZSjec16h2+zxbzwkdS6b+yIYkSlaoAxmDYrMtae0C8G4e0YS9";
String pubKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2RZZISModRzproL3eTxRtvVK/nToDbeLmAVdmaVtHgNCwjXMeNCZvHySZKO7+t7XySzBd2PhhQjvAkDd8HRKB5Y0uvP6TFwvhxOMkMydTeBFcUobQWNeAI7ttRms1txSNrmyrZr0WpWfk79VIsO+yI/jFN/Pj2gxD+vh5UUKU1LD2IQq/VxgtEpf8Vs6w7SvafPwYkpdPGCKUFkRvN1FrY2+tq0j1MRVJbB2rIunWDnT8cDUh2sWLXf4yNaJVOaaTFB0zbAk/qcoicGQyW7bVG7dVW8WywKmOAPeQCCQa+SJ4BhfI1k8eEAwFVRuxz/f9Ecfog9hZJ+RgELkpS8qhQIDAQAB";
rsaSigner signer = new rsaSigner();
Map<String, Object> params = new HashMap<>();
params.put("app_id", "hxgmau9imt86qky9");
params.put("version", "1.0");
params.put("key_version", "admin");
params.put("time", Long.toString(System.currentTimeMillis() / 1000));
try {
params.put("sign", signer.genSign(params, priKey));
Gson gson = new GsonBuilder().create();
System.out.println("params = " + gson.toJson(params));
String res = doPost(baseUrl + "/balance/generalAccount", gson.toJson(params));
if (null == res) {
throw new RuntimeException("http error");
}
System.out.println("response = " + res);
JsonParser jp = new JsonParser();
JsonObject resEle = jp.parse(res).getAsJsonObject();
boolean retSignOK = signer.verifySign(resEle, resEle.get("sign").getAsString(), pubKey);
if (!retSignOK) {
throw new RuntimeException("verify response sign fail");
}
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("OK");
}
返回结果示例:
{
"status":200,
"msg":"请求成功",
"data":[
{
"coin" :"eth",
"receive_amount":"2.202508",
"send_amount":0,
"hot_address_amount":"28.49831843",
"settlement_amount":"2.15252525",
"wait_settlement_amount":"0.04998275",
},
{
"coin" :"trx",
"receive_amount":0,
"send_amount":0,
"hot_address_amount":0,
"settlement_amount":0,
"wait_settlement_amount":0,
},
"usdt_erc20":
{
"coin" :"trx",
"receive_amount":"23092870.028105",
"send_amount":"1242995.611177",
"hot_address_amount":"357014.388823",
"settlement_amount":"23033124.2080808",
"wait_settlement_amount":"59745.8200242",
}
],
"date_time":"2020-09-07 11:12:49",
"time_stamp":1599448369,
"sign":"Ddhz62FBeMzsxD9ARVwOmMXIgBRHWksbESZ2SFbKymcU94ZP0HIq4UkjaIw/HcU+LFiTLuTIxogsvAhCDVQAA1JPP78eiQCty98Q2HrN/uei5J3lvQFrBxk+/8ys/J9c7tKAU5ltDUBTAMshcSrcMivfGFXFBxwNOHbIFt6WXxDyq9R32EtgzNNLTCsLx9jU76+0aFthgxcy/At6/I5OLRcCya32GsqIi7YK7UOK5wSC64rCnroZFN7OWNkAlVgk9Fo0tyLjTO8ga+SX8BHgWBci2Ue1S4u8ctspWulsP7BLEhQDSKCe0pFDHc3//vWyeOEuLZxM/xDCE0BXmvjzNkqiog=="
}
- 查询:商家总充值、总提现、总结算等情况
HTTP Request
POST : /balance/generalAccount
请求参数
| 参数名 | 必选 | 类型 | 说明 |
|---|---|---|---|
| 公共参数 | 是 | string | 公参指:签名(sign)、版本(version)、商户ID(app_id)、时间(time) |
返回参数说明
| 参数名 | 类型 | 说明 |
|---|---|---|
| status | int | 状态码 |
| msg | string | 状态描述 |
| data | jsonObject | 具体见下面 “data细节说明”。 |
| data.coin | string | 币名 |
| data.receive_amount | string | 链上充值总额 |
| data.send_amount | string | 链上提现总额 |
| data.hot_address_amount | string | 热钱包余额 |
| data.settlement_amount | string | 已结算给商家金额 |
| data.wait_settlement_amount | string | 待结算给商家金额 |
| date_time | string | 响应时间 |
| time_stamp | int | 无时区的秒 |
| sign | string | 签名 |
商家充值/提现成功数量
$url = "http://api.xxxx.com/shopapi/statistics/transfer";
$header = [
'Content-Type:application/json',
];
$params = [
"version"=> "1.0",
"app_id"=> "hxgmau9imt86qky9",
"time"=> "1578736053",
"coin"=> "eth",
"sign" => "dLtK+uiPcnxt2ACKMbBqQ6wI5ttAvesOHzK5ybVID1R6hqYPDTkagl7Tsjr5iLJafehcSLTZyJLtCRI8O2CtIWQUUroGXBneHZC486NUi/4FMOQs0FaAgm17pWlbhX5/96cWXXXMVeoe3IZFKaFNYSWaA14v3RcdDU6QDE/9ixGiSJ0DIxm9NKA0+RkbIFbyYeuFn8d63OcjmUhv7tsOE6rKCc3Q2yi7Qe9i6BNAQFYMFATztb18MsxsBHKUxNqklqyVnl0ofETAHmQhfOHLmungOJQnOqAAuwfmRtg50Qci5F+R2mXeqjmIXko/u3E+DLYW1ygDBp3afKZmU4PwmA=="
];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
$return = curl_exec($ch);
print_r($return);
var url = "http://api.xxxx.com/shopapi/statistics/transfer"
data := map[string]string{
"version": "1.0",
"app_id": "hxgmau9imt86qky9",
"time": "1578736053",
"coin": "eth",
"sign":"IUtWA3HEkK+wvTGaSBYwIrdx+ANyoOPl2/1LQTDevCSTxf4/lDXPrg6/ph+skNXIbZTR8Qs2yGGkqTUHEW/vbiTPzWkYZ874rRgplp06vhOBM/Pkw289K7PVCKy1ksOtLjwj1dUfDD/2AEqTgxRDjGyn+yDWRa7HLL/28bjU3pZoFwPPjbPyRxMK9BVL/li9IQ6hb8lyOyQNHNxS3C82sDVaQKqrB0dOqtP61OH0hBonrxMhBAMD8dUmaqO6Ef+bhHzbBm3BCC5VapkOkdthb+UWXKCiBoCipg3gqrwnBdOUGXqx/1mYicNZ+oHeVpBwnJlXudff6FT+HySszr5ISw==",
}
dataType, _ := json.Marshal(data)
resp, err := http.Post(url, "application/json", strings.NewReader(string(dataType)))
if err != nil {
fmt.Println(err)
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Println(err)
}
fmt.Println(string(body))
let HTTP = require('http')
let postData = {
"version": "1.0",
"app_id": "hxgmau9imt86qky9",
"time": "1578736053",
"coin": "eth",
"sign":"IUtWA3HEkK+wvTGaSBYwIrdx+ANyoOPl2/1LQTDevCSTxf4/lDXPrg6/ph+skNXIbZTR8Qs2yGGkqTUHEW/vbiTPzWkYZ874rRgplp06vhOBM/Pkw289K7PVCKy1ksOtLjwj1dUfDD/2AEqTgxRDjGyn+yDWRa7HLL/28bjU3pZoFwPPjbPyRxMK9BVL/li9IQ6hb8lyOyQNHNxS3C82sDVaQKqrB0dOqtP61OH0hBonrxMhBAMD8dUmaqO6Ef+bhHzbBm3BCC5VapkOkdthb+UWXKCiBoCipg3gqrwnBdOUGXqx/1mYicNZ+oHeVpBwnJlXudff6FT+HySszr5ISw==",
};
let POST_OPTIONS = {
port: 80,
host: "api.xxxx.com",
path: "/shopapi/statistics/transfer",
method: 'POST',
headers: {
"Content-Type": "application/json; charset=utf-8"
}
};
const REQUEST = HTTP.request(POST_OPTIONS,function (res) {
let data = []
res.on('data', chunk => {
data.push(...chunk)
})
res.on('end', () => {
let _date = JSON.parse( new TextDecoder().decode(new Uint8Array(data)))
console.log(_date)
})
});
REQUEST.setTimeout(6000)
REQUEST.write(JSON.stringify(postData), 'utf8')
REQUEST.end()
public static void main(String[] args) {
// 完整实例请查看"签名规则"中的Java示例代码
String baseUrl = "http://api.xxxx.com/shopapi";
String priKey = "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCtdgvcfozY7fe/x6UlXR/Fff8+wX++CiG05YVRafDe90O8y5KJAMZ156TgajEUXSRyKZqASz7iVoMAcu5FqfK1KuOOdjTAg0LFe/twIZvKmAqHcCSS2pjUXk0fTpZEgQ5lmDCK12Mg07YXvr+BeHjF+kBpwRJMPMG/+DGBDYNFNeRSJqWyopt6yyF528soAykHIUQ7TTultJV5IPCrvjRQQrGdJ/QtCdE0vZg+tA09nFN7AqgraU99kIvzyS0sqysj+pP1SJRmTRSGtlVAO3mILfkXOekZl1KD60G7CF+7BIaaW83FPD55tZhAGhnbLMYyiq7OiIyU61LTRcNSaJ0tAgMBAAECggEBAIGgGKcSzxCBbMYdXLV6TPbZ/HeaRGrwyVWUu7cmc0E8CJu6iWvmb2jGzbiCwuCT5luF6ZZ8JKchvU4FlTfsE5r9TQY2IZ/Ht4s65qBaDUEts5iY3kv8HX9+ZSXDJZpV0ztqqsPmx4ZNj+NYwWXwcFiKdb5R8OmV8bgSsnPddD6wFhwewglUOBPRAjropHE4sqk1Vam6q1MlFq5kiekMn/CItyFYFFzST/ruqAtVTp7YIvazAMrfCKH+pvXWk6pYNHZmL/JZey0GglRyJ1nItiqL33X8Lji056FcbAclidq022h/KPLEJpZk6irWqYdqYZeF6YMLHtdZFDkTZ/hXY+UCgYEA5i794UTQ1Kd6K+iui/S8K5H8nGdiXb3+uZ5j5VKYfbRmzXhAdVYisYe8czeTECxhH+MeHgM4tLR4ifx9q60ylvZxl9Fav1p6EaE36YcvGVmpm7Gm3q6QDDBa4gB+X9u7CxCS4LpotV917YS1QvOIF9lnRonSj1zNzFtbXkywrN8CgYEAwOpx/mR40ZvgZxNCq9DsIdrSZYAFFKpw0xy0OtF1PpuwMaREoRabnlVw6Bb3Hofg50XA3JxemzAX6fB92ee+NfXfeL4UtC4vG1K9JyiXHtHq8p9Uw2W03ehIEeNa3xdoRRnLmD4VUpyfL19ViE2+7TM1Gd3TogjDT+AMOCSuq3MCgYBsurPH7gaq/LVT+mRAzgj4l8v4YUlwuGeTbIMJdvt7HXUWB4CDLH3U2CYnUpAQKrZyJok6ahEmIr1xiKggKP7lmmHL8eNo0icpHrtXfzi7Q8Q/PCpzs4dtioXTjaIkS5nNvzVyG/uL+RyuZmpsxrZ5dYM4KbAhchfwORMutxEZhwKBgQC5zpVw4jCEItBmNuTWO+nTScGvxTgfiXIVw+XLaQa2AJoZlhAL34yPWdffko79tv3lgweY9HsimZXO2rU8dbp8mo5c6ydhy8HPXUeWOcAkDSdv/ApWENW9jgYsRIC3swHY3Fl+Dv3Wjce8huQI3mjwaYvRmBhIToxfmHnscVhTBQKBgB9uciEHfz8hMI7ePrPo2PkyK/RbJDm3HnuWE2lFBp7MOUMlh53MXwv4dIRaYMbRrFuN1UIKEFxuKhWwTHSzZJufk/UENrha/81fpj2BoFsAKkEunKeETvaIh6fZSjec16h2+zxbzwkdS6b+yIYkSlaoAxmDYrMtae0C8G4e0YS9";
String pubKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2RZZISModRzproL3eTxRtvVK/nToDbeLmAVdmaVtHgNCwjXMeNCZvHySZKO7+t7XySzBd2PhhQjvAkDd8HRKB5Y0uvP6TFwvhxOMkMydTeBFcUobQWNeAI7ttRms1txSNrmyrZr0WpWfk79VIsO+yI/jFN/Pj2gxD+vh5UUKU1LD2IQq/VxgtEpf8Vs6w7SvafPwYkpdPGCKUFkRvN1FrY2+tq0j1MRVJbB2rIunWDnT8cDUh2sWLXf4yNaJVOaaTFB0zbAk/qcoicGQyW7bVG7dVW8WywKmOAPeQCCQa+SJ4BhfI1k8eEAwFVRuxz/f9Ecfog9hZJ+RgELkpS8qhQIDAQAB";
rsaSigner signer = new rsaSigner();
Map<String, Object> params = new HashMap<>();
params.put("app_id", "hxgmau9imt86qky9");
params.put("version", "1.0");
params.put("key_version", "admin");
params.put("time", Long.toString(System.currentTimeMillis() / 1000));
params.put("coin","eth");
try {
params.put("sign", signer.genSign(params, priKey));
Gson gson = new GsonBuilder().create();
System.out.println("params = " + gson.toJson(params));
String res = doPost(baseUrl + "/statistics/transfer", gson.toJson(params));
if (null == res) {
throw new RuntimeException("http error");
}
System.out.println("response = " + res);
JsonParser jp = new JsonParser();
JsonObject resEle = jp.parse(res).getAsJsonObject();
boolean retSignOK = signer.verifySign(resEle, resEle.get("sign").getAsString(), pubKey);
if (!retSignOK) {
throw new RuntimeException("verify response sign fail");
}
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("OK");
}
返回结果示例:
{
"status": 200,
"msg": "处理成功",
"data": {
"success_send_count": 60,
"success_receive_count": 57
},
"date_time": "2020-06-02 16:52:05",
"time_stamp": 1591087925,
"sign": "tZI1x6RqVW4llNpqMIPe1avItAOWHSqUAdeUrK/8Jpswlq5XyFlOXypDlx/d/ctVkIly8n5qw/po/AUQhEpKCM+rs6pDjk7xRoT1i1dpU01cAvc32D/2Z+olmPeo7iikIDeUlZKxHWtu9V9/xxjEtlEyZXNpJmlCTVttPmYjr1D0WbfL0gXKPK0Qkm8rQlih3mv0BsiTzea7RFOiFP5bWG8FYj0QjL8WqglUgm0AS8812HTmvwlQTkJWO9PS7lsa+Q0nBny5JZ1Rv/rJ4RhhRPXcskgUWqDB26wljHYEppoGJh1XOx/pTVeDIJA0iZohGBmHruYG79m+nCLxF5B5KA=="
}
- 查询 充值/提现成功 处理 数量
HTTP Request
POST : /statistics/transfer
请求参数
| 参数名 | 必选 | 类型 | 说明 |
|---|---|---|---|
| 公共参数 | 是 | string | 公参指:签名(sign)、版本(version)、商户ID(app_id)、时间(time) |
| coin | 否 | string |
返回参数说明
| 参数名 | 类型 | 说明 |
|---|---|---|
| status | int | 状态码 |
| msg | string | 状态描述 |
| data | jsonObject | 具体见下面 “data细节说明”。 |
| data.success_send_count | int | 成功提现数量 |
| data.success_receive_count | int | 成功充值数量 |
| date_time | string | 响应时间 |
| time_stamp | int | 无时区的秒 |
| sign | string | 签名 |
风控回调
提现订单二次复核
$url = "http://*****/withdrawal/order/check";
$header = [
'Content-Type:application/json',
];
$params = [
"data" => [
"amount" => 2.00000000,
"coin_symbol" => "USDT_TRC20",
"address" => "TLhdZuFU1fDPnzxPoXfJ6WZZMpKzY15DUi",
"user_id" => "1",
"order_id" => "1394934189494173697",
"timestamp" => 1621493658
],
"sign" => "dLtK+uiPcnxt2ACKMbBqQ6wI5ttAvesOHzK5ybVID1R6hqYPDTkagl7Tsjr5iLJafehcSLTZyJLtCRI8O2CtIWQUUroGXBneHZC486NUi/4FMOQs0FaAgm17pWlbhX5/96cWXXXMVeoe3IZFKaFNYSWaA14v3RcdDU6QDE/9ixGiSJ0DIxm9NKA0+RkbIFbyYeuFn8d63OcjmUhv7tsOE6rKCc3Q2yi7Qe9i6BNAQFYMFATztb18MsxsBHKUxNqklqyVnl0ofETAHmQhfOHLmungOJQnOqAAuwfmRtg50Qci5F+R2mXeqjmIXko/u3E+DLYW1ygDBp3afKZmU4PwmA=="
];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
$return = curl_exec($ch);
print_r($return);
var url = "http://*****/withdrawal/order/check"
data := map[string]interface{}{
"data": map[string]string{
"amount":"2.00000000",
"coin_symbol":"USDT_TRC20",
"address":"TLhdZuFU1fDPnzxPoXfJ6WZZMpKzY15DUi",
"user_id":"1",
"order_id":"1394934189494173697",
"timestamp":"1621493658",
},
"sign": "OTA8utI8y8G93p7RPCyb4qIilFQ0B4Aq4iUjhaXWK9m2kgektqlHOASDKXT2VE7NPNysrGycYlVfjDR2WGZn1G66phHo3qa9CcCNpG9klOBEuBEMjiVbb/d8AXcxEzvQr9OCwNsikyxonyzLiY/lsNHeGm9cC5eRvlNLdUSVBipH+ajPd0lDHCayZPs1eCMfbm/xnf8e2lfy6z0UPOpHGfyX/0+hz99Ir5Xnx+0sBBzyZZJxKm4ROid5aDv/9m9guILpURae+Yw/IrkYF4uAKGX+/44cBvtTRQSdX76CAOBSiywZa6BAgDYBLRtkAPM+i+vwNzFBovqHUvI+4Ponaw==",
}
dataType, _ := json.Marshal(data)
resp, err := http.Post(url, "application/json", strings.NewReader(string(dataType)))
if err != nil {
fmt.Println(err)
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Println(err)
}
fmt.Println(string(body))
let HTTP = require('http')
let postData = {
"data": {
"amount":"2.00000000",
"coin_symbol":"USDT_TRC20",
"address":"TLhdZuFU1fDPnzxPoXfJ6WZZMpKzY15DUi",
"user_id":"1",
"order_id":"1394934189494173697",
"timestamp":"1621493658",
},
"sign": "OTA8utI8y8G93p7RPCyb4qIilFQ0B4Aq4iUjhaXWK9m2kgektqlHOASDKXT2VE7NPNysrGycYlVfjDR2WGZn1G66phHo3qa9CcCNpG9klOBEuBEMjiVbb/d8AXcxEzvQr9OCwNsikyxonyzLiY/lsNHeGm9cC5eRvlNLdUSVBipH+ajPd0lDHCayZPs1eCMfbm/xnf8e2lfy6z0UPOpHGfyX/0+hz99Ir5Xnx+0sBBzyZZJxKm4ROid5aDv/9m9guILpURae+Yw/IrkYF4uAKGX+/44cBvtTRQSdX76CAOBSiywZa6BAgDYBLRtkAPM+i+vwNzFBovqHUvI+4Ponaw==",
};
let POST_OPTIONS = {
port: 80,
host: "api.xxxx.com",
path: "/withdrawal/order/check",
method: 'POST',
headers: {
"Content-Type": "application/json; charset=utf-8"
}
};
const REQUEST = HTTP.request(POST_OPTIONS,function (res) {
let data = []
res.on('data', chunk => {
data.push(...chunk)
})
res.on('end', () => {
let _date = JSON.parse( new TextDecoder().decode(new Uint8Array(data)))
console.log(_date)
})
});
REQUEST.setTimeout(6000)
REQUEST.write(JSON.stringify(postData), 'utf8')
REQUEST.end()
public static void main() {
String priKey = "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCtdgvcfozY7fe/x6UlXR/Fff8+wX++CiG05YVRafDe90O8y5KJAMZ156TgajEUXSRyKZqASz7iVoMAcu5FqfK1KuOOdjTAg0LFe/twIZvKmAqHcCSS2pjUXk0fTpZEgQ5lmDCK12Mg07YXvr+BeHjF+kBpwRJMPMG/+DGBDYNFNeRSJqWyopt6yyF528soAykHIUQ7TTultJV5IPCrvjRQQrGdJ/QtCdE0vZg+tA09nFN7AqgraU99kIvzyS0sqysj+pP1SJRmTRSGtlVAO3mILfkXOekZl1KD60G7CF+7BIaaW83FPD55tZhAGhnbLMYyiq7OiIyU61LTRcNSaJ0tAgMBAAECggEBAIGgGKcSzxCBbMYdXLV6TPbZ/HeaRGrwyVWUu7cmc0E8CJu6iWvmb2jGzbiCwuCT5luF6ZZ8JKchvU4FlTfsE5r9TQY2IZ/Ht4s65qBaDUEts5iY3kv8HX9+ZSXDJZpV0ztqqsPmx4ZNj+NYwWXwcFiKdb5R8OmV8bgSsnPddD6wFhwewglUOBPRAjropHE4sqk1Vam6q1MlFq5kiekMn/CItyFYFFzST/ruqAtVTp7YIvazAMrfCKH+pvXWk6pYNHZmL/JZey0GglRyJ1nItiqL33X8Lji056FcbAclidq022h/KPLEJpZk6irWqYdqYZeF6YMLHtdZFDkTZ/hXY+UCgYEA5i794UTQ1Kd6K+iui/S8K5H8nGdiXb3+uZ5j5VKYfbRmzXhAdVYisYe8czeTECxhH+MeHgM4tLR4ifx9q60ylvZxl9Fav1p6EaE36YcvGVmpm7Gm3q6QDDBa4gB+X9u7CxCS4LpotV917YS1QvOIF9lnRonSj1zNzFtbXkywrN8CgYEAwOpx/mR40ZvgZxNCq9DsIdrSZYAFFKpw0xy0OtF1PpuwMaREoRabnlVw6Bb3Hofg50XA3JxemzAX6fB92ee+NfXfeL4UtC4vG1K9JyiXHtHq8p9Uw2W03ehIEeNa3xdoRRnLmD4VUpyfL19ViE2+7TM1Gd3TogjDT+AMOCSuq3MCgYBsurPH7gaq/LVT+mRAzgj4l8v4YUlwuGeTbIMJdvt7HXUWB4CDLH3U2CYnUpAQKrZyJok6ahEmIr1xiKggKP7lmmHL8eNo0icpHrtXfzi7Q8Q/PCpzs4dtioXTjaIkS5nNvzVyG/uL+RyuZmpsxrZ5dYM4KbAhchfwORMutxEZhwKBgQC5zpVw4jCEItBmNuTWO+nTScGvxTgfiXIVw+XLaQa2AJoZlhAL34yPWdffko79tv3lgweY9HsimZXO2rU8dbp8mo5c6ydhy8HPXUeWOcAkDSdv/ApWENW9jgYsRIC3swHY3Fl+Dv3Wjce8huQI3mjwaYvRmBhIToxfmHnscVhTBQKBgB9uciEHfz8hMI7ePrPo2PkyK/RbJDm3HnuWE2lFBp7MOUMlh53MXwv4dIRaYMbRrFuN1UIKEFxuKhWwTHSzZJufk/UENrha/81fpj2BoFsAKkEunKeETvaIh6fZSjec16h2+zxbzwkdS6b+yIYkSlaoAxmDYrMtae0C8G4e0YS9";
String pubKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArXYL3H6M2O33v8elJV0fxX3/PsF/vgohtOWFUWnw3vdDvMuSiQDGdeek4GoxFF0kcimagEs+4laDAHLuRanytSrjjnY0wINCxXv7cCGbypgKh3AkktqY1F5NH06WRIEOZZgwitdjINO2F76/gXh4xfpAacESTDzBv/gxgQ2DRTXkUialsqKbesshedvLKAMpByFEO007pbSVeSDwq740UEKxnSf0LQnRNL2YPrQNPZxTewKoK2lPfZCL88ktLKsrI/qT9UiUZk0UhrZVQDt5iC35FznpGZdSg+tBuwhfuwSGmlvNxTw+ebWYQBoZ2yzGMoquzoiMlOtS00XDUmidLQIDAQAB";
rsaSigner signer = new rsaSigner();
Map<String, Object> data = new HashMap<>();
data.put("amount", "2.00000000");
data.put("coin_symbol", "USDT_TRC20");
data.put("address", "TLhdZuFU1fDPnzxPoXfJ6WZZMpKzY15DUi");
data.put("user_id", "1");
data.put("order_id", "1394934189494173697");
data.put("timestamp", "1621493658");
try {
Map<String, Object> params = new HashMap<>();
params.put("data", data);
params.put("sign", signer.genSign(data, priKey));
Gson gson = new GsonBuilder().create();
System.out.println("params = " + gson.toJson(params));
String res;
// platform request shop callback API
// res = doPost("http://api.shophost.com/withdrawal/order/check", gson.toJson(params));
// if (null == res) {
// throw new RuntimeException("http error");
// }
// mock response from shop callback API
{
res = """
{
"status":200,
"data":{
"status_code": 200,
"timestamp":1620617260,
"order_id":"202105101123221335892766889804"
},
"sign":"YbRyMoUmsCxLbWopD2JD5EZqkT+pIRARsdTSFo+WyhebOMP/TZ96zV/vy4CYn+9gk6nJ55acFnqSO78N4/uemiOyBgE+a8SaIjutc+kFCWGaCorboy9alFBFUbYPvHvFFKHNFJx19Z2cyv9uceGdOdz09g0OBgp8bTyfkCUNrhbUmut2M2S2ixSH3wSefqUq2SUpohb5hlD6tOsyO3JfZr7M/16aiRGcEye2XglsOMFTO5XRkj4hwHKB+nHacttvuZKnGH67ELyoajCc+ef1DkmzmO3P7vFLIuVtVXQ2FPlXVkzCR/+VesyDOpYogHwqyR1BzCCSzxpbZ/aFc/uANg=="
}
""";
}
System.out.println("response = " + res);
JsonParser jp = new JsonParser();
JsonObject resEle = jp.parse(res).getAsJsonObject();
boolean retSignOK = signer.verifySign(resEle.get("data"), resEle.get("sign").getAsString(), pubKey);
if (!retSignOK) {
throw new RuntimeException("verify response sign fail");
}
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("OK");
}
返回结果示例:
{
"status":200,
"data":{
"status_code": 200,
"timestamp":1620617260,
"order_id":"202105101123221335892766889804"
},
"sign":"YbRyMoUmsCxLbWopD2JD5EZqkT+pIRARsdTSFo+WyhebOMP/TZ96zV/vy4CYn+9gk6nJ55acFnqSO78N4/uemiOyBgE+a8SaIjutc+kFCWGaCorboy9alFBFUbYPvHvFFKHNFJx19Z2cyv9uceGdOdz09g0OBgp8bTyfkCUNrhbUmut2M2S2ixSH3wSefqUq2SUpohb5hlD6tOsyO3JfZr7M/16aiRGcEye2XglsOMFTO5XRkj4hwHKB+nHacttvuZKnGH67ELyoajCc+ef1DkmzmO3P7vFLIuVtVXQ2FPlXVkzCR/+VesyDOpYogHwqyR1BzCCSzxpbZ/aFc/uANg=="
}
- 商户提现订单风控二次复核接口
- 注意:平台 给商户分配单独的风控公钥(与充值/提现公钥不同)
HTTP Request
POST 具体回调地址,由商户提供给平台方
请求参数
| 参数名 | 必选 | 类型 | 说明 |
|---|---|---|---|
| data | 否 | string | 如下 |
| data.order_id | 是 | string | 商户端交易唯一ID(提现时的 trade_id) |
| data.user_id | 是 | string | 订单所属用户 |
| data.coin_symbol | 是 | string | 币种名称小写,以平台提供的币种为准 |
| data.address | 是 | string | 提现地址 |
| data.amount | 是 | decimal(20,8) | 提现金额 |
| data.timestamp | 是 | int | 当前时间戳 |
| sign | 是 | string | 签名,只对data中的参数进行加签 |
返回参数说明
| 参数名 | 类型 | 说明 |
|---|---|---|
| status | int | 200 通过,2001 等待审核,5400 签名验证不通过,5401 时间小于30s,5402 订单号不存在,5001 平台order_id有差异,5002 金额不对,5003 用户uid不对,5004 地址不对,5005 币种symbol不对,5006 订单拒绝,5007 其他,描述信息可自行扩展 |
| data | jsonObject | |
| data.timestamp | int | 当前时间戳,单位秒 |
| data.status_code | int | 订单状态,与status值相同,2021-12-10 后,该参数为必须参数 |
| data.order_id | String | 订单Id |
| sign | string | 签名-对响应参数中的data字段内容的签名 |
- status=200;该笔订单直接通过
- status in (2001,5400);订单会进入等待下次请求队列,如果商户服务器发生未知错误,请捕获后给出2001的状态码,这样下次就还会请求,如果给了其他状态码,则会被标记为拒绝,不再请求
- status=其他;订单直接拒绝
兑换订单二次复核
$url = "http://*****/exchange/order/check";
$header = [
'Content-Type:application/json',
];
$params = [
"data" => [
"amount" => "2.00000000",
"source_coin" => "eth",
"target_coin" => "usdt_erc20",
"user_id" => "1",
"trade_id" => "1394934189494173697",
"time" => 1621493658
],
"sign" => "dLtK+uiPcnxt2ACKMbBqQ6wI5ttAvesOHzK5ybVID1R6hqYPDTkagl7Tsjr5iLJafehcSLTZyJLtCRI8O2CtIWQUUroGXBneHZC486NUi/4FMOQs0FaAgm17pWlbhX5/96cWXXXMVeoe3IZFKaFNYSWaA14v3RcdDU6QDE/9ixGiSJ0DIxm9NKA0+RkbIFbyYeuFn8d63OcjmUhv7tsOE6rKCc3Q2yi7Qe9i6BNAQFYMFATztb18MsxsBHKUxNqklqyVnl0ofETAHmQhfOHLmungOJQnOqAAuwfmRtg50Qci5F+R2mXeqjmIXko/u3E+DLYW1ygDBp3afKZmU4PwmA=="
];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
$return = curl_exec($ch);
print_r($return);
var url = "http://*****/exchange/order/check"
data := map[string]interface{}{
"data": map[string]string{
"amount":"2.00000000",
"source_coin":"eth",
"target_coin":"usdt_erc20",
"user_id":"1",
"trade_id":"1394934189494173697",
"time":"1621493658",
},
"sign": "OTA8utI8y8G93p7RPCyb4qIilFQ0B4Aq4iUjhaXWK9m2kgektqlHOASDKXT2VE7NPNysrGycYlVfjDR2WGZn1G66phHo3qa9CcCNpG9klOBEuBEMjiVbb/d8AXcxEzvQr9OCwNsikyxonyzLiY/lsNHeGm9cC5eRvlNLdUSVBipH+ajPd0lDHCayZPs1eCMfbm/xnf8e2lfy6z0UPOpHGfyX/0+hz99Ir5Xnx+0sBBzyZZJxKm4ROid5aDv/9m9guILpURae+Yw/IrkYF4uAKGX+/44cBvtTRQSdX76CAOBSiywZa6BAgDYBLRtkAPM+i+vwNzFBovqHUvI+4Ponaw==",
}
dataType, _ := json.Marshal(data)
resp, err := http.Post(url, "application/json", strings.NewReader(string(dataType)))
if err != nil {
fmt.Println(err)
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Println(err)
}
fmt.Println(string(body))
let HTTP = require('http')
let postData = {
"data": {
"amount":"2.00000000",
"source_coin":"eth",
"target_coin":"usdt_erc20",
"user_id":"1",
"trade_id":"1394934189494173697",
"time":"1621493658",
},
"sign": "OTA8utI8y8G93p7RPCyb4qIilFQ0B4Aq4iUjhaXWK9m2kgektqlHOASDKXT2VE7NPNysrGycYlVfjDR2WGZn1G66phHo3qa9CcCNpG9klOBEuBEMjiVbb/d8AXcxEzvQr9OCwNsikyxonyzLiY/lsNHeGm9cC5eRvlNLdUSVBipH+ajPd0lDHCayZPs1eCMfbm/xnf8e2lfy6z0UPOpHGfyX/0+hz99Ir5Xnx+0sBBzyZZJxKm4ROid5aDv/9m9guILpURae+Yw/IrkYF4uAKGX+/44cBvtTRQSdX76CAOBSiywZa6BAgDYBLRtkAPM+i+vwNzFBovqHUvI+4Ponaw==",
};
let POST_OPTIONS = {
port: 80,
host: "api.xxxx.com",
path: "/exchange/order/check",
method: 'POST',
headers: {
"Content-Type": "application/json; charset=utf-8"
}
};
const REQUEST = HTTP.request(POST_OPTIONS,function (res) {
let data = []
res.on('data', chunk => {
data.push(...chunk)
})
res.on('end', () => {
let _date = JSON.parse( new TextDecoder().decode(new Uint8Array(data)))
console.log(_date)
})
});
REQUEST.setTimeout(6000)
REQUEST.write(JSON.stringify(postData), 'utf8')
REQUEST.end()
public static void main() {
String priKey = "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCtdgvcfozY7fe/x6UlXR/Fff8+wX++CiG05YVRafDe90O8y5KJAMZ156TgajEUXSRyKZqASz7iVoMAcu5FqfK1KuOOdjTAg0LFe/twIZvKmAqHcCSS2pjUXk0fTpZEgQ5lmDCK12Mg07YXvr+BeHjF+kBpwRJMPMG/+DGBDYNFNeRSJqWyopt6yyF528soAykHIUQ7TTultJV5IPCrvjRQQrGdJ/QtCdE0vZg+tA09nFN7AqgraU99kIvzyS0sqysj+pP1SJRmTRSGtlVAO3mILfkXOekZl1KD60G7CF+7BIaaW83FPD55tZhAGhnbLMYyiq7OiIyU61LTRcNSaJ0tAgMBAAECggEBAIGgGKcSzxCBbMYdXLV6TPbZ/HeaRGrwyVWUu7cmc0E8CJu6iWvmb2jGzbiCwuCT5luF6ZZ8JKchvU4FlTfsE5r9TQY2IZ/Ht4s65qBaDUEts5iY3kv8HX9+ZSXDJZpV0ztqqsPmx4ZNj+NYwWXwcFiKdb5R8OmV8bgSsnPddD6wFhwewglUOBPRAjropHE4sqk1Vam6q1MlFq5kiekMn/CItyFYFFzST/ruqAtVTp7YIvazAMrfCKH+pvXWk6pYNHZmL/JZey0GglRyJ1nItiqL33X8Lji056FcbAclidq022h/KPLEJpZk6irWqYdqYZeF6YMLHtdZFDkTZ/hXY+UCgYEA5i794UTQ1Kd6K+iui/S8K5H8nGdiXb3+uZ5j5VKYfbRmzXhAdVYisYe8czeTECxhH+MeHgM4tLR4ifx9q60ylvZxl9Fav1p6EaE36YcvGVmpm7Gm3q6QDDBa4gB+X9u7CxCS4LpotV917YS1QvOIF9lnRonSj1zNzFtbXkywrN8CgYEAwOpx/mR40ZvgZxNCq9DsIdrSZYAFFKpw0xy0OtF1PpuwMaREoRabnlVw6Bb3Hofg50XA3JxemzAX6fB92ee+NfXfeL4UtC4vG1K9JyiXHtHq8p9Uw2W03ehIEeNa3xdoRRnLmD4VUpyfL19ViE2+7TM1Gd3TogjDT+AMOCSuq3MCgYBsurPH7gaq/LVT+mRAzgj4l8v4YUlwuGeTbIMJdvt7HXUWB4CDLH3U2CYnUpAQKrZyJok6ahEmIr1xiKggKP7lmmHL8eNo0icpHrtXfzi7Q8Q/PCpzs4dtioXTjaIkS5nNvzVyG/uL+RyuZmpsxrZ5dYM4KbAhchfwORMutxEZhwKBgQC5zpVw4jCEItBmNuTWO+nTScGvxTgfiXIVw+XLaQa2AJoZlhAL34yPWdffko79tv3lgweY9HsimZXO2rU8dbp8mo5c6ydhy8HPXUeWOcAkDSdv/ApWENW9jgYsRIC3swHY3Fl+Dv3Wjce8huQI3mjwaYvRmBhIToxfmHnscVhTBQKBgB9uciEHfz8hMI7ePrPo2PkyK/RbJDm3HnuWE2lFBp7MOUMlh53MXwv4dIRaYMbRrFuN1UIKEFxuKhWwTHSzZJufk/UENrha/81fpj2BoFsAKkEunKeETvaIh6fZSjec16h2+zxbzwkdS6b+yIYkSlaoAxmDYrMtae0C8G4e0YS9";
String pubKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArXYL3H6M2O33v8elJV0fxX3/PsF/vgohtOWFUWnw3vdDvMuSiQDGdeek4GoxFF0kcimagEs+4laDAHLuRanytSrjjnY0wINCxXv7cCGbypgKh3AkktqY1F5NH06WRIEOZZgwitdjINO2F76/gXh4xfpAacESTDzBv/gxgQ2DRTXkUialsqKbesshedvLKAMpByFEO007pbSVeSDwq740UEKxnSf0LQnRNL2YPrQNPZxTewKoK2lPfZCL88ktLKsrI/qT9UiUZk0UhrZVQDt5iC35FznpGZdSg+tBuwhfuwSGmlvNxTw+ebWYQBoZ2yzGMoquzoiMlOtS00XDUmidLQIDAQAB";
rsaSigner signer = new rsaSigner();
Map<String, Object> data = new HashMap<>();
data.put("amount", "2.00000000");
data.put("source_coin", "eth");
data.put("target_coin", "usdt_erc20");
data.put("user_id", "1");
data.put("trade_id", "1394934189494173697");
data.put("time", "1621493658");
try {
Map<String, Object> params = new HashMap<>();
params.put("data", data);
params.put("sign", signer.genSign(data, priKey));
Gson gson = new GsonBuilder().create();
System.out.println("params = " + gson.toJson(params));
String res;
// platform request shop callback API
// res = doPost("http://api.shophost.com/exchange/order/check", gson.toJson(params));
// if (null == res) {
// throw new RuntimeException("http error");
// }
// mock response from shop callback API
{
res = """
{
"status":200,
"data":{
"time":1620617260,
"trade_id":"202105101123221335892766889804"
},
"sign":"YbRyMoUmsCxLbWopD2JD5EZqkT+pIRARsdTSFo+WyhebOMP/TZ96zV/vy4CYn+9gk6nJ55acFnqSO78N4/uemiOyBgE+a8SaIjutc+kFCWGaCorboy9alFBFUbYPvHvFFKHNFJx19Z2cyv9uceGdOdz09g0OBgp8bTyfkCUNrhbUmut2M2S2ixSH3wSefqUq2SUpohb5hlD6tOsyO3JfZr7M/16aiRGcEye2XglsOMFTO5XRkj4hwHKB+nHacttvuZKnGH67ELyoajCc+ef1DkmzmO3P7vFLIuVtVXQ2FPlXVkzCR/+VesyDOpYogHwqyR1BzCCSzxpbZ/aFc/uANg=="
}
""";
}
System.out.println("response = " + res);
JsonParser jp = new JsonParser();
JsonObject resEle = jp.parse(res).getAsJsonObject();
boolean retSignOK = signer.verifySign(resEle.get("data"), resEle.get("sign").getAsString(), pubKey);
if (!retSignOK) {
throw new RuntimeException("verify response sign fail");
}
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("OK");
}
返回结果示例:
{
"status":200,
"data":{
"time":1620617260,
"trade_id":"202105101123221335892766889804"
},
"sign":"YbRyMoUmsCxLbWopD2JD5EZqkT+pIRARsdTSFo+WyhebOMP/TZ96zV/vy4CYn+9gk6nJ55acFnqSO78N4/uemiOyBgE+a8SaIjutc+kFCWGaCorboy9alFBFUbYPvHvFFKHNFJx19Z2cyv9uceGdOdz09g0OBgp8bTyfkCUNrhbUmut2M2S2ixSH3wSefqUq2SUpohb5hlD6tOsyO3JfZr7M/16aiRGcEye2XglsOMFTO5XRkj4hwHKB+nHacttvuZKnGH67ELyoajCc+ef1DkmzmO3P7vFLIuVtVXQ2FPlXVkzCR/+VesyDOpYogHwqyR1BzCCSzxpbZ/aFc/uANg=="
}
- 商户兑换订单风控二次复核接口
- 注意:平台给商户分配单独的风控公钥(与充值/提现公钥不同)
- 该接口使用单独的 rsa密钥对,商户和平台各生成一对rsa密钥
- 请求时,平台私钥签名生成sign,商户使用平台公钥解密验证签名
- 响应时,商户使用商户私钥加密签名,平台使用商户公钥解签
- 签名参数规则跟api接口签名规则一致
HTTP Request
POST 具体回调地址,由商户提供给平台方
请求参数
| 参数名 | 必选 | 类型 | 说明 |
|---|---|---|---|
| data | 否 | string | 如下 |
| data.trade_id | 是 | string | 商户端交易唯一ID |
| data.user_id | 是 | string | 订单所属用户 |
| data.source_coin | 是 | string | 原币种,币种名称小写,以平台提供的币种为准 |
| data.target_coin | 是 | string | 目标币种,币种名称小写,以平台提供的币种为准 |
| data.amount | 是 | decimal(20,8) | 兑换金额 |
| data.time | 是 | int | 当前时间戳 |
| sign | 是 | string | 对data内数据签名 |
返回参数说明
| 参数名 | 类型 | 说明 |
|---|---|---|
| status | int | 200 通过,2001 等待审核,5400 签名验证不通过,5401 时间小于30s,5402 订单号不存在,5001 平台order_id有差异,5002 金额不对,5003 用户uid不对,5004 地址不对,5005 币种symbol不对,5006 订单拒绝,5007 其他,描述信息可自行扩展 |
| msg | string | 状态描述 |
| data | jsonObject | |
| data.time | int | 当前时间 |
| data.trade_id | String | 订单Id |
| sign | string | 签名-对响应参数中的data字段内容的签名 |
- status=200;该笔订单直接通过
- status in (2001,5400);订单会进入等待下次请求队列,如果商户服务器发生未知错误,请捕获后给出2001的状态码,这样下次就还会请求,如果给了其他状态码,则会被标记为拒绝,不再请求
- status=其他;订单直接拒绝
mpc订单复核接口
$url = "http://*****/mpc/order/check";
$header = [
'Content-Type:application/json',
];
$params = [
"data" => [
"amount" => 2.00000000,
"coin_symbol" => "USDT_TRC20",
"address" => "TLhdZuFU1fDPnzxPoXfJ6WZZMpKzY15DUi",
"user_id" => "1",
"order_id" => "1394934189494173697",
"timestamp" => 1621493658
],
"sign" => "dLtK+uiPcnxt2ACKMbBqQ6wI5ttAvesOHzK5ybVID1R6hqYPDTkagl7Tsjr5iLJafehcSLTZyJLtCRI8O2CtIWQUUroGXBneHZC486NUi/4FMOQs0FaAgm17pWlbhX5/96cWXXXMVeoe3IZFKaFNYSWaA14v3RcdDU6QDE/9ixGiSJ0DIxm9NKA0+RkbIFbyYeuFn8d63OcjmUhv7tsOE6rKCc3Q2yi7Qe9i6BNAQFYMFATztb18MsxsBHKUxNqklqyVnl0ofETAHmQhfOHLmungOJQnOqAAuwfmRtg50Qci5F+R2mXeqjmIXko/u3E+DLYW1ygDBp3afKZmU4PwmA=="
];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
$return = curl_exec($ch);
print_r($return);
var url = "http://*****/mpc/order/check"
data := map[string]interface{}{
"data": map[string]string{
"amount":"2.00000000",
"coin_symbol":"USDT_TRC20",
"address":"TLhdZuFU1fDPnzxPoXfJ6WZZMpKzY15DUi",
"user_id":"1",
"order_id":"1394934189494173697",
"timestamp":"1621493658",
},
"sign": "OTA8utI8y8G93p7RPCyb4qIilFQ0B4Aq4iUjhaXWK9m2kgektqlHOASDKXT2VE7NPNysrGycYlVfjDR2WGZn1G66phHo3qa9CcCNpG9klOBEuBEMjiVbb/d8AXcxEzvQr9OCwNsikyxonyzLiY/lsNHeGm9cC5eRvlNLdUSVBipH+ajPd0lDHCayZPs1eCMfbm/xnf8e2lfy6z0UPOpHGfyX/0+hz99Ir5Xnx+0sBBzyZZJxKm4ROid5aDv/9m9guILpURae+Yw/IrkYF4uAKGX+/44cBvtTRQSdX76CAOBSiywZa6BAgDYBLRtkAPM+i+vwNzFBovqHUvI+4Ponaw==",
}
dataType, _ := json.Marshal(data)
resp, err := http.Post(url, "application/json", strings.NewReader(string(dataType)))
if err != nil {
fmt.Println(err)
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Println(err)
}
fmt.Println(string(body))
let HTTP = require('http')
let postData = {
"data": {
"amount":"2.00000000",
"coin_symbol":"USDT_TRC20",
"address":"TLhdZuFU1fDPnzxPoXfJ6WZZMpKzY15DUi",
"user_id":"1",
"order_id":"1394934189494173697",
"timestamp":"1621493658",
},
"sign": "OTA8utI8y8G93p7RPCyb4qIilFQ0B4Aq4iUjhaXWK9m2kgektqlHOASDKXT2VE7NPNysrGycYlVfjDR2WGZn1G66phHo3qa9CcCNpG9klOBEuBEMjiVbb/d8AXcxEzvQr9OCwNsikyxonyzLiY/lsNHeGm9cC5eRvlNLdUSVBipH+ajPd0lDHCayZPs1eCMfbm/xnf8e2lfy6z0UPOpHGfyX/0+hz99Ir5Xnx+0sBBzyZZJxKm4ROid5aDv/9m9guILpURae+Yw/IrkYF4uAKGX+/44cBvtTRQSdX76CAOBSiywZa6BAgDYBLRtkAPM+i+vwNzFBovqHUvI+4Ponaw==",
};
let POST_OPTIONS = {
port: 80,
host: "api.xxxx.com",
path: "/mpc/order/check",
method: 'POST',
headers: {
"Content-Type": "application/json; charset=utf-8"
}
};
const REQUEST = HTTP.request(POST_OPTIONS,function (res) {
let data = []
res.on('data', chunk => {
data.push(...chunk)
})
res.on('end', () => {
let _date = JSON.parse( new TextDecoder().decode(new Uint8Array(data)))
console.log(_date)
})
});
REQUEST.setTimeout(6000)
REQUEST.write(JSON.stringify(postData), 'utf8')
REQUEST.end()
public static void main() {
String priKey = "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCtdgvcfozY7fe/x6UlXR/Fff8+wX++CiG05YVRafDe90O8y5KJAMZ156TgajEUXSRyKZqASz7iVoMAcu5FqfK1KuOOdjTAg0LFe/twIZvKmAqHcCSS2pjUXk0fTpZEgQ5lmDCK12Mg07YXvr+BeHjF+kBpwRJMPMG/+DGBDYNFNeRSJqWyopt6yyF528soAykHIUQ7TTultJV5IPCrvjRQQrGdJ/QtCdE0vZg+tA09nFN7AqgraU99kIvzyS0sqysj+pP1SJRmTRSGtlVAO3mILfkXOekZl1KD60G7CF+7BIaaW83FPD55tZhAGhnbLMYyiq7OiIyU61LTRcNSaJ0tAgMBAAECggEBAIGgGKcSzxCBbMYdXLV6TPbZ/HeaRGrwyVWUu7cmc0E8CJu6iWvmb2jGzbiCwuCT5luF6ZZ8JKchvU4FlTfsE5r9TQY2IZ/Ht4s65qBaDUEts5iY3kv8HX9+ZSXDJZpV0ztqqsPmx4ZNj+NYwWXwcFiKdb5R8OmV8bgSsnPddD6wFhwewglUOBPRAjropHE4sqk1Vam6q1MlFq5kiekMn/CItyFYFFzST/ruqAtVTp7YIvazAMrfCKH+pvXWk6pYNHZmL/JZey0GglRyJ1nItiqL33X8Lji056FcbAclidq022h/KPLEJpZk6irWqYdqYZeF6YMLHtdZFDkTZ/hXY+UCgYEA5i794UTQ1Kd6K+iui/S8K5H8nGdiXb3+uZ5j5VKYfbRmzXhAdVYisYe8czeTECxhH+MeHgM4tLR4ifx9q60ylvZxl9Fav1p6EaE36YcvGVmpm7Gm3q6QDDBa4gB+X9u7CxCS4LpotV917YS1QvOIF9lnRonSj1zNzFtbXkywrN8CgYEAwOpx/mR40ZvgZxNCq9DsIdrSZYAFFKpw0xy0OtF1PpuwMaREoRabnlVw6Bb3Hofg50XA3JxemzAX6fB92ee+NfXfeL4UtC4vG1K9JyiXHtHq8p9Uw2W03ehIEeNa3xdoRRnLmD4VUpyfL19ViE2+7TM1Gd3TogjDT+AMOCSuq3MCgYBsurPH7gaq/LVT+mRAzgj4l8v4YUlwuGeTbIMJdvt7HXUWB4CDLH3U2CYnUpAQKrZyJok6ahEmIr1xiKggKP7lmmHL8eNo0icpHrtXfzi7Q8Q/PCpzs4dtioXTjaIkS5nNvzVyG/uL+RyuZmpsxrZ5dYM4KbAhchfwORMutxEZhwKBgQC5zpVw4jCEItBmNuTWO+nTScGvxTgfiXIVw+XLaQa2AJoZlhAL34yPWdffko79tv3lgweY9HsimZXO2rU8dbp8mo5c6ydhy8HPXUeWOcAkDSdv/ApWENW9jgYsRIC3swHY3Fl+Dv3Wjce8huQI3mjwaYvRmBhIToxfmHnscVhTBQKBgB9uciEHfz8hMI7ePrPo2PkyK/RbJDm3HnuWE2lFBp7MOUMlh53MXwv4dIRaYMbRrFuN1UIKEFxuKhWwTHSzZJufk/UENrha/81fpj2BoFsAKkEunKeETvaIh6fZSjec16h2+zxbzwkdS6b+yIYkSlaoAxmDYrMtae0C8G4e0YS9";
String pubKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArXYL3H6M2O33v8elJV0fxX3/PsF/vgohtOWFUWnw3vdDvMuSiQDGdeek4GoxFF0kcimagEs+4laDAHLuRanytSrjjnY0wINCxXv7cCGbypgKh3AkktqY1F5NH06WRIEOZZgwitdjINO2F76/gXh4xfpAacESTDzBv/gxgQ2DRTXkUialsqKbesshedvLKAMpByFEO007pbSVeSDwq740UEKxnSf0LQnRNL2YPrQNPZxTewKoK2lPfZCL88ktLKsrI/qT9UiUZk0UhrZVQDt5iC35FznpGZdSg+tBuwhfuwSGmlvNxTw+ebWYQBoZ2yzGMoquzoiMlOtS00XDUmidLQIDAQAB";
rsaSigner signer = new rsaSigner();
Map<String, Object> data = new HashMap<>();
data.put("amount", "2.00000000");
data.put("coin_symbol", "USDT_TRC20");
data.put("address", "TLhdZuFU1fDPnzxPoXfJ6WZZMpKzY15DUi");
data.put("user_id", "1");
data.put("order_id", "1394934189494173697");
data.put("timestamp", "1621493658");
try {
Map<String, Object> params = new HashMap<>();
params.put("data", data);
params.put("sign", signer.genSign(data, priKey));
Gson gson = new GsonBuilder().create();
System.out.println("params = " + gson.toJson(params));
String res;
// platform request shop callback API
// res = doPost("http://api.shophost.com/mpc/order/check", gson.toJson(params));
// if (null == res) {
// throw new RuntimeException("http error");
// }
// mock response from shop callback API
{
res = """
{
"status":200,
"data":{
"time":1620617260,
"trade_id":"202105101123221335892766889804"
},
"sign":"YbRyMoUmsCxLbWopD2JD5EZqkT+pIRARsdTSFo+WyhebOMP/TZ96zV/vy4CYn+9gk6nJ55acFnqSO78N4/uemiOyBgE+a8SaIjutc+kFCWGaCorboy9alFBFUbYPvHvFFKHNFJx19Z2cyv9uceGdOdz09g0OBgp8bTyfkCUNrhbUmut2M2S2ixSH3wSefqUq2SUpohb5hlD6tOsyO3JfZr7M/16aiRGcEye2XglsOMFTO5XRkj4hwHKB+nHacttvuZKnGH67ELyoajCc+ef1DkmzmO3P7vFLIuVtVXQ2FPlXVkzCR/+VesyDOpYogHwqyR1BzCCSzxpbZ/aFc/uANg=="
}
""";
}
System.out.println("response = " + res);
JsonParser jp = new JsonParser();
JsonObject resEle = jp.parse(res).getAsJsonObject();
boolean retSignOK = signer.verifySign(resEle.get("data"), resEle.get("sign").getAsString(), pubKey);
if (!retSignOK) {
throw new RuntimeException("verify response sign fail");
}
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("OK");
}
返回结果示例:
{
"status":200,
"data":{
"is_valid": 1,
"timestamp":1620617260,
"order_id":"1394934189494173697"
},
"sign":"YbRyMoUmsCxLbWopD2JD5EZqkT+pIRARsdTSFo+WyhebOMP/TZ96zV/vy4CYn+9gk6nJ55acFnqSO78N4/uemiOyBgE+a8SaIjutc+kFCWGaCorboy9alFBFUbYPvHvFFKHNFJx19Z2cyv9uceGdOdz09g0OBgp8bTyfkCUNrhbUmut2M2S2ixSH3wSefqUq2SUpohb5hlD6tOsyO3JfZr7M/16aiRGcEye2XglsOMFTO5XRkj4hwHKB+nHacttvuZKnGH67ELyoajCc+ef1DkmzmO3P7vFLIuVtVXQ2FPlXVkzCR/+VesyDOpYogHwqyR1BzCCSzxpbZ/aFc/uANg=="
}
- 商户mpc提现订单复核接口
- 注意:平台给商户分配单独的mpc公钥(与充值/提现/风控公钥不同)
- 该接口使用单独的 rsa密钥对,商户和平台各生成一对rsa密钥
- 请求时,平台使用私钥签名生成sign,商户使用平台公钥解密验证签名
- 响应时,商户使用商户私钥加密签名,平台使用商户公钥解签
- 签名参数规则跟api接口签名规则一致
HTTP Request
POST 具体回调地址,由商户提供给平台方
请求参数
| 参数名 | 必选 | 类型 | 说明 |
|---|---|---|---|
| data | 否 | string | 如下 |
| data.order_id | 是 | string | 商户端交易唯一ID(提现时的 trade_id) |
| data.user_id | 是 | string | 订单所属用户 |
| data.coin_symbol | 是 | string | 币种名称小写,以平台提供的币种为准 |
| data.address | 是 | string | 提现地址 |
| data.amount | 是 | decimal(20,8) | 提现金额 |
| data.timestamp | 是 | int | 当前时间戳 |
| sign | 是 | string | 对data内数据签名 |
返回参数说明
| 参数名 | 类型 | 说明 |
|---|---|---|
| status | int | 200 通过,2001 等待审核,5400 签名验证不通过,5401 时间小于30s,5402 订单号不存在,5001 平台order_id有差异,5002 金额不对,5003 用户uid不对,5004 地址不对,5005 币种symbol不对,5006 订单拒绝,5007 其他,描述信息可自行扩展 |
| msg | string | 状态描述 |
| data | jsonObject | |
| data.is_valid | int | 1 通过;2 不通过 |
| data.order_id | string | 订单号 |
| data.timestamp | int | 当前时间 |
| sign | string | 签名-对响应参数中的data字段内容的签名 |
H5充值
创建订单
$url = "/h5_order/create";
$header = [
'Content-Type:application/json',
];
$params = [
"version": "1.0",
"app_id": "hxgmamt86qk",
"time": "1663741239",
"sign": "nR+UEj2oCup5bhcxrQlJ24+jeq3AMHdnC5BfOxaqCKwE6EcPc1020ogHHcZ0sLeqAg==",
"amount": "0.0013",
"currency": "usd",
"merchant_order_id" :"8MrxIV1lJd",
"return_url" :"http://xxxx.com",
"lang" :"en"
];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
$return = curl_exec($ch);
print_r($return);
var url = "/h5_order/create"
data := map[string]string{
"version": "1.0",
"app_id": "hxgmamt86qk",
"time": "1663741239",
"sign": "nR+UEj2oCup5bhcxrQlJ24+jeq3AMHdnC5BfOxaqCKwE6EcPc1020ogHHcZ0sLeqAg==",
"amount": "0.0013",
"currency": "usd",
"merchant_order_id" :"8MrxIV1lJd",
"return_url" :"http://xxxx.com",
"lang" :"en",
}
dataType, _ := json.Marshal(data)
resp, err := http.Post(url, "application/json", strings.NewReader(string(dataType)))
if err != nil {
fmt.Println(err)
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Println(err)
}
fmt.Println(string(body))
let HTTP = require('http')
let postData = {
"version": "1.0",
"app_id": "hxgmamt86qk",
"time": "1663741239",
"sign": "nR+UEj2oCup5bhcxrQlJ24+jeq3AMHdnC5BfOxaqCKwE6EcPc1020ogHHcZ0sLeqAg==",
"amount": "0.0013",
"currency": "usd",
"merchant_order_id" :"8MrxIV1lJd",
"return_url" :"http://xxxx.com",
"lang" :"en",
};
let POST_OPTIONS = {
port: 80,
host: "api.xxxx.com",
path: "/shopapi/h5_order/create",
method: 'POST',
headers: {
"Content-Type": "application/json; charset=utf-8"
}
};
const REQUEST = HTTP.request(POST_OPTIONS,function (res) {
let data = []
res.on('data', chunk => {
data.push(...chunk)
})
res.on('end', () => {
let _date = JSON.parse( new TextDecoder().decode(new Uint8Array(data)))
console.log(_date)
})
});
REQUEST.setTimeout(6000)
REQUEST.write(JSON.stringify(postData), 'utf8')
REQUEST.end()
public static void main(String[] args) {
// 完整实例请查看"签名规则"中的Java示例代码
String baseUrl = "http://api.xxxx.com/shopapi";
String priKey = "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCtdgvcfozY7fe/x6UlXR/Fff8+wX++CiG05YVRafDe90O8y5KJAMZ156TgajEUXSRyKZqASz7iVoMAcu5FqfK1KuOOdjTAg0LFe/twIZvKmAqHcCSS2pjUXk0fTpZEgQ5lmDCK12Mg07YXvr+BeHjF+kBpwRJMPMG/+DGBDYNFNeRSJqWyopt6yyF528soAykHIUQ7TTultJV5IPCrvjRQQrGdJ/QtCdE0vZg+tA09nFN7AqgraU99kIvzyS0sqysj+pP1SJRmTRSGtlVAO3mILfkXOekZl1KD60G7CF+7BIaaW83FPD55tZhAGhnbLMYyiq7OiIyU61LTRcNSaJ0tAgMBAAECggEBAIGgGKcSzxCBbMYdXLV6TPbZ/HeaRGrwyVWUu7cmc0E8CJu6iWvmb2jGzbiCwuCT5luF6ZZ8JKchvU4FlTfsE5r9TQY2IZ/Ht4s65qBaDUEts5iY3kv8HX9+ZSXDJZpV0ztqqsPmx4ZNj+NYwWXwcFiKdb5R8OmV8bgSsnPddD6wFhwewglUOBPRAjropHE4sqk1Vam6q1MlFq5kiekMn/CItyFYFFzST/ruqAtVTp7YIvazAMrfCKH+pvXWk6pYNHZmL/JZey0GglRyJ1nItiqL33X8Lji056FcbAclidq022h/KPLEJpZk6irWqYdqYZeF6YMLHtdZFDkTZ/hXY+UCgYEA5i794UTQ1Kd6K+iui/S8K5H8nGdiXb3+uZ5j5VKYfbRmzXhAdVYisYe8czeTECxhH+MeHgM4tLR4ifx9q60ylvZxl9Fav1p6EaE36YcvGVmpm7Gm3q6QDDBa4gB+X9u7CxCS4LpotV917YS1QvOIF9lnRonSj1zNzFtbXkywrN8CgYEAwOpx/mR40ZvgZxNCq9DsIdrSZYAFFKpw0xy0OtF1PpuwMaREoRabnlVw6Bb3Hofg50XA3JxemzAX6fB92ee+NfXfeL4UtC4vG1K9JyiXHtHq8p9Uw2W03ehIEeNa3xdoRRnLmD4VUpyfL19ViE2+7TM1Gd3TogjDT+AMOCSuq3MCgYBsurPH7gaq/LVT+mRAzgj4l8v4YUlwuGeTbIMJdvt7HXUWB4CDLH3U2CYnUpAQKrZyJok6ahEmIr1xiKggKP7lmmHL8eNo0icpHrtXfzi7Q8Q/PCpzs4dtioXTjaIkS5nNvzVyG/uL+RyuZmpsxrZ5dYM4KbAhchfwORMutxEZhwKBgQC5zpVw4jCEItBmNuTWO+nTScGvxTgfiXIVw+XLaQa2AJoZlhAL34yPWdffko79tv3lgweY9HsimZXO2rU8dbp8mo5c6ydhy8HPXUeWOcAkDSdv/ApWENW9jgYsRIC3swHY3Fl+Dv3Wjce8huQI3mjwaYvRmBhIToxfmHnscVhTBQKBgB9uciEHfz8hMI7ePrPo2PkyK/RbJDm3HnuWE2lFBp7MOUMlh53MXwv4dIRaYMbRrFuN1UIKEFxuKhWwTHSzZJufk/UENrha/81fpj2BoFsAKkEunKeETvaIh6fZSjec16h2+zxbzwkdS6b+yIYkSlaoAxmDYrMtae0C8G4e0YS9";
String pubKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2RZZISModRzproL3eTxRtvVK/nToDbeLmAVdmaVtHgNCwjXMeNCZvHySZKO7+t7XySzBd2PhhQjvAkDd8HRKB5Y0uvP6TFwvhxOMkMydTeBFcUobQWNeAI7ttRms1txSNrmyrZr0WpWfk79VIsO+yI/jFN/Pj2gxD+vh5UUKU1LD2IQq/VxgtEpf8Vs6w7SvafPwYkpdPGCKUFkRvN1FrY2+tq0j1MRVJbB2rIunWDnT8cDUh2sWLXf4yNaJVOaaTFB0zbAk/qcoicGQyW7bVG7dVW8WywKmOAPeQCCQa+SJ4BhfI1k8eEAwFVRuxz/f9Ecfog9hZJ+RgELkpS8qhQIDAQAB";
rsaSigner signer = new rsaSigner();
Map<String, Object> params = new HashMap<>();
params.put("app_id", "hxgmau9imt86qky9");
params.put("version", "1.0");
params.put("key_version", "admin");
params.put("time", Long.toString(System.currentTimeMillis() / 1000));
params.put("amount","0.0013");
params.put("currency","usd");
params.put("merchant_order_id","8MrxIV1lJd");
params.put("return_url","http://xxxx.com");
params.put("lang","en");
try {
params.put("sign", signer.genSign(params, priKey));
Gson gson = new GsonBuilder().create();
System.out.println("params = " + gson.toJson(params));
String res = doPost(baseUrl + "/h5_order/create", gson.toJson(params));
if (null == res) {
throw new RuntimeException("http error");
}
System.out.println("response = " + res);
JsonParser jp = new JsonParser();
JsonObject resEle = jp.parse(res).getAsJsonObject();
boolean retSignOK = signer.verifySign(resEle, resEle.get("sign").getAsString(), pubKey);
if (!retSignOK) {
throw new RuntimeException("verify response sign fail");
}
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("OK");
}
返回结果示例:
{
"status":200,
"msg":"success",
"data":{
"order_no":"BCTOTNI57P",
"merchant_order_id":"8MrxIV1lJd",
"amount":"0.0013",
"currency":"usd",
"status":0,
"created_at":1665659047,
"expires_at":1665660847,
"addresses":[
{
"coin":"usdt_erc20",
"address":"0x1708F6b16D5437730D410D983B8D0235c345433c",
"amount":"0.0013"
},
{
"coin":"usdt_trc20",
"address":"TKzqd9hTDgeeQcHf1RXiCuG6vPPFJK8BDP",
"amount":"0.0013"
}
],
"return_url":"https://xxx.com/pay",
"checkout_url":"http://api.xxxx.com/order/BCTOTNI57P?lang=en"
},
"date_time":"2022-10-13 19:04:07",
"time_stamp":1665659047,
"sign":"C4XPA9jK32xYngKAEsb1KEQDyOFBD29H1MqfQNSl4jnxvT2RQHdiUtf2TMX96O2Pv0AGHv3EJU89l6k1hHa5arQ6LQUIbD8c/WbpXvhaoWYbhnrPhrVXcHMFlP714W6hmURWXkauySq5VzB8iS+Bb2HAv"
}
HTTP Request
POST : /h5_order/create
请求参数
| 参数名 | 必选 | 类型 | 说明 |
|---|---|---|---|
| 公共参数 | 是 | string | 公参指:签名(sign)、版本(version)、商户ID(app_id)、时间(time) |
| merchant_order_id | 是 | string | 商家⾃定义订单号 |
| amount | 是 | string | 订单⾦额 |
| currency | 否 | string | 法币币种,默认usd |
| return_url | 否 | string | 页面跳转返回地址 |
| lang | 否 | string | 语⾔ “en”, “ko”, “zh” |
返回参数说明
| 参数名 | 类型 | 说明 |
|---|---|---|
| status | int | 状态码 |
| msg | string | 状态描述 |
| data | jsonObject | 具体见下面 “data细节说明”。 |
| data.order_no | string | 订单号 |
| data.merchant_order_id | string | 商家⾃定义订单号 |
| data.amount | string | 订单⾦额 |
| data.currency | string | 法币币种 |
| data.status | int | 0待⽀付 1已完成 2异常支付 10已取消 |
| data.return_url | string | 返回地址 |
| data.checkout_url | string | 收银台地址 |
| data.expires_time | int | 订单过期时间 |
| data.create_time | int | 创建时间 |
| data.addresses | jsonArray | 地址信息 |
| data.addresses.coin | string | 币名 |
| data.addresses.address | string | 地址 |
| data.addresses.amount | string | 应支付币种数额 |
| date_time | string | 响应时间 |
| time_stamp | int | 响应时间单位秒 |
| sign | string | 签名 |
订单取消
$url = "/h5_order/cancel";
$header = [
'Content-Type:application/json',
];
$params = [
"version": "1.0",
"app_id": "hxgmamt86qk",
"time": "1663741239",
"sign": "nR+UEj2oCup5bhcxrQlJ24+jeq3AMHdnC5BfOxaqCKwE6EcPc1020ogHHcZ0sLeqAg==",
"order_no": "test123",
];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
$return = curl_exec($ch);
print_r($return);
var url = "/h5_order/cancel"
data := map[string]string{
"version": "1.0",
"app_id": "hxgmamt86qk",
"time": "1663741239",
"sign": "nR+UEj2oCup5bhcxrQlJ24+jeq3AMHdnC5BfOxaqCKwE6EcPc1020ogHHcZ0sLeqAg==",
"order_no": "test123",
}
dataType, _ := json.Marshal(data)
resp, err := http.Post(url, "application/json", strings.NewReader(string(dataType)))
if err != nil {
fmt.Println(err)
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Println(err)
}
fmt.Println(string(body))
let HTTP = require('http')
let postData = {
"version": "1.0",
"app_id": "hxgmamt86qk",
"time": "1663741239",
"sign": "nR+UEj2oCup5bhcxrQlJ24+jeq3AMHdnC5BfOxaqCKwE6EcPc1020ogHHcZ0sLeqAg==",
"order_no": "test123",
};
let POST_OPTIONS = {
port: 80,
host: "api.xxxx.com",
path: "/shopapi/h5_order/cancel",
method: 'POST',
headers: {
"Content-Type": "application/json; charset=utf-8"
}
};
const REQUEST = HTTP.request(POST_OPTIONS,function (res) {
let data = []
res.on('data', chunk => {
data.push(...chunk)
})
res.on('end', () => {
let _date = JSON.parse( new TextDecoder().decode(new Uint8Array(data)))
console.log(_date)
})
});
REQUEST.setTimeout(6000)
REQUEST.write(JSON.stringify(postData), 'utf8')
REQUEST.end()
public static void main(String[] args) {
// 完整实例请查看"签名规则"中的Java示例代码
String baseUrl = "http://api.xxxx.com/shopapi";
String priKey = "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCtdgvcfozY7fe/x6UlXR/Fff8+wX++CiG05YVRafDe90O8y5KJAMZ156TgajEUXSRyKZqASz7iVoMAcu5FqfK1KuOOdjTAg0LFe/twIZvKmAqHcCSS2pjUXk0fTpZEgQ5lmDCK12Mg07YXvr+BeHjF+kBpwRJMPMG/+DGBDYNFNeRSJqWyopt6yyF528soAykHIUQ7TTultJV5IPCrvjRQQrGdJ/QtCdE0vZg+tA09nFN7AqgraU99kIvzyS0sqysj+pP1SJRmTRSGtlVAO3mILfkXOekZl1KD60G7CF+7BIaaW83FPD55tZhAGhnbLMYyiq7OiIyU61LTRcNSaJ0tAgMBAAECggEBAIGgGKcSzxCBbMYdXLV6TPbZ/HeaRGrwyVWUu7cmc0E8CJu6iWvmb2jGzbiCwuCT5luF6ZZ8JKchvU4FlTfsE5r9TQY2IZ/Ht4s65qBaDUEts5iY3kv8HX9+ZSXDJZpV0ztqqsPmx4ZNj+NYwWXwcFiKdb5R8OmV8bgSsnPddD6wFhwewglUOBPRAjropHE4sqk1Vam6q1MlFq5kiekMn/CItyFYFFzST/ruqAtVTp7YIvazAMrfCKH+pvXWk6pYNHZmL/JZey0GglRyJ1nItiqL33X8Lji056FcbAclidq022h/KPLEJpZk6irWqYdqYZeF6YMLHtdZFDkTZ/hXY+UCgYEA5i794UTQ1Kd6K+iui/S8K5H8nGdiXb3+uZ5j5VKYfbRmzXhAdVYisYe8czeTECxhH+MeHgM4tLR4ifx9q60ylvZxl9Fav1p6EaE36YcvGVmpm7Gm3q6QDDBa4gB+X9u7CxCS4LpotV917YS1QvOIF9lnRonSj1zNzFtbXkywrN8CgYEAwOpx/mR40ZvgZxNCq9DsIdrSZYAFFKpw0xy0OtF1PpuwMaREoRabnlVw6Bb3Hofg50XA3JxemzAX6fB92ee+NfXfeL4UtC4vG1K9JyiXHtHq8p9Uw2W03ehIEeNa3xdoRRnLmD4VUpyfL19ViE2+7TM1Gd3TogjDT+AMOCSuq3MCgYBsurPH7gaq/LVT+mRAzgj4l8v4YUlwuGeTbIMJdvt7HXUWB4CDLH3U2CYnUpAQKrZyJok6ahEmIr1xiKggKP7lmmHL8eNo0icpHrtXfzi7Q8Q/PCpzs4dtioXTjaIkS5nNvzVyG/uL+RyuZmpsxrZ5dYM4KbAhchfwORMutxEZhwKBgQC5zpVw4jCEItBmNuTWO+nTScGvxTgfiXIVw+XLaQa2AJoZlhAL34yPWdffko79tv3lgweY9HsimZXO2rU8dbp8mo5c6ydhy8HPXUeWOcAkDSdv/ApWENW9jgYsRIC3swHY3Fl+Dv3Wjce8huQI3mjwaYvRmBhIToxfmHnscVhTBQKBgB9uciEHfz8hMI7ePrPo2PkyK/RbJDm3HnuWE2lFBp7MOUMlh53MXwv4dIRaYMbRrFuN1UIKEFxuKhWwTHSzZJufk/UENrha/81fpj2BoFsAKkEunKeETvaIh6fZSjec16h2+zxbzwkdS6b+yIYkSlaoAxmDYrMtae0C8G4e0YS9";
String pubKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2RZZISModRzproL3eTxRtvVK/nToDbeLmAVdmaVtHgNCwjXMeNCZvHySZKO7+t7XySzBd2PhhQjvAkDd8HRKB5Y0uvP6TFwvhxOMkMydTeBFcUobQWNeAI7ttRms1txSNrmyrZr0WpWfk79VIsO+yI/jFN/Pj2gxD+vh5UUKU1LD2IQq/VxgtEpf8Vs6w7SvafPwYkpdPGCKUFkRvN1FrY2+tq0j1MRVJbB2rIunWDnT8cDUh2sWLXf4yNaJVOaaTFB0zbAk/qcoicGQyW7bVG7dVW8WywKmOAPeQCCQa+SJ4BhfI1k8eEAwFVRuxz/f9Ecfog9hZJ+RgELkpS8qhQIDAQAB";
rsaSigner signer = new rsaSigner();
Map<String, Object> params = new HashMap<>();
params.put("app_id", "hxgmau9imt86qky9");
params.put("version", "1.0");
params.put("key_version", "admin");
params.put("time", Long.toString(System.currentTimeMillis() / 1000));
params.put("order_no","test123");
try {
params.put("sign", signer.genSign(params, priKey));
Gson gson = new GsonBuilder().create();
System.out.println("params = " + gson.toJson(params));
String res = doPost(baseUrl + "/h5_order/cancel", gson.toJson(params));
if (null == res) {
throw new RuntimeException("http error");
}
System.out.println("response = " + res);
JsonParser jp = new JsonParser();
JsonObject resEle = jp.parse(res).getAsJsonObject();
boolean retSignOK = signer.verifySign(resEle, resEle.get("sign").getAsString(), pubKey);
if (!retSignOK) {
throw new RuntimeException("verify response sign fail");
}
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("OK");
}
返回结果示例:
{
"status": 200,
"msg": "success",
"data": [],
"date_time": "2020-11-23 16:51:51",
"time_stamp": 1606121511,
"sign": "OotOCtyUPfYQFjE+FEPMQQK5PQ2eGJtcvwNBCI0ilTpNn/B9gBtzR+ibmyK00kW/bg=="
}
HTTP Request
POST : /h5_order/cancel
请求参数
| 参数名 | 必选 | 类型 | 说明 |
|---|---|---|---|
| 公共参数 | 是 | string | 公参指:签名(sign)、版本(version)、商户ID(app_id)、时间(time) |
| order_no | 是 | string | 平台订单号 |
返回参数说明
| 参数名 | 类型 | 说明 |
|---|---|---|
| status | int | 状态码 |
| msg | string | 状态描述 |
| data | array | 为空 |
| date_time | string | 响应时间 |
| time_stamp | int | 响应时间单位秒 |
| sign | string | 签名 |
订单详情
$url = "/h5_order/detail";
$header = [
'Content-Type:application/json',
];
$params = [
"version": "1.0",
"app_id": "hxgmamt86qk",
"time": "1663741239",
"sign": "nR+UEj2oCup5bhcxrQlJ24+jeq3AMHdnC5BfOxaqCKwE6EcPc1020ogHHcZ0sLeqAg==",
"order_no": "JDYFJEEA7T",
];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
$return = curl_exec($ch);
print_r($return);
var url = "/h5_order/detail"
data := map[string]string{
"version": "1.0",
"app_id": "hxgmamt86qk",
"time": "1663741239",
"sign": "nR+UEj2oCup5bhcxrQlJ24+jeq3AMHdnC5BfOxaqCKwE6EcPc1020ogHHcZ0sLeqAg==",
"order_no": "JDYFJEEA7T",
}
dataType, _ := json.Marshal(data)
resp, err := http.Post(url, "application/json", strings.NewReader(string(dataType)))
if err != nil {
fmt.Println(err)
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Println(err)
}
fmt.Println(string(body))
let HTTP = require('http')
let postData = {
"version": "1.0",
"app_id": "hxgmamt86qk",
"time": "1663741239",
"sign": "nR+UEj2oCup5bhcxrQlJ24+jeq3AMHdnC5BfOxaqCKwE6EcPc1020ogHHcZ0sLeqAg==",
"order_no": "JDYFJEEA7T",
};
let POST_OPTIONS = {
port: 80,
host: "api.xxxx.com",
path: "/shopapi/h5_order/detail",
method: 'POST',
headers: {
"Content-Type": "application/json; charset=utf-8"
}
};
const REQUEST = HTTP.request(POST_OPTIONS,function (res) {
let data = []
res.on('data', chunk => {
data.push(...chunk)
})
res.on('end', () => {
let _date = JSON.parse( new TextDecoder().decode(new Uint8Array(data)))
console.log(_date)
})
});
REQUEST.setTimeout(6000)
REQUEST.write(JSON.stringify(postData), 'utf8')
REQUEST.end()
public static void main(String[] args) {
// 完整实例请查看"签名规则"中的Java示例代码
String baseUrl = "http://api.xxxx.com/shopapi";
String priKey = "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCtdgvcfozY7fe/x6UlXR/Fff8+wX++CiG05YVRafDe90O8y5KJAMZ156TgajEUXSRyKZqASz7iVoMAcu5FqfK1KuOOdjTAg0LFe/twIZvKmAqHcCSS2pjUXk0fTpZEgQ5lmDCK12Mg07YXvr+BeHjF+kBpwRJMPMG/+DGBDYNFNeRSJqWyopt6yyF528soAykHIUQ7TTultJV5IPCrvjRQQrGdJ/QtCdE0vZg+tA09nFN7AqgraU99kIvzyS0sqysj+pP1SJRmTRSGtlVAO3mILfkXOekZl1KD60G7CF+7BIaaW83FPD55tZhAGhnbLMYyiq7OiIyU61LTRcNSaJ0tAgMBAAECggEBAIGgGKcSzxCBbMYdXLV6TPbZ/HeaRGrwyVWUu7cmc0E8CJu6iWvmb2jGzbiCwuCT5luF6ZZ8JKchvU4FlTfsE5r9TQY2IZ/Ht4s65qBaDUEts5iY3kv8HX9+ZSXDJZpV0ztqqsPmx4ZNj+NYwWXwcFiKdb5R8OmV8bgSsnPddD6wFhwewglUOBPRAjropHE4sqk1Vam6q1MlFq5kiekMn/CItyFYFFzST/ruqAtVTp7YIvazAMrfCKH+pvXWk6pYNHZmL/JZey0GglRyJ1nItiqL33X8Lji056FcbAclidq022h/KPLEJpZk6irWqYdqYZeF6YMLHtdZFDkTZ/hXY+UCgYEA5i794UTQ1Kd6K+iui/S8K5H8nGdiXb3+uZ5j5VKYfbRmzXhAdVYisYe8czeTECxhH+MeHgM4tLR4ifx9q60ylvZxl9Fav1p6EaE36YcvGVmpm7Gm3q6QDDBa4gB+X9u7CxCS4LpotV917YS1QvOIF9lnRonSj1zNzFtbXkywrN8CgYEAwOpx/mR40ZvgZxNCq9DsIdrSZYAFFKpw0xy0OtF1PpuwMaREoRabnlVw6Bb3Hofg50XA3JxemzAX6fB92ee+NfXfeL4UtC4vG1K9JyiXHtHq8p9Uw2W03ehIEeNa3xdoRRnLmD4VUpyfL19ViE2+7TM1Gd3TogjDT+AMOCSuq3MCgYBsurPH7gaq/LVT+mRAzgj4l8v4YUlwuGeTbIMJdvt7HXUWB4CDLH3U2CYnUpAQKrZyJok6ahEmIr1xiKggKP7lmmHL8eNo0icpHrtXfzi7Q8Q/PCpzs4dtioXTjaIkS5nNvzVyG/uL+RyuZmpsxrZ5dYM4KbAhchfwORMutxEZhwKBgQC5zpVw4jCEItBmNuTWO+nTScGvxTgfiXIVw+XLaQa2AJoZlhAL34yPWdffko79tv3lgweY9HsimZXO2rU8dbp8mo5c6ydhy8HPXUeWOcAkDSdv/ApWENW9jgYsRIC3swHY3Fl+Dv3Wjce8huQI3mjwaYvRmBhIToxfmHnscVhTBQKBgB9uciEHfz8hMI7ePrPo2PkyK/RbJDm3HnuWE2lFBp7MOUMlh53MXwv4dIRaYMbRrFuN1UIKEFxuKhWwTHSzZJufk/UENrha/81fpj2BoFsAKkEunKeETvaIh6fZSjec16h2+zxbzwkdS6b+yIYkSlaoAxmDYrMtae0C8G4e0YS9";
String pubKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2RZZISModRzproL3eTxRtvVK/nToDbeLmAVdmaVtHgNCwjXMeNCZvHySZKO7+t7XySzBd2PhhQjvAkDd8HRKB5Y0uvP6TFwvhxOMkMydTeBFcUobQWNeAI7ttRms1txSNrmyrZr0WpWfk79VIsO+yI/jFN/Pj2gxD+vh5UUKU1LD2IQq/VxgtEpf8Vs6w7SvafPwYkpdPGCKUFkRvN1FrY2+tq0j1MRVJbB2rIunWDnT8cDUh2sWLXf4yNaJVOaaTFB0zbAk/qcoicGQyW7bVG7dVW8WywKmOAPeQCCQa+SJ4BhfI1k8eEAwFVRuxz/f9Ecfog9hZJ+RgELkpS8qhQIDAQAB";
rsaSigner signer = new rsaSigner();
Map<String, Object> params = new HashMap<>();
params.put("app_id", "hxgmau9imt86qky9");
params.put("version", "1.0");
params.put("key_version", "admin");
params.put("time", Long.toString(System.currentTimeMillis() / 1000));
params.put("order_no","JDYFJEEA7T");
try {
params.put("sign", signer.genSign(params, priKey));
Gson gson = new GsonBuilder().create();
System.out.println("params = " + gson.toJson(params));
String res = doPost(baseUrl + "/h5_order/detail", gson.toJson(params));
if (null == res) {
throw new RuntimeException("http error");
}
System.out.println("response = " + res);
JsonParser jp = new JsonParser();
JsonObject resEle = jp.parse(res).getAsJsonObject();
boolean retSignOK = signer.verifySign(resEle, resEle.get("sign").getAsString(), pubKey);
if (!retSignOK) {
throw new RuntimeException("verify response sign fail");
}
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("OK");
}
返回结果示例:
{
"status":200,
"msg":"success",
"data":{
"order_no":"JDYFJEEA7T",
"merchant_order_id":"8MrxIV1lJd",
"amount":"0.0013",
"currency":"usd",
"status":1,
"created_at":1664360232,
"expires_at":1664362032,
"addresses":[
{
"coin":"usdt_erc20",
"address":"0x1708F6b16D5437730D410D983B8D0235c345433c",
"amount":"0.0013"
},
{
"coin":"usdt_trc20",
"address":"TKzqd9hTDgeeQcHf1RXiCuG6vPPFJK8BDP",
"amount":"0.0013"
}
],
"payments":[
{
"coin":"usdt_trc20",
"address":"TKzqd9hTDgeeQcHf1RXiCuG6vPPFJK8BDP",
"txid":"422a7eef6af75960efa3e204fee1e642caf0b7d25dccd2678d6ae4e086733096",
"amount":"0.0013",
"confirm_time":1664360357,
"status":1,
"check_status":0
}
],
"return_url":"https://xxx.com/pay"
},
"date_time":"2022-10-13 19:24:26",
"time_stamp":1665660266,
"sign":"ERROp+Kr46ZjjGlIVcNXT0iEpvh8KCyfJNGax3gA5qdfa4Gw+k8qdKoJl+FYBHQsarlsaush8b5uhjFbbJQc7BxvEi+CvbAVm1CkqBITPZHNNr4B3dDBWkn3Fk0m+OLGvW+JB7ueDKy+rzwaFsHw46CIcFBRAdasfieQRqu9TuO+Y4IpFaROxDoicXQLMN28PReVLxAqwAxkZW16ujnviSOHlHlbO+CIxCrKRqZISnUKY8q9Ej649BtE1s0mFwCd9HJ0Ti5oawHAGvwhcw++aEh2cCKMNJ1ICZVqcqf5B6Xt+K2a/M7ifqHORRKjO4GkEWyPVLY27aA/v9329tAeFw=="
}
HTTP Request
POST : /h5_order/detail
请求参数
| 参数名 | 必选 | 类型 | 说明 |
|---|---|---|---|
| 公共参数 | 是 | string | 公参指:签名(sign)、版本(version)、商户ID(app_id)、时间(time) |
| order_no | 是 | string | 平台订单号 |
返回参数说明
| 参数名 | 类型 | 说明 |
|---|---|---|
| status | int | 状态码 |
| msg | string | 状态描述 |
| data | jsonObject | 具体见下面 “data细节说明”。 |
| data.order_no | string | 平台订单号 |
| data.merchant_order_id | string | 商家⾃定义订单号 |
| data.amount | string | 订单⾦额 |
| data.currency | string | 法币币种 |
| data.status | int | 0待⽀付 1已完成 2异常支付 10已取消 |
| data.return_url | string | 返回地址 |
| data.expires_time | int | 订单过期时间 |
| data.create_time | int | 创建时间 |
| data.addresses | jsonObject | 具体见下面 “addresses细节说明”。 |
| data.addresses.coin | string | 币名 |
| data.addresses.address | string | 地址 |
| data.addresses.amount | string | 应支付币种数额 |
| data.payments | jsonObject | 具体见下面 “payments细节说明”。 |
| data.payments.coin | string | 支付币种 |
| data.payments.address | string | 支付地址 |
| data.payments.txid | string | txid |
| data.payments.amount | string | 支付金额 |
| data.payments.confirm_time | int | 确认时间 |
| data.payments.status | int | 状态: 0 待支付 1 正常支付 2 异常支付 |
| data.payments.check_status | int | 异常原因: 1001⽀付⾦额不匹配 1002已完成订单重复⽀付 |
| date_time | string | 响应时间 |
| time_stamp | int | 响应时间单位秒 |
| sign | string | 签名 |
订单回调通知
$url = "具体回调地址,由商户提供给平台方";
$header = [
'Content-Type:application/json',
];
$params = [
"data":[
"order_no":"2020010211153423123456",
"merchant_order_id":"ESIOqIfhKnY",
"status":1,
"payments":[
[
"address":"0x038B8E7406dED2Be112B6c7E4681Df5316957cad",
"coin":"eth",
"txid":"0x038B8E7406dED2Be112B6c7E4681Df5316957cad",
"amount":"0.1"
"confirm_time":"15612312112"
"check_code":"0",
],
]
],
"sign": "ywZa6BAgDYBLRtkAPM+i+vwNzFBovqHUvI+4Ponaw==",
];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
$return = curl_exec($ch);
print_r($return);
var url = "具体回调地址,由商户提供给平台方"
data := map[string]interface{}{
"data": map[string]interface{}{
"order_no": "IGQUNC2WHT",
"merchant_order_id": "ESIOqIfhKnY",
"status": 1,
"payments": []interface{}{
map[string]interface{}{
"address": "0x038B8E7406dED2Be112B6c7E4681Df5316957cad",
"coin": "eth",
"txid": "0x038B8E7406dED2Be112B6c7E4681Df5316957cad",
"amount": "1",
"confirm_time": 15612312112,
"check_code": 1001,
},
},
},
"sign": "OTA8utI8y8G93p7RPCyb4qIilFQ0B4Aq4iUjhaXWK9m2kgektqlHOASDKXT2VE7NPNysrGycYlVfjDR2WGZn1G66phHo3qa9CcCNpG9klOBEuBEMjiVbb/d8AXcxEzvQr9OCwNsikyxonyzLiY/lsNHeGm9cC5eRvlNLdUSVBipH+ajPd0lDHCayZPs1eCMfbm/xnf8e2lfy6z0UPOpHGfyX/0+hz99Ir5Xnx+0sBBzyZZJxKm4ROid5aDv/9m9guILpURae+Yw/IrkYF4uAKGX+/44cBvtTRQSdX76CAOBSiywZa6BAgDYBLRtkAPM+i+vwNzFBovqHUvI+4Ponaw==",
}
dataType, _ := json.Marshal(data)
resp, err := http.Post(url, "application/json", strings.NewReader(string(dataType)))
if err != nil {
fmt.Println(err)
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Println(err)
}
fmt.Println(string(body))
let HTTP = require('http')
let postData = {
"data": {
"order_no": "IGQUNC2WHT",
"merchant_order_id": "ESIOqIfhKnY",
"status": 1,
"payments": [
{
"address": "0x038B8E7406dED2Be112B6c7E4681Df5316957cad",
"coin": "eth",
"txid": "0x038B8E7406dED2Be112B6c7E4681Df5316957cad",
"amount": "1",
"confirm_time": 15612312112,
"check_code": 1001,
},
],
},
"sign": "OTA8utI8y8G93p7RPCyb4qIilFQ0B4Aq4iUjhaXWK9m2kgektqlHOASDKXT2VE7NPNysrGycYlVfjDR2WGZn1G66phHo3qa9CcCNpG9klOBEuBEMjiVbb/d8AXcxEzvQr9OCwNsikyxonyzLiY/lsNHeGm9cC5eRvlNLdUSVBipH+ajPd0lDHCayZPs1eCMfbm/xnf8e2lfy6z0UPOpHGfyX/0+hz99Ir5Xnx+0sBBzyZZJxKm4ROid5aDv/9m9guILpURae+Yw/IrkYF4uAKGX+/44cBvtTRQSdX76CAOBSiywZa6BAgDYBLRtkAPM+i+vwNzFBovqHUvI+4Ponaw==",
};
let POST_OPTIONS = {
port: 80,
host: "具体回调地址,由商户提供给平台方",
path: "",
method: 'POST',
headers: {
"Content-Type": "application/json; charset=utf-8"
}
};
const REQUEST = HTTP.request(POST_OPTIONS,function (res) {
let data = []
res.on('data', chunk => {
data.push(...chunk)
})
res.on('end', () => {
let _date = JSON.parse( new TextDecoder().decode(new Uint8Array(data)))
console.log(_date)
})
});
REQUEST.setTimeout(6000)
REQUEST.write(JSON.stringify(postData), 'utf8')
REQUEST.end()
public static void main() {
String priKey = "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCtdgvcfozY7fe/x6UlXR/Fff8+wX++CiG05YVRafDe90O8y5KJAMZ156TgajEUXSRyKZqASz7iVoMAcu5FqfK1KuOOdjTAg0LFe/twIZvKmAqHcCSS2pjUXk0fTpZEgQ5lmDCK12Mg07YXvr+BeHjF+kBpwRJMPMG/+DGBDYNFNeRSJqWyopt6yyF528soAykHIUQ7TTultJV5IPCrvjRQQrGdJ/QtCdE0vZg+tA09nFN7AqgraU99kIvzyS0sqysj+pP1SJRmTRSGtlVAO3mILfkXOekZl1KD60G7CF+7BIaaW83FPD55tZhAGhnbLMYyiq7OiIyU61LTRcNSaJ0tAgMBAAECggEBAIGgGKcSzxCBbMYdXLV6TPbZ/HeaRGrwyVWUu7cmc0E8CJu6iWvmb2jGzbiCwuCT5luF6ZZ8JKchvU4FlTfsE5r9TQY2IZ/Ht4s65qBaDUEts5iY3kv8HX9+ZSXDJZpV0ztqqsPmx4ZNj+NYwWXwcFiKdb5R8OmV8bgSsnPddD6wFhwewglUOBPRAjropHE4sqk1Vam6q1MlFq5kiekMn/CItyFYFFzST/ruqAtVTp7YIvazAMrfCKH+pvXWk6pYNHZmL/JZey0GglRyJ1nItiqL33X8Lji056FcbAclidq022h/KPLEJpZk6irWqYdqYZeF6YMLHtdZFDkTZ/hXY+UCgYEA5i794UTQ1Kd6K+iui/S8K5H8nGdiXb3+uZ5j5VKYfbRmzXhAdVYisYe8czeTECxhH+MeHgM4tLR4ifx9q60ylvZxl9Fav1p6EaE36YcvGVmpm7Gm3q6QDDBa4gB+X9u7CxCS4LpotV917YS1QvOIF9lnRonSj1zNzFtbXkywrN8CgYEAwOpx/mR40ZvgZxNCq9DsIdrSZYAFFKpw0xy0OtF1PpuwMaREoRabnlVw6Bb3Hofg50XA3JxemzAX6fB92ee+NfXfeL4UtC4vG1K9JyiXHtHq8p9Uw2W03ehIEeNa3xdoRRnLmD4VUpyfL19ViE2+7TM1Gd3TogjDT+AMOCSuq3MCgYBsurPH7gaq/LVT+mRAzgj4l8v4YUlwuGeTbIMJdvt7HXUWB4CDLH3U2CYnUpAQKrZyJok6ahEmIr1xiKggKP7lmmHL8eNo0icpHrtXfzi7Q8Q/PCpzs4dtioXTjaIkS5nNvzVyG/uL+RyuZmpsxrZ5dYM4KbAhchfwORMutxEZhwKBgQC5zpVw4jCEItBmNuTWO+nTScGvxTgfiXIVw+XLaQa2AJoZlhAL34yPWdffko79tv3lgweY9HsimZXO2rU8dbp8mo5c6ydhy8HPXUeWOcAkDSdv/ApWENW9jgYsRIC3swHY3Fl+Dv3Wjce8huQI3mjwaYvRmBhIToxfmHnscVhTBQKBgB9uciEHfz8hMI7ePrPo2PkyK/RbJDm3HnuWE2lFBp7MOUMlh53MXwv4dIRaYMbRrFuN1UIKEFxuKhWwTHSzZJufk/UENrha/81fpj2BoFsAKkEunKeETvaIh6fZSjec16h2+zxbzwkdS6b+yIYkSlaoAxmDYrMtae0C8G4e0YS9";
String pubKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArXYL3H6M2O33v8elJV0fxX3/PsF/vgohtOWFUWnw3vdDvMuSiQDGdeek4GoxFF0kcimagEs+4laDAHLuRanytSrjjnY0wINCxXv7cCGbypgKh3AkktqY1F5NH06WRIEOZZgwitdjINO2F76/gXh4xfpAacESTDzBv/gxgQ2DRTXkUialsqKbesshedvLKAMpByFEO007pbSVeSDwq740UEKxnSf0LQnRNL2YPrQNPZxTewKoK2lPfZCL88ktLKsrI/qT9UiUZk0UhrZVQDt5iC35FznpGZdSg+tBuwhfuwSGmlvNxTw+ebWYQBoZ2yzGMoquzoiMlOtS00XDUmidLQIDAQAB";
rsaSigner signer = new rsaSigner();
Map<String, Object> data = new HashMap<>();
data.put("order_no", "IGQUNC2WHT");
data.put("merchant_order_id", "ESIOqIfhKnY");
data.put("status", 1);
List<Object> payments = new ArrayList<>();
payments.add(new HashMap<String, Object>() {{
put("address", "0x038B8E7406dED2Be112B6c7E4681Df5316957cad");
put("coin", "eth");
put("txid", "0xttt");
put("amount", "1");
put("confirm_time", 15612312112L);
put("check_code", 1001);
}});
data.put("payments", payments);
try {
Map<String, Object> params = new HashMap<>();
params.put("data", data);
params.put("sign", signer.genSign(data, priKey));
Gson gson = new GsonBuilder().create();
System.out.println("params = " + gson.toJson(params));
String res;
// platform request shop callback API
// res = doPost("http://api.shophost.com/h5order/callback", gson.toJson(params));
// if (null == res) {
// throw new RuntimeException("http error");
// }
// mock response from shop callback API
{
res = """
{
"status":200,
"sign": "OTA8utI8y8G93p7RPCyb4qIilFQ0B4Aq4iUjhaXWK9m2kgektqlHOASDKXT2VE7NPNysrGycYlVfjDR2WGZn1G66phHo3qa9CcCNpG9klOBEuBEMjiVbb/d8AXcxEzvQr9OCwNsikyxonyzLiY/lsNHeGm9cC5eRvlNLdUSVBipH+ajPd0lDHCayZPs1eCMfbm/xnf8e2lfy6z0UPOpHGfyX/0+hz99Ir5Xnx+0sBBzyZZJxKm4ROid5aDv/9m9guILpURae+Yw/IrkYF4uAKGX+/44cBvtTRQSdX76CAOBSiywZa6BAgDYBLRtkAPM+i+vwNzFBovqHUvI+4Ponaw==",
"data":{
"success_data":"success"
}
}
""";
}
System.out.println("response = " + res);
JsonParser jp = new JsonParser();
JsonObject resEle = jp.parse(res).getAsJsonObject();
boolean retSignOK = signer.verifySign(resEle.get("data"), resEle.get("sign").getAsString(), pubKey);
if (!retSignOK) {
throw new RuntimeException("verify response sign fail");
}
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("OK");
}
返回结果示例:
{
"status":200,
"sign": "OTA8utI8y8G93p7RPCyb4qIilFQ0B4Aq4iUjhaXWK9m2kgektqlHOASDKXT2VE7NPNysrGycYlVfjDR2WGZn1G66phHo3qa9CcCNpG9klOBEuBEMjiVbb/d8AXcxEzvQr9OCwNsikyxonyzLiY/lsNHeGm9cC5eRvlNLdUSVBipH+ajPd0lDHCayZPs1eCMfbm/xnf8e2lfy6z0UPOpHGfyX/0+hz99Ir5Xnx+0sBBzyZZJxKm4ROid5aDv/9m9guILpURae+Yw/IrkYF4uAKGX+/44cBvtTRQSdX76CAOBSiywZa6BAgDYBLRtkAPM+i+vwNzFBovqHUvI+4Ponaw==",
"data":{
"success_data":"success"
}
}
用户充值到账通知回调,有平台发起请求,商户响应
HTTP Request
POST: 具体回调地址,由商户提供给平台方
请求参数
| 参数名 | 必选 | 类型 | 说明 |
|---|---|---|---|
| data | 否 | string | 回调通知携带数据结构 |
| data.order_no | 是 | string | 订单号 |
| data.merchant_order_id | 是 | string | 商户订单号 |
| data.status | 是 | int | 0待支付 1正常支付 2异常支付 10已取消 |
| data.payments | 是 | jsonArray | 支付信息 |
| data.payments.coin | 是 | string | 支付币种 |
| data.payments.address | 是 | string | 支付地址 |
| data.payments.txid | 是 | string | txid |
| data.payments.amount | 是 | string | 支付金额 |
| data.payments.confirm_time | 是 | int | 确认时间 |
| data.payments.check_code | 是 | int | 0正常 1001⽀付⾦额不匹配 1002已完成订单重复⽀付 |
| sign | 是 | string | 对data内数据签名 |
返回参数说明
| 参数名 | 必选 | 类型 | 说明 |
|---|---|---|---|
| status | 是 | int | 状态码 |
| data | 是 | jsonObject | 返回数据对象 |
| data.success_data | 是 | sring | success 接收成功 |
| sign | 是 | string | 签名 |
外部地址
新增外部地址
$url = "http://api.xxxx.com/shopapi/outer_address/add";
$header = [
'Content-Type:application/json',
];
$params = [
"addresses": [
"0xeb482aee7b329058ec81223f98488d28e12b15a2",
"0x4d5fa5df5963405d5ecc40ea25c08fbed129004f"
],
"app_id": "hxgmau9imt86qky9",
"chain": "bnb_bsc",
"key_version": "admin",
"sign": "OZYwC4br4wti9PFst9X5QBuxRh3voVn29pkzxEUTc92npPoVa1plnsYCcTzvAr7sy9a8dk63My2dlNhnzsypI4XvLT0/zSboC+MCtM9Q8Q8l1B4lb4nZMBkAUZFfb/80UtEBUGOni2KfnU/ciHNOsE+f9bs8i+AnRypstHnajDEuhoKEqSwmOkeYA+PRtA5SVvUdvIXM6CMnlmWokYzRys6kvb9XET1gBo9HBMI5YdTZnLavCDky3mPv5jTyiIzN4NScnxC7hIepolEUbB8smsz3oNtXSDpzZDhzm9ZjJ/5ZWEbEvK413GmsV4fodnJHJdJM+EhvAWTgxVLIbyCuFA==",
"time": 1665478775,
"version": "1.0"
];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
$return = curl_exec($ch);
print_r($return);
var url = "http://api.xxxx.com/shopapi/outer_address/add"
data := map[string]string{
"addresses": [
"0xeb482aee7b329058ec81223f98488d28e12b15a2",
"0x4d5fa5df5963405d5ecc40ea25c08fbed129004f"
],
"app_id": "hxgmau9imt86qky9",
"chain": "bnb_bsc",
"key_version": "admin",
"sign": "OZYwC4br4wti9PFst9X5QBuxRh3voVn29pkzxEUTc92npPoVa1plnsYCcTzvAr7sy9a8dk63My2dlNhnzsypI4XvLT0/zSboC+MCtM9Q8Q8l1B4lb4nZMBkAUZFfb/80UtEBUGOni2KfnU/ciHNOsE+f9bs8i+AnRypstHnajDEuhoKEqSwmOkeYA+PRtA5SVvUdvIXM6CMnlmWokYzRys6kvb9XET1gBo9HBMI5YdTZnLavCDky3mPv5jTyiIzN4NScnxC7hIepolEUbB8smsz3oNtXSDpzZDhzm9ZjJ/5ZWEbEvK413GmsV4fodnJHJdJM+EhvAWTgxVLIbyCuFA==",
"time": 1665478775,
"version": "1.0",
}
dataType, _ := json.Marshal(data)
resp, err := http.Post(url, "application/json", strings.NewReader(string(dataType)))
if err != nil {
fmt.Println(err)
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Println(err)
}
fmt.Println(string(body))
let HTTP = require('http')
let postData = {
"addresses": [
"0xeb482aee7b329058ec81223f98488d28e12b15a2",
"0x4d5fa5df5963405d5ecc40ea25c08fbed129004f"
],
"app_id": "hxgmau9imt86qky9",
"chain": "bnb_bsc",
"key_version": "admin",
"sign": "OZYwC4br4wti9PFst9X5QBuxRh3voVn29pkzxEUTc92npPoVa1plnsYCcTzvAr7sy9a8dk63My2dlNhnzsypI4XvLT0/zSboC+MCtM9Q8Q8l1B4lb4nZMBkAUZFfb/80UtEBUGOni2KfnU/ciHNOsE+f9bs8i+AnRypstHnajDEuhoKEqSwmOkeYA+PRtA5SVvUdvIXM6CMnlmWokYzRys6kvb9XET1gBo9HBMI5YdTZnLavCDky3mPv5jTyiIzN4NScnxC7hIepolEUbB8smsz3oNtXSDpzZDhzm9ZjJ/5ZWEbEvK413GmsV4fodnJHJdJM+EhvAWTgxVLIbyCuFA==",
"time": 1665478775,
"version": "1.0",
};
let POST_OPTIONS = {
port: 80,
host: "api.xxxx.com",
path: "/shopapi/outer_address/add",
method: 'POST',
headers: {
"Content-Type": "application/json; charset=utf-8"
}
};
const REQUEST = HTTP.request(POST_OPTIONS,function (res) {
let data = []
res.on('data', chunk => {
data.push(...chunk)
})
res.on('end', () => {
let _date = JSON.parse( new TextDecoder().decode(new Uint8Array(data)))
console.log(_date)
})
});
REQUEST.setTimeout(6000)
REQUEST.write(JSON.stringify(postData), 'utf8')
REQUEST.end()
public static void main(String[] args) {
// 完整实例请查看"签名规则"中的Java示例代码
String baseUrl = "http://api.xxxx.com/shopapi";
String priKey = "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCtdgvcfozY7fe/x6UlXR/Fff8+wX++CiG05YVRafDe90O8y5KJAMZ156TgajEUXSRyKZqASz7iVoMAcu5FqfK1KuOOdjTAg0LFe/twIZvKmAqHcCSS2pjUXk0fTpZEgQ5lmDCK12Mg07YXvr+BeHjF+kBpwRJMPMG/+DGBDYNFNeRSJqWyopt6yyF528soAykHIUQ7TTultJV5IPCrvjRQQrGdJ/QtCdE0vZg+tA09nFN7AqgraU99kIvzyS0sqysj+pP1SJRmTRSGtlVAO3mILfkXOekZl1KD60G7CF+7BIaaW83FPD55tZhAGhnbLMYyiq7OiIyU61LTRcNSaJ0tAgMBAAECggEBAIGgGKcSzxCBbMYdXLV6TPbZ/HeaRGrwyVWUu7cmc0E8CJu6iWvmb2jGzbiCwuCT5luF6ZZ8JKchvU4FlTfsE5r9TQY2IZ/Ht4s65qBaDUEts5iY3kv8HX9+ZSXDJZpV0ztqqsPmx4ZNj+NYwWXwcFiKdb5R8OmV8bgSsnPddD6wFhwewglUOBPRAjropHE4sqk1Vam6q1MlFq5kiekMn/CItyFYFFzST/ruqAtVTp7YIvazAMrfCKH+pvXWk6pYNHZmL/JZey0GglRyJ1nItiqL33X8Lji056FcbAclidq022h/KPLEJpZk6irWqYdqYZeF6YMLHtdZFDkTZ/hXY+UCgYEA5i794UTQ1Kd6K+iui/S8K5H8nGdiXb3+uZ5j5VKYfbRmzXhAdVYisYe8czeTECxhH+MeHgM4tLR4ifx9q60ylvZxl9Fav1p6EaE36YcvGVmpm7Gm3q6QDDBa4gB+X9u7CxCS4LpotV917YS1QvOIF9lnRonSj1zNzFtbXkywrN8CgYEAwOpx/mR40ZvgZxNCq9DsIdrSZYAFFKpw0xy0OtF1PpuwMaREoRabnlVw6Bb3Hofg50XA3JxemzAX6fB92ee+NfXfeL4UtC4vG1K9JyiXHtHq8p9Uw2W03ehIEeNa3xdoRRnLmD4VUpyfL19ViE2+7TM1Gd3TogjDT+AMOCSuq3MCgYBsurPH7gaq/LVT+mRAzgj4l8v4YUlwuGeTbIMJdvt7HXUWB4CDLH3U2CYnUpAQKrZyJok6ahEmIr1xiKggKP7lmmHL8eNo0icpHrtXfzi7Q8Q/PCpzs4dtioXTjaIkS5nNvzVyG/uL+RyuZmpsxrZ5dYM4KbAhchfwORMutxEZhwKBgQC5zpVw4jCEItBmNuTWO+nTScGvxTgfiXIVw+XLaQa2AJoZlhAL34yPWdffko79tv3lgweY9HsimZXO2rU8dbp8mo5c6ydhy8HPXUeWOcAkDSdv/ApWENW9jgYsRIC3swHY3Fl+Dv3Wjce8huQI3mjwaYvRmBhIToxfmHnscVhTBQKBgB9uciEHfz8hMI7ePrPo2PkyK/RbJDm3HnuWE2lFBp7MOUMlh53MXwv4dIRaYMbRrFuN1UIKEFxuKhWwTHSzZJufk/UENrha/81fpj2BoFsAKkEunKeETvaIh6fZSjec16h2+zxbzwkdS6b+yIYkSlaoAxmDYrMtae0C8G4e0YS9";
String pubKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2RZZISModRzproL3eTxRtvVK/nToDbeLmAVdmaVtHgNCwjXMeNCZvHySZKO7+t7XySzBd2PhhQjvAkDd8HRKB5Y0uvP6TFwvhxOMkMydTeBFcUobQWNeAI7ttRms1txSNrmyrZr0WpWfk79VIsO+yI/jFN/Pj2gxD+vh5UUKU1LD2IQq/VxgtEpf8Vs6w7SvafPwYkpdPGCKUFkRvN1FrY2+tq0j1MRVJbB2rIunWDnT8cDUh2sWLXf4yNaJVOaaTFB0zbAk/qcoicGQyW7bVG7dVW8WywKmOAPeQCCQa+SJ4BhfI1k8eEAwFVRuxz/f9Ecfog9hZJ+RgELkpS8qhQIDAQAB";
rsaSigner signer = new rsaSigner();
Map<String, Object> params = new HashMap<>();
params.put("app_id", "hxgmau9imt86qky9");
params.put("version", "1.0");
params.put("key_version", "admin");
params.put("time", Long.toString(System.currentTimeMillis() / 1000));
params.put("chain", "bnb_bsc");
List<String> addresses = new ArrayList<>();
addresses.add("0x4d5fa5df5963405d5ecc40ea25c08fbed129004f");
addresses.add("0xeb482aee7b329058ec81223f98488d28e12b15a2");
params.put("addresses", addresses);
try {
params.put("sign", signer.genSign(params, priKey));
Gson gson = new GsonBuilder().create();
System.out.println("params = " + gson.toJson(params));
String res = doPost(baseUrl + "/outer_address/add", gson.toJson(params));
if (null == res) {
throw new RuntimeException("http error");
}
System.out.println("response = " + res);
JsonParser jp = new JsonParser();
JsonObject resEle = jp.parse(res).getAsJsonObject();
boolean retSignOK = signer.verifySign(resEle, resEle.get("sign").getAsString(), pubKey);
if (!retSignOK) {
throw new RuntimeException("verify response sign fail");
}
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("OK");
}
返回结果示例:
{
"status": 200,
"msg": "请求成功",
"data": {
"fail_addresses": []
},
"date_time": "2022-10-11 16:59:35",
"time_stamp": 1665478775,
"sign": "AcNiY8kJTb/L2fZqtN0kVIVazbMdr/jiYSDetNBIlmEbEzwFhT7ZJxx15AzUcU62Ptnyb0wZF+xN/h/2YPo1XuMNVNcQdRvmdLfeDM8Pnk4+QCVnQjzqJ8fEjRTdkoujMS3VpywGJxL8ncMDMgmbnSWpXWMYprupQb27sKhPak7mSuib7xozc2/6D9T+oWxKIRMfvV7ZPq6p24PqUt1R9z6z2e3kxZanx/MMv2XljrAEMkI8iMbwQ910gNwuKkYP2GDCEXMBgzWMxJd2JdIEFexN+DFUk/pP1S5B+EPAwpoSB8Brflmpr1XAfwQKdocq+lDWRVI/HNEExcfuLdtUFA=="
}
- 商户提交想要监控交易的地址到平台
HTTP Request
POST : /outer_address/add
请求参数
| 参数名 | 必选 | 类型 | 说明 |
|---|---|---|---|
| 公共参数 | 是 | string | 公参指:签名(sign)、版本(version)、商户ID(app_id)、时间(time) |
| chain | 是 | string | 12个字符以内,地址所属主链 |
| addresses | 是 | string数组 | 地址,数组长度限制不超过100个 |
返回参数说明
| 参数名 | 类型 | 说明 |
|---|---|---|
| status | int | 状态码 |
| msg | string | 状态描述 |
| data | jsonObject | 具体见下面 “data细节说明”。 |
| data.fail_addresses | string数组 | 保存出错的地址,全部保存成功则该值为空 |
| date_time | string | 响应时间 |
| time_stamp | int | 响应时间单位秒 |
| sign | string | 签名 |
删除外部地址
$url = "http://api.xxxx.com/shopapi/outer_address/delete";
$header = [
'Content-Type:application/json',
];
$params = [
"addresses": [
"0xeb482aee7b329058ec81223f98488d28e12b15a2",
"0x4d5fa5df5963405d5ecc40ea25c08fbed129004f"
],
"app_id": "hxgmau9imt86qky9",
"chain": "bnb_bsc",
"key_version": "admin",
"sign": "OZYwC4br4wti9PFst9X5QBuxRh3voVn29pkzxEUTc92npPoVa1plnsYCcTzvAr7sy9a8dk63My2dlNhnzsypI4XvLT0/zSboC+MCtM9Q8Q8l1B4lb4nZMBkAUZFfb/80UtEBUGOni2KfnU/ciHNOsE+f9bs8i+AnRypstHnajDEuhoKEqSwmOkeYA+PRtA5SVvUdvIXM6CMnlmWokYzRys6kvb9XET1gBo9HBMI5YdTZnLavCDky3mPv5jTyiIzN4NScnxC7hIepolEUbB8smsz3oNtXSDpzZDhzm9ZjJ/5ZWEbEvK413GmsV4fodnJHJdJM+EhvAWTgxVLIbyCuFA==",
"time": 1665478775,
"version": "1.0"
];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
$return = curl_exec($ch);
print_r($return);
var url = "http://api.xxxx.com/shopapi/outer_address/delete"
data := map[string]string{
"addresses": [
"0xeb482aee7b329058ec81223f98488d28e12b15a2",
"0x4d5fa5df5963405d5ecc40ea25c08fbed129004f"
],
"app_id": "hxgmau9imt86qky9",
"chain": "bnb_bsc",
"key_version": "admin",
"sign": "OZYwC4br4wti9PFst9X5QBuxRh3voVn29pkzxEUTc92npPoVa1plnsYCcTzvAr7sy9a8dk63My2dlNhnzsypI4XvLT0/zSboC+MCtM9Q8Q8l1B4lb4nZMBkAUZFfb/80UtEBUGOni2KfnU/ciHNOsE+f9bs8i+AnRypstHnajDEuhoKEqSwmOkeYA+PRtA5SVvUdvIXM6CMnlmWokYzRys6kvb9XET1gBo9HBMI5YdTZnLavCDky3mPv5jTyiIzN4NScnxC7hIepolEUbB8smsz3oNtXSDpzZDhzm9ZjJ/5ZWEbEvK413GmsV4fodnJHJdJM+EhvAWTgxVLIbyCuFA==",
"time": 1665478775,
"version": "1.0",
}
dataType, _ := json.Marshal(data)
resp, err := http.Post(url, "application/json", strings.NewReader(string(dataType)))
if err != nil {
fmt.Println(err)
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Println(err)
}
fmt.Println(string(body))
let HTTP = require('http')
let postData = {
"addresses": [
"0xeb482aee7b329058ec81223f98488d28e12b15a2",
"0x4d5fa5df5963405d5ecc40ea25c08fbed129004f"
],
"app_id": "hxgmau9imt86qky9",
"chain": "bnb_bsc",
"key_version": "admin",
"sign": "OZYwC4br4wti9PFst9X5QBuxRh3voVn29pkzxEUTc92npPoVa1plnsYCcTzvAr7sy9a8dk63My2dlNhnzsypI4XvLT0/zSboC+MCtM9Q8Q8l1B4lb4nZMBkAUZFfb/80UtEBUGOni2KfnU/ciHNOsE+f9bs8i+AnRypstHnajDEuhoKEqSwmOkeYA+PRtA5SVvUdvIXM6CMnlmWokYzRys6kvb9XET1gBo9HBMI5YdTZnLavCDky3mPv5jTyiIzN4NScnxC7hIepolEUbB8smsz3oNtXSDpzZDhzm9ZjJ/5ZWEbEvK413GmsV4fodnJHJdJM+EhvAWTgxVLIbyCuFA==",
"time": 1665478775,
"version": "1.0",
};
let POST_OPTIONS = {
port: 80,
host: "api.xxxx.com",
path: "/shopapi/outer_address/delete",
method: 'POST',
headers: {
"Content-Type": "application/json; charset=utf-8"
}
};
const REQUEST = HTTP.request(POST_OPTIONS,function (res) {
let data = []
res.on('data', chunk => {
data.push(...chunk)
})
res.on('end', () => {
let _date = JSON.parse( new TextDecoder().decode(new Uint8Array(data)))
console.log(_date)
})
});
REQUEST.setTimeout(6000)
REQUEST.write(JSON.stringify(postData), 'utf8')
REQUEST.end()
public static void main(String[] args) {
// 完整实例请查看"签名规则"中的Java示例代码
String baseUrl = "http://api.xxxx.com/shopapi";
String priKey = "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCtdgvcfozY7fe/x6UlXR/Fff8+wX++CiG05YVRafDe90O8y5KJAMZ156TgajEUXSRyKZqASz7iVoMAcu5FqfK1KuOOdjTAg0LFe/twIZvKmAqHcCSS2pjUXk0fTpZEgQ5lmDCK12Mg07YXvr+BeHjF+kBpwRJMPMG/+DGBDYNFNeRSJqWyopt6yyF528soAykHIUQ7TTultJV5IPCrvjRQQrGdJ/QtCdE0vZg+tA09nFN7AqgraU99kIvzyS0sqysj+pP1SJRmTRSGtlVAO3mILfkXOekZl1KD60G7CF+7BIaaW83FPD55tZhAGhnbLMYyiq7OiIyU61LTRcNSaJ0tAgMBAAECggEBAIGgGKcSzxCBbMYdXLV6TPbZ/HeaRGrwyVWUu7cmc0E8CJu6iWvmb2jGzbiCwuCT5luF6ZZ8JKchvU4FlTfsE5r9TQY2IZ/Ht4s65qBaDUEts5iY3kv8HX9+ZSXDJZpV0ztqqsPmx4ZNj+NYwWXwcFiKdb5R8OmV8bgSsnPddD6wFhwewglUOBPRAjropHE4sqk1Vam6q1MlFq5kiekMn/CItyFYFFzST/ruqAtVTp7YIvazAMrfCKH+pvXWk6pYNHZmL/JZey0GglRyJ1nItiqL33X8Lji056FcbAclidq022h/KPLEJpZk6irWqYdqYZeF6YMLHtdZFDkTZ/hXY+UCgYEA5i794UTQ1Kd6K+iui/S8K5H8nGdiXb3+uZ5j5VKYfbRmzXhAdVYisYe8czeTECxhH+MeHgM4tLR4ifx9q60ylvZxl9Fav1p6EaE36YcvGVmpm7Gm3q6QDDBa4gB+X9u7CxCS4LpotV917YS1QvOIF9lnRonSj1zNzFtbXkywrN8CgYEAwOpx/mR40ZvgZxNCq9DsIdrSZYAFFKpw0xy0OtF1PpuwMaREoRabnlVw6Bb3Hofg50XA3JxemzAX6fB92ee+NfXfeL4UtC4vG1K9JyiXHtHq8p9Uw2W03ehIEeNa3xdoRRnLmD4VUpyfL19ViE2+7TM1Gd3TogjDT+AMOCSuq3MCgYBsurPH7gaq/LVT+mRAzgj4l8v4YUlwuGeTbIMJdvt7HXUWB4CDLH3U2CYnUpAQKrZyJok6ahEmIr1xiKggKP7lmmHL8eNo0icpHrtXfzi7Q8Q/PCpzs4dtioXTjaIkS5nNvzVyG/uL+RyuZmpsxrZ5dYM4KbAhchfwORMutxEZhwKBgQC5zpVw4jCEItBmNuTWO+nTScGvxTgfiXIVw+XLaQa2AJoZlhAL34yPWdffko79tv3lgweY9HsimZXO2rU8dbp8mo5c6ydhy8HPXUeWOcAkDSdv/ApWENW9jgYsRIC3swHY3Fl+Dv3Wjce8huQI3mjwaYvRmBhIToxfmHnscVhTBQKBgB9uciEHfz8hMI7ePrPo2PkyK/RbJDm3HnuWE2lFBp7MOUMlh53MXwv4dIRaYMbRrFuN1UIKEFxuKhWwTHSzZJufk/UENrha/81fpj2BoFsAKkEunKeETvaIh6fZSjec16h2+zxbzwkdS6b+yIYkSlaoAxmDYrMtae0C8G4e0YS9";
String pubKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2RZZISModRzproL3eTxRtvVK/nToDbeLmAVdmaVtHgNCwjXMeNCZvHySZKO7+t7XySzBd2PhhQjvAkDd8HRKB5Y0uvP6TFwvhxOMkMydTeBFcUobQWNeAI7ttRms1txSNrmyrZr0WpWfk79VIsO+yI/jFN/Pj2gxD+vh5UUKU1LD2IQq/VxgtEpf8Vs6w7SvafPwYkpdPGCKUFkRvN1FrY2+tq0j1MRVJbB2rIunWDnT8cDUh2sWLXf4yNaJVOaaTFB0zbAk/qcoicGQyW7bVG7dVW8WywKmOAPeQCCQa+SJ4BhfI1k8eEAwFVRuxz/f9Ecfog9hZJ+RgELkpS8qhQIDAQAB";
rsaSigner signer = new rsaSigner();
Map<String, Object> params = new HashMap<>();
params.put("app_id", "hxgmau9imt86qky9");
params.put("version", "1.0");
params.put("key_version", "admin");
params.put("time", Long.toString(System.currentTimeMillis() / 1000));
params.put("chain", "bnb_bsc");
List<String> addresses = new ArrayList<>();
addresses.add("0x4d5fa5df5963405d5ecc40ea25c08fbed129004f");
addresses.add("0xeb482aee7b329058ec81223f98488d28e12b15a2");
params.put("addresses", addresses);
try {
params.put("sign", signer.genSign(params, priKey));
Gson gson = new GsonBuilder().create();
System.out.println("params = " + gson.toJson(params));
String res = doPost(baseUrl + "/outer_address/delete", gson.toJson(params));
if (null == res) {
throw new RuntimeException("http error");
}
System.out.println("response = " + res);
JsonParser jp = new JsonParser();
JsonObject resEle = jp.parse(res).getAsJsonObject();
boolean retSignOK = signer.verifySign(resEle, resEle.get("sign").getAsString(), pubKey);
if (!retSignOK) {
throw new RuntimeException("verify response sign fail");
}
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("OK");
}
返回结果示例:
{
"status": 200,
"msg": "请求成功",
"data": [],
"date_time": "2022-10-11 16:59:35",
"time_stamp": 1665478775,
"sign": "AcNiY8kJTb/L2fZqtN0kVIVazbMdr/jiYSDetNBIlmEbEzwFhT7ZJxx15AzUcU62Ptnyb0wZF+xN/h/2YPo1XuMNVNcQdRvmdLfeDM8Pnk4+QCVnQjzqJ8fEjRTdkoujMS3VpywGJxL8ncMDMgmbnSWpXWMYprupQb27sKhPak7mSuib7xozc2/6D9T+oWxKIRMfvV7ZPq6p24PqUt1R9z6z2e3kxZanx/MMv2XljrAEMkI8iMbwQ910gNwuKkYP2GDCEXMBgzWMxJd2JdIEFexN+DFUk/pP1S5B+EPAwpoSB8Brflmpr1XAfwQKdocq+lDWRVI/HNEExcfuLdtUFA=="
}
- 删除已加入交易监控的地址
HTTP Request
POST : /outer_address/delete
请求参数
| 参数名 | 必选 | 类型 | 说明 |
|---|---|---|---|
| 公共参数 | 是 | string | 公参指:签名(sign)、版本(version)、商户ID(app_id)、时间(time) |
| chain | 是 | string | 12个字符以内,地址所属主链 |
| addresses | 是 | string数组 | 地址,数组长度限制不超过100个 |
返回参数说明
| 参数名 | 类型 | 说明 |
|---|---|---|
| status | int | 状态码 |
| msg | string | 状态描述 |
| data | jsonObject | 无具体数据,返回空 |
| date_time | string | 响应时间 |
| time_stamp | int | 响应时间单位秒 |
| sign | string | 签名 |
外部地址交易变动回调通知
$url = "具体回调地址,由商户提供给平台方";
$header = [
'Content-Type:application/json',
];
$params = [
"data": {
"address": "0xeb482aee7b329058ec81223f98488d28e12b15a2",
"amount": "0.00013556",
"chain": "bnb_bsc",
"coin": "bnb_bsc",
"confirm_count": 12,
"gas_fee": "0.000105",
"status": 1,
"time": 1665479732,
"token_address": "",
"transaction_type": 2,
"txid": "0x735dc8becd0d5dc0023b526584b75c8772551fc9268668991608dadc69facb39",
},
"sign": "Yyyyg==",
];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
$return = curl_exec($ch);
print_r($return);
var url = "具体回调地址,由商户提供给平台方"
data := map[string]interface{}{
"data": {
"address": "0xeb482aee7b329058ec81223f98488d28e12b15a2",
"amount": "0.00013556",
"chain": "bnb_bsc",
"coin": "bnb_bsc",
"confirm_count": 12,
"gas_fee": "0.000105",
"status": 1,
"time": 1665479732,
"token_address": "",
"transaction_type": 2,
"txid": "0x735dc8becd0d5dc0023b526584b75c8772551fc9268668991608dadc69facb39",
},
"sign": "Yyyyg==",
}
dataType, _ := json.Marshal(data)
resp, err := http.Post(url, "application/json", strings.NewReader(string(dataType)))
if err != nil {
fmt.Println(err)
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Println(err)
}
fmt.Println(string(body))
let HTTP = require('http')
let postData = {
"data": {
"address": "0xeb482aee7b329058ec81223f98488d28e12b15a2",
"amount": "0.00013556",
"chain": "bnb_bsc",
"coin": "bnb_bsc",
"confirm_count": 12,
"gas_fee": "0.000105",
"status": 1,
"time": 1665479732,
"token_address": "",
"transaction_type": 2,
"txid": "0x735dc8becd0d5dc0023b526584b75c8772551fc9268668991608dadc69facb39",
},
"sign": "Yyyyg==",
};
let POST_OPTIONS = {
port: 80,
host: "具体回调地址,由商户提供给平台方",
path: "",
method: 'POST',
headers: {
"Content-Type": "application/json; charset=utf-8"
}
};
const REQUEST = HTTP.request(POST_OPTIONS,function (res) {
let data = []
res.on('data', chunk => {
data.push(...chunk)
})
res.on('end', () => {
let _date = JSON.parse( new TextDecoder().decode(new Uint8Array(data)))
console.log(_date)
})
});
REQUEST.setTimeout(6000)
REQUEST.write(JSON.stringify(postData), 'utf8')
REQUEST.end()
public static void main() {
String priKey = "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCtdgvcfozY7fe/x6UlXR/Fff8+wX++CiG05YVRafDe90O8y5KJAMZ156TgajEUXSRyKZqASz7iVoMAcu5FqfK1KuOOdjTAg0LFe/twIZvKmAqHcCSS2pjUXk0fTpZEgQ5lmDCK12Mg07YXvr+BeHjF+kBpwRJMPMG/+DGBDYNFNeRSJqWyopt6yyF528soAykHIUQ7TTultJV5IPCrvjRQQrGdJ/QtCdE0vZg+tA09nFN7AqgraU99kIvzyS0sqysj+pP1SJRmTRSGtlVAO3mILfkXOekZl1KD60G7CF+7BIaaW83FPD55tZhAGhnbLMYyiq7OiIyU61LTRcNSaJ0tAgMBAAECggEBAIGgGKcSzxCBbMYdXLV6TPbZ/HeaRGrwyVWUu7cmc0E8CJu6iWvmb2jGzbiCwuCT5luF6ZZ8JKchvU4FlTfsE5r9TQY2IZ/Ht4s65qBaDUEts5iY3kv8HX9+ZSXDJZpV0ztqqsPmx4ZNj+NYwWXwcFiKdb5R8OmV8bgSsnPddD6wFhwewglUOBPRAjropHE4sqk1Vam6q1MlFq5kiekMn/CItyFYFFzST/ruqAtVTp7YIvazAMrfCKH+pvXWk6pYNHZmL/JZey0GglRyJ1nItiqL33X8Lji056FcbAclidq022h/KPLEJpZk6irWqYdqYZeF6YMLHtdZFDkTZ/hXY+UCgYEA5i794UTQ1Kd6K+iui/S8K5H8nGdiXb3+uZ5j5VKYfbRmzXhAdVYisYe8czeTECxhH+MeHgM4tLR4ifx9q60ylvZxl9Fav1p6EaE36YcvGVmpm7Gm3q6QDDBa4gB+X9u7CxCS4LpotV917YS1QvOIF9lnRonSj1zNzFtbXkywrN8CgYEAwOpx/mR40ZvgZxNCq9DsIdrSZYAFFKpw0xy0OtF1PpuwMaREoRabnlVw6Bb3Hofg50XA3JxemzAX6fB92ee+NfXfeL4UtC4vG1K9JyiXHtHq8p9Uw2W03ehIEeNa3xdoRRnLmD4VUpyfL19ViE2+7TM1Gd3TogjDT+AMOCSuq3MCgYBsurPH7gaq/LVT+mRAzgj4l8v4YUlwuGeTbIMJdvt7HXUWB4CDLH3U2CYnUpAQKrZyJok6ahEmIr1xiKggKP7lmmHL8eNo0icpHrtXfzi7Q8Q/PCpzs4dtioXTjaIkS5nNvzVyG/uL+RyuZmpsxrZ5dYM4KbAhchfwORMutxEZhwKBgQC5zpVw4jCEItBmNuTWO+nTScGvxTgfiXIVw+XLaQa2AJoZlhAL34yPWdffko79tv3lgweY9HsimZXO2rU8dbp8mo5c6ydhy8HPXUeWOcAkDSdv/ApWENW9jgYsRIC3swHY3Fl+Dv3Wjce8huQI3mjwaYvRmBhIToxfmHnscVhTBQKBgB9uciEHfz8hMI7ePrPo2PkyK/RbJDm3HnuWE2lFBp7MOUMlh53MXwv4dIRaYMbRrFuN1UIKEFxuKhWwTHSzZJufk/UENrha/81fpj2BoFsAKkEunKeETvaIh6fZSjec16h2+zxbzwkdS6b+yIYkSlaoAxmDYrMtae0C8G4e0YS9";
String pubKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArXYL3H6M2O33v8elJV0fxX3/PsF/vgohtOWFUWnw3vdDvMuSiQDGdeek4GoxFF0kcimagEs+4laDAHLuRanytSrjjnY0wINCxXv7cCGbypgKh3AkktqY1F5NH06WRIEOZZgwitdjINO2F76/gXh4xfpAacESTDzBv/gxgQ2DRTXkUialsqKbesshedvLKAMpByFEO007pbSVeSDwq740UEKxnSf0LQnRNL2YPrQNPZxTewKoK2lPfZCL88ktLKsrI/qT9UiUZk0UhrZVQDt5iC35FznpGZdSg+tBuwhfuwSGmlvNxTw+ebWYQBoZ2yzGMoquzoiMlOtS00XDUmidLQIDAQAB";
rsaSigner signer = new rsaSigner();
Map<String, Object> data = new HashMap<>();
data.put("address", "0xeb482aee7b329058ec81223f98488d28e12b15a2");
data.put("amount", "0.00013556");
data.put("chain", "bnb_bsc");
data.put("coin", "bnb_bsc");
data.put("confirm_count", 12);
data.put("gas_fee", "0.000105");
data.put("status", 1);
data.put("time", 1665479732);
data.put("token_address", "");
data.put("transaction_type", 2);
data.put("txid", "0x735dc8becd0d5dc0023b526584b75c8772551fc9268668991608dadc69facb39");
try {
Map<String, Object> params = new HashMap<>();
params.put("data", data);
params.put("sign", signer.genSign(data, priKey));
Gson gson = new GsonBuilder().create();
System.out.println("params = " + gson.toJson(params));
String res;
// platform request shop callback API
// res = doPost("http://api.shophost.com/outer_address/recharge/callback", gson.toJson(params));
// if (null == res) {
// throw new RuntimeException("http error");
// }
// mock response from shop callback API
{
res = """
{
"status": 200,
"msg":"请求成功",
"sign": "Yyyyg==",
"data": {
"success_data": "success"
}
}
""";
}
System.out.println("response = " + res);
JsonParser jp = new JsonParser();
JsonObject resEle = jp.parse(res).getAsJsonObject();
boolean retSignOK = signer.verifySign(resEle.get("data"), resEle.get("sign").getAsString(), pubKey);
if (!retSignOK) {
throw new RuntimeException("verify response sign fail");
}
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("OK");
}
返回结果示例:
{
"status": 200,
"msg":"请求成功",
"sign": "Yyyyg==",
"data": {
"success_data": "success"
}
}
- 商户加入监控的地址上发生交易,平台将请求该接口,由商户响应
- 若商户没有正确返回结果,平台将会重试请求,直到得到正确返回或者时间超过1小时。重试时间,第30秒、第1分钟、第3分钟、第7分钟、第15分钟、第25分钟、第40分钟、第60分钟。
HTTP Request
POST: 具体回调地址,由商户提供给平台方
请求参数
| 参数名 | 必选 | 类型 | 说明 |
|---|---|---|---|
| sign | 是 | string | 签名 |
| data | 是 | 对象 | 交易信息对象 |
| data.address | 是 | string | 商户监控的地址 |
| data.amount | 是 | string | 金额 |
| data.chain | 是 | string | 主链名 |
| data.coin | 是 | string | 币名 |
| data.confirm_count | 是 | int | 区块确认数 |
| data.gas_fee | 是 | string | 交易gas费 |
| data.status | 是 | int | 状态:0=待确认,1=已确认 |
| data.time | 是 | int | 交易区块的时间戳(单位秒) |
| data.token_address | 否 | string | 合约地址,主链币种该值为空 |
| data.transaction_type | 是 | int | 地址交易类型:1=转入,2=转出 |
| data.txid | 是 | string | 链上交易hash |
返回参数说明
| 参数名 | 必选 | 类型 | 说明 |
|---|---|---|---|
| status | 是 | int | 返回状态码,200为正常 |
| msg | 是 | string | 状态码描述 |
| data | 是 | null或JSONObjectString | 返回数据 |
| data.success_data | 是 | string | 业务上确认该回调处理成功,如果返回不是'success',平台将间隔一段时间后重试请求 |
| sign | 是 | string | 签名 |
其他
币种查询
$url = "http://api.xxxx.com/shopapi/coin/list";
$header = [
'Content-Type:application/json',
];
$params = [
"app_id" => "hxgmau9imt86qky9",
"version" => "1.0",
"time" => 1579004943,
"coin" => "eth",
"chain" => "eth",
"page" => 1,
"page_size" => 20,
"sign" => "dLtK+uiPcnxt2ACKMbBqQ6wI5ttAvesOHzK5ybVID1R6hqYPDTkagl7Tsjr5iLJafehcSLTZyJLtCRI8O2CtIWQUUroGXBneHZC486NUi/4FMOQs0FaAgm17pWlbhX5/96cWXXXMVeoe3IZFKaFNYSWaA14v3RcdDU6QDE/9ixGiSJ0DIxm9NKA0+RkbIFbyYeuFn8d63OcjmUhv7tsOE6rKCc3Q2yi7Qe9i6BNAQFYMFATztb18MsxsBHKUxNqklqyVnl0ofETAHmQhfOHLmungOJQnOqAAuwfmRtg50Qci5F+R2mXeqjmIXko/u3E+DLYW1ygDBp3afKZmU4PwmA=="
];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
$return = curl_exec($ch);
print_r($return);
var url = "http://api.xxxx.com/shopapi/coin/list"
data := map[string]string{
"version": "1.0",
"app_id":"hxgmau9imt86qky9",
"time":"1579004943",
"coin":"eth",
"chain":"eth",
"page":"1",
"page_size":"20",
"sign":"IUtWA3HEkK+wvTGaSBYwIrdx+ANyoOPl2/1LQTDevCSTxf4/lDXPrg6/ph+skNXIbZTR8Qs2yGGkqTUHEW/vbiTPzWkYZ874rRgplp06vhOBM/Pkw289K7PVCKy1ksOtLjwj1dUfDD/2AEqTgxRDjGyn+yDWRa7HLL/28bjU3pZoFwPPjbPyRxMK9BVL/li9IQ6hb8lyOyQNHNxS3C82sDVaQKqrB0dOqtP61OH0hBonrxMhBAMD8dUmaqO6Ef+bhHzbBm3BCC5VapkOkdthb+UWXKCiBoCipg3gqrwnBdOUGXqx/1mYicNZ+oHeVpBwnJlXudff6FT+HySszr5ISw==",
}
dataType, _ := json.Marshal(data)
resp, err := http.Post(url, "application/json", strings.NewReader(string(dataType)))
if err != nil {
fmt.Println(err)
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Println(err)
}
fmt.Println(string(body))
let HTTP = require('http')
let postData = {
"version": "1.0",
"app_id":"hxgmau9imt86qky9",
"time":"1579004943",
"coin":"eth",
"chain":"eth",
"page":"1",
"page_size":"20",
"sign":"IUtWA3HEkK+wvTGaSBYwIrdx+ANyoOPl2/1LQTDevCSTxf4/lDXPrg6/ph+skNXIbZTR8Qs2yGGkqTUHEW/vbiTPzWkYZ874rRgplp06vhOBM/Pkw289K7PVCKy1ksOtLjwj1dUfDD/2AEqTgxRDjGyn+yDWRa7HLL/28bjU3pZoFwPPjbPyRxMK9BVL/li9IQ6hb8lyOyQNHNxS3C82sDVaQKqrB0dOqtP61OH0hBonrxMhBAMD8dUmaqO6Ef+bhHzbBm3BCC5VapkOkdthb+UWXKCiBoCipg3gqrwnBdOUGXqx/1mYicNZ+oHeVpBwnJlXudff6FT+HySszr5ISw==",
};
let POST_OPTIONS = {
port: 80,
host: "api.xxxx.com",
path: "/shopapi/coin/list",
method: 'POST',
headers: {
"Content-Type": "application/json; charset=utf-8"
}
};
const REQUEST = HTTP.request(POST_OPTIONS,function (res) {
let data = []
res.on('data', chunk => {
data.push(...chunk)
})
res.on('end', () => {
let _date = JSON.parse( new TextDecoder().decode(new Uint8Array(data)))
console.log(_date)
})
});
REQUEST.setTimeout(6000)
REQUEST.write(JSON.stringify(postData), 'utf8')
REQUEST.end()
public static void main(String[] args) {
// 完整实例请查看"签名规则"中的Java示例代码
String baseUrl = "http://api.xxxx.com/shopapi";
String priKey = "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCtdgvcfozY7fe/x6UlXR/Fff8+wX++CiG05YVRafDe90O8y5KJAMZ156TgajEUXSRyKZqASz7iVoMAcu5FqfK1KuOOdjTAg0LFe/twIZvKmAqHcCSS2pjUXk0fTpZEgQ5lmDCK12Mg07YXvr+BeHjF+kBpwRJMPMG/+DGBDYNFNeRSJqWyopt6yyF528soAykHIUQ7TTultJV5IPCrvjRQQrGdJ/QtCdE0vZg+tA09nFN7AqgraU99kIvzyS0sqysj+pP1SJRmTRSGtlVAO3mILfkXOekZl1KD60G7CF+7BIaaW83FPD55tZhAGhnbLMYyiq7OiIyU61LTRcNSaJ0tAgMBAAECggEBAIGgGKcSzxCBbMYdXLV6TPbZ/HeaRGrwyVWUu7cmc0E8CJu6iWvmb2jGzbiCwuCT5luF6ZZ8JKchvU4FlTfsE5r9TQY2IZ/Ht4s65qBaDUEts5iY3kv8HX9+ZSXDJZpV0ztqqsPmx4ZNj+NYwWXwcFiKdb5R8OmV8bgSsnPddD6wFhwewglUOBPRAjropHE4sqk1Vam6q1MlFq5kiekMn/CItyFYFFzST/ruqAtVTp7YIvazAMrfCKH+pvXWk6pYNHZmL/JZey0GglRyJ1nItiqL33X8Lji056FcbAclidq022h/KPLEJpZk6irWqYdqYZeF6YMLHtdZFDkTZ/hXY+UCgYEA5i794UTQ1Kd6K+iui/S8K5H8nGdiXb3+uZ5j5VKYfbRmzXhAdVYisYe8czeTECxhH+MeHgM4tLR4ifx9q60ylvZxl9Fav1p6EaE36YcvGVmpm7Gm3q6QDDBa4gB+X9u7CxCS4LpotV917YS1QvOIF9lnRonSj1zNzFtbXkywrN8CgYEAwOpx/mR40ZvgZxNCq9DsIdrSZYAFFKpw0xy0OtF1PpuwMaREoRabnlVw6Bb3Hofg50XA3JxemzAX6fB92ee+NfXfeL4UtC4vG1K9JyiXHtHq8p9Uw2W03ehIEeNa3xdoRRnLmD4VUpyfL19ViE2+7TM1Gd3TogjDT+AMOCSuq3MCgYBsurPH7gaq/LVT+mRAzgj4l8v4YUlwuGeTbIMJdvt7HXUWB4CDLH3U2CYnUpAQKrZyJok6ahEmIr1xiKggKP7lmmHL8eNo0icpHrtXfzi7Q8Q/PCpzs4dtioXTjaIkS5nNvzVyG/uL+RyuZmpsxrZ5dYM4KbAhchfwORMutxEZhwKBgQC5zpVw4jCEItBmNuTWO+nTScGvxTgfiXIVw+XLaQa2AJoZlhAL34yPWdffko79tv3lgweY9HsimZXO2rU8dbp8mo5c6ydhy8HPXUeWOcAkDSdv/ApWENW9jgYsRIC3swHY3Fl+Dv3Wjce8huQI3mjwaYvRmBhIToxfmHnscVhTBQKBgB9uciEHfz8hMI7ePrPo2PkyK/RbJDm3HnuWE2lFBp7MOUMlh53MXwv4dIRaYMbRrFuN1UIKEFxuKhWwTHSzZJufk/UENrha/81fpj2BoFsAKkEunKeETvaIh6fZSjec16h2+zxbzwkdS6b+yIYkSlaoAxmDYrMtae0C8G4e0YS9";
String pubKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2RZZISModRzproL3eTxRtvVK/nToDbeLmAVdmaVtHgNCwjXMeNCZvHySZKO7+t7XySzBd2PhhQjvAkDd8HRKB5Y0uvP6TFwvhxOMkMydTeBFcUobQWNeAI7ttRms1txSNrmyrZr0WpWfk79VIsO+yI/jFN/Pj2gxD+vh5UUKU1LD2IQq/VxgtEpf8Vs6w7SvafPwYkpdPGCKUFkRvN1FrY2+tq0j1MRVJbB2rIunWDnT8cDUh2sWLXf4yNaJVOaaTFB0zbAk/qcoicGQyW7bVG7dVW8WywKmOAPeQCCQa+SJ4BhfI1k8eEAwFVRuxz/f9Ecfog9hZJ+RgELkpS8qhQIDAQAB";
rsaSigner signer = new rsaSigner();
Map<String, Object> params = new HashMap<>();
params.put("app_id", "hxgmau9imt86qky9");
params.put("version", "1.0");
params.put("key_version", "admin");
params.put("time", Long.toString(System.currentTimeMillis() / 1000));
params.put("coin","eth");
params.put("chain","eth");
params.put("page","1");
params.put("page_size","20");
try {
params.put("sign", signer.genSign(params, priKey));
Gson gson = new GsonBuilder().create();
System.out.println("params = " + gson.toJson(params));
String res = doPost(baseUrl + "/coin/list", gson.toJson(params));
if (null == res) {
throw new RuntimeException("http error");
}
System.out.println("response = " + res);
JsonParser jp = new JsonParser();
JsonObject resEle = jp.parse(res).getAsJsonObject();
boolean retSignOK = signer.verifySign(resEle, resEle.get("sign").getAsString(), pubKey);
if (!retSignOK) {
throw new RuntimeException("verify response sign fail");
}
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("OK");
}
返回结果示例:
{
"status": 200,
"msg": "处理成功",
"data": {
"page": 1,
"max_page": 2,
"count": 20,
"list": [
{
"coin": "eth",
"chain": "eth",
"contract_address": "",
"status": "1",
"open_in": 1,
"open_out": 1,
"open_address": "1",
"confirm_count": "6",
"min_transfer_in_amount": "0.00000001",
"min_transfer_out_amount": "0"
},
{
"coin": "hc",
"chain": "hc",
"contract_address": "",
"status": "1",
"open_in": 1,
"open_out": 1,
"open_address": "1",
"confirm_count": "1",
"min_transfer_in_amount": "0",
"min_transfer_out_amount": "0.0001"
},
……
]
},
"date_time": "2020-08-04 15:19:56",
"time_stamp": 1596525596,
"sign": "OD3xNGUDAsR0G9IXH6JIAJIrzU5rftHQLQT9qSe5qBqO9hDp+LXE2vJ5AAMqZoX6YNeeJy0tQUBM6aF/OIl6czKr520Y6xOhYvagw5Ip3iyOARZordlUhGR+KmJq3BFarxsiTL01bWQOPIz9v3CY4s0xgkl/nL6ZeNn9woDqw50vaDPSNC/tB9Qb/yFZdOI5npFipTRvxGFh2/EVH+1STlDjWyVPAnri26YEbob3xtSkCZP6894ScRW8ps/+7EW8FCKlhg/39XuysyNtMKt9rT5+yHzuDe/1oJZ9r5zTV8pDs2D3SjPWVLT1naMLhNFH0TLGUcgOneNjG6aMzWb9WA=="
}
商家支持币种查询接口
HTTP Request
POST: /coin/list
请求参数
| 参数名 | 必选 | 类型 | 说明 |
|---|---|---|---|
| 公共参数 | 是 | string | 公参指:签名(sign)、版本(version)、商户ID(app_id)、时间(time) |
| coin | 否 | varchar | 币名(如:eth) |
| chain | 否 | varchar | 主链名(查询 主链及其代币,如:eth) |
| page | 否 | int,默认值为1 | 1<= N <=Max, N>Max ? N=Max ; N<1 ? N=1 |
| page_size | 否 | int | 每页数量 (20 ~500),默认 20 |
返回参数说明
| 参数名 | 类型 | 说明 |
|---|---|---|
| status | int | 状态码 |
| msg | string | 状态描述 |
| data | jsonObject | 具体见下面 “data细节说明”。 |
| data.page | int | 第几页 |
| data.max_page | int | 总页数 |
| data.count | int | 当前页记录数 |
| data.list | jsonArray | 具体每条记录 |
| data.list.coin | string | 币种 |
| data.list.chain | string | 主链名 |
| data.list.status | int | 状态:1 开启;0 关闭 |
| data.list.open_in | int | 充值状态:1 开启;0 关闭 |
| data.list.open_out | int | 提现状态:1 开启;0 关闭 |
| data.list.open_address | int | 分配地址状态::1 开启;0 关闭 |
| data.list.confirm_count | int | 充值确认数(默认 6 实际入账以订单状态为准) |
| data.list.min_transfer_in_amount | string | 最小转入金额(0 表示不限制 ) |
| data.list.min_transfer_out_amount | string | 最小提现金额(0 表示不限制 ) |
| data.list.contract_address | string | 合约币种的合约地址 |
| date_time | string | 响应时间 |
| time_stamp | int | 无时区的秒 |
| sign | string | 签名 |
币价汇率
$url = "http://api.xxxx.com/shopapi/rate/index";
$header = [
'Content-Type:application/json',
];
$params = [
"app_id" => "hxgmau9imt86qky9",
"version" => "1.0",
"time" => 1579004943,
"source_coin" => "eth",
"target_coin" => "usdt",
"sign" => "dLtK+uiPcnxt2ACKMbBqQ6wI5ttAvesOHzK5ybVID1R6hqYPDTkagl7Tsjr5iLJafehcSLTZyJLtCRI8O2CtIWQUUroGXBneHZC486NUi/4FMOQs0FaAgm17pWlbhX5/96cWXXXMVeoe3IZFKaFNYSWaA14v3RcdDU6QDE/9ixGiSJ0DIxm9NKA0+RkbIFbyYeuFn8d63OcjmUhv7tsOE6rKCc3Q2yi7Qe9i6BNAQFYMFATztb18MsxsBHKUxNqklqyVnl0ofETAHmQhfOHLmungOJQnOqAAuwfmRtg50Qci5F+R2mXeqjmIXko/u3E+DLYW1ygDBp3afKZmU4PwmA=="
];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
$return = curl_exec($ch);
print_r($return);
var url = "http://api.xxxx.com/shopapi/rate/index"
data := map[string]string{
"app_id":"hxgmau9imt86qky9",
"version":"1.0",
"time":"1579004943",
"source_coin":"eth",
"target_coin":"usdt",
"sign":"IUtWA3HEkK+wvTGaSBYwIrdx+ANyoOPl2/1LQTDevCSTxf4/lDXPrg6/ph+skNXIbZTR8Qs2yGGkqTUHEW/vbiTPzWkYZ874rRgplp06vhOBM/Pkw289K7PVCKy1ksOtLjwj1dUfDD/2AEqTgxRDjGyn+yDWRa7HLL/28bjU3pZoFwPPjbPyRxMK9BVL/li9IQ6hb8lyOyQNHNxS3C82sDVaQKqrB0dOqtP61OH0hBonrxMhBAMD8dUmaqO6Ef+bhHzbBm3BCC5VapkOkdthb+UWXKCiBoCipg3gqrwnBdOUGXqx/1mYicNZ+oHeVpBwnJlXudff6FT+HySszr5ISw==",
}
dataType, _ := json.Marshal(data)
resp, err := http.Post(url, "application/json", strings.NewReader(string(dataType)))
if err != nil {
fmt.Println(err)
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Println(err)
}
fmt.Println(string(body))
let HTTP = require('http')
let postData = {
"app_id":"hxgmau9imt86qky9",
"version":"1.0",
"time":"1579004943",
"source_coin":"eth",
"target_coin":"usdt",
"sign":"IUtWA3HEkK+wvTGaSBYwIrdx+ANyoOPl2/1LQTDevCSTxf4/lDXPrg6/ph+skNXIbZTR8Qs2yGGkqTUHEW/vbiTPzWkYZ874rRgplp06vhOBM/Pkw289K7PVCKy1ksOtLjwj1dUfDD/2AEqTgxRDjGyn+yDWRa7HLL/28bjU3pZoFwPPjbPyRxMK9BVL/li9IQ6hb8lyOyQNHNxS3C82sDVaQKqrB0dOqtP61OH0hBonrxMhBAMD8dUmaqO6Ef+bhHzbBm3BCC5VapkOkdthb+UWXKCiBoCipg3gqrwnBdOUGXqx/1mYicNZ+oHeVpBwnJlXudff6FT+HySszr5ISw==",
};
let POST_OPTIONS = {
port: 80,
host: "api.xxxx.com",
path: "/shopapi/rate/index",
method: 'POST',
headers: {
"Content-Type": "application/json; charset=utf-8"
}
};
const REQUEST = HTTP.request(POST_OPTIONS,function (res) {
let data = []
res.on('data', chunk => {
data.push(...chunk)
})
res.on('end', () => {
let _date = JSON.parse( new TextDecoder().decode(new Uint8Array(data)))
console.log(_date)
})
});
REQUEST.setTimeout(6000)
REQUEST.write(JSON.stringify(postData), 'utf8')
REQUEST.end()
public static void main(String[] args) {
// 完整实例请查看"签名规则"中的Java示例代码
String baseUrl = "http://api.xxxx.com/shopapi";
String priKey = "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCtdgvcfozY7fe/x6UlXR/Fff8+wX++CiG05YVRafDe90O8y5KJAMZ156TgajEUXSRyKZqASz7iVoMAcu5FqfK1KuOOdjTAg0LFe/twIZvKmAqHcCSS2pjUXk0fTpZEgQ5lmDCK12Mg07YXvr+BeHjF+kBpwRJMPMG/+DGBDYNFNeRSJqWyopt6yyF528soAykHIUQ7TTultJV5IPCrvjRQQrGdJ/QtCdE0vZg+tA09nFN7AqgraU99kIvzyS0sqysj+pP1SJRmTRSGtlVAO3mILfkXOekZl1KD60G7CF+7BIaaW83FPD55tZhAGhnbLMYyiq7OiIyU61LTRcNSaJ0tAgMBAAECggEBAIGgGKcSzxCBbMYdXLV6TPbZ/HeaRGrwyVWUu7cmc0E8CJu6iWvmb2jGzbiCwuCT5luF6ZZ8JKchvU4FlTfsE5r9TQY2IZ/Ht4s65qBaDUEts5iY3kv8HX9+ZSXDJZpV0ztqqsPmx4ZNj+NYwWXwcFiKdb5R8OmV8bgSsnPddD6wFhwewglUOBPRAjropHE4sqk1Vam6q1MlFq5kiekMn/CItyFYFFzST/ruqAtVTp7YIvazAMrfCKH+pvXWk6pYNHZmL/JZey0GglRyJ1nItiqL33X8Lji056FcbAclidq022h/KPLEJpZk6irWqYdqYZeF6YMLHtdZFDkTZ/hXY+UCgYEA5i794UTQ1Kd6K+iui/S8K5H8nGdiXb3+uZ5j5VKYfbRmzXhAdVYisYe8czeTECxhH+MeHgM4tLR4ifx9q60ylvZxl9Fav1p6EaE36YcvGVmpm7Gm3q6QDDBa4gB+X9u7CxCS4LpotV917YS1QvOIF9lnRonSj1zNzFtbXkywrN8CgYEAwOpx/mR40ZvgZxNCq9DsIdrSZYAFFKpw0xy0OtF1PpuwMaREoRabnlVw6Bb3Hofg50XA3JxemzAX6fB92ee+NfXfeL4UtC4vG1K9JyiXHtHq8p9Uw2W03ehIEeNa3xdoRRnLmD4VUpyfL19ViE2+7TM1Gd3TogjDT+AMOCSuq3MCgYBsurPH7gaq/LVT+mRAzgj4l8v4YUlwuGeTbIMJdvt7HXUWB4CDLH3U2CYnUpAQKrZyJok6ahEmIr1xiKggKP7lmmHL8eNo0icpHrtXfzi7Q8Q/PCpzs4dtioXTjaIkS5nNvzVyG/uL+RyuZmpsxrZ5dYM4KbAhchfwORMutxEZhwKBgQC5zpVw4jCEItBmNuTWO+nTScGvxTgfiXIVw+XLaQa2AJoZlhAL34yPWdffko79tv3lgweY9HsimZXO2rU8dbp8mo5c6ydhy8HPXUeWOcAkDSdv/ApWENW9jgYsRIC3swHY3Fl+Dv3Wjce8huQI3mjwaYvRmBhIToxfmHnscVhTBQKBgB9uciEHfz8hMI7ePrPo2PkyK/RbJDm3HnuWE2lFBp7MOUMlh53MXwv4dIRaYMbRrFuN1UIKEFxuKhWwTHSzZJufk/UENrha/81fpj2BoFsAKkEunKeETvaIh6fZSjec16h2+zxbzwkdS6b+yIYkSlaoAxmDYrMtae0C8G4e0YS9";
String pubKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2RZZISModRzproL3eTxRtvVK/nToDbeLmAVdmaVtHgNCwjXMeNCZvHySZKO7+t7XySzBd2PhhQjvAkDd8HRKB5Y0uvP6TFwvhxOMkMydTeBFcUobQWNeAI7ttRms1txSNrmyrZr0WpWfk79VIsO+yI/jFN/Pj2gxD+vh5UUKU1LD2IQq/VxgtEpf8Vs6w7SvafPwYkpdPGCKUFkRvN1FrY2+tq0j1MRVJbB2rIunWDnT8cDUh2sWLXf4yNaJVOaaTFB0zbAk/qcoicGQyW7bVG7dVW8WywKmOAPeQCCQa+SJ4BhfI1k8eEAwFVRuxz/f9Ecfog9hZJ+RgELkpS8qhQIDAQAB";
rsaSigner signer = new rsaSigner();
Map<String, Object> params = new HashMap<>();
params.put("app_id", "hxgmau9imt86qky9");
params.put("version", "1.0");
params.put("key_version", "admin");
params.put("time", Long.toString(System.currentTimeMillis() / 1000));
params.put("source_coin","eth");
params.put("target_coin","usdt");
try {
params.put("sign", signer.genSign(params, priKey));
Gson gson = new GsonBuilder().create();
System.out.println("params = " + gson.toJson(params));
String res = doPost(baseUrl + "/rate/index", gson.toJson(params));
if (null == res) {
throw new RuntimeException("http error");
}
System.out.println("response = " + res);
JsonParser jp = new JsonParser();
JsonObject resEle = jp.parse(res).getAsJsonObject();
boolean retSignOK = signer.verifySign(resEle, resEle.get("sign").getAsString(), pubKey);
if (!retSignOK) {
throw new RuntimeException("verify response sign fail");
}
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("OK");
}
返回结果示例:
{
"status":200,
"msg":"请求成功",
"data":{
"rate":"19490.64944834 "
},
"date_time":"2020-01-14 00:50:27",
"sign":"ib1gqr0E0gJ02yo3InXKcKGaPqIp+r1izMego+KMRvE0B4ZdkFGrLmOtxGStUBibGVMzJRGWppKyU4PzcK877AOEvQlSFiUI+hDL1z8WaZsWD3r3ykbPzU0uWo4U+6WQTpOEo1gJ/N2zJsdTRcMVgJMSC7LEAg7oib4se2NPFlw="
}
各种币对应usdt 的汇率(用于币价计算,不用于兑换,兑换请走兑换汇率接口)。目前支持(btc eth hc eos trx xrp)
HTTP Request
POST: /rate/index
请求参数
| 参数名 | 必选 | 类型 | 说明 |
|---|---|---|---|
| 公共参数 | 是 | string | 公参指:签名(sign)、版本(version)、商户ID(app_id)、时间(time) |
| source_coin | 是 | string | 兑换币 |
| target_coin | 是 | string | 目标币 目前只支持 usdt |
返回参数说明
| 参数名 | 类型 | 说明 |
|---|---|---|
| status | int | 状态码 |
| msg | string | 状态描述 |
| data | jsonObject | 具体见下面 “data细节说明”。 |
| data.rate | string | 汇率 如 1btc= 19490.64944834 usdt |
| date_time | string | 响应时间 |
| time_stamp | int | 无时区的秒 |
| sign | string | 签名 |
币种对法币价格汇率
$url = "http://api.xxxx.com/shopapi/rate/fiat_currency";
$header = [
'Content-Type:application/json',
];
$params = [
"app_id" => "hxgmau9imt86qky9",
"version" => "1.0",
"time" => 1579004943,
"source_coin" => "eth",
"target_currency" => "usd",
"sign" => "dLtK+uiPcnxt2ACKMbBqQ6wI5ttAvesOHzK5ybVID1R6hqYPDTkagl7Tsjr5iLJafehcSLTZyJLtCRI8O2CtIWQUUroGXBneHZC486NUi/4FMOQs0FaAgm17pWlbhX5/96cWXXXMVeoe3IZFKaFNYSWaA14v3RcdDU6QDE/9ixGiSJ0DIxm9NKA0+RkbIFbyYeuFn8d63OcjmUhv7tsOE6rKCc3Q2yi7Qe9i6BNAQFYMFATztb18MsxsBHKUxNqklqyVnl0ofETAHmQhfOHLmungOJQnOqAAuwfmRtg50Qci5F+R2mXeqjmIXko/u3E+DLYW1ygDBp3afKZmU4PwmA=="
];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
$return = curl_exec($ch);
print_r($return);
var url = "http://api.xxxx.com/shopapi/rate/fiat_currency"
data := map[string]string{
"app_id":"hxgmau9imt86qky9",
"version":"1.0",
"time":"1579004943",
"source_coin":"eth",
"target_currency":"usd",
"sign":"IUtWA3HEkK+wvTGaSBYwIrdx+ANyoOPl2/1LQTDevCSTxf4/lDXPrg6/ph+skNXIbZTR8Qs2yGGkqTUHEW/vbiTPzWkYZ874rRgplp06vhOBM/Pkw289K7PVCKy1ksOtLjwj1dUfDD/2AEqTgxRDjGyn+yDWRa7HLL/28bjU3pZoFwPPjbPyRxMK9BVL/li9IQ6hb8lyOyQNHNxS3C82sDVaQKqrB0dOqtP61OH0hBonrxMhBAMD8dUmaqO6Ef+bhHzbBm3BCC5VapkOkdthb+UWXKCiBoCipg3gqrwnBdOUGXqx/1mYicNZ+oHeVpBwnJlXudff6FT+HySszr5ISw==",
}
dataType, _ := json.Marshal(data)
resp, err := http.Post(url, "application/json", strings.NewReader(string(dataType)))
if err != nil {
fmt.Println(err)
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Println(err)
}
fmt.Println(string(body))
let HTTP = require('http')
let postData = {
"app_id":"hxgmau9imt86qky9",
"version":"1.0",
"time":"1579004943",
"source_coin":"eth",
"target_currency":"usd",
"sign":"IUtWA3HEkK+wvTGaSBYwIrdx+ANyoOPl2/1LQTDevCSTxf4/lDXPrg6/ph+skNXIbZTR8Qs2yGGkqTUHEW/vbiTPzWkYZ874rRgplp06vhOBM/Pkw289K7PVCKy1ksOtLjwj1dUfDD/2AEqTgxRDjGyn+yDWRa7HLL/28bjU3pZoFwPPjbPyRxMK9BVL/li9IQ6hb8lyOyQNHNxS3C82sDVaQKqrB0dOqtP61OH0hBonrxMhBAMD8dUmaqO6Ef+bhHzbBm3BCC5VapkOkdthb+UWXKCiBoCipg3gqrwnBdOUGXqx/1mYicNZ+oHeVpBwnJlXudff6FT+HySszr5ISw==",
};
let POST_OPTIONS = {
port: 80,
host: "api.xxxx.com",
path: "/shopapi/rate/fiat_currency",
method: 'POST',
headers: {
"Content-Type": "application/json; charset=utf-8"
}
};
const REQUEST = HTTP.request(POST_OPTIONS,function (res) {
let data = []
res.on('data', chunk => {
data.push(...chunk)
})
res.on('end', () => {
let _date = JSON.parse( new TextDecoder().decode(new Uint8Array(data)))
console.log(_date)
})
});
REQUEST.setTimeout(6000)
REQUEST.write(JSON.stringify(postData), 'utf8')
REQUEST.end()
public static void main(String[] args) {
// 完整实例请查看"签名规则"中的Java示例代码
String baseUrl = "http://api.xxxx.com/shopapi";
String priKey = "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCtdgvcfozY7fe/x6UlXR/Fff8+wX++CiG05YVRafDe90O8y5KJAMZ156TgajEUXSRyKZqASz7iVoMAcu5FqfK1KuOOdjTAg0LFe/twIZvKmAqHcCSS2pjUXk0fTpZEgQ5lmDCK12Mg07YXvr+BeHjF+kBpwRJMPMG/+DGBDYNFNeRSJqWyopt6yyF528soAykHIUQ7TTultJV5IPCrvjRQQrGdJ/QtCdE0vZg+tA09nFN7AqgraU99kIvzyS0sqysj+pP1SJRmTRSGtlVAO3mILfkXOekZl1KD60G7CF+7BIaaW83FPD55tZhAGhnbLMYyiq7OiIyU61LTRcNSaJ0tAgMBAAECggEBAIGgGKcSzxCBbMYdXLV6TPbZ/HeaRGrwyVWUu7cmc0E8CJu6iWvmb2jGzbiCwuCT5luF6ZZ8JKchvU4FlTfsE5r9TQY2IZ/Ht4s65qBaDUEts5iY3kv8HX9+ZSXDJZpV0ztqqsPmx4ZNj+NYwWXwcFiKdb5R8OmV8bgSsnPddD6wFhwewglUOBPRAjropHE4sqk1Vam6q1MlFq5kiekMn/CItyFYFFzST/ruqAtVTp7YIvazAMrfCKH+pvXWk6pYNHZmL/JZey0GglRyJ1nItiqL33X8Lji056FcbAclidq022h/KPLEJpZk6irWqYdqYZeF6YMLHtdZFDkTZ/hXY+UCgYEA5i794UTQ1Kd6K+iui/S8K5H8nGdiXb3+uZ5j5VKYfbRmzXhAdVYisYe8czeTECxhH+MeHgM4tLR4ifx9q60ylvZxl9Fav1p6EaE36YcvGVmpm7Gm3q6QDDBa4gB+X9u7CxCS4LpotV917YS1QvOIF9lnRonSj1zNzFtbXkywrN8CgYEAwOpx/mR40ZvgZxNCq9DsIdrSZYAFFKpw0xy0OtF1PpuwMaREoRabnlVw6Bb3Hofg50XA3JxemzAX6fB92ee+NfXfeL4UtC4vG1K9JyiXHtHq8p9Uw2W03ehIEeNa3xdoRRnLmD4VUpyfL19ViE2+7TM1Gd3TogjDT+AMOCSuq3MCgYBsurPH7gaq/LVT+mRAzgj4l8v4YUlwuGeTbIMJdvt7HXUWB4CDLH3U2CYnUpAQKrZyJok6ahEmIr1xiKggKP7lmmHL8eNo0icpHrtXfzi7Q8Q/PCpzs4dtioXTjaIkS5nNvzVyG/uL+RyuZmpsxrZ5dYM4KbAhchfwORMutxEZhwKBgQC5zpVw4jCEItBmNuTWO+nTScGvxTgfiXIVw+XLaQa2AJoZlhAL34yPWdffko79tv3lgweY9HsimZXO2rU8dbp8mo5c6ydhy8HPXUeWOcAkDSdv/ApWENW9jgYsRIC3swHY3Fl+Dv3Wjce8huQI3mjwaYvRmBhIToxfmHnscVhTBQKBgB9uciEHfz8hMI7ePrPo2PkyK/RbJDm3HnuWE2lFBp7MOUMlh53MXwv4dIRaYMbRrFuN1UIKEFxuKhWwTHSzZJufk/UENrha/81fpj2BoFsAKkEunKeETvaIh6fZSjec16h2+zxbzwkdS6b+yIYkSlaoAxmDYrMtae0C8G4e0YS9";
String pubKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2RZZISModRzproL3eTxRtvVK/nToDbeLmAVdmaVtHgNCwjXMeNCZvHySZKO7+t7XySzBd2PhhQjvAkDd8HRKB5Y0uvP6TFwvhxOMkMydTeBFcUobQWNeAI7ttRms1txSNrmyrZr0WpWfk79VIsO+yI/jFN/Pj2gxD+vh5UUKU1LD2IQq/VxgtEpf8Vs6w7SvafPwYkpdPGCKUFkRvN1FrY2+tq0j1MRVJbB2rIunWDnT8cDUh2sWLXf4yNaJVOaaTFB0zbAk/qcoicGQyW7bVG7dVW8WywKmOAPeQCCQa+SJ4BhfI1k8eEAwFVRuxz/f9Ecfog9hZJ+RgELkpS8qhQIDAQAB";
rsaSigner signer = new rsaSigner();
Map<String, Object> params = new HashMap<>();
params.put("app_id", "hxgmau9imt86qky9");
params.put("version", "1.0");
params.put("key_version", "admin");
params.put("time", Long.toString(System.currentTimeMillis() / 1000));
params.put("source_coin","eth");
params.put("target_currency","usd");
try {
params.put("sign", signer.genSign(params, priKey));
Gson gson = new GsonBuilder().create();
System.out.println("params = " + gson.toJson(params));
String res = doPost(baseUrl + "/rate/fiat_currency", gson.toJson(params));
if (null == res) {
throw new RuntimeException("http error");
}
System.out.println("response = " + res);
JsonParser jp = new JsonParser();
JsonObject resEle = jp.parse(res).getAsJsonObject();
boolean retSignOK = signer.verifySign(resEle, resEle.get("sign").getAsString(), pubKey);
if (!retSignOK) {
throw new RuntimeException("verify response sign fail");
}
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("OK");
}
返回结果示例:
{
"status":200,
"msg":"请求成功",
"data":{
"rate":"2166.81",
"source_coin": "eth",
"target_currency": "usd"
},
"date_time":"2020-01-14 00:50:27",
"sign":"ib1gqr0E0gJ02yo3InXKcKGaPqIp+r1izMego+KMRvE0B4ZdkFGrLmOtxGStUBibGVMzJRGWppKyU4PzcK877AOEvQlSFiUI+hDL1z8WaZsWD3r3ykbPzU0uWo4U+6WQTpOEo1gJ/N2zJsdTRcMVgJMSC7LEAg7oib4se2NPFlw="
}
HTTP Request
POST: /rate/fiat_currency
请求参数
| 参数名 | 必选 | 类型 | 说明 |
|---|---|---|---|
| 公共参数 | 是 | string | 公参指:签名(sign)、版本(version)、商户ID(app_id)、时间(time) |
| source_coin | 是 | string | 待换算数字货币币名 |
| target_currency | 是 | string | 目标法币,默认usd。支持usd,cny,aed,sgd,jpy,krw等。 |
返回参数说明
| 参数名 | 类型 | 说明 |
|---|---|---|
| status | int | 状态码 |
| msg | string | 状态描述 |
| data | jsonObject | 具体见下面 “data细节说明”。 |
| data.rate | string | 汇率价格 如 1eth= 2166.81 usd |
| data.source_coin | string | 待换算数字货币币名 |
| data.target_currency | string | 目标法币 |
| date_time | string | 响应时间 |
| time_stamp | int | 无时区的秒 |
| sign | string | 签名 |
归集手续费计算
$url = "http://api.xxxx.com/shopapi/balance/transactionFee";
$header = [
'Content-Type:application/json',
];
$params = [
"version" => "1.0",
"app_id" => "hxgmau9imt86qky9",
"time" => "1578736053",
"sign" => "OTA8utI8y8G93p7RPCyb4qIilFQ0B4Aq4iUjhaXWK9m2kgektqlHOASDKXT2VE7NPNysrGycYlVfjDR2WGZn1G66phHo3qa9CcCNpG9klOBEuBEMjiVbb/d8AXcxEzvQr9OCwNsikyxonyzLiY/lsNHeGm9cC5eRvlNLdUSVBipH+ajPd0lDHCayZPs1eCMfbm/xnf8e2lfy6z0UPOpHGfyX/0+hz99Ir5Xnx+0sBBzyZZJxKm4ROid5aDv/9m9guILpURae+Yw/IrkYF4uAKGX+/44cBvtTRQSdX76CAOBSiywZa6BAgDYBLRtkAPM+i+vwNzFBovqHUvI+4Ponaw==",
"coin" => "eth"
];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
$return = curl_exec($ch);
print_r($return);
var url = "http://api.xxxx.com/shopapi/balance/transactionFee"
data := map[string]string{
"version": "1.0",
"app_id": "hxgmau9imt86qky9",
"time": "1578736053",
"sign": "OTA8utI8y8G93p7RPCyb4qIilFQ0B4Aq4iUjhaXWK9m2kgektqlHOASDKXT2VE7NPNysrGycYlVfjDR2WGZn1G66phHo3qa9CcCNpG9klOBEuBEMjiVbb/d8AXcxEzvQr9OCwNsikyxonyzLiY/lsNHeGm9cC5eRvlNLdUSVBipH+ajPd0lDHCayZPs1eCMfbm/xnf8e2lfy6z0UPOpHGfyX/0+hz99Ir5Xnx+0sBBzyZZJxKm4ROid5aDv/9m9guILpURae+Yw/IrkYF4uAKGX+/44cBvtTRQSdX76CAOBSiywZa6BAgDYBLRtkAPM+i+vwNzFBovqHUvI+4Ponaw==",
"coin": "eth",
}
dataType, _ := json.Marshal(data)
resp, err := http.Post(url, "application/json", strings.NewReader(string(dataType)))
if err != nil {
fmt.Println(err)
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Println(err)
}
fmt.Println(string(body))
let http = require('http');
let postData = {
"version": "1.0",
"app_id": "hxgmau9imt86qky9",
"time": "1578736053",
"sign": "OTA8utI8y8G93p7RPCyb4qIilFQ0B4Aq4iUjhaXWK9m2kgektqlHOASDKXT2VE7NPNysrGycYlVfjDR2WGZn1G66phHo3qa9CcCNpG9klOBEuBEMjiVbb/d8AXcxEzvQr9OCwNsikyxonyzLiY/lsNHeGm9cC5eRvlNLdUSVBipH+ajPd0lDHCayZPs1eCMfbm/xnf8e2lfy6z0UPOpHGfyX/0+hz99Ir5Xnx+0sBBzyZZJxKm4ROid5aDv/9m9guILpURae+Yw/IrkYF4uAKGX+/44cBvtTRQSdX76CAOBSiywZa6BAgDYBLRtkAPM+i+vwNzFBovqHUvI+4Ponaw==",
"coin": "eth",
};
let options = {
hostname: 'api.xxxx.com',
port: 80,
path: '/shopapi/balance/transactionFee',
method: 'POST',
headers: {
'Content-Type': 'application/json'
}
};
const REQUEST = HTTP.request(POST_OPTIONS,function (res) {
let data = []
res.on('data', chunk => {
data.push(...chunk)
})
res.on('end', () => {
let _date = JSON.parse( new TextDecoder().decode(new Uint8Array(data)))
console.log(_date)
})
});
REQUEST.setTimeout(6000)
REQUEST.write(JSON.stringify(postData), 'utf8')
REQUEST.end()
public static void main(String[] args) {
// 完整实例请查看"签名规则"中的Java示例代码
String baseUrl = "http://api.xxxx.com/shopapi";
String priKey = "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCtdgvcfozY7fe/x6UlXR/Fff8+wX++CiG05YVRafDe90O8y5KJAMZ156TgajEUXSRyKZqASz7iVoMAcu5FqfK1KuOOdjTAg0LFe/twIZvKmAqHcCSS2pjUXk0fTpZEgQ5lmDCK12Mg07YXvr+BeHjF+kBpwRJMPMG/+DGBDYNFNeRSJqWyopt6yyF528soAykHIUQ7TTultJV5IPCrvjRQQrGdJ/QtCdE0vZg+tA09nFN7AqgraU99kIvzyS0sqysj+pP1SJRmTRSGtlVAO3mILfkXOekZl1KD60G7CF+7BIaaW83FPD55tZhAGhnbLMYyiq7OiIyU61LTRcNSaJ0tAgMBAAECggEBAIGgGKcSzxCBbMYdXLV6TPbZ/HeaRGrwyVWUu7cmc0E8CJu6iWvmb2jGzbiCwuCT5luF6ZZ8JKchvU4FlTfsE5r9TQY2IZ/Ht4s65qBaDUEts5iY3kv8HX9+ZSXDJZpV0ztqqsPmx4ZNj+NYwWXwcFiKdb5R8OmV8bgSsnPddD6wFhwewglUOBPRAjropHE4sqk1Vam6q1MlFq5kiekMn/CItyFYFFzST/ruqAtVTp7YIvazAMrfCKH+pvXWk6pYNHZmL/JZey0GglRyJ1nItiqL33X8Lji056FcbAclidq022h/KPLEJpZk6irWqYdqYZeF6YMLHtdZFDkTZ/hXY+UCgYEA5i794UTQ1Kd6K+iui/S8K5H8nGdiXb3+uZ5j5VKYfbRmzXhAdVYisYe8czeTECxhH+MeHgM4tLR4ifx9q60ylvZxl9Fav1p6EaE36YcvGVmpm7Gm3q6QDDBa4gB+X9u7CxCS4LpotV917YS1QvOIF9lnRonSj1zNzFtbXkywrN8CgYEAwOpx/mR40ZvgZxNCq9DsIdrSZYAFFKpw0xy0OtF1PpuwMaREoRabnlVw6Bb3Hofg50XA3JxemzAX6fB92ee+NfXfeL4UtC4vG1K9JyiXHtHq8p9Uw2W03ehIEeNa3xdoRRnLmD4VUpyfL19ViE2+7TM1Gd3TogjDT+AMOCSuq3MCgYBsurPH7gaq/LVT+mRAzgj4l8v4YUlwuGeTbIMJdvt7HXUWB4CDLH3U2CYnUpAQKrZyJok6ahEmIr1xiKggKP7lmmHL8eNo0icpHrtXfzi7Q8Q/PCpzs4dtioXTjaIkS5nNvzVyG/uL+RyuZmpsxrZ5dYM4KbAhchfwORMutxEZhwKBgQC5zpVw4jCEItBmNuTWO+nTScGvxTgfiXIVw+XLaQa2AJoZlhAL34yPWdffko79tv3lgweY9HsimZXO2rU8dbp8mo5c6ydhy8HPXUeWOcAkDSdv/ApWENW9jgYsRIC3swHY3Fl+Dv3Wjce8huQI3mjwaYvRmBhIToxfmHnscVhTBQKBgB9uciEHfz8hMI7ePrPo2PkyK/RbJDm3HnuWE2lFBp7MOUMlh53MXwv4dIRaYMbRrFuN1UIKEFxuKhWwTHSzZJufk/UENrha/81fpj2BoFsAKkEunKeETvaIh6fZSjec16h2+zxbzwkdS6b+yIYkSlaoAxmDYrMtae0C8G4e0YS9";
String pubKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2RZZISModRzproL3eTxRtvVK/nToDbeLmAVdmaVtHgNCwjXMeNCZvHySZKO7+t7XySzBd2PhhQjvAkDd8HRKB5Y0uvP6TFwvhxOMkMydTeBFcUobQWNeAI7ttRms1txSNrmyrZr0WpWfk79VIsO+yI/jFN/Pj2gxD+vh5UUKU1LD2IQq/VxgtEpf8Vs6w7SvafPwYkpdPGCKUFkRvN1FrY2+tq0j1MRVJbB2rIunWDnT8cDUh2sWLXf4yNaJVOaaTFB0zbAk/qcoicGQyW7bVG7dVW8WywKmOAPeQCCQa+SJ4BhfI1k8eEAwFVRuxz/f9Ecfog9hZJ+RgELkpS8qhQIDAQAB";
rsaSigner signer = new rsaSigner();
Map<String, Object> params = new HashMap<>();
params.put("app_id", "hxgmau9imt86qky9");
params.put("version", "1.0");
params.put("key_version", "admin");
params.put("time", Long.toString(System.currentTimeMillis() / 1000));
params.put("coin","eth");
try {
params.put("sign", signer.genSign(params, priKey));
Gson gson = new GsonBuilder().create();
System.out.println("params = " + gson.toJson(params));
String res = doPost(baseUrl + "/balance/transactionFee", gson.toJson(params));
if (null == res) {
throw new RuntimeException("http error");
}
System.out.println("response = " + res);
JsonParser jp = new JsonParser();
JsonObject resEle = jp.parse(res).getAsJsonObject();
boolean retSignOK = signer.verifySign(resEle, resEle.get("sign").getAsString(), pubKey);
if (!retSignOK) {
throw new RuntimeException("verify response sign fail");
}
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("OK");
}
返回结果示例:
{
"status":200,
"msg":"请求成功",
"data":{
"fee":"0.01386",
"coin":"eth"
},
"date_time":"2020-10-20 15:58:53",
"time_stamp":1603180733,
"sign":"e7gvr/t/5E6Me2Y/ZL2RPd8Ua2vWayndE9+YwElQMn7lw1gTsWe3PLFjdIbICB/cZEAQdY2Aiwy+KHAydUA0QMqrufXBmXYhwDCmcf/z362gpD+e1X+beyU/u7wy9qSdgnyTpqyuAoXGffs/lY4TAwel8J/YBp79h+7YHCWT2u54XOAH0tMKMxhxhyMo7wiBBalDa1Nf/i5WZs92encHFQLceF1JMkAZ57c0bGaUs/ks+MUNMR09Va8BaTL9ZSi0oy5xhwXRCprOQ7Fqe8ivUvUn99WwL2KeldY2HKoJYZsz+4J5UZJp2xgupOVwnaH51MiUW9lI0F6Augo+laOI1A=="
}
- 功能: 充值订单归集手续费计算
- 目前仅支持 eth 、usdt_erc20 ,其他币种后续持续扩充。
HTTP Request
POST: /balance/transactionFee
请求参数
| 参数名 | 必选 | 类型 | 说明 |
|---|---|---|---|
| 公共参数 | 是 | JSON | 公参指:签名(sign)、版本(version)、商户ID(app_id)、时间(time) |
| coin | 是 | string | 币名 由平台提供为准 |
返回参数说明
| 参数名 | 类型 | 说明 |
|---|---|---|
| status | int | 状态码 |
| msg | string | 状态描述 |
| data | jsonObject | |
| data.fee | string | 手续费 |
| data.coin | string | 币名(手续费单位) |
| date_time | string | 响应时间 |
| time_stamp | int | 无时区的秒 |
| sign | string | 签名 |
提现gas费预估查询
$url = "http://api.xxxx.com/shopapi/transfer/transactionFee";
$header = [
'Content-Type:application/json',
];
$params = [
"version" => "1.0",
"app_id" => "hxgmau9imt86qky9",
"time" => "1578736053",
"coin" => "eth",
"sign" => "dLtK+uiPcnxt2ACKMbBqQ6wI5ttAvesOHzK5ybVID1R6hqYPDTkagl7Tsjr5iLJafehcSLTZyJLtCRI8O2CtIWQUUroGXBneHZC486NUi/4FMOQs0FaAgm17pWlbhX5/96cWXXXMVeoe3IZFKaFNYSWaA14v3RcdDU6QDE/9ixGiSJ0DIxm9NKA0+RkbIFbyYeuFn8d63OcjmUhv7tsOE6rKCc3Q2yi7Qe9i6BNAQFYMFATztb18MsxsBHKUxNqklqyVnl0ofETAHmQhfOHLmungOJQnOqAAuwfmRtg50Qci5F+R2mXeqjmIXko/u3E+DLYW1ygDBp3afKZmU4PwmA=="
];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
$return = curl_exec($ch);
print_r($return);
var url = "http://api.xxxx.com/shopapi/transfer/transactionFee"
data := map[string]string{
"version": "1.0",
"app_id": "hxgmau9imt86qky9",
"time": "1578736053",
"sign": "OTA8utI8y8G93p7RPCyb4qIilFQ0B4Aq4iUjhaXWK9m2kgektqlHOASDKXT2VE7NPNysrGycYlVfjDR2WGZn1G66phHo3qa9CcCNpG9klOBEuBEMjiVbb/d8AXcxEzvQr9OCwNsikyxonyzLiY/lsNHeGm9cC5eRvlNLdUSVBipH+ajPd0lDHCayZPs1eCMfbm/xnf8e2lfy6z0UPOpHGfyX/0+hz99Ir5Xnx+0sBBzyZZJxKm4ROid5aDv/9m9guILpURae+Yw/IrkYF4uAKGX+/44cBvtTRQSdX76CAOBSiywZa6BAgDYBLRtkAPM+i+vwNzFBovqHUvI+4Ponaw==",
"coin": "eth",
}
dataType, _ := json.Marshal(data)
resp, err := http.Post(url, "application/json", strings.NewReader(string(dataType)))
if err != nil {
fmt.Println(err)
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Println(err)
}
fmt.Println(string(body))
let http = require('http');
let postData = {
"version": "1.0",
"app_id": "hxgmau9imt86qky9",
"time": "1578736053",
"sign": "OTA8utI8y8G93p7RPCyb4qIilFQ0B4Aq4iUjhaXWK9m2kgektqlHOASDKXT2VE7NPNysrGycYlVfjDR2WGZn1G66phHo3qa9CcCNpG9klOBEuBEMjiVbb/d8AXcxEzvQr9OCwNsikyxonyzLiY/lsNHeGm9cC5eRvlNLdUSVBipH+ajPd0lDHCayZPs1eCMfbm/xnf8e2lfy6z0UPOpHGfyX/0+hz99Ir5Xnx+0sBBzyZZJxKm4ROid5aDv/9m9guILpURae+Yw/IrkYF4uAKGX+/44cBvtTRQSdX76CAOBSiywZa6BAgDYBLRtkAPM+i+vwNzFBovqHUvI+4Ponaw==",
"coin": "eth",
};
let options = {
hostname: 'api.xxxx.com',
port: 80,
path: '/shopapi/transfer/transactionFee',
method: 'POST',
headers: {
'Content-Type': 'application/json'
}
};
const REQUEST = HTTP.request(POST_OPTIONS,function (res) {
let data = []
res.on('data', chunk => {
data.push(...chunk)
})
res.on('end', () => {
let _date = JSON.parse( new TextDecoder().decode(new Uint8Array(data)))
console.log(_date)
})
});
REQUEST.setTimeout(6000)
REQUEST.write(JSON.stringify(postData), 'utf8')
REQUEST.end()
public static void main(String[] args) {
// 完整实例请查看"签名规则"中的Java示例代码
String baseUrl = "http://api.xxxx.com/shopapi";
String priKey = "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCtdgvcfozY7fe/x6UlXR/Fff8+wX++CiG05YVRafDe90O8y5KJAMZ156TgajEUXSRyKZqASz7iVoMAcu5FqfK1KuOOdjTAg0LFe/twIZvKmAqHcCSS2pjUXk0fTpZEgQ5lmDCK12Mg07YXvr+BeHjF+kBpwRJMPMG/+DGBDYNFNeRSJqWyopt6yyF528soAykHIUQ7TTultJV5IPCrvjRQQrGdJ/QtCdE0vZg+tA09nFN7AqgraU99kIvzyS0sqysj+pP1SJRmTRSGtlVAO3mILfkXOekZl1KD60G7CF+7BIaaW83FPD55tZhAGhnbLMYyiq7OiIyU61LTRcNSaJ0tAgMBAAECggEBAIGgGKcSzxCBbMYdXLV6TPbZ/HeaRGrwyVWUu7cmc0E8CJu6iWvmb2jGzbiCwuCT5luF6ZZ8JKchvU4FlTfsE5r9TQY2IZ/Ht4s65qBaDUEts5iY3kv8HX9+ZSXDJZpV0ztqqsPmx4ZNj+NYwWXwcFiKdb5R8OmV8bgSsnPddD6wFhwewglUOBPRAjropHE4sqk1Vam6q1MlFq5kiekMn/CItyFYFFzST/ruqAtVTp7YIvazAMrfCKH+pvXWk6pYNHZmL/JZey0GglRyJ1nItiqL33X8Lji056FcbAclidq022h/KPLEJpZk6irWqYdqYZeF6YMLHtdZFDkTZ/hXY+UCgYEA5i794UTQ1Kd6K+iui/S8K5H8nGdiXb3+uZ5j5VKYfbRmzXhAdVYisYe8czeTECxhH+MeHgM4tLR4ifx9q60ylvZxl9Fav1p6EaE36YcvGVmpm7Gm3q6QDDBa4gB+X9u7CxCS4LpotV917YS1QvOIF9lnRonSj1zNzFtbXkywrN8CgYEAwOpx/mR40ZvgZxNCq9DsIdrSZYAFFKpw0xy0OtF1PpuwMaREoRabnlVw6Bb3Hofg50XA3JxemzAX6fB92ee+NfXfeL4UtC4vG1K9JyiXHtHq8p9Uw2W03ehIEeNa3xdoRRnLmD4VUpyfL19ViE2+7TM1Gd3TogjDT+AMOCSuq3MCgYBsurPH7gaq/LVT+mRAzgj4l8v4YUlwuGeTbIMJdvt7HXUWB4CDLH3U2CYnUpAQKrZyJok6ahEmIr1xiKggKP7lmmHL8eNo0icpHrtXfzi7Q8Q/PCpzs4dtioXTjaIkS5nNvzVyG/uL+RyuZmpsxrZ5dYM4KbAhchfwORMutxEZhwKBgQC5zpVw4jCEItBmNuTWO+nTScGvxTgfiXIVw+XLaQa2AJoZlhAL34yPWdffko79tv3lgweY9HsimZXO2rU8dbp8mo5c6ydhy8HPXUeWOcAkDSdv/ApWENW9jgYsRIC3swHY3Fl+Dv3Wjce8huQI3mjwaYvRmBhIToxfmHnscVhTBQKBgB9uciEHfz8hMI7ePrPo2PkyK/RbJDm3HnuWE2lFBp7MOUMlh53MXwv4dIRaYMbRrFuN1UIKEFxuKhWwTHSzZJufk/UENrha/81fpj2BoFsAKkEunKeETvaIh6fZSjec16h2+zxbzwkdS6b+yIYkSlaoAxmDYrMtae0C8G4e0YS9";
String pubKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2RZZISModRzproL3eTxRtvVK/nToDbeLmAVdmaVtHgNCwjXMeNCZvHySZKO7+t7XySzBd2PhhQjvAkDd8HRKB5Y0uvP6TFwvhxOMkMydTeBFcUobQWNeAI7ttRms1txSNrmyrZr0WpWfk79VIsO+yI/jFN/Pj2gxD+vh5UUKU1LD2IQq/VxgtEpf8Vs6w7SvafPwYkpdPGCKUFkRvN1FrY2+tq0j1MRVJbB2rIunWDnT8cDUh2sWLXf4yNaJVOaaTFB0zbAk/qcoicGQyW7bVG7dVW8WywKmOAPeQCCQa+SJ4BhfI1k8eEAwFVRuxz/f9Ecfog9hZJ+RgELkpS8qhQIDAQAB";
rsaSigner signer = new rsaSigner();
Map<String, Object> params = new HashMap<>();
params.put("app_id", "hxgmau9imt86qky9");
params.put("version", "1.0");
params.put("key_version", "admin");
params.put("time", Long.toString(System.currentTimeMillis() / 1000));
params.put("coin","eth");
try {
params.put("sign", signer.genSign(params, priKey));
Gson gson = new GsonBuilder().create();
System.out.println("params = " + gson.toJson(params));
String res = doPost(baseUrl + "/transfer/transactionFee", gson.toJson(params));
if (null == res) {
throw new RuntimeException("http error");
}
System.out.println("response = " + res);
JsonParser jp = new JsonParser();
JsonObject resEle = jp.parse(res).getAsJsonObject();
boolean retSignOK = signer.verifySign(resEle, resEle.get("sign").getAsString(), pubKey);
if (!retSignOK) {
throw new RuntimeException("verify response sign fail");
}
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("OK");
}
返回结果示例:
{
"status": 200,
"msg": "请求成功",
"data": [
{
"coin": "fil", //币名
"fee": "0.00379379", //当前币(coin) 交易手续费
"unit": "fil"//手续费单位
}, {
"coin": "eth",
"fee": "0.000231",
"unit": "eth"
}, {
"coin": "mof",
"fee": "0.00000005",
"unit": "eth"
}
],
"date_time": "2021-06-17 16:58:52",
"time_stamp": 1623920332,
"sign": "d1cAN64orfoNQMklGCep3E2t4BVbbsWt3pcb1T84ZfASFAy9p8fn5eSuoQD3q0AjPCUd+tjdhSUyiRXs3aGIAEAQh88jWf4EoCw8V0bG1TrRFw23rS84FmeWwHEnMOY8gRekWuzrfh0y33ThW6b81q7ARpMaONQWRLq2i6d7xAQIP5jZgSg1npGfTGwGnNlJbMiWLN2WTF7KbiUHy2WZ7cx8t2qaXopCxE0G2si8AFcmdOhBiooETFCP+jMr3wdn7DzZs39lVeIaG+XjplsSpQjc1ESKdTWDCAw1vpfQUGBpAyrF2eXuS+rT9caVgUwUluhwbDTI2npUsw=="
}
提现手续费预估查询接口,返回支持币种提现的手续费。(目前只支持eth及其合约、fil)
HTTP Request
POST: /transfer/transactionFee
请求参数
| 参数名 | 必选 | 类型 | 说明 |
|---|---|---|---|
| 公共参数 | 是 | string | 公参指:签名(sign)、版本(version)、商户ID(app_id)、时间(time) |
| coin | 否 | string | 币名 由平台提供为准 |
返回参数说明
| 参数名 | 类型 | 说明 |
|---|---|---|
| status | int | 状态码 |
| msg | string | 状态描述 |
| data | jsonObject | trade_id-由商户提供 |
| data.coin | sring | 币名 |
| data.fee | sring | 手续费 |
| data.unit | sring | 手续费单位 |
| date_time | string | 响应时间 |
| time_stamp | int | 无时区的秒 |
| sign | string | 签名 |
退款记录列表
$url = "http://api.xxxx.com/shopapi/refund/list";
$header = [
'Content-Type:application/json',
];
$params = [
"version" => "1.0",
"app_id" => "hxgmau9imt86qky9",
"time" => "1578736053",
"page" => 1,
"sign" => "dLtK+uiPcnxt2ACKMbBqQ6wI5ttAvesOHzK5ybVID1R6hqYPDTkagl7Tsjr5iLJafehcSLTZyJLtCRI8O2CtIWQUUroGXBneHZC486NUi/4FMOQs0FaAgm17pWlbhX5/96cWXXXMVeoe3IZFKaFNYSWaA14v3RcdDU6QDE/9ixGiSJ0DIxm9NKA0+RkbIFbyYeuFn8d63OcjmUhv7tsOE6rKCc3Q2yi7Qe9i6BNAQFYMFATztb18MsxsBHKUxNqklqyVnl0ofETAHmQhfOHLmungOJQnOqAAuwfmRtg50Qci5F+R2mXeqjmIXko/u3E+DLYW1ygDBp3afKZmU4PwmA=="
];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
$return = curl_exec($ch);
print_r($return);
var url = "http://api.xxxx.com/shopapi/refund/list"
data := map[string]string{
"version": "1.0",
"app_id": "hxgmau9imt86qky9",
"time": "1578736053",
"page": "1",
"sign": "OTA8utI8y8G93p7RPCyb4qIilFQ0B4Aq4iUjhaXWK9m2kgektqlHOASDKXT2VE7NPNysrGycYlVfjDR2WGZn1G66phHo3qa9CcCNpG9klOBEuBEMjiVbb/d8AXcxEzvQr9OCwNsikyxonyzLiY/lsNHeGm9cC5eRvlNLdUSVBipH+ajPd0lDHCayZPs1eCMfbm/xnf8e2lfy6z0UPOpHGfyX/0+hz99Ir5Xnx+0sBBzyZZJxKm4ROid5aDv/9m9guILpURae+Yw/IrkYF4uAKGX+/44cBvtTRQSdX76CAOBSiywZa6BAgDYBLRtkAPM+i+vwNzFBovqHUvI+4Ponaw==",
}
dataType, _ := json.Marshal(data)
resp, err := http.Post(url, "application/json", strings.NewReader(string(dataType)))
if err != nil {
fmt.Println(err)
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Println(err)
}
fmt.Println(string(body))
let HTTP = require('http')
let postData = {
"version": "1.0",
"app_id": "hxgmau9imt86qky9",
"time": "1578736053",
"page": "1",
"sign": "OTA8utI8y8G93p7RPCyb4qIilFQ0B4Aq4iUjhaXWK9m2kgektqlHOASDKXT2VE7NPNysrGycYlVfjDR2WGZn1G66phHo3qa9CcCNpG9klOBEuBEMjiVbb/d8AXcxEzvQr9OCwNsikyxonyzLiY/lsNHeGm9cC5eRvlNLdUSVBipH+ajPd0lDHCayZPs1eCMfbm/xnf8e2lfy6z0UPOpHGfyX/0+hz99Ir5Xnx+0sBBzyZZJxKm4ROid5aDv/9m9guILpURae+Yw/IrkYF4uAKGX+/44cBvtTRQSdX76CAOBSiywZa6BAgDYBLRtkAPM+i+vwNzFBovqHUvI+4Ponaw==",
};
let POST_OPTIONS = {
port: 80,
host: "api.xxxx.com",
path: "/shopapi/refund/list",
method: 'POST',
headers: {
"Content-Type": "application/json; charset=utf-8"
}
};
const REQUEST = HTTP.request(POST_OPTIONS,function (res) {
let data = []
res.on('data', chunk => {
data.push(...chunk)
})
res.on('end', () => {
let _date = JSON.parse( new TextDecoder().decode(new Uint8Array(data)))
console.log(_date)
})
});
REQUEST.setTimeout(6000)
REQUEST.write(JSON.stringify(postData), 'utf8')
REQUEST.end()
public static void main(String[] args) {
// 完整实例请查看"签名规则"中的Java示例代码
String baseUrl = "http://api.xxxx.com/shopapi";
String priKey = "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCtdgvcfozY7fe/x6UlXR/Fff8+wX++CiG05YVRafDe90O8y5KJAMZ156TgajEUXSRyKZqASz7iVoMAcu5FqfK1KuOOdjTAg0LFe/twIZvKmAqHcCSS2pjUXk0fTpZEgQ5lmDCK12Mg07YXvr+BeHjF+kBpwRJMPMG/+DGBDYNFNeRSJqWyopt6yyF528soAykHIUQ7TTultJV5IPCrvjRQQrGdJ/QtCdE0vZg+tA09nFN7AqgraU99kIvzyS0sqysj+pP1SJRmTRSGtlVAO3mILfkXOekZl1KD60G7CF+7BIaaW83FPD55tZhAGhnbLMYyiq7OiIyU61LTRcNSaJ0tAgMBAAECggEBAIGgGKcSzxCBbMYdXLV6TPbZ/HeaRGrwyVWUu7cmc0E8CJu6iWvmb2jGzbiCwuCT5luF6ZZ8JKchvU4FlTfsE5r9TQY2IZ/Ht4s65qBaDUEts5iY3kv8HX9+ZSXDJZpV0ztqqsPmx4ZNj+NYwWXwcFiKdb5R8OmV8bgSsnPddD6wFhwewglUOBPRAjropHE4sqk1Vam6q1MlFq5kiekMn/CItyFYFFzST/ruqAtVTp7YIvazAMrfCKH+pvXWk6pYNHZmL/JZey0GglRyJ1nItiqL33X8Lji056FcbAclidq022h/KPLEJpZk6irWqYdqYZeF6YMLHtdZFDkTZ/hXY+UCgYEA5i794UTQ1Kd6K+iui/S8K5H8nGdiXb3+uZ5j5VKYfbRmzXhAdVYisYe8czeTECxhH+MeHgM4tLR4ifx9q60ylvZxl9Fav1p6EaE36YcvGVmpm7Gm3q6QDDBa4gB+X9u7CxCS4LpotV917YS1QvOIF9lnRonSj1zNzFtbXkywrN8CgYEAwOpx/mR40ZvgZxNCq9DsIdrSZYAFFKpw0xy0OtF1PpuwMaREoRabnlVw6Bb3Hofg50XA3JxemzAX6fB92ee+NfXfeL4UtC4vG1K9JyiXHtHq8p9Uw2W03ehIEeNa3xdoRRnLmD4VUpyfL19ViE2+7TM1Gd3TogjDT+AMOCSuq3MCgYBsurPH7gaq/LVT+mRAzgj4l8v4YUlwuGeTbIMJdvt7HXUWB4CDLH3U2CYnUpAQKrZyJok6ahEmIr1xiKggKP7lmmHL8eNo0icpHrtXfzi7Q8Q/PCpzs4dtioXTjaIkS5nNvzVyG/uL+RyuZmpsxrZ5dYM4KbAhchfwORMutxEZhwKBgQC5zpVw4jCEItBmNuTWO+nTScGvxTgfiXIVw+XLaQa2AJoZlhAL34yPWdffko79tv3lgweY9HsimZXO2rU8dbp8mo5c6ydhy8HPXUeWOcAkDSdv/ApWENW9jgYsRIC3swHY3Fl+Dv3Wjce8huQI3mjwaYvRmBhIToxfmHnscVhTBQKBgB9uciEHfz8hMI7ePrPo2PkyK/RbJDm3HnuWE2lFBp7MOUMlh53MXwv4dIRaYMbRrFuN1UIKEFxuKhWwTHSzZJufk/UENrha/81fpj2BoFsAKkEunKeETvaIh6fZSjec16h2+zxbzwkdS6b+yIYkSlaoAxmDYrMtae0C8G4e0YS9";
String pubKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2RZZISModRzproL3eTxRtvVK/nToDbeLmAVdmaVtHgNCwjXMeNCZvHySZKO7+t7XySzBd2PhhQjvAkDd8HRKB5Y0uvP6TFwvhxOMkMydTeBFcUobQWNeAI7ttRms1txSNrmyrZr0WpWfk79VIsO+yI/jFN/Pj2gxD+vh5UUKU1LD2IQq/VxgtEpf8Vs6w7SvafPwYkpdPGCKUFkRvN1FrY2+tq0j1MRVJbB2rIunWDnT8cDUh2sWLXf4yNaJVOaaTFB0zbAk/qcoicGQyW7bVG7dVW8WywKmOAPeQCCQa+SJ4BhfI1k8eEAwFVRuxz/f9Ecfog9hZJ+RgELkpS8qhQIDAQAB";
rsaSigner signer = new rsaSigner();
Map<String, Object> params = new HashMap<>();
params.put("app_id", "hxgmau9imt86qky9");
params.put("version", "1.0");
params.put("key_version", "admin");
params.put("time", Long.toString(System.currentTimeMillis() / 1000));
params.put("page", "1");
try {
params.put("sign", signer.genSign(params, priKey));
Gson gson = new GsonBuilder().create();
System.out.println("params = " + gson.toJson(params));
String res = doPost(baseUrl + "/refund/list", gson.toJson(params));
if (null == res) {
throw new RuntimeException("http error");
}
System.out.println("response = " + res);
JsonParser jp = new JsonParser();
JsonObject resEle = jp.parse(res).getAsJsonObject();
boolean retSignOK = signer.verifySign(resEle, resEle.get("sign").getAsString(), pubKey);
if (!retSignOK) {
throw new RuntimeException("verify response sign fail");
}
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("OK");
}
返回结果示例:
{
"status": 200,
"msg": "处理成功",
"data": {
"page": 1,
"max_page": 1,
"count": 1,
"list": [{
"block_number": 69471385,
"block_time": 1742882698,
"coin": "pol",
"contract": "pol",
"contract_address": "",
"created_at": 1742882633,
"creator": "CS007",
"end_time": 1742882749,
"from_address": "0xDCE6e20FfC7b651Cd5d7ad922b8B77691E999dB2",
"gas_fee": "0.00062635",
"method": 0,
"order_id": "20250101123456",
"receive_amount": "0.03",
"receive_order_id": "",
"receive_txid": "0xb6042b5eac8a9b7fbc538ad9564b2ada7d59cbc39a462d2da784494562556590",
"refund_amount": "0.029",
"remark": "",
"status": 1,
"to_address": "0xb4bd96957e7b078566cd1e40de2c131d1f4374e4",
"txid": "0xc3b148c2ede826bbadf68682486fce8fabe5a5c53e3973c45b9e5578787ff359",
"type": 1
}]
},
"date_time": "2022-07-22 18:36:36",
"time_stamp": 1658486196,
"sign": "uuYWvmoMqM5xh7aTcxspJmW78y8op5BBjYXp0XoqcqFXe+HrSGzxN2Ls6LA7SlfsNndCtS4AX1/J+2o1MWZw/HFVfRqtxu02AEfWhM5ZSiJfEtO8f47H2/EGcsKw/eK8nxOnYAyAKwG6Ia6L4KgYIXLwsGt6Dt0VYWADu+vEQEes83/c6+Tc8QdqpdnLbs2XXXkYkl5eijoja+QEMaENbx+DHxnsVZV0iRK5FcSQH9PdOIpWmC944BA2v0tnPQWb6WDnOTsw5xoVKiL57WGIeOaxepvjo6poi1a/+HYrowT4IcejZZHi9YW0iM4eNm8MPK0tloAQ8GWY7kVs9uEwOA=="
}
HTTP Request
POST: /refund/list
请求参数
| 参数名 | 必选 | 类型 | 说明 |
|---|---|---|---|
| 公共参数 | 是 | string | 公参指:签名(sign)、版本(version)、商户ID(app_id)、时间(time) |
| page | 否 | int | 1<= N <=Max,对于超过Max的取Max,小于1或没有传参数的返回1 |
| page_size | 否 | int | 每页数量 (20 ~100),默认 20 |
| sort_num | 否 | int | 列表排序规则 默认按入系统时间正序排列( 1 正序 ; 2 倒序) |
| status | 否 | string | 状态,默认不传返回所有状态。0 等待退款; 1 退款成功; 2 退款失败; 5 待商户审核; 6 审核不通过; 10 待平台审核; 11 平台审核不通过; 25 退款中; 26 退款Gas费不足等待中; |
| start_time | 否 | int | 开始时间(创建时间) 格式 :时间戳 |
| end_time | 否 | int | 结束时间(创建时间) 格式 :时间戳 |
| contract | 否 | string | 网络主币名 |
| coin | 否 | string | 币名 |
| receive_order_id | 否 | string | 关联的充值订单号 |
| receive_txid | 否 | string | 关联充值记录的链上交易hash |
| txid | 否 | string | 该退款交易的链上交易hash |
| from_address | 否 | string | 退款来源地址,即充值交易的收款用户地址 |
| to_address | 否 | string | 退款目标地址(冷地址或充值的来源地址) |
返回参数说明
| 参数名 | 类型 | 说明 |
|---|---|---|
| status | int | 状态码 |
| msg | string | 状态描述 |
| data | jsonObject | trade_id-由商户提供 |
| data.page | int | 第几页 |
| data.count | int | 本页记录数 |
| data.list | jsonArray | 具体每条记录 |
| data.list.block_number | int | 退款交易区块高度 |
| data.list.block_time | int | 退款交易上链时间 |
| data.list.coin | string | 币种 |
| data.list.contract | string | 主链 |
| data.list.contract_address | string | 币种合约地址 |
| data.list.created_at | int | 退款创建时间 |
| data.list.creator | string | 退款发起商家管理员 |
| data.list.end_time | int | 退款结束时间 |
| data.list.from_address | string | 退款来源地址,即充值交易的收款用户地址 |
| data.list.gas_fee | string | 退款交易链上手续费 |
| data.list.method | int | 退款方式,0原路返回,1冷钱包 |
| data.list.order_id | string | 退款订单号 |
| data.list.receive_amount | string | 被退款的充值交易金额 |
| data.list.receive_order_id | string | 关联的充值订单号 |
| data.list.receive_txid | string | 关联充值记录的链上交易hash |
| data.list.refund_amount | string | 实际退款金额 |
| data.list.remark | string | 备注 |
| data.list.status | int | 状态,0 等待退款; 1 退款成功; 2 退款失败; 5 待商户审核; 6 审核不通过; 10 待平台审核; 11 平台审核不通过; 25 退款中; 26 退款Gas费不足等待中; |
| data.list.to_address | string | 退款目标地址(冷地址或充值的来源地址) |
| data.list.txid | string | 退款交易的链上交易hash |
| data.list.type | int | 类型,0关联充值单 1无充值单且平台支持币种 2无充值单且平台不支持币种 3无充值单且平台不支持的主链 |
| date_time | string | 响应时间 |
| time_stamp | int | 无时区的秒 |
| sign | string | 签名 |
检测其账本记录的币种数量是否和其链上钱包的数据一致
$url = "http://api.xxxx.com/shopapi/reconcile/balances";
$header = [
'Content-Type:application/json',
];
$params = [
"version" => "1.0",
"app_id" => "hxgmau9imt86qky9",
"time" => "1578736053",
"list" => [
[
"chain" => "eth",
"coin" => "usdt_erc20",
"ledger_balance" => "100"
],
[
"chain" => "btc",
"coin" => "btc",
"ledger_balance" => "10"
]
],
"sign" => "dLtK+uiPcnxt2ACKMbBqQ6wI5ttAvesOHzK5ybVID1R6hqYPDTkagl7Tsjr5iLJafehcSLTZyJLtCRI8O2CtIWQUUroGXBneHZC486NUi/4FMOQs0FaAgm17pWlbhX5/96cWXXXMVeoe3IZFKaFNYSWaA14v3RcdDU6QDE/9ixGiSJ0DIxm9NKA0+RkbIFbyYeuFn8d63OcjmUhv7tsOE6rKCc3Q2yi7Qe9i6BNAQFYMFATztb18MsxsBHKUxNqklqyVnl0ofETAHmQhfOHLmungOJQnOqAAuwfmRtg50Qci5F+R2mXeqjmIXko/u3E+DLYW1ygDBp3afKZmU4PwmA=="
];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
$return = curl_exec($ch);
print_r($return);
var url = "http://api.xxxx.com/shopapi/reconcile/balances"
data := map[string]string{
"version": "1.0",
"app_id": "hxgmau9imt86qky9",
"time": "1578736053",
"list": [
{
"chain": "eth",
"coin": "usdt_erc20",
"ledger_balance": "100"
},
{
"chain": "btc",
"coin": "btc",
"ledger_balance": "10"
}
],
"sign": "OTA8utI8y8G93p7RPCyb4qIilFQ0B4Aq4iUjhaXWK9m2kgektqlHOASDKXT2VE7NPNysrGycYlVfjDR2WGZn1G66phHo3qa9CcCNpG9klOBEuBEMjiVbb/d8AXcxEzvQr9OCwNsikyxonyzLiY/lsNHeGm9cC5eRvlNLdUSVBipH+ajPd0lDHCayZPs1eCMfbm/xnf8e2lfy6z0UPOpHGfyX/0+hz99Ir5Xnx+0sBBzyZZJxKm4ROid5aDv/9m9guILpURae+Yw/IrkYF4uAKGX+/44cBvtTRQSdX76CAOBSiywZa6BAgDYBLRtkAPM+i+vwNzFBovqHUvI+4Ponaw==",
}
dataType, _ := json.Marshal(data)
resp, err := http.Post(url, "application/json", strings.NewReader(string(dataType)))
if err != nil {
fmt.Println(err)
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Println(err)
}
fmt.Println(string(body))
let HTTP = require('http')
let postData = {
"version": "1.0",
"app_id": "hxgmau9imt86qky9",
"time": "1578736053",
"list": [
{
"chain": "eth",
"coin": "usdt_erc20",
"ledger_balance": "100"
},
{
"chain": "btc",
"coin": "btc",
"ledger_balance": "10"
}
],
"sign": "OTA8utI8y8G93p7RPCyb4qIilFQ0B4Aq4iUjhaXWK9m2kgektqlHOASDKXT2VE7NPNysrGycYlVfjDR2WGZn1G66phHo3qa9CcCNpG9klOBEuBEMjiVbb/d8AXcxEzvQr9OCwNsikyxonyzLiY/lsNHeGm9cC5eRvlNLdUSVBipH+ajPd0lDHCayZPs1eCMfbm/xnf8e2lfy6z0UPOpHGfyX/0+hz99Ir5Xnx+0sBBzyZZJxKm4ROid5aDv/9m9guILpURae+Yw/IrkYF4uAKGX+/44cBvtTRQSdX76CAOBSiywZa6BAgDYBLRtkAPM+i+vwNzFBovqHUvI+4Ponaw==",
};
let POST_OPTIONS = {
port: 80,
host: "api.xxxx.com",
path: "/shopapi/reconcile/balances",
method: 'POST',
headers: {
"Content-Type": "application/json; charset=utf-8"
}
};
const REQUEST = HTTP.request(POST_OPTIONS,function (res) {
let data = []
res.on('data', chunk => {
data.push(...chunk)
})
res.on('end', () => {
let _date = JSON.parse( new TextDecoder().decode(new Uint8Array(data)))
console.log(_date)
})
});
REQUEST.setTimeout(6000)
REQUEST.write(JSON.stringify(postData), 'utf8')
REQUEST.end()
public static void main(String[] args) {
// 完整实例请查看"签名规则"中的Java示例代码
String baseUrl = "http://api.xxxx.com/shopapi";
String priKey = "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCtdgvcfozY7fe/x6UlXR/Fff8+wX++CiG05YVRafDe90O8y5KJAMZ156TgajEUXSRyKZqASz7iVoMAcu5FqfK1KuOOdjTAg0LFe/twIZvKmAqHcCSS2pjUXk0fTpZEgQ5lmDCK12Mg07YXvr+BeHjF+kBpwRJMPMG/+DGBDYNFNeRSJqWyopt6yyF528soAykHIUQ7TTultJV5IPCrvjRQQrGdJ/QtCdE0vZg+tA09nFN7AqgraU99kIvzyS0sqysj+pP1SJRmTRSGtlVAO3mILfkXOekZl1KD60G7CF+7BIaaW83FPD55tZhAGhnbLMYyiq7OiIyU61LTRcNSaJ0tAgMBAAECggEBAIGgGKcSzxCBbMYdXLV6TPbZ/HeaRGrwyVWUu7cmc0E8CJu6iWvmb2jGzbiCwuCT5luF6ZZ8JKchvU4FlTfsE5r9TQY2IZ/Ht4s65qBaDUEts5iY3kv8HX9+ZSXDJZpV0ztqqsPmx4ZNj+NYwWXwcFiKdb5R8OmV8bgSsnPddD6wFhwewglUOBPRAjropHE4sqk1Vam6q1MlFq5kiekMn/CItyFYFFzST/ruqAtVTp7YIvazAMrfCKH+pvXWk6pYNHZmL/JZey0GglRyJ1nItiqL33X8Lji056FcbAclidq022h/KPLEJpZk6irWqYdqYZeF6YMLHtdZFDkTZ/hXY+UCgYEA5i794UTQ1Kd6K+iui/S8K5H8nGdiXb3+uZ5j5VKYfbRmzXhAdVYisYe8czeTECxhH+MeHgM4tLR4ifx9q60ylvZxl9Fav1p6EaE36YcvGVmpm7Gm3q6QDDBa4gB+X9u7CxCS4LpotV917YS1QvOIF9lnRonSj1zNzFtbXkywrN8CgYEAwOpx/mR40ZvgZxNCq9DsIdrSZYAFFKpw0xy0OtF1PpuwMaREoRabnlVw6Bb3Hofg50XA3JxemzAX6fB92ee+NfXfeL4UtC4vG1K9JyiXHtHq8p9Uw2W03ehIEeNa3xdoRRnLmD4VUpyfL19ViE2+7TM1Gd3TogjDT+AMOCSuq3MCgYBsurPH7gaq/LVT+mRAzgj4l8v4YUlwuGeTbIMJdvt7HXUWB4CDLH3U2CYnUpAQKrZyJok6ahEmIr1xiKggKP7lmmHL8eNo0icpHrtXfzi7Q8Q/PCpzs4dtioXTjaIkS5nNvzVyG/uL+RyuZmpsxrZ5dYM4KbAhchfwORMutxEZhwKBgQC5zpVw4jCEItBmNuTWO+nTScGvxTgfiXIVw+XLaQa2AJoZlhAL34yPWdffko79tv3lgweY9HsimZXO2rU8dbp8mo5c6ydhy8HPXUeWOcAkDSdv/ApWENW9jgYsRIC3swHY3Fl+Dv3Wjce8huQI3mjwaYvRmBhIToxfmHnscVhTBQKBgB9uciEHfz8hMI7ePrPo2PkyK/RbJDm3HnuWE2lFBp7MOUMlh53MXwv4dIRaYMbRrFuN1UIKEFxuKhWwTHSzZJufk/UENrha/81fpj2BoFsAKkEunKeETvaIh6fZSjec16h2+zxbzwkdS6b+yIYkSlaoAxmDYrMtae0C8G4e0YS9";
String pubKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2RZZISModRzproL3eTxRtvVK/nToDbeLmAVdmaVtHgNCwjXMeNCZvHySZKO7+t7XySzBd2PhhQjvAkDd8HRKB5Y0uvP6TFwvhxOMkMydTeBFcUobQWNeAI7ttRms1txSNrmyrZr0WpWfk79VIsO+yI/jFN/Pj2gxD+vh5UUKU1LD2IQq/VxgtEpf8Vs6w7SvafPwYkpdPGCKUFkRvN1FrY2+tq0j1MRVJbB2rIunWDnT8cDUh2sWLXf4yNaJVOaaTFB0zbAk/qcoicGQyW7bVG7dVW8WywKmOAPeQCCQa+SJ4BhfI1k8eEAwFVRuxz/f9Ecfog9hZJ+RgELkpS8qhQIDAQAB";
rsaSigner signer = new rsaSigner();
Map<String, Object> params = new HashMap<>();
params.put("app_id", "hxgmau9imt86qky9");
params.put("version", "1.0");
params.put("key_version", "admin");
params.put("time", Long.toString(System.currentTimeMillis() / 1000));
List<Map<String, String>> list = new ArrayList<>();
Map<String, String> item1 = new HashMap<>();
item1.put("chain", "eth");
item1.put("coin", "usdt_erc20");
item1.put("ledger_balance", "100");
list.add(item1);
params.put("list", list);
try {
params.put("sign", signer.genSign(params, priKey));
Gson gson = new GsonBuilder().create();
System.out.println("params = " + gson.toJson(params));
String res = doPost(baseUrl + "/reconcile/balances", gson.toJson(params));
if (null == res) {
throw new RuntimeException("http error");
}
System.out.println("response = " + res);
JsonParser jp = new JsonParser();
JsonObject resEle = jp.parse(res).getAsJsonObject();
boolean retSignOK = signer.verifySign(resEle, resEle.get("sign").getAsString(), pubKey);
if (!retSignOK) {
throw new RuntimeException("verify response sign fail");
}
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("OK");
}
返回结果示例:
{
"status": 200,
"msg": "处理成功",
"data": {
"list": [
{
"chain": "eth",
"coin": "usdt_erc20",
"ledger_balance": "100",
"onchain_balance": "100",
"matched": true,
"note": "",
"difference": "0"
},
{
"chain": "btc",
"coin": "btc",
"ledger_balance": "10",
"onchain_balance": "9",
"matched": false,
"note": "",
"difference": "-1"
}
]
},
"date_time": "2022-07-22 18:36:36",
"time_stamp": 1658486196,
"sign": "uuYWvmoMqM5xh7aTcxspJmW78y8op5BBjYXp0XoqcqFXe+HrSGzxN2Ls6LA7SlfsNndCtS4AX1/J+2o1MWZw/HFVfRqtxu02AEfWhM5ZSiJfEtO8f47H2/EGcsKw/eK8nxOnYAyAKwG6Ia6L4KgYIXLwsGt6Dt0VYWADu+vEQEes83/c6+Tc8QdqpdnLbs2XXXkYkl5eijoja+QEMaENbx+DHxnsVZV0iRK5FcSQH9PdOIpWmC944BA2v0tnPQWb6WDnOTsw5xoVKiL57WGIeOaxepvjo6poi1a/+HYrowT4IcejZZHi9YW0iM4eNm8MPK0tloAQ8GWY7kVs9uEwOA=="
}
HTTP Request
POST: /reconcile/balances
请求参数
| 参数名 | 必选 | 类型 | 说明 |
|---|---|---|---|
| 公共参数 | 是 | string | 公参指:签名(sign)、版本(version)、商户ID(app_id)、时间(time) |
| list.chain | 否 | string | 主链 |
| list.coin | 是 | string | 币种 |
| list.ledger_balance | 否 | string | 账本余额 |
返回参数说明
| 参数名 | 类型 | 说明 |
|---|---|---|
| status | int | 状态码 |
| msg | string | 状态描述 |
| data | jsonObject | data |
| data.list | jsonArray | 具体每条记录 |
| data.list.chain | string | 主链 |
| data.list.coin | string | 币种 |
| data.list.ledger_balance | string | 账本余额 |
| data.list.onchain_balance | string | 账本余额 |
| data.list.difference | string | 余额差值 |
| data.list.matched | bool | 余额是否匹配 |
| data.list.note | string | 说明描述 |
| date_time | string | 响应时间 |
| time_stamp | int | 无时区的秒 |
| sign | string | 签名 |
检测其某个账户地址的币种数量是否其链上数量一致
$url = "http://api.xxxx.com/shopapi/reconcile/addressBalance";
$header = [
'Content-Type:application/json',
];
$params = [
"version" => "1.0",
"app_id" => "hxgmau9imt86qky9",
"time" => "1578736053",
"list" => [
[
"chain" => "eth",
"coin" => "usdt_erc20",
"address" => "0x111...2222",
"ledger_balance" => "100"
],
[
"chain" => "btc",
"coin" => "btc",
"address" => "1bcd...zxc",
"ledger_balance" => "10"
]
],
"sign" => "dLtK+uiPcnxt2ACKMbBqQ6wI5ttAvesOHzK5ybVID1R6hqYPDTkagl7Tsjr5iLJafehcSLTZyJLtCRI8O2CtIWQUUroGXBneHZC486NUi/4FMOQs0FaAgm17pWlbhX5/96cWXXXMVeoe3IZFKaFNYSWaA14v3RcdDU6QDE/9ixGiSJ0DIxm9NKA0+RkbIFbyYeuFn8d63OcjmUhv7tsOE6rKCc3Q2yi7Qe9i6BNAQFYMFATztb18MsxsBHKUxNqklqyVnl0ofETAHmQhfOHLmungOJQnOqAAuwfmRtg50Qci5F+R2mXeqjmIXko/u3E+DLYW1ygDBp3afKZmU4PwmA=="
];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
$return = curl_exec($ch);
print_r($return);
var url = "http://api.xxxx.com/shopapi/reconcile/addressBalance"
data := map[string]string{
"version": "1.0",
"app_id": "hxgmau9imt86qky9",
"time": "1578736053",
"list": [
{
"chain": "eth",
"coin": "usdt_erc20",
"address": "0x111...2222",
"ledger_amount": "100"
},
{
"chain": "btc",
"coin": "btc",
"address": "1bcd...zxc",
"ledger_amount": "10",
"difference": "0"
}
],
"sign": "OTA8utI8y8G93p7RPCyb4qIilFQ0B4Aq4iUjhaXWK9m2kgektqlHOASDKXT2VE7NPNysrGycYlVfjDR2WGZn1G66phHo3qa9CcCNpG9klOBEuBEMjiVbb/d8AXcxEzvQr9OCwNsikyxonyzLiY/lsNHeGm9cC5eRvlNLdUSVBipH+ajPd0lDHCayZPs1eCMfbm/xnf8e2lfy6z0UPOpHGfyX/0+hz99Ir5Xnx+0sBBzyZZJxKm4ROid5aDv/9m9guILpURae+Yw/IrkYF4uAKGX+/44cBvtTRQSdX76CAOBSiywZa6BAgDYBLRtkAPM+i+vwNzFBovqHUvI+4Ponaw==",
}
dataType, _ := json.Marshal(data)
resp, err := http.Post(url, "application/json", strings.NewReader(string(dataType)))
if err != nil {
fmt.Println(err)
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Println(err)
}
fmt.Println(string(body))
let HTTP = require('http')
let postData = {
"version": "1.0",
"app_id": "hxgmau9imt86qky9",
"time": "1578736053",
"list": [
{
"chain": "eth",
"coin": "usdt_erc20",
"address": "0x111...2222",
"ledger_amount": "100"
},
{
"chain": "btc",
"coin": "btc",
"address": "1bcd...zxc",
"ledger_amount": "10",
"difference": "0"
}
],
"sign": "OTA8utI8y8G93p7RPCyb4qIilFQ0B4Aq4iUjhaXWK9m2kgektqlHOASDKXT2VE7NPNysrGycYlVfjDR2WGZn1G66phHo3qa9CcCNpG9klOBEuBEMjiVbb/d8AXcxEzvQr9OCwNsikyxonyzLiY/lsNHeGm9cC5eRvlNLdUSVBipH+ajPd0lDHCayZPs1eCMfbm/xnf8e2lfy6z0UPOpHGfyX/0+hz99Ir5Xnx+0sBBzyZZJxKm4ROid5aDv/9m9guILpURae+Yw/IrkYF4uAKGX+/44cBvtTRQSdX76CAOBSiywZa6BAgDYBLRtkAPM+i+vwNzFBovqHUvI+4Ponaw==",
};
let POST_OPTIONS = {
port: 80,
host: "api.xxxx.com",
path: "/shopapi/reconcile/addressBalance",
method: 'POST',
headers: {
"Content-Type": "application/json; charset=utf-8"
}
};
const REQUEST = HTTP.request(POST_OPTIONS,function (res) {
let data = []
res.on('data', chunk => {
data.push(...chunk)
})
res.on('end', () => {
let _date = JSON.parse( new TextDecoder().decode(new Uint8Array(data)))
console.log(_date)
})
});
REQUEST.setTimeout(6000)
REQUEST.write(JSON.stringify(postData), 'utf8')
REQUEST.end()
public static void main(String[] args) {
// 完整实例请查看"签名规则"中的Java示例代码
String baseUrl = "http://api.xxxx.com/shopapi";
String priKey = "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCtdgvcfozY7fe/x6UlXR/Fff8+wX++CiG05YVRafDe90O8y5KJAMZ156TgajEUXSRyKZqASz7iVoMAcu5FqfK1KuOOdjTAg0LFe/twIZvKmAqHcCSS2pjUXk0fTpZEgQ5lmDCK12Mg07YXvr+BeHjF+kBpwRJMPMG/+DGBDYNFNeRSJqWyopt6yyF528soAykHIUQ7TTultJV5IPCrvjRQQrGdJ/QtCdE0vZg+tA09nFN7AqgraU99kIvzyS0sqysj+pP1SJRmTRSGtlVAO3mILfkXOekZl1KD60G7CF+7BIaaW83FPD55tZhAGhnbLMYyiq7OiIyU61LTRcNSaJ0tAgMBAAECggEBAIGgGKcSzxCBbMYdXLV6TPbZ/HeaRGrwyVWUu7cmc0E8CJu6iWvmb2jGzbiCwuCT5luF6ZZ8JKchvU4FlTfsE5r9TQY2IZ/Ht4s65qBaDUEts5iY3kv8HX9+ZSXDJZpV0ztqqsPmx4ZNj+NYwWXwcFiKdb5R8OmV8bgSsnPddD6wFhwewglUOBPRAjropHE4sqk1Vam6q1MlFq5kiekMn/CItyFYFFzST/ruqAtVTp7YIvazAMrfCKH+pvXWk6pYNHZmL/JZey0GglRyJ1nItiqL33X8Lji056FcbAclidq022h/KPLEJpZk6irWqYdqYZeF6YMLHtdZFDkTZ/hXY+UCgYEA5i794UTQ1Kd6K+iui/S8K5H8nGdiXb3+uZ5j5VKYfbRmzXhAdVYisYe8czeTECxhH+MeHgM4tLR4ifx9q60ylvZxl9Fav1p6EaE36YcvGVmpm7Gm3q6QDDBa4gB+X9u7CxCS4LpotV917YS1QvOIF9lnRonSj1zNzFtbXkywrN8CgYEAwOpx/mR40ZvgZxNCq9DsIdrSZYAFFKpw0xy0OtF1PpuwMaREoRabnlVw6Bb3Hofg50XA3JxemzAX6fB92ee+NfXfeL4UtC4vG1K9JyiXHtHq8p9Uw2W03ehIEeNa3xdoRRnLmD4VUpyfL19ViE2+7TM1Gd3TogjDT+AMOCSuq3MCgYBsurPH7gaq/LVT+mRAzgj4l8v4YUlwuGeTbIMJdvt7HXUWB4CDLH3U2CYnUpAQKrZyJok6ahEmIr1xiKggKP7lmmHL8eNo0icpHrtXfzi7Q8Q/PCpzs4dtioXTjaIkS5nNvzVyG/uL+RyuZmpsxrZ5dYM4KbAhchfwORMutxEZhwKBgQC5zpVw4jCEItBmNuTWO+nTScGvxTgfiXIVw+XLaQa2AJoZlhAL34yPWdffko79tv3lgweY9HsimZXO2rU8dbp8mo5c6ydhy8HPXUeWOcAkDSdv/ApWENW9jgYsRIC3swHY3Fl+Dv3Wjce8huQI3mjwaYvRmBhIToxfmHnscVhTBQKBgB9uciEHfz8hMI7ePrPo2PkyK/RbJDm3HnuWE2lFBp7MOUMlh53MXwv4dIRaYMbRrFuN1UIKEFxuKhWwTHSzZJufk/UENrha/81fpj2BoFsAKkEunKeETvaIh6fZSjec16h2+zxbzwkdS6b+yIYkSlaoAxmDYrMtae0C8G4e0YS9";
String pubKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2RZZISModRzproL3eTxRtvVK/nToDbeLmAVdmaVtHgNCwjXMeNCZvHySZKO7+t7XySzBd2PhhQjvAkDd8HRKB5Y0uvP6TFwvhxOMkMydTeBFcUobQWNeAI7ttRms1txSNrmyrZr0WpWfk79VIsO+yI/jFN/Pj2gxD+vh5UUKU1LD2IQq/VxgtEpf8Vs6w7SvafPwYkpdPGCKUFkRvN1FrY2+tq0j1MRVJbB2rIunWDnT8cDUh2sWLXf4yNaJVOaaTFB0zbAk/qcoicGQyW7bVG7dVW8WywKmOAPeQCCQa+SJ4BhfI1k8eEAwFVRuxz/f9Ecfog9hZJ+RgELkpS8qhQIDAQAB";
rsaSigner signer = new rsaSigner();
Map<String, Object> params = new HashMap<>();
params.put("app_id", "hxgmau9imt86qky9");
params.put("version", "1.0");
params.put("key_version", "admin");
params.put("time", Long.toString(System.currentTimeMillis() / 1000));
List<Map<String, String>> list = new ArrayList<>();
Map<String, String> item1 = new HashMap<>();
item1.put("chain", "eth");
item1.put("coin", "usdt_erc20");
item1.put("address", "0x111...2222");
item1.put("ledger_balance", "100");
list.add(item1);
params.put("list", list);
try {
params.put("sign", signer.genSign(params, priKey));
Gson gson = new GsonBuilder().create();
System.out.println("params = " + gson.toJson(params));
String res = doPost(baseUrl + "/reconcile/addressBalance", gson.toJson(params));
if (null == res) {
throw new RuntimeException("http error");
}
System.out.println("response = " + res);
JsonParser jp = new JsonParser();
JsonObject resEle = jp.parse(res).getAsJsonObject();
boolean retSignOK = signer.verifySign(resEle, resEle.get("sign").getAsString(), pubKey);
if (!retSignOK) {
throw new RuntimeException("verify response sign fail");
}
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("OK");
}
返回结果示例:
{
"status": 200,
"msg": "处理成功",
"data": {
"list": [
{
"chain": "eth",
"coin": "usdt_erc20",
"address": "0x111...2222",
"matched": true,
"ledger_amount": "100",
"onchain_balance": "100",
"note": "",
"difference": "0"
},
{
"chain": "btc",
"coin": "btc",
"address": "1bcd...zxc",
"matched": false,
"ledger_amount": "10",
"onchain_balance": "9",
"note": "",
"difference": "-1"
}
]
},
"date_time": "2022-07-22 18:36:36",
"time_stamp": 1658486196,
"sign": "uuYWvmoMqM5xh7aTcxspJmW78y8op5BBjYXp0XoqcqFXe+HrSGzxN2Ls6LA7SlfsNndCtS4AX1/J+2o1MWZw/HFVfRqtxu02AEfWhM5ZSiJfEtO8f47H2/EGcsKw/eK8nxOnYAyAKwG6Ia6L4KgYIXLwsGt6Dt0VYWADu+vEQEes83/c6+Tc8QdqpdnLbs2XXXkYkl5eijoja+QEMaENbx+DHxnsVZV0iRK5FcSQH9PdOIpWmC944BA2v0tnPQWb6WDnOTsw5xoVKiL57WGIeOaxepvjo6poi1a/+HYrowT4IcejZZHi9YW0iM4eNm8MPK0tloAQ8GWY7kVs9uEwOA=="
}
HTTP Request
POST: /reconcile/addressBalance
请求参数
| 参数名 | 必选 | 类型 | 说明 |
|---|---|---|---|
| 公共参数 | 是 | string | 公参指:签名(sign)、版本(version)、商户ID(app_id)、时间(time) |
| list.chain | 否 | string | 主链 |
| list.coin | 是 | string | 币种 |
| list.address | 是 | string | 链上账户地址 |
| list.ledger_balance | 否 | string | 账本余额 |
返回参数说明
| 参数名 | 类型 | 说明 |
|---|---|---|
| status | int | 状态码 |
| msg | string | 状态描述 |
| data | jsonObject | data |
| data.list | jsonArray | 具体每条记录 |
| data.list.chain | string | 主链 |
| data.list.coin | string | 币种 |
| data.list.address | string | 链上账户地址 |
| data.list.ledger_balance | string | 账本余额 |
| data.list.onchain_balance | string | 账本余额 |
| data.list.difference | string | 余额差值 |
| data.list.matched | bool | 余额是否匹配 |
| data.list.note | bool | 说明描述 |
| date_time | string | 响应时间 |
| time_stamp | int | 无时区的秒 |
| sign | string | 签名 |
检测内部账本记录的提币数据是否和其钱包链上的数据一致
$url = "http://api.xxxx.com/shopapi/reconcile/withdrawal";
$header = [
'Content-Type:application/json',
];
$params = [
"version" => "1.0",
"app_id" => "hxgmau9imt86qky9",
"time" => "1578736053",
"list" => [
[
"trade_id" => "W20250001",
"chain" => "eth",
"coin" => "usdt_erc20",
"from_address" => "0x111...222",
"to_address" => "0x111...333",
"txid" => "0x123...321",
"ledger_amount" => "100"
],
[
"trade_id" => "W20250002",
"chain" => "btc",
"coin" => "btc",
"from_address" => "bc1q...3cyx",
"to_address" => "bc1q...0cur",
"txid" => "dd8a...7ff8",
"ledger_amount" => "100"
]
],
"sign" => "dLtK+uiPcnxt2ACKMbBqQ6wI5ttAvesOHzK5ybVID1R6hqYPDTkagl7Tsjr5iLJafehcSLTZyJLtCRI8O2CtIWQUUroGXBneHZC486NUi/4FMOQs0FaAgm17pWlbhX5/96cWXXXMVeoe3IZFKaFNYSWaA14v3RcdDU6QDE/9ixGiSJ0DIxm9NKA0+RkbIFbyYeuFn8d63OcjmUhv7tsOE6rKCc3Q2yi7Qe9i6BNAQFYMFATztb18MsxsBHKUxNqklqyVnl0ofETAHmQhfOHLmungOJQnOqAAuwfmRtg50Qci5F+R2mXeqjmIXko/u3E+DLYW1ygDBp3afKZmU4PwmA=="
];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
$return = curl_exec($ch);
print_r($return);
var url = "http://api.xxxx.com/shopapi/reconcile/withdrawal"
data := map[string]string{
"version": "1.0",
"app_id": "hxgmau9imt86qky9",
"time": "1578736053",
"list": [
{
"trade_id": "W20250001",
"chain": "eth",
"coin": "usdt_erc20",
"from_address": "0x111...222",
"to_address": "0x111...333",
"txid": "0x123...321",
"ledger_amount": "100"
},
{
"trade_id": "W20250002",
"chain": "btc",
"coin": "btc",
"from_address": "bc1q...3cyx",
"to_address": "bc1q...0cur",
"txid": "dd8a...7ff8",
"ledger_amount": "100"
}
],
"sign": "OTA8utI8y8G93p7RPCyb4qIilFQ0B4Aq4iUjhaXWK9m2kgektqlHOASDKXT2VE7NPNysrGycYlVfjDR2WGZn1G66phHo3qa9CcCNpG9klOBEuBEMjiVbb/d8AXcxEzvQr9OCwNsikyxonyzLiY/lsNHeGm9cC5eRvlNLdUSVBipH+ajPd0lDHCayZPs1eCMfbm/xnf8e2lfy6z0UPOpHGfyX/0+hz99Ir5Xnx+0sBBzyZZJxKm4ROid5aDv/9m9guILpURae+Yw/IrkYF4uAKGX+/44cBvtTRQSdX76CAOBSiywZa6BAgDYBLRtkAPM+i+vwNzFBovqHUvI+4Ponaw==",
}
dataType, _ := json.Marshal(data)
resp, err := http.Post(url, "application/json", strings.NewReader(string(dataType)))
if err != nil {
fmt.Println(err)
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Println(err)
}
fmt.Println(string(body))
let HTTP = require('http')
let postData = {
"version": "1.0",
"app_id": "hxgmau9imt86qky9",
"time": "1578736053",
"list": [
{
"trade_id": "W20250001",
"chain": "eth",
"coin": "usdt_erc20",
"from_address": "0x111...222",
"to_address": "0x111...333",
"txid": "0x123...321",
"ledger_amount": "100"
},
{
"trade_id": "W20250002",
"chain": "btc",
"coin": "btc",
"from_address": "bc1q...3cyx",
"to_address": "bc1q...0cur",
"txid": "dd8a...7ff8",
"ledger_amount": "100"
}
],
"sign": "OTA8utI8y8G93p7RPCyb4qIilFQ0B4Aq4iUjhaXWK9m2kgektqlHOASDKXT2VE7NPNysrGycYlVfjDR2WGZn1G66phHo3qa9CcCNpG9klOBEuBEMjiVbb/d8AXcxEzvQr9OCwNsikyxonyzLiY/lsNHeGm9cC5eRvlNLdUSVBipH+ajPd0lDHCayZPs1eCMfbm/xnf8e2lfy6z0UPOpHGfyX/0+hz99Ir5Xnx+0sBBzyZZJxKm4ROid5aDv/9m9guILpURae+Yw/IrkYF4uAKGX+/44cBvtTRQSdX76CAOBSiywZa6BAgDYBLRtkAPM+i+vwNzFBovqHUvI+4Ponaw==",
};
let POST_OPTIONS = {
port: 80,
host: "api.xxxx.com",
path: "/shopapi/reconcile/withdrawal",
method: 'POST',
headers: {
"Content-Type": "application/json; charset=utf-8"
}
};
const REQUEST = HTTP.request(POST_OPTIONS,function (res) {
let data = []
res.on('data', chunk => {
data.push(...chunk)
})
res.on('end', () => {
let _date = JSON.parse( new TextDecoder().decode(new Uint8Array(data)))
console.log(_date)
})
});
REQUEST.setTimeout(6000)
REQUEST.write(JSON.stringify(postData), 'utf8')
REQUEST.end()
public static void main(String[] args) {
// 完整实例请查看"签名规则"中的Java示例代码
String baseUrl = "http://api.xxxx.com/shopapi";
String priKey = "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCtdgvcfozY7fe/x6UlXR/Fff8+wX++CiG05YVRafDe90O8y5KJAMZ156TgajEUXSRyKZqASz7iVoMAcu5FqfK1KuOOdjTAg0LFe/twIZvKmAqHcCSS2pjUXk0fTpZEgQ5lmDCK12Mg07YXvr+BeHjF+kBpwRJMPMG/+DGBDYNFNeRSJqWyopt6yyF528soAykHIUQ7TTultJV5IPCrvjRQQrGdJ/QtCdE0vZg+tA09nFN7AqgraU99kIvzyS0sqysj+pP1SJRmTRSGtlVAO3mILfkXOekZl1KD60G7CF+7BIaaW83FPD55tZhAGhnbLMYyiq7OiIyU61LTRcNSaJ0tAgMBAAECggEBAIGgGKcSzxCBbMYdXLV6TPbZ/HeaRGrwyVWUu7cmc0E8CJu6iWvmb2jGzbiCwuCT5luF6ZZ8JKchvU4FlTfsE5r9TQY2IZ/Ht4s65qBaDUEts5iY3kv8HX9+ZSXDJZpV0ztqqsPmx4ZNj+NYwWXwcFiKdb5R8OmV8bgSsnPddD6wFhwewglUOBPRAjropHE4sqk1Vam6q1MlFq5kiekMn/CItyFYFFzST/ruqAtVTp7YIvazAMrfCKH+pvXWk6pYNHZmL/JZey0GglRyJ1nItiqL33X8Lji056FcbAclidq022h/KPLEJpZk6irWqYdqYZeF6YMLHtdZFDkTZ/hXY+UCgYEA5i794UTQ1Kd6K+iui/S8K5H8nGdiXb3+uZ5j5VKYfbRmzXhAdVYisYe8czeTECxhH+MeHgM4tLR4ifx9q60ylvZxl9Fav1p6EaE36YcvGVmpm7Gm3q6QDDBa4gB+X9u7CxCS4LpotV917YS1QvOIF9lnRonSj1zNzFtbXkywrN8CgYEAwOpx/mR40ZvgZxNCq9DsIdrSZYAFFKpw0xy0OtF1PpuwMaREoRabnlVw6Bb3Hofg50XA3JxemzAX6fB92ee+NfXfeL4UtC4vG1K9JyiXHtHq8p9Uw2W03ehIEeNa3xdoRRnLmD4VUpyfL19ViE2+7TM1Gd3TogjDT+AMOCSuq3MCgYBsurPH7gaq/LVT+mRAzgj4l8v4YUlwuGeTbIMJdvt7HXUWB4CDLH3U2CYnUpAQKrZyJok6ahEmIr1xiKggKP7lmmHL8eNo0icpHrtXfzi7Q8Q/PCpzs4dtioXTjaIkS5nNvzVyG/uL+RyuZmpsxrZ5dYM4KbAhchfwORMutxEZhwKBgQC5zpVw4jCEItBmNuTWO+nTScGvxTgfiXIVw+XLaQa2AJoZlhAL34yPWdffko79tv3lgweY9HsimZXO2rU8dbp8mo5c6ydhy8HPXUeWOcAkDSdv/ApWENW9jgYsRIC3swHY3Fl+Dv3Wjce8huQI3mjwaYvRmBhIToxfmHnscVhTBQKBgB9uciEHfz8hMI7ePrPo2PkyK/RbJDm3HnuWE2lFBp7MOUMlh53MXwv4dIRaYMbRrFuN1UIKEFxuKhWwTHSzZJufk/UENrha/81fpj2BoFsAKkEunKeETvaIh6fZSjec16h2+zxbzwkdS6b+yIYkSlaoAxmDYrMtae0C8G4e0YS9";
String pubKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2RZZISModRzproL3eTxRtvVK/nToDbeLmAVdmaVtHgNCwjXMeNCZvHySZKO7+t7XySzBd2PhhQjvAkDd8HRKB5Y0uvP6TFwvhxOMkMydTeBFcUobQWNeAI7ttRms1txSNrmyrZr0WpWfk79VIsO+yI/jFN/Pj2gxD+vh5UUKU1LD2IQq/VxgtEpf8Vs6w7SvafPwYkpdPGCKUFkRvN1FrY2+tq0j1MRVJbB2rIunWDnT8cDUh2sWLXf4yNaJVOaaTFB0zbAk/qcoicGQyW7bVG7dVW8WywKmOAPeQCCQa+SJ4BhfI1k8eEAwFVRuxz/f9Ecfog9hZJ+RgELkpS8qhQIDAQAB";
rsaSigner signer = new rsaSigner();
Map<String, Object> params = new HashMap<>();
params.put("app_id", "hxgmau9imt86qky9");
params.put("version", "1.0");
params.put("key_version", "admin");
params.put("time", Long.toString(System.currentTimeMillis() / 1000));
List<Map<String, String>> list = new ArrayList<>();
Map<String, String> item1 = new HashMap<>();
item1.put("trade_id", "W20250001");
item1.put("chain", "eth");
item1.put("coin", "usdt_erc20");
item1.put("from_address", "0x111...2222");
item1.put("to_address", "0x111...333");
item1.put("ledger_balance", "100");
list.add(item1);
params.put("list", list);
try {
params.put("sign", signer.genSign(params, priKey));
Gson gson = new GsonBuilder().create();
System.out.println("params = " + gson.toJson(params));
String res = doPost(baseUrl + "/reconcile/withdrawal", gson.toJson(params));
if (null == res) {
throw new RuntimeException("http error");
}
System.out.println("response = " + res);
JsonParser jp = new JsonParser();
JsonObject resEle = jp.parse(res).getAsJsonObject();
boolean retSignOK = signer.verifySign(resEle, resEle.get("sign").getAsString(), pubKey);
if (!retSignOK) {
throw new RuntimeException("verify response sign fail");
}
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("OK");
}
返回结果示例:
{
"status": 200,
"msg": "处理成功",
"data": {
"list": [
{
"trade_id": "W20250001",
"chain": "eth",
"coin": "usdt_erc20",
"from_address": "0x111...222",
"to_address": "0x111...333",
"txid": "0x123...321",
"matched": true,
"ledger_amount": "100.00",
"onchain_amount": "100.00",
"difference": "0",
"note": ""
},
{
"trade_id": "W20250002",
"chain": "btc",
"coin": "btc",
"from_address": "bc1q...3cyx",
"to_address": "bc1q...0cur",
"txid": "dd8a...7ff8",
"matched": false,
"onchain_amount": "99.12",
"ledger_amount": "100.00",
"difference": "-0.88",
"note": ""
}
]
},
"date_time": "2022-07-22 18:36:36",
"time_stamp": 1658486196,
"sign": "uuYWvmoMqM5xh7aTcxspJmW78y8op5BBjYXp0XoqcqFXe+HrSGzxN2Ls6LA7SlfsNndCtS4AX1/J+2o1MWZw/HFVfRqtxu02AEfWhM5ZSiJfEtO8f47H2/EGcsKw/eK8nxOnYAyAKwG6Ia6L4KgYIXLwsGt6Dt0VYWADu+vEQEes83/c6+Tc8QdqpdnLbs2XXXkYkl5eijoja+QEMaENbx+DHxnsVZV0iRK5FcSQH9PdOIpWmC944BA2v0tnPQWb6WDnOTsw5xoVKiL57WGIeOaxepvjo6poi1a/+HYrowT4IcejZZHi9YW0iM4eNm8MPK0tloAQ8GWY7kVs9uEwOA=="
}
HTTP Request
POST: /reconcile/withdrawal
请求参数
| 参数名 | 必选 | 类型 | 说明 |
|---|---|---|---|
| 公共参数 | 是 | string | 公参指:签名(sign)、版本(version)、商户ID(app_id)、时间(time) |
| list.trade_id | 是 | string | 商户提现单号 |
| list.coin | 否 | string | 币种 |
| list.ledger_amount | 否 | string | 转账数量 |
| list.from_address | 否 | string | 提现单链上出款账户地址 |
| list.to_address | 否 | string | 提现单链上收款账户地址 |
| list.txid | 否 | string | 提现单链上交易hash |
返回参数说明
| 参数名 | 类型 | 说明 |
|---|---|---|
| status | int | 状态码 |
| msg | string | 状态描述 |
| data | jsonObject | data |
| data.list | jsonArray | 具体每条记录 |
| data.list.trade_id | string | 商户提现单号 |
| data.list.chain | string | 主链 |
| data.list.coin | string | 币种 |
| data.list.from_address | string | 提现单链上出款账户地址 |
| data.list.to_address | string | 提现单链上收款账户地址 |
| data.list.ledger_amount | string | 账单记录转账数量 |
| data.list.onchain_amount | string | 链上交易转账数量 |
| data.list.difference | string | 数量差值 |
| data.list.matched | bool | 交易数量是否匹配 |
| data.list.note | string | 说明描述 |
| date_time | string | 响应时间 |
| time_stamp | int | 无时区的秒 |
| sign | string | 签名 |
全局状态码
| 状态码 | 含义 | 备注 |
|---|---|---|
| 200 | 处理成功 | |
| 500 | 请求失败 | |
| 501 | 参数错误 | |
| 502 | 公共参数错误 | |
| 503 | 无效的app_id | |
| 504 | 无效的商户 | |
| 505 | 签名错误 | |
| 506 | 数据不存在 | |
| 507 | 系统维护中,暂停服务 | |
| — | — | — |
| 520 | 币种为必填项 | |
| 521 | 地址为必填项 | |
| 522 | 用户id为必填项 | |
| 523 | 地址不存在 | |
| 524 | 该地址已分配给其他用户不能重复分配 | |
| 525 | 该用户id已分配地址,不能重复分配 | |
| 526 | eos 及其代币memo参数为必填项,值可以为空 | |
| 527 | 该币种及合约地址组合不存在 | |
| 528 | 用户不存在 | |
| 529 | 币种不存在 | |
| 530 | 访问频次过高,请稍后再试 | |
| — | — | — |
| 533 | 主链名格式错误 | |
| 534 | 订单号填写错误 | |
| 535 | 汇率异常错误 | |
| 536 | 该商家尚未配置币种的兑换,请联系平台管理员开通 | |
| 537 | 商家审核不通过 | |
| 538 | 兑换目标币名为必填项 | |
| 539 | 兑换币名为必填项 | |
| 540 | 兑换目标币名格式错误 | |
| 541 | 兑换币名格式错误 | |
| 542 | user_id格式错误 | |
| 543 | 地址格式错误 | |
| 544 | txid格式错误 | |
| 545 | 币名格式错误 | |
| 546 | 金额过大不支持 | |
| 547 | 金额最多8位小数 | |
| 548 | 转账地址不是有效地址 | |
| 549 | 转账金额应大于最小转出金额%s | |
| 550 | 超出今日请求次数,如需更多次数,请联系客服 | |
| 551 | 有已分配未使用地址,请使用完再请求新的地址 | |
| 552 | 地址不足或获取地址失败 | |
| 553 | 转账金额应需大于0 | |
| 554 | 账户余额不足 | |
| 555 | 交易ID不能为空且不能大于32位 | |
| 556 | 重复提交 | |
| 557 | 未找到该交易 | |
| 558 | 审核中 | |
| 559 | 转账中 | |
| — | — | — |
| 560 | 撤销 | |
| 561 | 转账失败 | |
| 562 | 不支持该币种或该币种不是主链币 | |
| 563 | ip错误,请联系管理员处理 | |
| 564 | IP 错误 | |
| 565 | 该币种不支持 | |
| 566 | IP 访问次数限制 | |
| 567 | 地址创建功能为关闭状态 | |
| 568 | 提现状态为关闭状态,不可提现 | |
| 569 | 提现数据异常,转账失败 | |
| — | — | — |
| 570 | 商户未开启密钥设置 | |
| 571 | 商家密钥版本号错误 | |
| 572 | refund_txid格式错误 | |
| 573 | refund_txid为必填项 | |
| 574 | refund_txid不存在 | |
| 575 | refund_txid所属交易尚未到账,请等候 | |
| 576 | 兑换交易不存在 | |
| 577 | 兑换成功,不可以退款 | |
| 578 | 兑换交易中,不可以退款 | |
| 579 | 该商家尚未配置钱包地址,请联系管理员 | |
| — | — | — |
| 580 | 撤单 | 钱包层撤单 |
| 581 | 不支持该币种手续费查询 | |
| 582 | 请配置hyperpay共管钱包 | |
| 583 | 类型错误 | |
| 584 | 兑换币种不支持 | |
| 585 | 兑换交易对不支持 | |
| 586 | 汇率目标币目前只支持usdt |
- 备注: 后期如果有版本升级或状态码新增修改等更新以此文档为准。