Z Zise Developers
账户中心 › 指南

换一条链接给终端用户,他在我方的屏上填十五个字段、传证件照片 —— 数据不经过你。

L1 实名:托管屏与资料清单

你要做的只有一步


POST /v1/kyc/sessions
x-on-behalf-of:    <external_member_id>
x-idempotency-key: <UUID>

拿回 201


{
  "hosted_url": "https://api.ziseinfotest.com/hosted/kyc/kyc_352ffcf7efe94531b3da9f902f2e4348",
  "expires_at": "2026-08-14T15:47:53.000Z"
}

x-idempotency-key 是必填的(所有写端点都是)。漏了直接 400

idempotency_key_required —— 这是你在这条线上会遇到的第一个错误。

expires_atISO8601 字符串,不是 unix 秒。

把这条链接交给终端用户(App 内嵌 WebView、短信、邮件都行)。剩下的事在我方的页面上发生。

这张票绑三样

绑什么少了会怎样
会员你能拿 A 的链接给 B 建档
商户一张票被另一个商户拿去消费
24 小时 + 一次性链接躺在聊天记录里被转发重用

⚠ 有效期是 24 小时,不是 5 分钟。它要经你转交给终端用户、

他再去翻证件、拍照片。但别指望它更久 —— 拿到这条 URL 的人

就能以那个会员的名义提交一份实名档案。过期了补发一次即可。

终端用户在那一屏上填什么

十五个文本 / 选择字段(全部必填)

字段类型备注
first_name / last_name文本 ≤60
sex选择male | female
birth_date日期有年龄窗口,见下
nationality文本 2 位国家码
occupation文本 ≤60
phone_zone_number文本 ≤6区号
phone电话 ≤20
identity_type选择id_card | passport | resident_card | drivers_license
identity_number文本 ≤60我方不校验号码格式 —— 各国规则不一,误拦的代价大于放过
cardholder_residence选择chinese-mainland | chinese-mainland-residents-living-overseas | overseas-countries —— 见下面那条警告
address_province / address_city文本 ≤60
address文本 ≤160
street_number文本 ≤40

邮箱是预填的、不可改 —— 审核结果会发到会员建档时那个邮箱。

证件号与邮箱都会跨人查重,撞了是提交期 400

kyc_identity_taken / kyc_email_taken),没有人工通道

且你这一侧收不到任何信号。成因与预防见

KYC 概览那一节。

年龄窗口默认是 18–65 岁(后台可配)。超出直接拒,

而这个上限不在任何出参里 —— 你没有办法提前判断。

66 岁以上的用户会填完 15 个字段、传完三张证件照才在提交那一刻被挡住。

面向年长用户的产品请在引导文案里先说。

chinese-mainland 目前会被拒(「暂不支持中国大陆居民注册」),

手机号那一侧也拒中国大陆号码。这是一个后台开关

allow_mainland),不是永久规则 —— 所以选项还在表里。

你的用户引导里最好提前说清楚,别让他填完十五个字段才被挡。

三张照片

表单名必填
证件正面photo_front
证件背面photo_back否 —— 护照只有信息页
手持证件自拍photo_handheld

back 在页面上不标必填,但非护照证件实际要求有背面 ——

判据在服务端,页面不重复判一遍(那会变成第二个事实源)。

单张 ≤ 8 MB。我方按魔数嗅探真实类型,不信客户端声明的Content-Type。影像直传我方私有存储,只有本人与审核员读得回来。

⚠ 按居住地类型,审核时可能追加要求居留许可文件 ——

那走补件,不在首次表单里。

表单填完之后,数据怎么提交?

不经过你。这一步你什么都不用做。

那张页面是我方渲染的,它的 <form> 指向的就是 hosted_url 本身


<form method="post"
      action="/hosted/kyc/kyc_352ffcf7…"
      enctype="multipart/form-data">

终端用户点「提交」→ 浏览器把 15 个文本字段与照片以multipart/form-data 同源 POST 回我方(照片的表单名是photo_front / photo_back / photo_handheld)。

⚠⚠ 这正是托管屏存在的全部理由:证件影像与证件号从头到尾没有经过

你的服务器、你的日志、你的 CDN、你的错误上报。

你手上永远只有一条 URL 和一个后来的审核结论。

所以不要去找「提交资料」的 API —— 没有那个端点,也不该有。

提交之后会发生什么

结果页面票据
校验通过「已提交」终止页此时才被消费
校验失败原样回填文本、显示错误、可以直接重填仍然有效

⚠ 校验失败不会烧掉这张票 —— 否则用户填错一个字就得回来找你重开链接。

照片必须重选:浏览器不允许回填 file 控件,页面上那句提示说的就是这件事。

提交成功之后再调 POST /v1/kyc/sessions,会拿到400 state_invalid(这个会员已经有一份在途/已通过的档案了)。

会员的 kyc_level 不会当场变

提交只是把资料交上来,审核是异步的。在结论出来之前GET /v1/members/{id}kyc_level 仍然是 0。别把「提交成功」当成「实名通过」去放行业务 —— 等kyc.result.updated

你实际能看到什么

⚠⚠ 先说这一条,因为它决定你的状态机怎么写。

GET /v1/kyc 的出参只有四个字段,status 只有三档

status什么时候
approvedlevel ≥ 1
pending有一份档案在审
rejected被驳回了,且名下没有在审的档案
none从没提交过

pending 优先于 rejected 驳回之后重新提交的人名下同时有两行,

而他此刻的真实状态是「在审」—— 别再催他一次。

⚠ 拿到 rejected 就该引导用户重新走一遍:调 POST /v1/kyc/sessions

换一条新链接(没有「改几个字段再提交」那种能力,见下)。

fail_reason(驳回原因)开放 API 一律不下发。 事件体的红线是

只带 ID 与状态。别去找这个字段,也别在界面上承诺给用户看原因。

我方内部的五档你拿不到

UNREVIEWED / APPROVED / REJECTED / SUPPLEMENT_REQUIRED / SUPPLEMENT_SUBMITTED我方内部的流转,写在这里只是为了让你理解事件为什么会来好几次。

⚠ 照它们写 switch (status) { case "APPROVED": … } 的话,

一个分支都不会命中,且零报错 —— 事件正常到达、签名正确、你回 2xx。

表现是「用户实名通过了,但我们系统里一直是待审」。

事件不是每一次流转都发

kyc.result.updated 只在两种时刻发

不发的两处:

流转后果
用户提交完 L1(→ 待审)没有「他交了」这条事件 —— 要知道就轮询 GET /v1/kycpending
用户交完补件(→ 待复审)同上,没有事件

⚠ 把「收到事件」当成推进自己状态机的唯一触发,这两档会永久卡住,

而你排查时会先怀疑自己的 webhook 端点。

被驳回之后怎么办

没有「回到上一份档案改几个字段」这种能力(那条路要会员自己的登录态,而经 POST /v1/members 建的会员拿的是随机占位密码,登不进我方 App)。

开放 API 上唯一的路是:重新调 POST /v1/kyc/sessions 换一条新链接

⚠ 新链接打开的是一张空表单 —— 上一次填的内容不会回填。

界面上要提前告诉用户「需要重新填一遍」。

相关端点