CanPay 为商户提供聚合支付能力。商户服务端调用开放 API 创建订单,用户在支付页完成付款后,平台向商户回调地址发送异步通知,商户亦可主动查询订单状态。
API 基础地址:https://canpay.vip
payUrl 域名:与 API 基础地址相同(生产 https://canpay.vip/pay/{token},无端口)
通信协议:HTTPS · JSON · Content-Type: application/json
金额单位:人民币分(整数,例如 100 表示 1.00 元)
| 类型 | 路径 | 说明 |
|---|---|---|
| 统一下单 | POST /api/pay/unifiedorder | 开放 API,与商户门户同域 |
| 查询订单 | POST /api/pay/query | 开放 API,与商户门户同域 |
| 支付页 | GET /pay/{token} | 下单返回的 payUrl |
| 商户门户 | /merchant/ | 浏览器登录,非开放 API |
| 管理后台 | /admin/ | 独立端口 :18888,非开放 API |
| 项目 | 说明 |
|---|---|
| mchId | 平台分配的商户号(10 位数字) |
| secretKey | 商户密钥,用于签名;管理后台创建商户时随机生成,明文保存 |
| wayCode | 支付通道编码,固定 6020 |
汇率说明:商户侧金额为人民币;支付通道侧按平台配置汇率换算为印尼盾完成收款。
所有开放 API 请求均需携带 sign 字段。签名步骤如下:
1. 取请求 JSON 中所有非空参数(sign 本身不参与签名)
2. 按参数名 ASCII 码升序排序
3. 拼接为 key1=value1&key2=value2...
4. 末尾追加 &key=secretKey(商户密钥)
5. 对拼接字符串做 MD5,取 32 位小写十六进制
示例待签名字符串:
amount=100&clientIp=127.0.0.1&mchId=1234567890¬ifyUrl=https://example.com/notify&outTradeNo=T20250101120000&reqTime=1735689600000&subject=测试商品&wayCode=6020&key=your_secret_key
商户发起收款,返回系统订单号与支付链接 payUrl,用户访问支付页扫码完成付款。
POST
请求参数:
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
mchId | String | 是 | 商户号 |
wayCode | Integer | 是 | 支付通道编码 |
subject | String | 是 | 商品标题 |
outTradeNo | String | 是 | 商户订单号,同一商户下唯一 |
amount | Integer | 是 | 金额(人民币分) |
clientIp | String | 是 | 客户端 IP |
notifyUrl | String | 是 | 支付成功异步通知地址 |
reqTime | Long | 是 | 请求时间戳(毫秒) |
sign | String | 是 | 签名 |
body | String | 否 | 商品描述 |
extParam | String | 否 | 扩展参数,原样回传 |
returnUrl | String | 否 | 支付完成跳转地址(预留) |
请求示例:
{
"mchId": "1234567890",
"wayCode": 6020,
"subject": "测试商品",
"body": "测试描述",
"outTradeNo": "T20250101120000",
"amount": 100,
"clientIp": "127.0.0.1",
"notifyUrl": "https://example.com/notify",
"reqTime": 1735689600000,
"sign": "..."
}
响应参数(data):
| 字段 | 类型 | 说明 |
|---|---|---|
mchId | String | 商户号 |
tradeNo | String | 平台订单号 |
outTradeNo | String | 商户订单号 |
originTradeNo | String | 上游通道单号 |
amount | String | 金额(人民币分) |
payUrl | String | 支付页链接,可生成二维码供用户扫码 |
expiredTime | String | 订单过期时间(毫秒时间戳) |
响应示例:
{
"code": 0,
"message": "success",
"sign": "...",
"data": {
"mchId": "1234567890",
"tradeNo": "20250101120000123456",
"outTradeNo": "T20250101120000",
"originTradeNo": "48243067968064",
"amount": "100",
"payUrl": "https://canpay.vip/pay/xxxxxxxx",
"expiredTime": "1735691400000"
}
}
code 为 0 表示成功,非 0 为失败,message 为错误描述。
订单支付成功后,平台向统一下单时指定的 notifyUrl 发起 POST 异步通知(JSON)。
POST(平台 → 商户)
通知参数:
| 字段 | 类型 | 说明 |
|---|---|---|
mchId | String | 商户号 |
tradeNo | String | 平台订单号 |
outTradeNo | String | 商户订单号 |
originTradeNo | String | 上游通道单号 |
amount | Integer | 金额(人民币分) |
subject | String | 商品标题 |
body | String | 商品描述 |
extParam | String | 扩展参数 |
state | Integer | 支付状态,1 表示支付成功 |
notifyTime | Long | 通知时间(毫秒时间戳) |
sign | String | 签名 |
通知示例:
{
"mchId": "1234567890",
"tradeNo": "20250101120000123456",
"outTradeNo": "T20250101120000",
"originTradeNo": "48243067968064",
"amount": 100,
"subject": "测试商品",
"body": "测试描述",
"extParam": "",
"state": 1,
"notifyTime": 1735689700000,
"sign": "..."
}
商户应返回:纯文本 SUCCESS 或 OK(大小写不敏感)。
根据商户订单号查询订单最新状态与支付信息。
POST
请求参数:
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
mchId | String | 是 | 商户号 |
outTradeNo | String | 是 | 商户订单号 |
reqTime | Long | 是 | 请求时间戳(毫秒) |
sign | String | 是 | 签名 |
响应参数(data):
| 字段 | 类型 | 说明 |
|---|---|---|
mchId | String | 商户号 |
wayCode | Integer | 通道编码 |
tradeNo | String | 平台订单号 |
outTradeNo | String | 商户订单号 |
originTradeNo | String | 上游通道单号 |
amount | String | 金额(人民币分) |
subject | String | 商品标题 |
body | String | 商品描述 |
extParam | String | 扩展参数 |
notifyUrl | String | 异步通知地址 |
payUrl | String | 支付页链接 |
expiredTime | String | 过期时间(毫秒) |
successTime | String | 支付成功时间(毫秒),未支付为空 |
createTime | String | 创建时间(毫秒) |
state | Integer | 0 未支付,1 已支付 |
notifyState | Integer | 通知状态:0 未通知,1 成功,2 失败 |
响应示例:
{
"code": 0,
"message": "success",
"sign": "...",
"data": {
"mchId": "1234567890",
"wayCode": 6020,
"tradeNo": "20250101120000123456",
"outTradeNo": "T20250101120000",
"amount": "100",
"state": 1,
"payUrl": "https://canpay.vip/pay/xxxxxxxx",
"successTime": "1735689700000",
"createTime": "1735689600000",
"notifyState": 1
}
}
| wayCode | 说明 |
|---|---|
6020 | QRIS 动态二维码(印尼盾通道,人民币计价) |
更多通道请联系平台运营开通。
| state | 说明 |
|---|---|
0 | 未支付 |
1 | 支付成功 |
| notifyState | 说明 |
|---|---|
0 | 尚未通知商户 |
1 | 通知成功 |
2 | 通知失败 |
接口层 code 为 0 表示请求处理成功;业务是否支付成功以 data.state 为准。