②之二 建收款人档案(入驻第二步)
散户刷脸通过之后必须再做这一步:把散户的姓名、身份证、收款银行卡报给工行,在回收企业名下建成「收款人」。★刷脸只是实名认证,不等于已入驻 —— 不做这一步,工行侧根本没有这个收方,后面开票会被退回。数据类接口。
属「工商银行 · 业务型接口」——底层编排 乐企直联原子接口,你只调这一个。
接口(数据类)
POST https://openapi.kailingteck.com/api/v1/rinv/seller/register
鉴权:X-App-Key + X-Timestamp + X-Sign(= sha256(appKey + 时间戳 + 报文 + appSecret))。
请求参数
| 字段 | 必填 | 大白话说明 |
|---|---|---|
userId | 必填 | 散户ID,必须与②发起扫脸时传的同一个 |
name | 必填 | ★收款人姓名。必须与身份证、银行卡户名三者完全一致,对不上工行会返「姓名和身份证信息不匹配」 |
idNo | 必填 | 身份证号 |
phone | 必填 | 散户手机号 |
bankCard | 必填 | 散户收款的银行卡号。受理成功后平台会记住它,「③查散户状态」查入驻结果要用 |
isIcbcCard | 必填 | 是不是工行卡:true=工行卡 / false=其他银行卡 |
accountCode | 选填 | 与 isIcbcCard 等价的工行原字段:1=工行卡 / 0=非工行卡,传了直接透传给工行;与 isIcbcCard 同时传时以 isIcbcCard 为准 |
bankName | 非工行卡必填 | 开户行名称,如「中国建设银行重庆巴南支行」 |
bankCode | 非工行卡必填 | 开户行联行号(12 位) |
idStartDate | 必填 | 身份证签发日期,格式 yyyy-MM-dd |
idEndDate | 必填 | 身份证截止日期 yyyy-MM-dd;永久有效填 9999-12-30 |
occupation | 散户无工行账户时必填 | 职业代码:1公务员/2事业单位/3公司员工/4军警/5工人/6农民/7管理/8技术/9私营业主/10文体明星/11自由职业/12学生/13无职业/14其他/15退休 |
address | 散户无工行账户时必填 | 常用住址,不少于 4 个汉字 |
vendorId | 选填 | 企业子商户编号。不传自动取后台「工行参数」里为贵司配置的值 |
businessType | 选填 | 业务类型。不传自动取后台配置(默认 0006 开票业务)。★0004 再生资源、0005 农产品收购 这两个取值会被工行以「平台商户未开启智慧清分」拒掉,0006 不受此限 |
请求示例
{
"userId": "NP333",
"name": "唐雪妮",
"idNo": "500113199301287129",
"phone": "18523176826",
"bankCard": "6212260200000000000",
"isIcbcCard": true,
"idStartDate": "2015-06-18",
"idEndDate": "2035-06-18",
"occupation": "6",
"address": "重庆市巴南区龙洲湾街道"
}返回
所有接口都用同一层信封:code/msg/requestId/timestamp/data。业务字段都在 data 里,下表列的就是 data 的内容。code 为 CYT_00000 表示调用成功。
返回参数(data)
| 字段 | 大白话说明 |
|---|---|
accepted | ★先看这个:true=工行已受理建档申请(含「工行侧本来就有档案」的情况);false=没受理,看 reason |
alreadyExists | true=工行侧本来就有这个收方(已入驻或审核中),本次已自动补录平台侧档案映射。对历史/旁路建档的散户重放本接口即可对齐数据,幂等、无副作用 |
userId | 回显你传的散户ID |
autoAudited | true=工行自动审核已通过;false=还要工行分行人工审核 |
applyTime | 申请入驻时间 |
auditTime | 审核通过时间(还没审就没有) |
reason | accepted=false 时才有,工行给的原始说法 |
hint | 下一步该干什么 |
raw | 工行原始返回,排查时看这个 |
返回示例(成功)
{
"code": "CYT_00000",
"msg": "success",
"data": {
"userId": "NP333",
"accepted": true,
"autoAudited": false,
"applyTime": "2026-09-15 17:20:31",
"hint": "已受理,等工行审核。用 ③ 查散户状态轮询 onboarded 字段",
"mock": false
}
}返回示例(失败 / 业务拦截)
// 姓名与身份证对不上(最常见)
{
"code": "CYT_00000",
"msg": "success",
"data": {
"userId": "NP333",
"accepted": false,
"reason": "30601019#&姓名和身份证信息不匹配",
"raw": { "return_code": "30601019" }
}
}异常与报错
| 情形 | 含义与处理 |
|---|---|
| 30601019 姓名和身份证信息不匹配 | ★姓名、身份证号、银行卡户名三者必须完全一致。测试时用假身份证必然报这个 |
| 30601008 / 30601009 / 30601013 已入驻或审批中 | ★不算失败:接口已幂等化,这三种情况返回 accepted=true + alreadyExists=true,并自动补录平台侧档案映射(编号↔卡号)。对已在工行建档的散户重放本接口,即可让平台与工行数据对齐 |
| 30601004 平台商户未开启智慧清分 | 业务类型传成了 0004 或 0005。本场景用 0006,不传即默认 0006 |
| 30601001 入参有误,必输项为空 | 缺必填项。重点查 appIdSub(企业子商户编号)有没有配、bankName/bankCode 非工行卡时有没有传 |
| 缺少 name / idNo / bankCard | 返回 400 CYT_40001,data.hint 写了缺哪个 |
| 非工行卡没传开户行 | 返回 400,非工行卡必须同时传 bankName 与 bankCode;工行卡请传 isIcbcCard=true |
前端怎么用
const r = await post('/api/v1/rinv/seller/register', body);
if (!r.data.accepted) return alert(r.data.reason); // 没受理,按 reason 让用户改
// 受理了 → 轮询 ③ 查散户状态,直到 onboarded 变成 true★这一步和②发起扫脸是两件事,都要做,顺序是先②刷脸、再②之二建档。刷脸解决「这个人是不是本人」,建档解决「工行认不认这个收款人、钱往哪张卡打」。只做②不做②之二,工行侧不存在这个收方,④开票会被退回。建档提交后不是立刻生效,要工行审核,用 ③ 查散户状态 轮询 onboarded 字段。平台会自动补齐 appId、appIdSub、accountKind=02 个人、receiverType=03 自然人、idType=0 身份证、以及审核结果通知地址,这些不用你传。
所有接口通用的报错(平台层)
| 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 | 尚未配置工行凭据,返回的是演示数据、并未真调工行 |
