跳转到主要内容

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 字段返回,再判断业务返回,最后判断交易状态

响应格式

字段名类型说明
statusstring接口响应结果,SUCCESS 成功,FAIL 失败
codestring响应错误码
labelstring响应错误名称
errorMessagestring错误描述
datastringJSON 格式业务响应数据

成功示例

{
  "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 格式的通知参数,具体的通知参数列表如下:
名称类型说明
bizTypestring异步回调类型枚举,“PAY” 表示非地址支付,“PAY_BATCH” 异步奖励单,“PAY_ADDRESS” 地址支付,“PAY_FIXED_ADDRESS” 固定收款码地址支付,“TRANSFER_ADDRESS” 地址支付转账
bizIdstring支付订单 ID
bizStatusstring订单状态
client_idstring支付订单关联的 client_id
datajson 格式对象根据不同业务订单 data 格式不同,请参考具体业务文档

回调验签与应答

商户接收到回调通知报文后,需完成对报文的验签,并应答回调通知。 商户验签后响应字段如下:
参数描述
returnCode回调是否成功处理。“SUCCESS” 表示成功处理,当返回 “SUCCESS” GatePay 不会再重试异步回调发送。“FAIL” 表示处理失败,当 GatePay 收到该状态会发送重试
returnMessage失败原因字符串类型描述,可以为空
响应 JSON 格式:
{
    "returnCode": "SUCCESS",
    "returnMessage": ""
}

回调处理步骤

对回调进行验签步骤: 回调报文的 HTTP 请求头中会包含报文的签名信息,用于验签,具体如下:
参数描述
X-GatePay-Timestamp验签的时间戳
X-GatePay-Nonce验签的随机字符串
X-GatePay-Signature验签的签名值
验签需使用请求头中的 X-GatePay-TimestampX-GatePay-Nonce 以及请求主体中 JSON 格式的通知参数构建出验签串(验签计算参考签名算法章节),然后使用商户支付密钥计算出验签再跟 X-GatePay-Signature 值进行比较是否相等,确保接收的回调内容是来自 Gate Pay。

签名验证工具

商户的技术开发人员可使用该工具来排查签名验证不通过的原因。 签名验证工具