PAYROAD跨境支付API文档
1. 概述
1.1 编写目的
目的是约定商户与PAYROAD收单系统间的业务接口。包括通讯协议、交易接口规范、文件格式、加密和摘要规范。指 导商户开发人员依据本规范开发,并与PAYROAD收单系统对接。
2. 通讯协议
2.1 协议约定
- 平台与PAYROAD之间基于HTTPS1.2协议通讯,报文组织形式采用 json 规范。
- 双方的报文都密文形式发送,必须同时将报文的密文、会话密钥密文和签名传输给对方。
- 平台和PAYROAD双方互为客户端和服务端。根据应用的要求,可以由平台作为客户端主动发起交易请求,PAYROAD 来做应答。也可以由PAYROAD主动发起交易请求,平台来做应答,平台在开户时需提前设置接收PAYROAD的请求地址。
- 客户端提交请求使用POST表单方式 (Content-Type:application/json) 提交,内容采用UTF-8编码。
- 请求和响应均由四个域:merchantNo=平台代码、jsonEnc=报文密文、keyEnc=会话密钥密文、sign=报文签名
3 加密及签名规范
3.1 原则
- 交易报文传输都需要进行加密、签名和校验。
- 无论是请求端还是响应端接收到报文后,都需要进行签名验证,即按照约定算法重新生成签名,然后和收到的签名进 行对比,对比通过后才能进行报文内容的解析,否则报文或文件内容可能出现篡改、部分丢失、伪造的问题。
- 报文加密算法:DES/CBC/PKCS5Padding
- 会话密钥生成:KeyGenerator生成
- 会话密钥加密算法:RSA/ECB/PKCS1Padding
- 签名算法:SHA1withRSA
3.2 RSA密钥对获得
openssl genrsa –out rsa_private_key_2048.pem2048
#生成rsa私钥,以X509编码,指定生成的密钥的位数:2048
openssl pkcs8 –topk8 –in rsa_private_key_2048.pem –out pkcs8_rsa_private_key_2048.pem –nocrypt
#将上一步生成的rsa私钥转换成PKCS#8编码
openssl rsa –in rsa_private_key_2048.pem –out rsa_public_key_2048.pem –pubout
#导出rsa公钥,以X509编码商户需要按上面步骤生成商户的公钥pem发给PAYROAD,
#或商户直接可以向PAYROAD索要密钥对的生成脚本,生成商户所需的公私钥。
#PAYROAD也需要把PAYROAD生成的对应的公钥pem发给商户。
对于商户来说,需要生成商户自己的RSA密钥对(包含公钥和私钥),其中,私钥合作方自己保留,。 同时公钥提供给PAYROAD 对于PAYROAD来说,需要为每个商户生成对应的公私钥对。其中,私钥PAYROAD自己保留,公钥需要提供给商户。
3.3 报文加密及签名

