绑卡 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

提交单张卡执行绑定。批量场景建议循环调用并控制并发,或使用批量接口(开通后提供)。

请求参数

字段类型必填说明
requestIdstring是商户侧唯一请求号,长度 ≤ 64,用于幂等
cardTypestring是卡种编码:JD / TH / RT / YH / CTRIP / TMALL / BL / RX / HEMA
cardNostring是卡号,去除空格与全角字符
cardPwdstring是卡密,明文仅在传输中出现,落库前加密
accountIdstring否指定绑定的账号;不传则由平台按卡种调度可用账号
callbackUrlstring否单次回调地址;不传使用应用默认配置

请求示例

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 秒
1004requestId 已存在直接使用返回的原任务结果,勿新建
2001卡号格式不正确本地先做长度与字符集校验
2002卡密错误提示用户核对,勿自动无限重试
2003卡已绑定或已使用标记为不可回收,转人工核查
2004卡状态异常(冻结/过期)记录失败原因,联系发卡方
2005卡种暂不支持或通道维护进入待处理队列,稍后重试
3001绑定账号异常平台自动切换账号,无需商户处理
3002账号绑定额度已满平台调度新账号,可能延长处理时间
4290触发限流指数退避重试,必要时申请提额
5000系统异常重试 2 次仍失败请携 taskId 联系技术

限流与额度

  • 默认单商户 20 QPS,突发允许 2 倍持续 10 秒;需要更高并发可申请专属通道。
  • 单次请求仅提交 1 张卡;批量场景请控制客户端并发,或申请批量接口。
  • 绑卡额度按套餐计算,失败任务不计费;重复 requestId 不重复计费。
  • 额度剩余 10% 时会通过邮件与企业微信提醒。

上线检查清单

  • AppSecret 仅存放于服务端环境变量或密钥管理服务,未出现在代码仓库与前端包中。
  • 签名基于实际发送的 body 计算,已用 sandbox 环境验证通过。
  • 创建任务、查询、回调三条链路均实现超时与重试,且回调处理幂等。
  • 错误码已映射为业务提示,用户可理解「卡密错误」与「系统异常」的区别。
  • 回调地址已配置 HTTPS 且公网可达,证书链完整。
  • 日志中对卡号、卡密做脱敏,禁止打印完整卡密。
本页为接口文档的结构示例,具体字段、域名与额度以开通后提供的正式文档为准。对接过程中遇到问题,可在技术群内直接贴出 taskId 与响应体。

申请 AppKey 与沙箱环境