6.7 KiB
设备直接绑定接口联调文档
1. 接口说明
该接口用于设备无法正常获取绑定验证码时,由白名单来源的业务页面发起直接绑定。
接口完成的业务效果与验证码绑定一致:
- 创建当前程序用户与设备的有效绑定关系;
- 将设备绑定状态更新为
bound; - 作废该设备尚未使用的绑定验证码;
- 清理绑定验证码缓存;
- 写入绑定审计记录。
接口不会自动创建不存在的 ICCID。调用前,设备必须已经登记在后端 sim_card 表中,并且设备状态为 active。
2. 接口地址
POST /api/v1/program/bindings/by-iccid
生产环境示例:
https://<traffic-api-domain>/api/v1/program/bindings/by-iccid
将 <traffic-api-domain> 替换为实际 4G 管理后端域名。
3. 调用前提
3.1 程序用户登录
调用方必须先通过程序用户登录接口获取 PROGRAM_USER 的 accessToken:
POST /api/v1/program/auth/login
后续请求携带:
Authorization: Bearer <accessToken>
不能使用 SUPER_ADMIN、FACTORY_PROVISIONER 或设备 Token 调用此接口。
3.2 来源白名单
当前默认允许以下 Origin:
https://banban.api.talkingq.com
http://192.168.101.151
请求必须携带与页面实际来源完全一致的 Origin 请求头:
Origin: https://banban.api.talkingq.com
或:
Origin: http://192.168.101.151
白名单由环境变量配置:
BINDING_ALLOWED_ORIGINS=https://banban.api.talkingq.com,http://192.168.101.151
多个来源使用英文逗号分隔。来源匹配包含协议、主机和端口,不能只填写裸域名或裸 IP。
例如,下面这些值不是同一个 Origin:
http://192.168.101.151
https://192.168.101.151
http://192.168.101.151:8080
如果页面实际通过 HTTPS 或非默认端口访问,需要把实际 Origin 加入 BINDING_ALLOWED_ORIGINS 后重启后端。
4. 请求格式
4.1 请求头
Origin: https://banban.api.talkingq.com
Authorization: Bearer <PROGRAM_USER_ACCESS_TOKEN>
Content-Type: application/json
X-Request-Id: direct-bind-20260920-0001
Origin 是来源白名单校验字段;Authorization 是业务身份认证字段;X-Request-Id 用于日志追踪,建议每次请求使用唯一值。
4.2 请求体
{
"iccid": "898604E91123D1334901",
"requestId": "direct-bind-20260920-0001"
}
字段说明:
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
iccid |
string | 是 | 设备 ICCID,18 至 22 位字母或数字,后端会统一转为大写 |
requestId |
string | 是 | 幂等请求号,最长 64 个字符;同一用户重试必须使用相同值 |
5. curl 联调示例
请将 Token 和 ICCID 替换为真实值,不要把 Token 提交到代码仓库或群聊。
curl -i -X POST \
"https://<traffic-api-domain>/api/v1/program/bindings/by-iccid" \
-H "Origin: https://banban.api.talkingq.com" \
-H "Authorization: Bearer <PROGRAM_USER_ACCESS_TOKEN>" \
-H "Content-Type: application/json" \
-H "X-Request-Id: direct-bind-20260920-0001" \
--data '{
"iccid": "898604E91123D1334901",
"requestId": "direct-bind-20260920-0001"
}'
使用 IP 来源联调时,将 Origin 改为:
Origin: http://192.168.101.151
6. 成功响应
{
"code": "OK",
"message": "success",
"data": {
"iccid": "898604E91123D1334901",
"bindingStatus": "active",
"idempotent": false,
"boundAt": "2026-09-20T15:30:00"
},
"requestId": "http-request-id",
"timestamp": "2026-09-20T07:30:00Z"
}
字段说明:
| 字段 | 说明 |
|---|---|
data.iccid |
实际完成绑定的 ICCID |
data.bindingStatus |
成功时为 active,表示用户绑定关系有效 |
data.idempotent |
false 表示本次新建绑定,true 表示重复请求已返回原绑定结果 |
data.boundAt |
绑定时间 |
7. 幂等重试规则
请求超时或网络断开时,使用同一个 requestId 重试,不要生成新的请求号:
{
"iccid": "898604E91123D1334901",
"requestId": "direct-bind-20260920-0001"
}
同一程序用户、同一 ICCID、同一 requestId 重试时,接口返回 idempotent=true。
同一 requestId 改用其他 ICCID 时,接口返回 IDEMPOTENCY_CONFLICT。
8. 常见失败响应
8.1 来源不在白名单
HTTP/1.1 403 Forbidden
可能原因:
- 未携带
Origin; - Origin 协议不一致,例如配置了 HTTPS 但请求使用 HTTP;
- IP 使用了非默认端口;
- 后端环境变量未更新或服务未重启。
8.2 未登录或 Token 无效
{
"code": "UNAUTHORIZED"
}
请确认使用的是程序用户登录返回的 accessToken,并且 Token 尚未过期或撤销。
8.3 设备不存在
{
"code": "DEVICE_NOT_FOUND"
}
表示 ICCID 尚未登记到后端。该接口不会自动创建设备档案,应先通过设备接入或预置流程登记设备。
8.4 设备已被其他用户绑定
{
"code": "DEVICE_ALREADY_BOUND"
}
不能通过该接口覆盖其他用户的绑定关系,需要先由当前绑定用户解绑或由管理员执行解绑流程。
8.5 设备已禁用
{
"code": "DEVICE_DISABLED"
}
需要先恢复设备状态为 active。
8.6 参数错误
{
"code": "INVALID_REQUEST"
}
请检查 iccid 是否为 18 至 22 位字母数字,以及 requestId 是否为空或超过 64 个字符。
9. 浏览器联调注意事项
- 前端请求必须使用
Authorization请求头携带 Token,不能只依赖 Cookie; - 页面来源必须与白名单完全一致;
- 浏览器会先发送 CORS 预检请求,后端已经允许
POST、OPTIONS以及Authorization、Content-Type、X-Request-Id请求头; - 如果通过后端服务调用,HTTP 客户端通常不会自动添加
Origin,需要按接口要求主动设置; Origin不是加密签名,不能替代登录 Token;- 联调日志中可以使用响应里的
requestId联系后端排查。
10. 验收检查
建议至少验证以下场景:
- 使用
https://banban.api.talkingq.com来源和有效程序用户 Token,绑定一个未绑定的 active ICCID,返回idempotent=false。 - 使用相同用户、相同 ICCID、相同
requestId再次调用,返回idempotent=true。 - 使用其他 Origin 调用,返回 HTTP 403。
- 不携带
Authorization,返回UNAUTHORIZED。 - 使用已绑定到其他用户的 ICCID,返回
DEVICE_ALREADY_BOUND。 - 使用不存在的 ICCID,返回
DEVICE_NOT_FOUND。 - 确认数据库中
sim_card.binding_status为bound,并且user_device_binding.status为active。