- 对请求或响应Json报文明文(UTF-8编码. 使用发送方的私钥进行签名(SHA1withRSA. ,并将签名结果转换为HEX字符串,得到sign域。
- 使用KeyGenerator生成器,生成DES加密会话密钥SK;
- 使用SK对Json明文进行加密(DES/CBC/PKCS5Padding. ,并将加密结果转换为HEX字符串,得到jsonEnc 域。
- 使用接收方公钥对会话密钥SK加密(RSA/ECB/PKCS1Padding. ,并将结果转换为HEX字符串,得到keyEnc 域。
3.4 报文解密及验签

- 将keyEnc域转换为二进制byte数组,使用接收方放的私钥对会话密钥,得到明文SK;
- 将jsonEnc与转换为二进制byte数组,使用上一步得到的会话密钥SK解密,得到明文json;
- 使用上一步解密得到的明文、发送方公钥和sign域数据验证签名的有效性。
4 业务接口
本章节描述商户接入PAYROAD相关业务接口。
M表示必输字段,O表示可选字段
4.1 交易接口
4.1.1 获取商户支持收取的加密货币信息接口
1 请求地址
Url: https://{baseUrl}/api/payment/getMerchantSupportChain
请求示例:
{
"merchantNo": "123456789"
}
2 请求参数
| 名称 | Json标签 | 类型 | 属性 | 取值说明 |
|---|---|---|---|---|
| 商户号 | merchantNo | string(32) | M | 平台分配的唯一商户号 |
返回示例:
{
"code": 200,
"msg": "success",
"data": {
"merchantNo": "MN202602130001",
"supportChainInfos": [
{
"chainNo": "1",
"currency": "USDT"
},
{
"chainNo": "1",
"currency": "USDC"
},
{
"chainNo": "1",
"currency": "PRUSD"
},
{
"chainNo": "SOL",
"currency": "PRUSD"
}
]
}
}
3 响应参数
| 名称 | Json标签 | 类型 | 属性 | 取值说明 |
|---|---|---|---|---|
| 商户号 | code | int | M | 返回200为成功,其余为失败 |
| 支持链信息 | supportChainInfos | List | M | 支持的链和币种信息 |
4.1.2 获取商户接受用户付款的支付地址接口
1 请求地址
Url: https://{baseUrl}/api/payment/getCustomerPaymentInfo
请求示例:
{
"merchantNo": "MN202602130001",
"customerNo": "23",
"currencyChainList":[{"chainNo":"1","currency":"USDT"},{"chainNo":"1","currency":"PRUSD"}]
}
2 请求参数
| 名称 | Json标签 | 类型 | 属性 | 取值说明 |
|---|---|---|---|---|
| 商户号 | merchantNo | string(32) | M | 平台分配的唯一商户号 |
| 客户号 | customerNo | string(32) | M | 商户自有系统的分配给客户的商户号(为每一个客户分配收单地址,如果相同客户则使用相同的地址,不会额外创建新的地址) |
| 加密货币信息列表 | currencyChainList | List | M | 商户想要接收的货币信息列表 |
| |
返回示例:
{
"code": 200,
"msg": "success",
"data": {
"merchantNo": "MN202602130001",
"customerNo": "23",
"receiveCyptoInfos": [
{
"chainNo": "1",
"currency": "USDT",
"receiveAddress": "0xEFEE76CD31c5cC7aB79d36991Af3AC9b27347034"
},
{
"chainNo": "1",
"currency": "USDC",
"receiveAddress": "0xEFEE76CD31c5cC7aB79d36991Af3AC9b27347034"
},
{
"chainNo": "1",
"currency": "PRUSD",
"receiveAddress": "0xEFEE76CD31c5cC7aB79d36991Af3AC9b27347034"
},
{
"chainNo": "SOL",
"currency": "PRUSD",
"receiveAddress": "bosZ1yL9rNRtLcJWxADaMGUKa9TVZFyFejKfidbasQ4"
}
]
}
}
3 响应参数
| 名称 | Json标签 | 类型 | 属性 | 取值说明 |
|---|---|---|---|---|
| 商户号 | code | int | M | 返回200为成功,其余为失败 |
| 客户号 | customerNo | string(32) | M | 商户自有系统的分配给客户的商户号(为每一个客户分配收单地址,如果相同客户则使用相同的地址,不会额外创建新的地址) |
| 支付地址信息列表 | receiveCyptoInfos | List | M | 商户针对该用户的支付地址信息 |
4.1.3 创建订单
1 请求地址
Url: https://{baseUrl}/api/createOrder
请求示例:
{
"cancelUrl": "https://www.baidu.com",
"chainNo": "1",
"customerNo": "T125487",
"goodsList": [
{
"currency": "CNY",
"goodsDesc": "测试",
"goodsId": "123456",
"goodsName": "测试",
"goodsUrl": "https://www.baidu.com",
"num": 1,
"price": 0.01
}
],
"merchantNo": "123456789",
"merchantOrderNo": "DD021300005",
"orderAmount": 1500,
"orderCurrency": "USDT",
"receiveAddress": "0xc0b00df7f09e86b65907cbaeef01385e6fa1909d",
"reference": "测试",
"requestId": "DD021300005",
"returnUrl": "https://www.payroad.com",
"terminal": "WEB"
}
2 请求参数
| 名称 | Json标签 | 类型 | 属性 | 取值说明 |
|---|---|---|---|---|
| 商户号 | merchantNo | string(32) | M | 平台分配的唯一商户号 |
| 商户订单号 | merchantOrderNo | string(32) | M | 商户订单号,商户生成的唯一订单号,不可重复 |
| 请求id | requestId | string(100) | M | 该次请求的唯一标识,不可重复 |
| 交易币种 | orderCurrency | string(10) | M | 交易币种(目前只支持USDT、USDC) |
| 交易金额 | orderAmount | decimal(28,18) | M | 交易金额 |
| 客户号 | customerNo | string(32) | M | 商户自有系统的分配给客户的商户号(为每一个客户分配收单地址,如果相同客户则使用相同的地址,不会额外创建新的地址) |
| 收单地址 | receiveAddress | string(128) | M | 收单地址 |
| 链编码 | chainNo | string(10) | M | 链编码 |
| 商品信息 | goodsList | List | M | 如:02 |
| 透传字段 | reference | string(100) | O | 原样返回给商户 |
| 返回地址 | returnUrl | string(256) | O | 返回网址 |
| 取消地址 | cancelUrl | String(256) | O | 取消地址 |
| 终端类型 | terminal | string(50) | O | ANDROID、IOS、WEB |
| 支付地区 | payRegion | string(100) | O | 为满足特殊地区法规要求填写,具体可联系运营人员 |
| goodsList | ||||
| 商品id | goodsId | string(32) | M | 商户平台商品id |
| 商品名称 | goodsName | string(32) | M | 商品名称 |
| 商品描述 | goodsDesc | string(300) | O | 商品描述 |
| 商品单价 | price | decimal(28,18) | M | 商品金额 |
| 商品币种 | currency | string(10) | M | 商品币种(法币或者稳定币皆可) |
| 商品数量 | num | int | M | 数量整数 |
| 商品链接 | goodsUrl | string(255) | O | 商品链接 |
返回示例:
{
"merchantNo": "147258",
"merchantOrderNo": "1705743863442",
"paymentOrderNo": "OM00085634",
"orderAmount": 500,
"orderCurrency": "USDT",
"reference": "",
"redirectUrl": "https://payroad/verify/",
"status": "02",
"paymentExpireTime": 1770884345,
"requestId": "DD021300005",
"qrcodeUrl": "https://api.qrserver.com/v1/create-qr-code/?size=150x150&data=https://example.com",
"receiveAddress": "0xc0b00df7f09e86b65907cbaeef01385e6fa1909d"
}
3 响应参数
| 名称 | Json标签 | 类型 | 属性 | 取值说明 |
|---|---|---|---|---|
| 商户号 | merchantNo | string(32) | M | 平台分配唯一商户号 |
| 商户唯一订单号 | merchantOrderNo | string(32) | M | 商户订单号 |
| 支付订单号 | paymentOrderNo | string(32) | M | 支付订单号 |
| 订单状态 | status | string(2) | M | 订单状态 00-成功 01-失败 02-支付中 |
| 透传字段 | reference | string(100) | O | 透传字段 |
| 过期时间 | paymentExpireTime | long | O | 订单过期时间,10位时间戳 |
| 跳转地址 | redirectUrl | string(200) | O | 收银台模式跳转地址 |
| 订单金额 | orderAmount | decimal(28,18) | M | |
| 订单币种 | orderCurrency | string(10) | M | |
| 请求id | requestId | string(32) | M | 请求id |
| 二维码地址 | qrcodeUrl | string(32) | M | 手机钱包可进行支付扫码的二维码地址 |
| 收单地址 | receiveAddress | string(128) | M | 用户支付地址 |
4.1.4 关闭订单
1 请求地址
Url: https://{baseUrl}/api/closeOrder
请求示例:
{
"merchantNo": "123456789",
"paymentOrderNo": "DD021300005",
"requestId": "DD021300005"
}
2 请求参数
| 名称 | Json标签 | 类型 | 属性 | 取值说明 |
|---|---|---|---|---|
| 商户号 | merchantNo | string(32) | M | 平台分配的唯一商户号 |
| 支付订单号 | paymentOrderNo | string(32) | M | 支付订单号 |
| 请求id | requestId | string(32) | M | 该次请求的唯一标识,不可重复 |
返回示例:
{
"code": 200,
"msg": "success"
}
3 响应参数
| 名称 | Json标签 | 类型 | 属性 | 取值说明 |
|---|---|---|---|---|
| 商户号 | code | int | M | 返回200为成功,其余为失败 |
| 描述 | msg | string(256) | O | 描述 |
4.2 退款
4.2.1 退款请求参数
1 请求地址
Url: https://{baseUrl}/api/createRefund
Method: POST
请求示例:
{
"merchantNo": "MN202602130001",
"paymentOrderNo": "OM00003801",
"refundAmount": 1500,
"requestId": "1771935070",
"merchantRefundOrderNo": "REFUND024",
"reference": "refund",
"refundReason": "refund"
}
2 请求字段
| 名称 | Json标签 | 类型 | 属性 | 取值说明 |
|---|---|---|---|---|
| 商户号 | merchantNo | string(32) | M | 平台分配唯一商户号 |
| 商户退款订单号 | merchantRefundOrderNo | string(32) | M | 商户退款订单号,商户生成的唯一订单号,不可重复 |
| 支付订单号 | paymentOrderNo | string(32) | M | 支付订单号(交易返回的参数) |
| 退款金额 | refundAmount | decimal(28,18) | M | 退款金额 |
| 退款请求id | requestId | string(32) | M | 退款请求id |
| 透传字段 | reference | string(100) | O | 透传字段 |
| 退款原因 | refundReason | string(32) | O | 退款原因 |
返回示例:
{
"merchantNo": "888888",
"merchantRefundOrderNo": "1705745403486",
"paymentOrderNo": "OM00051892",
"refundAmount": 50,
"refundCurrency": "USDT",
"status": "02",
"requestId": "1771935070",
"refundOrderNo": "RF00051892"
}
3 响应字段
| 名称 | Json标签 | 类型 | 属性 | 取值说明 |
|---|---|---|---|---|
| 商户号 | merchantNo | string(32) | M | 平台分配唯一商户号 |
| 商户退款订单号 | merchantRefundOrderNo | string(32) | M | 商户退款订单号,商户生成的唯一订单号,不可重复 |
| 支付订单号 | paymentOrderNo | string(32) | M | 支付订单号(交易返回的参数) |
| 退款币种 | refundCurrency | string(10) | M | |
| 退款金额 | refundAmount | decimal(28,18) | M | |
| 退款状态 | status | string(2) | M | 订单状态 00-退款成功 01-退款失败 02-退款中 |
| 平台退款订单号 | refundOrderNo | string(32) | M | 平台生成的退款唯一标识(查询时输入) |
| 退款请求id | requestId | string(32) | M |
4.3 提现
4.3.1 提现请求参数
1 请求地址
Url: https://{baseUrl}/api/createWithdraw
Method: POST
请求示例:
{
"merchantNo": "MN202602130001",
"withdrawMerchantNo": "565600003801",
"chainNo": 1,
"withdrawAddress": "0x53211bd5f925dbc9d006947baffb16dc69ef0a6e",
"currency": "REFUND024",
"amount": 150,
"requestId": "with001124"
}
2 请求字段
| 名称 | Json标签 | 类型 | 属性 | 取值说明 |
|---|---|---|---|---|
| 商户号 | merchantNo | string(32) | M | 平台分配唯一商户号 |
| 商户提现订单号 | withdrawMerchantNo | string(32) | M | 商户提现订单号,商户生成的唯一订单号,不可重复 |
| 链编号 | chainNo | string(32) | M | 链编号 |
| 提现金额 | amount | decimal(28,18) | M | 提现金额 |
| 提现币种 | currency | string(10) | M | 提现币种 |
| 提现地址 | withdrawAddress | string(100) | M | 提现地址(商户入驻时录入的地址) |
| 提现请求id | requestId | string(32) | M | 提现请求id |
返回示例:
{
"merchantNo": "888888",
"withdrawMerchantNo": "1705745403486",
"withdrawNo": "OM00051892",
"amount": 50,
"currency": "USDT",
"status": "00",
"requestId": "1771935070"
}
3 响应字段
| 名称 | Json标签 | 类型 | 属性 | 取值说明 |
|---|---|---|---|---|
| 商户号 | merchantNo | string(32) | M | 平台分配唯一商户号 |
| 商户提现订单号 | withdrawMerchantNo | string(32) | M | 商户提现订单号,商户生成的唯一订单号,不可重复 |
| 平台提现订单号 | withdrawNo | string(32) | M | 平台提现订单号 |
| 提现币种 | currency | string(10) | M | |
| 提现金额 | amount | decimal(28,18) | M | |
| 提现状态 | status | string(2) | M | 订单状态 00-提现成功 01-提现失败 02-提现中 |
| 退款请求id | requestId | string(32) | M |
4.4 查询
4.4.1 交易查询请求参数
1 请求地址
Url: https://{baseUrl}/api/queryOrder
Method: POST
请求示例:
{
"paymentOrderNo":"20220725006"
}
2 请求字段
| 名称 | Json标签 | 类型 | 属性 | 取值说明 |
|---|---|---|---|---|
| 支付订单号 | paymentOrderNo | string(32) | M | 交易返回的支付订单号 |
返回示例:
{
"merchantNo": "888888",
"merchantOrderNo": "O8950051892",
"paymentOrderNo": "OM00051892",
"status": "00",
"orderAmount": 50,
"orderCurrency": "USD",
"reference": "query",
"requestId": "1771935070"
}
3 响应字段
| 名称 | Json标签 | 类型 | 属性 | 取值说明 |
|---|---|---|---|---|
| 商户号 | merchantNo | string(32) | M | 平台分配唯一商户号 |
| 商户订单号 | merchantOrderNo | string(32) | M | |
| 支付订单号 | paymentOrderNo | string(32) | M | |
| 订单状态 | status | string(2) | M | 00-成功 01-失败 02-支付中 |
| 金额 | orderAmount | decimal(28,18) | M | |
| 币种 | orderCurrency | string(10) | M | |
| 请求id | requestId | string(32) | M | |
| 透传字段 | reference | string(100) | O |
4.3.2 退款查询请求参数
1 请求地址
Url: https://{baseUrl}/api/queryRefund
Method: POST
请求示例:
{
"refundOrderNo":"RF20220725006"
}
2 请求字段
| 名称 | Json标签 | 类型 | 属性 | 取值说明 |
|---|---|---|---|---|
| 退款订单号 | refundOrderNo | string(32) | M | 退款返回的平台退款订单号 |
返回示例:
{
"merchantNo": "888888",
"merchantRefundOrderNo": "O8950051892",
"paymentOrderNo": "OM00051892",
"status": "00",
"refundAmount": 50,
"refundCurrency": "USD",
"reference": "query",
"requestId": "1771935070"
}
3 响应字段
| 名称 | Json标签 | 类型 | 属性 | 取值说明 |
|---|---|---|---|---|
| 商户号 | merchantNo | string(32) | M | 平台分配唯一商户号 |
| 商户退款订单号 | merchantRefundOrderNo | string(32) | M | |
| 支付订单号 | paymentOrderNo | string(32) | M | |
| 订单状态 | status | string(2) | M | 00-成功 01-失败 02-支付中 |
| 退款金额 | refundAmount | decimal(28,18) | M | |
| 退款币种 | refundCurrency | string(10) | M | |
| 退款请求id | requestId | string(32) | M | |
| 透传字段 | reference | string(100) | O |
4.3.3 提现查询请求参数
1 请求地址
Url: https://{baseUrl}/api/queryWithdraw
Method: POST
请求示例:
{
"merchantNo":"888888",
"withdrawNo":"WO00016855"
}
2 请求字段
| 名称 | Json标签 | 类型 | 属性 | 取值说明 |
|---|---|---|---|---|
| 商户号 | merchantNo | string(32) | M | 平台分配唯一商户号 |
| 平台提现订单号 | withdrawNo | string(32) | M | 提现返回的平台提现订单号 |
返回示例:
{
"merchantNo": "888888",
"withdrawMerchantNo": "O8950051892",
"withdrawNo": "OW00051892",
"withdrawStatus": "00",
"withdrawAmount": 50,
"withdrawCurrency": "USDT",
"chainNo": "1",
"withdrawAddress": "0x53211bd5f925dbc9d006947baffb16dc69ef0a6e",
"requestId": "1771935070"
}
3 响应字段
| 名称 | Json标签 | 类型 | 属性 | 取值说明 |
|---|---|---|---|---|
| 商户号 | merchantNo | string(32) | M | 平台分配唯一商户号 |
| 商户提现订单号 | withdrawMerchantNo | string(32) | M | |
| 提现订单号 | withdrawNo | string(32) | M | |
| 提现状态 | withdrawStatus | string(2) | M | 00-成功 01-失败 02-提现中 |
| 提现金额 | withdrawAmount | decimal(28,18) | M | |
| 提现币种 | withdrawCurrency | string(10) | M | |
| 提现请求id | requestId | string(32) | M | |
| 提现地址 | withdrawAddress | string(128) | M | |
| 链编号 | chainNo | string(10) | O |
5 请求域名
测试环境:https://uat.api.acquire.payroad.com
生产环境:https://api.acquire.payroad.com