跳到正文
开灵科技 - 北京开灵科技有限公司API百宝箱

⓪ 实人认证(独立刷脸核验)

不涉及开票的纯身份核验:发一个链接给本人,现场人脸与公安基准照比对 + 手机号短信验证码,两项都过才算通过。司机打卡、领料签收、现场确认这类「每次都要一个独立核验结果」的场景用它。★与②散户入驻的区别:入驻一个人只做一次、拿的是入驻状态;这里每次都是一次新的、独立的核验结果。被认证人不需要有工商银行卡、也不需要在工行开过户。

属「工商银行 · 业务型接口」——底层编排 乐企直联原子接口,你只调这一个。

发起认证

接口 · 发起认证(页面类)

POST  https://openapi.kailingteck.com/api/v1/rinv/face/start

鉴权:X-App-Key + X-Timestamp + X-Sign(= sha256(appKey + 时间戳 + 报文 + appSecret))。

请求参数

字段必填大白话说明
outUserId必填被认证人在你方的唯一编号(同一个人请长期保持同一个编号,工行以它识别人)
custName必填姓名
certNo必填身份证号(工行目前仅支持身份证)
mobile必填本人手机号——认证过程中工行会往这个号发短信验证码,填错就做不完
jumpUrl必填认证成功后页面「确认」按钮的回跳地址(可以带参数,便于你识别是哪次打卡)
failJumpUrl选填认证失败后的回跳地址;不传则与 jumpUrl 相同
transNo选填本次认证流水号。★工行要求全局唯一、不可重复;不传则平台自动生成一个,建议你自己传业务单号方便对账
callbackUrl选填你方接收认证结果通知的地址。传了平台就把工行的结果转发给你;不传则只能靠主动查询
authScene选填工行认证场景字典,不传默认 01

请求示例

{
  "outUserId": "DRIVER001",
  "custName": "张三",
  "certNo": "500101199001011234",
  "mobile": "13800001234",
  "jumpUrl": "https://你的系统/checkin/done?id=8899",
  "transNo": "CHECKIN20260923001",
  "callbackUrl": "https://你的系统/notify/face"
}

返回

所有接口都用同一层信封:code/msg/requestId/timestamp/data。业务字段都在 data 里,下表列的就是 data 的内容。code 为 CYT_00000 表示调用成功。

返回参数(data)

字段大白话说明
pageUrl★把这个地址交给本人在手机上打开,直接 location.href 过去即可——工行的签名和表单由平台代办,你不用处理
transNo本次认证流水号,查结果、对回调都用它
outUserId回显

返回示例(成功)

{
  "code": "CYT_00000",
  "msg": "success",
  "data": {
    "transNo": "CHECKIN20260923001",
    "outUserId": "DRIVER001",
    "pageUrl": "https://openapi.kailingteck.com/api/v1/icbc/redirect/rxxxx",
    "mock": false
  }
}

异常与报错

情形含义与处理
transNo 已被使用过工行要求每次认证流水号全局唯一,换一个新的
页面打不开摄像头让本人用手机浏览器或微信打开并允许摄像头权限;链接必须整行完整转发,断行丢参数会报错

前端怎么用

const r = await post('/api/v1/rinv/face/start', body);
location.href = r.data.pageUrl;   // 或把 pageUrl 转成二维码让本人扫

★pageUrl 即用即取:链接里含工行签名的时间戳,有时效,别提前很久生成放着。★transNo 重复会被工行直接拒绝,平台也会先帮你拦一道(返回 400 提示已使用过)。

查认证结果

接口 · 查认证结果(数据类)

POST  https://openapi.kailingteck.com/api/v1/rinv/face/status

鉴权:X-App-Key + X-Timestamp + X-Sign(= sha256(appKey + 时间戳 + 报文 + appSecret))。

请求参数

字段必填大白话说明
transNo必填发起认证时的流水号
outUserId选填不传则自动用发起时登记的那个(工行要求两头一致)

请求示例

{ "transNo": "CHECKIN20260923001" }

返回

所有接口都用同一层信封:code/msg/requestId/timestamp/data。业务字段都在 data 里,下表列的就是 data 的内容。code 为 CYT_00000 表示调用成功。

返回参数(data)

字段大白话说明
passed★直接看这个:true=本人核验通过
authResult工行原始状态:00 初始 / 01 认证中 / 02 认证成功 / 03 认证失败
authResultText上面那个码的中文说法
failReason失败原因(失败时才有)
hint查不到结果时的人话解释(比如本人还没打开链接)
notifiedResult工行异步通知已到达时回显通知结果(1 通过 / 0 未通过),与主动查询互为印证

返回示例(成功)

{
  "code": "CYT_00000",
  "data": {
    "transNo": "CHECKIN20260923001",
    "passed": true,
    "authResult": "02",
    "authResultText": "认证成功",
    "notifiedResult": "1"
  }
}

异常与报错

情形含义与处理
查不到结果 / hint 提示尚未开始本人还没打开链接,或人脸、短信验证码两步没走完,稍后再查
passed=false 且 authResult=03工行判定认证失败,看 failReason;常见是人脸与公安基准照比对不通过、或短信验证码没完成

前端怎么用

const r = await post('/api/v1/rinv/face/status', { transNo });
if (r.data.passed) 打卡通过(); else 提示(r.data.hint || r.data.failReason);

本人还没打开链接、或人脸与短信两步没走完时,工行返回「查询结果为空」,平台会在 hint 里说明,不要当成失败。★结果通知:认证完成后工行把结果推给平台,平台再转发到你发起时传的 callbackUrl,报文形如 {transNo, outUserId, verifyResult, passed}(verifyResult:1 通过 / 0 未通过)。工行只往平台推,所以你不需要向工行报备出口 IP;没传 callbackUrl 就用本接口轮询,两种方式结果一致。

所有接口通用的报错(平台层)

HTTP / code含义与处理
400 · CYT_40001必填参数没传,data.hint 里写了缺哪个
401 · CYT_40100 / 40102缺鉴权头,或签名算错。签名 = sha256(appKey + 时间戳 + 报文原文 + appSecret),参与签名的报文必须与实际发送的逐字节一致
401 · CYT_40103时间戳与服务器相差超过 300 秒,校准本机时间后重试
403 · CYT_40301这把密钥的产品或渠道不对(工行接口需要「反向开票」产品 + 「工商银行」渠道)
429 · CYT_42901超过每分钟 120 次限流,稍后重试
502 · CYT_50200工行侧暂时不可达。注意工行测试环境每晚 19:00 后关闭、次日恢复,联调请排在工作时间
200 · data.mock=true尚未配置工行凭据,返回的是演示数据、并未真调工行