Documentation Index
Fetch the complete documentation index at: https://docs.gate.com/llms.txt
Use this file to discover all available pages before exploring further.
协议规则
| 字段 | 描述 |
|---|
| 传输方式 | 为保证交易安全性,采用 HTTPS 传输,并使用 TLS1.2 及以上 |
| 数据格式 | 请求和响应数据都为 JSON 格式 |
| 签名算法 | HMAC-SHA512 算法 |
| 签名要求 | 请求和接收数据均需要校验签名 |
| 判断逻辑 | 先判断协议 status 字段返回,再判断业务返回,最后判断交易状态 |
响应格式
| 字段名 | 类型 | 说明 |
|---|
| status | string | 接口响应结果,SUCCESS 成功,FAIL 失败 |
| code | string | 响应错误码 |
| label | string | 响应错误名称 |
| errorMessage | string | 错误描述 |
| data | string | JSON 格式业务响应数据 |
成功示例
{
"status": "SUCCESS",
"code": "000000",
"label": "成功",
"errorMessage": "",
"data": "{...}"
}
失败示例
{
"status": "FAIL",
"code": "300001",
"label": "参数错误",
"errorMessage": "merchantTradeNo 不能为空",
"data": ""
}
参数规定
商户订单号
商户支付的订单号由商户自定义生成,仅支持使用字母、数字、中划线-、下划线_这些英文半角字符的组合,请勿使用汉字或全角等特殊字符,限定长度在 100 个字符内。GatePay 要求商户订单号保持唯一性(建议根据当前系统时间加随机序列来生成订单号)。重新发起一笔支付要使用原订单号,避免重复支付。
交易金额
所有金额参数都采用字符串传输,精度精确到小数点后 6 位,单笔交易金额最小单位为 0.0001,最大为 5000000,个人收款码最大金额为 10000。
币种类型
GatePay 支持的币种请参考支持币种章节。
所有时间字段,如果没有额外说明,格式都是毫秒级的 Unix 时间戳。
请求头
| 请求头 | 说明 |
|---|
| X-GatePay-Certificate-ClientId | 商户在 Gate 商户后台创建应用后分配的 ClientId |
| X-GatePay-On-Behalf-Of | 代理归属请求头。除机构专属接口外,本版所有 API 均支持按需携带该字段,用于标识请求归属的子主体或商户主体 |
| X-GatePay-Timestamp | 请求生成时的 UTC 毫秒时间戳;GatePay 收到请求时若与当前时间相差超过 10 秒,将拒绝处理 |
| X-GatePay-Nonce | 随机字符串,建议长度不超过 32 位,仅支持数字与字母 |
| X-GatePay-Signature | 请求签名字段,GatePay 使用该字段校验请求合法性 |
机构 API 的请求头规范请参见 机构公共头信息。
签名规范
构造签名串
我们希望商户的技术开发人员按照当前文档约定的规则构造签名串。GatePay 会使用同样的方式构造签名串。如果商户构造签名串的方式错误,将导致签名验证不通过。下面先说明签名串的具体格式。
每一行为一个参数。行尾以 \n(换行符,ASCII编码值为0x0A)结束。如果参数本身以 \n 结束,也需要附加一个 \n。
请求时间戳\n请求随机串\n请求报文主体\n
签名算法
Go 语言
import (
"crypto/hmac"
"crypto/sha512"
"encoding/hex"
"fmt"
)
// GenerateSignature 生成请求签名
// timestamp: 转换成字符串的UTC时间戳,精度是millisecond
// nonce: 随机字符串
// body: 请求体
// secretKey: Gate提供的api_secret
// return: 字符串签名
func GenerateSignature(timestamp string, nonce string, body string, secretKey string) string {
payload := fmt.Sprintf("%s\n%s\n%s\n", timestamp, nonce, body)
mac := hmac.New(sha512.New, []byte(secretKey))
mac.Write([]byte(payload))
signature := mac.Sum(nil)
return hex.EncodeToString(signature)
}
Java 语言
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Formatter;
public class Main {
private static final String HMAC_SHA512 = "HmacSHA512";
private static String toHexString(byte[] bytes) {
Formatter formatter = new Formatter();
for (byte b : bytes) {
formatter.format("%02x", b);
}
return formatter.toString();
}
public static String calculateHMAC(String data, String key)
throws InvalidKeyException, NoSuchAlgorithmException {
SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(), HMAC_SHA512);
Mac mac = Mac.getInstance(HMAC_SHA512);
mac.init(secretKeySpec);
return toHexString(mac.doFinal(data.getBytes()));
}
public static void main(String[] args) throws Exception {
String timeStamp = "1673613945439";
String nonce = "3133420233";
String body = "{\"code\":\"ac8B7Pl7C-XgfH6zxtd3SidYt7XIfWKU\",\"grant_type\":\"authorization_code\",\"redirect_uri\":\"https://gate.bytetopup.com\",\"client_id\":\"2Ugf9YGMCFRk85Yy\"}";
String data = String.format("%s\n%s\n%s\n", timeStamp, nonce, body);
String key = "zgsN5DntmQ2NCQiyJ4kJLyyEO25ewdDHydOSFIHdGrM=";
String hmac = calculateHMAC(data, key);
System.out.println(hmac);
}
}
Python 语言
import hashlib
import hmac
def generate_signature(timestamp: str, nonce: str, body: str, secret: str) -> str:
'''
生成请求签名
:param timestamp: 转换成字符串的UTC时间戳,精度是millisecond
:param nonce: 随机字符串
:param body: 请求体
:param secret: GatePay提供的api_secret
:return: 返回字符串签名
'''
payload = '%s\n%s\n%s\n' % (timestamp, nonce, body)
signed = hmac.new(secret.encode(), payload.encode(), hashlib.sha512)
return signed.digest().hex()
PHP 语言
<?php
function generateSignature($timestamp, $nonce, $body, $secretKey) {
$payload = "$timestamp\n$nonce\n$body\n";
$signature = hash_hmac('sha512', $payload, $secretKey, true);
return bin2hex($signature);
}
$timestamp = "1631257823000";
$nonce = "abcd1234";
$body = 'the post request body content';
$secretKey = "your_secret_key";
$signature = generateSignature($timestamp, $nonce, $body, $secretKey);
echo "Signature: " . $signature;
支付回调处理
回调描述
Gate Pay 会通过 POST 的方式向回调地址发送回调报文,回调通知的请求主体中会包含 JSON 格式的通知参数,具体的通知参数列表如下:
| 名称 | 类型 | 说明 |
|---|
| bizType | string | 异步回调类型枚举,“PAY” 表示非地址支付,“PAY_BATCH” 异步奖励单,“PAY_ADDRESS” 地址支付,“PAY_FIXED_ADDRESS” 固定收款码地址支付,“TRANSFER_ADDRESS” 地址支付转账 |
| bizId | string | 支付订单 ID |
| bizStatus | string | 订单状态 |
| client_id | string | 支付订单关联的 client_id |
| data | json 格式对象 | 根据不同业务订单 data 格式不同,请参考具体业务文档 |
回调验签与应答
商户接收到回调通知报文后,需完成对报文的验签,并应答回调通知。
商户验签后响应字段如下:
| 参数 | 描述 |
|---|
| returnCode | 回调是否成功处理。“SUCCESS” 表示成功处理,当返回 “SUCCESS” GatePay 不会再重试异步回调发送。“FAIL” 表示处理失败,当 GatePay 收到该状态会发送重试 |
| returnMessage | 失败原因字符串类型描述,可以为空 |
响应 JSON 格式:
{
"returnCode": "SUCCESS",
"returnMessage": ""
}
回调处理步骤
对回调进行验签步骤:
回调报文的 HTTP 请求头中会包含报文的签名信息,用于验签,具体如下:
| 参数 | 描述 |
|---|
| X-GatePay-Timestamp | 验签的时间戳 |
| X-GatePay-Nonce | 验签的随机字符串 |
| X-GatePay-Signature | 验签的签名值 |
验签需使用请求头中的 X-GatePay-Timestamp、X-GatePay-Nonce 以及请求主体中 JSON 格式的通知参数构建出验签串(验签计算参考签名算法章节),然后使用商户支付密钥计算出验签再跟 X-GatePay-Signature 值进行比较是否相等,确保接收的回调内容是来自 Gate Pay。
签名验证工具
商户的技术开发人员可使用该工具来排查签名验证不通过的原因。
签名验证工具