绑卡 API 对接文档
通过 3 个接口完成「创建任务 → 查询结果 → 接收回调」。文档中的域名为示例地址,正式 AppKey 与接口域名在开通后由顾问提供。
接入概览
云绑卡提供 RESTful 风格接口,请求与响应均为 UTF-8 编码的 JSON。建议的接入顺序:
- 开通账号,获取
AppKey与AppSecret(AppSecret 只在服务端保存,禁止写入前端代码)。 - 实现签名方法,用测试卡跑通一次创建任务,确认响应结构。
- 实现查询接口与回调验签,覆盖失败重试与超时场景。
- 压测你的消费队列,确保回调处理幂等(同一 taskId 只处理一次)。
环境地址
| 环境 | Base URL | 用途 |
|---|---|---|
| 测试环境 | https://api-sandbox.yunbangka.com/v1 | 联调,使用测试卡种额度 |
| 生产环境 | https://api.yunbangka.com/v1 | 正式绑卡,产生计费 |
通用约定
- 所有请求必须使用 HTTPS,仅支持 TLS 1.2 及以上。
- 金额字段为字符串,单位为元,保留两位小数,例如
"500.00"。 - 时间字段为 ISO 8601 带时区,例如
2026-10-19T11:02:13+08:00。 - 成功响应
code为0;业务失败通过code+message返回,HTTP 状态码保持语义化。
鉴权与签名
每个请求需携带以下请求头,服务端会校验时间戳(允许 ±300 秒)与 nonce 唯一性,防止重放。
| 请求头 | 必填 | 说明 |
|---|---|---|
X-App-Key | 是 | 应用标识,开通后获取 |
X-Timestamp | 是 | Unix 时间戳(秒) |
X-Nonce | 是 | 随机字符串,建议 16–32 位 |
X-Sign | 是 | HMAC-SHA256 签名,小写十六进制 |
Content-Type | 是 | application/json; charset=utf-8 |
签名算法
按下列顺序拼接待签名字符串(每项之间用 \n 分隔,末尾不加换行),再用 AppSecret 做 HMAC-SHA256:
stringToSign =
HTTP_METHOD + "\n" +
REQUEST_PATH + "\n" +
X-Timestamp + "\n" +
X-Nonce + "\n" +
SHA256(raw_body) // GET 请求传空字符串的 SHA256
sign = lower( hex( HMAC_SHA256(stringToSign, AppSecret) ) )
签名必须基于「实际发送的原始 body」计算。若先 JSON 序列化再签名但发送时字段顺序变化,会导致验签失败。建议签名与发送复用同一份字节。
PHP 签名示例
<?php
$appKey = getenv('BK_APP_KEY');
$appSecret = getenv('BK_APP_SECRET'); // 只放服务端环境变量
$body = json_encode($payload, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
$ts = (string) time();
$nonce = bin2hex(random_bytes(12));
$stringToSign = implode("\n", [
'POST',
'/v1/cards/bind',
$ts,
$nonce,
hash('sha256', $body),
]);
$sign = hash_hmac('sha256', $stringToSign, $appSecret);
创建绑卡任务
POST
/v1/cards/bind
提交单张卡执行绑定。批量场景建议循环调用并控制并发,或使用批量接口(开通后提供)。
请求参数
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
requestId | string | 是 | 商户侧唯一请求号,长度 ≤ 64,用于幂等 |
cardType | string | 是 | 卡种编码:JD / TH / RT / YH / CTRIP / TMALL / BL / RX / HEMA |
cardNo | string | 是 | 卡号,去除空格与全角字符 |
cardPwd | string | 是 | 卡密,明文仅在传输中出现,落库前加密 |
accountId | string | 否 | 指定绑定的账号;不传则由平台按卡种调度可用账号 |
callbackUrl | string | 否 | 单次回调地址;不传使用应用默认配置 |
请求示例
curl -X POST https://api.yunbangka.com/v1/cards/bind \
-H "X-App-Key: bk_live_9f2c****" \
-H "X-Timestamp: 1760860800" \
-H "X-Nonce: 7d1f3a9c5b2e" \
-H "X-Sign: 3f9a1c****" \
-H "Content-Type: application/json; charset=utf-8" \
-d '{"requestId":"20261019-0001","cardType":"JD","cardNo":"1000****8888","cardPwd":"******"}'
响应示例
{
"code": 0,
"message": "ok",
"data": {
"taskId": "task_20261019_8f2a",
"requestId": "20261019-0001",
"cardType": "JD",
"status": "processing",
"createdAt": "2026-10-19T11:02:13+08:00"
}
}
status 取值:processing(处理中)、success(绑定成功)、failed(失败)。创建成功仅代表任务已受理,最终结果以查询接口或回调为准。
幂等规则
- 相同
requestId重复提交,返回首次创建的任务,不重复计费。 - 相同卡号在平台内已成功绑定,返回
2003,并附带历史 taskId。 - 建议以「业务订单号」作为 requestId,天然保证唯一。
查询任务结果
GET
/v1/tasks/{taskId}
用于回调未到达时的补偿查询,建议在创建任务后 30 秒起做指数退避轮询(间隔 5s、15s、60s,最多 5 次)。
curl https://api.yunbangka.com/v1/tasks/task_20261019_8f2a \
-H "X-App-Key: bk_live_9f2c****" \
-H "X-Timestamp: 1760860830" \
-H "X-Nonce: 9c4b2a7e1d88" \
-H "X-Sign: 71c2ab****"
响应示例(成功)
{
"code": 0,
"message": "ok",
"data": {
"taskId": "task_20261019_8f2a",
"requestId": "20261019-0001",
"cardType": "JD",
"status": "success",
"balance": "500.00",
"accountId": "acc_1024",
"finishedAt": "2026-10-19T11:02:16+08:00"
}
}
响应示例(失败)
{
"code": 0,
"message": "ok",
"data": {
"taskId": "task_20261019_8f2b",
"requestId": "20261019-0002",
"cardType": "TH",
"status": "failed",
"failCode": 2002,
"failReason": "卡密校验不通过,请核对卡密后重试"
}
}
查询接口不返回完整卡号,仅返回掩码卡号(如
1000****8888),方便对账又不暴露敏感信息。异步回调
任务终态产生后,平台会向你的回调地址 POST 一条 JSON 通知。请务必:
- 先验签、再处理业务,验签失败直接返回 401,不落库。
- 处理成功返回 HTTP 200 且响应体为
{"code":0},否则视为失败。 - 按
taskId做幂等,同一事件可能重复投递。
回调报文
{
"event": "card.bound",
"taskId": "task_20261019_8f2a",
"requestId": "20261019-0001",
"cardType": "JD",
"cardNoMasked": "1000****8888",
"status": "success",
"balance": "500.00",
"boundAt": "2026-10-19T11:02:16+08:00",
"sign": "5a7e0c****"
}
回调签名:sign = HMAC_SHA256(raw_body_without_sign, AppSecret),与请求签名相互独立。请使用原始请求体参与计算,不要先反序列化再序列化。
重试策略
失败后按 1s、5s、30s、5min、30min、2h 退避重试,共 6 次。全部失败后可在后台「回调记录」中手动补发,或通过查询接口主动对账。
错误码
| code | 含义 | 建议处理 |
|---|---|---|
0 | 成功 | — |
1001 | 参数缺失或格式错误 | 检查必填字段与类型,修正后重试 |
1002 | 签名错误 | 核对 stringToSign 拼接顺序与原始 body |
1003 | 时间戳过期 | 校准服务器时间,允许 ±300 秒 |
1004 | requestId 已存在 | 直接使用返回的原任务结果,勿新建 |
2001 | 卡号格式不正确 | 本地先做长度与字符集校验 |
2002 | 卡密错误 | 提示用户核对,勿自动无限重试 |
2003 | 卡已绑定或已使用 | 标记为不可回收,转人工核查 |
2004 | 卡状态异常(冻结/过期) | 记录失败原因,联系发卡方 |
2005 | 卡种暂不支持或通道维护 | 进入待处理队列,稍后重试 |
3001 | 绑定账号异常 | 平台自动切换账号,无需商户处理 |
3002 | 账号绑定额度已满 | 平台调度新账号,可能延长处理时间 |
4290 | 触发限流 | 指数退避重试,必要时申请提额 |
5000 | 系统异常 | 重试 2 次仍失败请携 taskId 联系技术 |
限流与额度
- 默认单商户 20 QPS,突发允许 2 倍持续 10 秒;需要更高并发可申请专属通道。
- 单次请求仅提交 1 张卡;批量场景请控制客户端并发,或申请批量接口。
- 绑卡额度按套餐计算,失败任务不计费;重复 requestId 不重复计费。
- 额度剩余 10% 时会通过邮件与企业微信提醒。
上线检查清单
- AppSecret 仅存放于服务端环境变量或密钥管理服务,未出现在代码仓库与前端包中。
- 签名基于实际发送的 body 计算,已用 sandbox 环境验证通过。
- 创建任务、查询、回调三条链路均实现超时与重试,且回调处理幂等。
- 错误码已映射为业务提示,用户可理解「卡密错误」与「系统异常」的区别。
- 回调地址已配置 HTTPS 且公网可达,证书链完整。
- 日志中对卡号、卡密做脱敏,禁止打印完整卡密。
本页为接口文档的结构示例,具体字段、域名与额度以开通后提供的正式文档为准。对接过程中遇到问题,可在技术群内直接贴出 taskId 与响应体。