现金贷接入百度人脸采集与比对并完善采集数据落库 — 迭代需求
优先级:P1
状态:待评审
适用范围:现金贷 Android App 的注册建客、授信进件、人脸登录、重授信/提额及设备校验等现有人脸场景。
本期先在现金贷业务实现;手机分期、PocketBuy SA App、SA 入驻及签约合照不在本期范围。本文是独立增量需求,不改变
23-KYC Bypass中“Face Verification 仅作活人检测”的既有边界。
1. 背景与目标
现有现金贷 Android App 已在进入人脸页时向后端查询活体采集方式,并根据返回的 liveDetectionWay 进入 Google 或既有 Smileidentity 路径;现有代码在路由查询失败时会由客户端默认转为 Smileidentity。Google 采集 SDK 返回的数据尚未形成完整、统一、可追溯的服务端记录,人脸比对结果也缺少统一的供应商路由快照。
本期由后端统一控制 Google 与百度云人脸链路,不允许 App 自行默认供应商、随机分流或无记录切换。App 只上报设备能力并执行后端下发的路由决定。
本期新增百度人脸能力,目标如下:
- 在现金贷 Android App 集成百度人脸采集 SDK,由 App 完成现场照片采集和本地质量提示。
- 由服务端通过百度人脸 1:1 比对能力,将现场采集照片与本次 KYC 返回的客户证件人像进行比对。
- 百度 SDK 采集阶段产生的数据、百度人脸 1:1 比对请求/响应均完整落库;本期不调用在线图片活体 V3。
- 补齐现有 Google ML Kit 链路:ML Kit 实际返回给 App 的全部数据均上传服务端并落库,包括失败采集和重试过程数据。
- 建立统一供应商模型,使百度与 Google ML Kit 的采集结果可以按客户、业务申请、场景、采集会话和尝试次数追溯,但不把不同 SDK 的字段或分数强行等价。
- 由后端分别下发采集供应商和人脸比对供应商,路由结果在一次采集会话内固定,并完整保存命中规则、配置版本和降级关系。
- 优化人脸采集页面,放大现有固定
300dp × 300dp的人脸采集框,提升用户对齐面部的可见性和成功率。
2. 来源与能力映射
| 来源 | 对应产品能力 | 本期用途 | 边界 |
|---|---|---|---|
| 百度 Android 人脸采集 SDK | App 端人脸检测、质量检测、图片采集及动作活体能力 | 现金贷 Android App 现场采集、质量提示、生成待上传照片 | SDK 本地通过不等于服务端活体通过、身份相同或最终 KYC 通过 |
| 百度人脸 1:1 对比 V3 | 比对两张人脸图片并返回相似度得分和人脸标识 | 现场客户照片与 KYC/BVN/NIN 证件人像比对 | API Key、Secret Key、access token 只能保存在 crs 服务端,App 不得直调 |
| Google ML Kit Face Detection for Android | App 端人脸检测,按配置返回检测框、角度、关键点、轮廓、分类概率和跟踪标识 | 保留为现有采集供应商,并补齐全部实际返回数据的落库 | ML Kit 不做人脸身份识别,也不输出完整活体结论 |
百度官方人脸 1:1 对比 V3 当前返回相似度 score,官方示例建议阈值为 80;本期不得在 App 内写死 80。实际通过阈值由风险配置中心按产品、场景、供应商和版本配置,并固化到每次比对快照。
3. 本期范围与非范围
| 能力 | 本期处理 | 不处理 |
|---|---|---|
| Android SDK | 现金贷 App 新增百度 SDK;保留 Google ML Kit;记录实际 SDK、版本、模型和配置 | iOS、手机分期、PocketBuy SA App、SA 入驻流程 |
| 客户现场采集 | 仅允许实时相机采集,记录成功、失败、取消和重试 | 从相册选择、复用本地历史照片 |
| 在线图片活体 V3 | 本期不接入;不发起 /face/v3/faceverify,不建设调用路由或阈值配置 | 把本地动作完成或单一分数直接认定为最终 KYC 通过 |
| 人脸比对 | crs 调百度人脸 1:1 对比;现场照对比本次 KYC 证件人像 | App 直调百度 API;1:N 搜索;建设百度人脸库 |
| 数据落库 | 百度采集、百度人脸 1:1 比对、现有 ML Kit 采集的实际返回数据全部落库 | 将每一帧原始相机画面长期保存;在业务库保存图片 Base64、密钥或 access token |
| 路由 | 后端分别控制采集供应商和比对供应商;支持按产品、App 版本、场景、设备能力、灰度规则及供应商健康状态配置 | App 自行随机选择供应商、沿用本地上次供应商或失败后无记录地静默切换 |
| 页面交互 | 放大 Google 与百度共用的人脸采集框,保持检测区域、遮罩和引导一致 | 重做现金贷进件页面、修改其他资料采集步骤 |
4. 责任边界与调用链
| 系统 | 责任 |
|---|---|
| 现金贷 Android App | 上报设备/SDK能力;获取相机权限;执行后端路由;初始化指定采集 SDK;现场采集;序列化 SDK 实际返回的全部字段;上传采集照片和 SDK 结果;展示服务端返回的稳定结果 |
| BNS | 生成采集及比对路由;创建并绑定业务申请/客户/场景的采集会话;校验 route_decision_id、供应商、幂等和业务态;调用 crs;向 App 屏蔽供应商原始错误和内部阈值 |
| CRS | 统一封装百度人脸 1:1 比对;管理服务端凭证;保存三方请求/响应;输出标准化比对结果;支持查询原请求 |
| 文件服务 | 加密保存采集照片和 KYC 证件人像,返回不可猜测的文件引用;控制访问、保留期和删除审计 |
| 风险配置/审批 | 管理供应商路由、人脸比对阈值、失败处置和人工复核规则;消费结果但不修改供应商原始数据 |
4.1 现有链路与改造边界
本期沿用“进入人脸页前查询后端路由”的入口,扩展为 Google/百度双路由,并作如下改造:
- 新增百度兼容枚举
liveDetectionBaidu;liveDetectionGoogle保持不变,避免影响已上线版本。 - App 提交
/apply/faceDetection时必须携带route_decision_id。BNS 以服务端路由记录为准,校验 App 实际使用的采集供应商、场景和会话;比对供应商只从服务端路由记录读取。客户端传值只能用于一致性校验,不能覆盖后端路由。 - 对不支持百度 SDK 的旧 App 版本,后端不得下发百度;版本兼容规则由后端维护,不依赖 App 忽略未知枚举。
4.2 后端路由规则
路由分为两个独立维度,均由后端决定并固化:
| 路由维度 | 枚举 | 说明 |
|---|---|---|
capture_provider | GOOGLE_ML_KIT / BAIDU_SDK | 决定 App 使用哪个 SDK 完成人脸检测和照片采集 |
match_provider | EXISTING_CRS / BAIDU_CLOUD | 决定服务端使用既有人脸比对链路或百度人脸 1:1 对比;App 不直接感知供应商凭证 |
本期至少支持以下组合:
route_code | 采集 | 人脸比对 | 用途 |
|---|---|---|---|
GOOGLE_EXISTING | Google ML Kit | 沿用现有 CRS 比对链路;实际供应商及 real-call 状态必须落路由快照 | 保留现有主链路并补齐数据落库 |
BAIDU_CAPTURE_MATCH | 百度 SDK | 百度 1:1 比对 V3;不调用在线图片活体 V3 | 百度新接入链路 |
路由决策顺序:
- 校验业务线、场景、App 版本、Android 版本、CPU/ABI、包名/签名和 SDK 可用能力,先排除设备不兼容供应商。
- 应用运营强制配置和灰度名单;命中强制配置时记录规则 ID,不再由客户端二次判断。
- 在可用候选中结合供应商开关、授权有效期、余额/配额、成功率、超时率和熔断状态选择路由。
- 均未命中时使用后端配置的默认路由;默认路由也不可用时返回
FACE_ROUTE_UNAVAILABLE,不得放行或使用客户端默认值。 - Google 审核账号白名单不属于供应商路由,具体规则见第 4.3 节。它不能命中或覆盖 Google/百度的真实调用结果,更不得伪装为供应商成功。
路由在同一 capture_session_id + scene 内保持粘性。刷新页面、App 重启或重复查询在路由未过期且未熔断时返回同一 route_decision_id;确需降级时,由后端创建新的路由决定和新的 attempt_id,通过 fallback_from_route_decision_id/fallback_from_attempt_id 关联,不覆盖原记录。
路由接口响应及对应的服务端路由记录至少包含:
4.3 Google 审核账号白名单规则
4.3.1 现状代码与改造目标
现有后端以 google.reviewer.uid 的逗号分隔 UID 配置、忽略大小写方式判断审核账号。命中后当前代码会出现以下行为:首借跳过绑卡校验;人脸增强不执行;人脸记录直接被写为 faceStatus=S、resCode=0000、resMessage=False Successful;部分个人信息/KYC 分支直接置 bvnMatch=true,并绕过外部账户核验。这些行为是审核便利的临时实现,不是 Google、百度或其他供应商的真实核验结果。
本期将该临时配置替换为后端统一的审核账号白名单豁免规则。白名单仅允许 Google Play 审核所需的、时间受限的页面流程验证;它不是客户白名单、风控放行名单,也不是供应商路由条件。
4.3.2 白名单数据、权限与有效期
| 字段 | 规则 |
|---|---|
reviewer_rule_id | 后端生成的不可变规则 ID;所有豁免记录必须引用此 ID |
auth_subject | 以服务端认证主体的规范化 UID 精确匹配;不得从客户端请求体取 UID,不允许模糊、前后缀或通配符匹配 |
app_package/signature/channel | 必填,限定审核使用的正式包名、签名和 Google Play 渠道;不匹配时不命中 |
environment/product/scenes | 必填,限定环境、现金贷产品与允许场景;默认不跨产品、不跨国家、不跨环境 |
bypass_scopes | 显式枚举,见下表;禁止 ALL/* 或未定义 scope |
effective_from/effective_to | 必填;单次最长 30 个自然日,到期自动失效;不得创建永久白名单 |
status/approval_ticket | PENDING/ACTIVE/REVOKED/EXPIRED;仅双人审批后可 ACTIVE,撤销即时生效 |
| 审计字段 | 创建人、审批人、原因、Google Play 审核关联、创建/修改/撤销时间;审计日志中只记录规则 ID 和 UID 哈希,不输出完整白名单 |
白名单的创建、续期、撤销必须由受限后台权限完成;应用配置 google.reviewer.uid 仅可作为一次性迁移数据源,迁移完成后不得再由业务代码直接读取或打印完整 UID 列表。
4.3.3 允许的豁免范围
| Scope | 可做的事 | 结果记录与限制 |
|---|---|---|
FACE_COMPARE_BYPASS | 在照片、SDK 原始数据和采集质量结果都已保存后,跳过外部人脸比对调用 | face_verification_result.decision=BYPASSED、decision_reason_code=GOOGLE_REVIEWER_WHITELIST;不得写成 PASSED、不得伪造分数或供应商请求 ID |
BANK_CARD_CHECK_BYPASS | 仅跳过当前首借流程的绑卡校验入口 | 记录 bypassed_check=BANK_CARD_CHECK;不得创建、绑定、扣款或使用真实银行卡 |
ACCOUNT_KYC_MATCH_BYPASS | 仅跳过审核演示所需的账户/KYC 匹配阻断 | 记录 BYPASSED,不得写 bvnMatch=true、不得覆盖真实外部核验结果 |
不允许配置或隐含以下能力:实际放款、授信审批通过、真实还款扣款、客户身份认证通过、账户所有权通过、设备反欺诈通过、OTP/登录绕过、风险规则绕过或数据删除绕过。审核账号只能进入受控 Review Mode;若进入资金、合同、放款或真实支付动作,服务端必须拒绝并记录 REVIEWER_FINANCIAL_ACTION_FORBIDDEN。
4.3.4 执行规则
- BNS 在认证完成后,以服务端
auth_subject查询当前有效规则;App 不接收白名单状态,也不能传入“我是审核账号”标志。 - 白名单判断发生在供应商路由之后、每一项可豁免校验之前;路由仍按第 4.2 节执行,采集页面、SDK 初始化、照片上传、SDK 数据落库和本地质量校验均不可跳过。
- 实际执行的
route_decision_id、reviewer_rule_id、命中 scope、被跳过的校验、操作者 UID 哈希、客户端版本、场景与时间必须写入一次不可修改的审核记录。 - 对不在白名单、过期、被撤销、包名/签名/渠道不匹配、scope 不匹配或规则数据不完整的请求,按普通客户路径执行;不得因白名单查询异常而放行。
- 供应商请求已发起后,不得以白名单结果取消或覆盖其真实结果;白名单只决定是否在发起前跳过明确批准的外部调用。
- 当前代码中“直接建客”“写
False Successful”“强制bvnMatch=true”的分支必须迁移为BYPASSED审计态;正常结果表、供应商原始响应和风险判断不得出现伪造成功。 - 任何白名单命中都不重置人脸次数、路由失败次数或风控计数;审核用途的重试另以
reviewer_rule_id + scene限流并记录。
sequenceDiagram participant U as "现金贷客户" participant APP as "现金贷 Android App" participant BNS as "BNS" participant FS as "文件服务" participant CRS as "CRS" participant BD as "百度人脸服务" APP->>BNS: 查询路由(deviceCapability, appVersion, scene) BNS-->>APP: routeDecisionId, captureProvider, configVersion U->>APP: 现场完成人脸采集 APP->>APP: 百度 SDK 或 ML Kit 检测并生成完整 SDK 结果 APP->>FS: 加密上传最终候选照片 FS-->>APP: selfieImageRef APP->>BNS: routeDecisionId + SDK结果批次 + selfieImageRef BNS->>BNS: 校验路由、会话、场景与提交供应商一致 BNS->>CRS: 按matchProvider执行人脸比对 alt BAIDU_CAPTURE_MATCH CRS->>BD: 现场照与 KYC 证件人像 face/v3/match BD-->>CRS: 原始响应 + score + face_token else GOOGLE_EXISTING CRS->>CRS: 执行既有人脸比对链路并记录实际供应商/real-call end CRS-->>BNS: 标准化结果 + providerRequestId BNS-->>APP: PASSED / FAILED / REVIEW / UNKNOWN
5. App 端需求
5.1 SDK 路由与初始化
- App 进入采集页前调用后端路由接口,服务端返回
route_decision_id、capture_session_id、capture_provider=BAIDU_SDK/GOOGLE_ML_KIT、provider_config_version和允许使用的能力配置;match_provider由后端路由记录持有,App 不参与选择。 - App 必须按返回值初始化对应 SDK,并记录 SDK 版本、模型交付方式/版本、初始化耗时、初始化结果码和错误信息。
- 百度 SDK 的授权文件需与正式包名、正式签名匹配;测试授权不得进入生产包。授权文件可以随包交付,但百度云服务的 API Key、Secret Key、access token 不得进入 App、移动端日志或埋点。
- Google ML Kit 继续使用现有集成方式。本期“全部落库”是保存当前配置下 SDK 实际产生/返回 的全部字段,不要求仅为增加字段而开启轮廓、关键点、分类或跟踪能力;如后续启用新能力,其新增返回字段必须自动进入原始数据落库。
- SDK 初始化失败时,App 先上报本次失败并携带
route_decision_id。只有后端重新返回新的路由决定时才能进入备用供应商;新尝试必须有新的attempt_id,并通过fallback_from_attempt_id关联原失败记录,不得覆盖或伪装成同一次采集。 - App 不得根据 Google Play Services 是否可用、百度 SDK 初始化结果、网络情况或本地缓存自行改写后端路由;这些信息只能上报后端参与下一次决策。
5.2 现场采集与交互
- 仅允许实时相机采集,不提供相册、文件选择器或历史照片入口。
- App 展示单人正脸、光线、距离、遮挡和姿态提示;SDK 未检测到人脸、检测到多张人脸或质量不合格时提示重拍。
- 相机权限拒绝、用户拍摄前退出、SDK 初始化失败、照片上传失败均需落采集结果,但不计入服务端活体/人脸比对次数。
- 只有最终候选照片上传成功且 SDK 数据批次被 BNS 接收后,才允许发起服务端人脸比对。
- 页面不得展示百度/Google 原始错误、内部活体分、人脸相似度或风控阈值;仅展示服务端稳定文案和是否可以重试。
5.3 人脸采集框放大
现有现金贷人脸页 activity_google_face_detect.xml 中示例图 iv_face_id 与实际检测视图 face_detect 均为固定 300dp × 300dp。本期 Google 与百度采集页面共用统一的大尺寸采集区域,具体要求如下:
- 采集框保持居中,宽高一致。目标尺寸为
min(屏幕可用宽度 - 24dp, 360dp);左右安全边距各不少于12dp。 - 屏幕可用宽度允许时,采集框不得小于
330dp × 330dp,相较现有300dp至少放大 10%;小屏设备无法满足时按可用宽度自适应,不得横向裁切或超出安全区。 - 示例图、相机预览、遮罩镂空区、人脸引导框及 SDK 实际检测/裁剪坐标必须使用同一尺寸和坐标变换;不得只放大视觉图片而保留原
300dp检测区域。 - Google 与百度页面的可见采集框尺寸、中心点和边距保持一致,切换供应商时用户不感知布局跳变。
- 放大后继续展示标题、操作提示、光线/防抖/单人/无遮挡提示和开始按钮;在 320dp 宽小屏、常见 360/390/411dp 宽设备及大字体模式下不得重叠、截断或遮挡主按钮,可通过纵向滚动访问全部内容。
- 状态提示显示在采集框上方或下方,不覆盖眼睛、鼻子和嘴部核心区域;提示内容继续使用稳定对客文案,不展示供应商名称、分数或内部阈值。
- 横竖屏策略沿用现金贷 App 现状;若页面固定竖屏,旋转设备后仍保持竖屏布局和正确的相机旋转补偿。
采集框放大只调整页面引导和可视采集区域,不降低单人脸、完整度、姿态、亮度、模糊度、遮挡或活体阈值,也不改变最终图片输出分辨率要求。
5.4 Google ML Kit 全量返回数据
对 App 实际交给 ML Kit 处理的每个分析事件,需序列化并上传以下内容;字段未启用、SDK 返回 null 或字段在当前版本不存在时,需保留“未启用/未返回/不适用”的可区分状态,不得用 0 或空字符串伪造:
| 分类 | 必须保存的数据 |
|---|---|
| SDK 与配置 | SDK 版本、bundled/unbundled 模型方式、模型可用状态、performance/landmark/contour/classification 模式、minFaceSize、tracking 是否启用 |
| 输入信息 | 分析序号、客户端时间、图片宽高、旋转角、图像格式、镜头方向;禁止将整帧 Base64 放入业务库 |
| 调用结果 | 成功/失败、耗时、异常类型、SDK 错误码/规范化错误信息、返回人脸数量 |
| 每张人脸 | boundingBox、Head Euler X/Y/Z(SDK 实际提供项)、全部 landmarks 及坐标、全部 contours 及点集、smiling probability、左右眼睁开 probability、tracking ID |
| 业务派生值 | 是否主脸、是否贴边、脸部占比、单人脸校验结果、姿态/眼睛/质量规则结果、选中作为最终照片的原因和规则版本 |
| 原始结果 | App 统一序列化后的 raw_sdk_payload、序列化协议版本、字段存在性信息;不得仅保存业务派生的 pass/fail |
5.5 百度 SDK 全量返回数据
百度 SDK 需按实际采购版本和 Demo/交付包定义生成字段字典,并对每次检测/采集回调完整序列化。最低必须包含:
| 分类 | 必须保存的数据 |
|---|---|
| SDK 与授权 | SDK/算法模型版本、授权类型、授权到期日、初始化结果码与结果信息;不得保存授权文件明文或密钥 |
| 采集配置 | 检测、质量、动作活体、角度、光照、人脸大小等所有实际配置项及配置版本 |
| 输入信息 | 分析序号、客户端时间、图片宽高、旋转角、图像格式、镜头方向 |
| 检测/质量结果 | SDK 回调提供的人脸数量、位置/角度/关键点/质量项、当前动作及动作结果、活体结果、采集状态、耗时、错误码和错误信息 |
| 照片信息 | 最终候选照片引用、文件哈希、格式、宽高、字节数、拍摄时间;图片二进制仅进入加密文件服务 |
| 原始结果 | SDK 回调全部原始字段的 raw_sdk_payload、回调名称、回调序号、序列化协议版本和字段存在性信息 |
若百度实际交付 SDK 的字段与公开文档不同,以交付包接口为准:新增或未知字段先完整进入 raw_sdk_payload,再通过映射版本补充标准字段,不得因后端 DTO 未定义而丢弃整批数据。
6. 百度人脸 1:1 比对
本期不调用 /face/v3/faceverify;以下仅定义百度人脸 1:1 对比 V3 的服务端调用及数据留存。
- 超时、响应缺字段、响应无法解析或供应商未知错误统一输出
UNKNOWN,不得按通过处理。
6.1 人脸 1:1 比对
- 比对图片 A 为本次有效采集会话的客户现场照,
face_type=LIVE;图片 B 为本次 KYC/BVN/NIN 核验返回并已保存的客户证件人像,按真实来源设置IDCARD/CERT等类型,不得一律写成生活照。 - KYC 证件人像缺失、已失效、客户/业务申请不一致或文件不可读取时,不得调用百度;返回
FACE_REFERENCE_IMAGE_UNAVAILABLE,保留当前申请状态并按风险规则转重试/补件/人工复核。 - CRS 调用
POST /rest/2.0/face/v3/match;请求图片可使用 Base64 或已取得的合法FACE_TOKEN,但 API Key、Secret Key 和 access token 只在 CRS 内部管理。 - 保存请求参数中的
image_type、face_type、quality_control、liveness_control、spoofing_control、实际阈值和配置版本;保存响应中的score、两张图片对应的face_token、供应商请求标识、原始错误码/信息和完整原始响应。 - 标准化结果仅允许为
PASSED、FAILED、REVIEW、UNKNOWN。HTTP 200、有face_token或score非空均不能单独代表通过;必须由风险配置对score及质量/活体/合成图控制结果共同决策。 - 同一
attempt_id重复提交时返回原结果;超时或结果未知时先按供应商请求标识查询/确认原请求,不得直接新建第二次计费调用。
7. 数据落库设计
7.1 数据模型
| 表/实体 | 关键字段 | 说明 |
|---|---|---|
face_capture_session | capture_session_id、uid、cust_id、application_id、business_key、scene、route_decision_id、capture_provider、match_provider、sdk_version、provider_config_version、status、started_at、completed_at | 一次现金贷人脸采集会话;建客前允许 cust_id/application_id 为空,以 uid + business_key + scene 关联;后续补齐但不得覆盖供应商和配置 |
face_capture_attempt | attempt_id、capture_session_id、attempt_no、fallback_from_attempt_id、result、error_code、client_started_at、server_received_at | 每次采集/重试记录,成功和失败都保存 |
face_route_decision | route_decision_id、capture_session_id、route_code、capture_provider、match_provider、matched_rule_id、rule_version、capability_snapshot_json、health_snapshot_json、fallback_from_route_decision_id、expires_at | 后端路由审计记录;保存命中规则和当时的兼容/健康判断,不保存密钥 |
reviewer_bypass_rule | reviewer_rule_id、auth_subject_hash、app_package、signature_sha256、channel、environment、product_code、scene_scope、bypass_scopes、effective_from/to、status、approval_ticket | Google 审核账号白名单规则;UID 明文不得出现在普通日志或客户端 |
reviewer_bypass_audit | audit_id、reviewer_rule_id、route_decision_id、attempt_id、auth_subject_hash、scene、bypassed_check、decision、reason_code、app_version、created_at | 每次命中或拒绝命中均记录;decision 只能为 BYPASSED/DENIED,不能伪造 PASSED |
face_sdk_event | event_id、attempt_id、event_seq、callback_name、face_index、input_metadata_json、normalized_result_json、raw_sdk_payload、payload_schema_version、client_occurred_at | 保存 Google ML Kit 或百度 SDK 每次实际分析/回调结果;attempt_id + event_seq 唯一 |
face_image_asset | image_ref、attempt_id、image_role、sha256、format、width、height、byte_size、captured_at、storage_status | 业务库只保存加密文件引用和元数据;image_role 至少支持 LIVE_SELFIE/KYC_REFERENCE |
face_provider_request | provider_request_id、attempt_id、capability、provider、request_snapshot_json、raw_response_json、provider_error_code、provider_error_message、duration_ms、requested_at、responded_at | 本期 capability 为 FACE_MATCH;请求快照必须移除图片 Base64 和凭证 |
face_verification_result | verification_id、attempt_id、match_score、match_threshold、decision、decision_reason_code、rule_version、valid_until | 供 BNS、风险和审批消费的标准结果;不得覆盖三方原始记录 |
7.2 “全部落库”的统一口径
- “全部”指 SDK/API 在当前版本、当前配置下实际向我方返回的所有字段,以及本次调用使用的完整非敏感配置;不要求保存 SDK 内部未暴露数据。
- 原始数据与标准字段双写:
raw_sdk_payload/raw_response_json用于无损追溯,标准字段用于检索、规则和报表。字段映射升级只能新增映射版本,不得回写或覆盖原始数据。 - SDK 没有原生 JSON 时,App 使用统一序列化协议将对象的所有公开返回属性转换为 JSON,并写入
payload_schema_version;数组、关键点和轮廓不得截断。 - 失败、空结果、取消、权限拒绝、初始化失败、质量失败、上传失败、供应商失败和超时均需落库;不得只保存最终成功记录。
- App 按
attempt_id + event_seq批量补传,BNS 幂等入库。网络中断后恢复上传时,不得因重复上报产生重复事件。 - App 不得仅依赖本地缓存作为最终记录;服务端确认数据批次和照片均接收成功后,才能清理本次临时数据。
- 数据库 JSON 字段需支持字段新增,禁止以固定 DTO 反序列化后丢弃未知字段再保存。
7.3 图片与敏感数据安全
- 人脸照片、关键点、轮廓、概率、face token、比对分数均按生物识别敏感数据管理;传输使用 TLS,文件和数据库敏感列加密,访问遵循最小权限并记录审计。
- 图片二进制/Base64 不进入业务表、普通日志、埋点、告警或客服页面;业务库只保存文件引用、哈希和必要元数据。
- API Key、Secret Key、access token、授权文件内容不得落入上述业务表或原始响应字段;入库前执行字段级脱敏与凭证扫描。
- 日志仅允许记录
capture_session_id/attempt_id/provider_request_id、稳定错误码和耗时,不记录客户完整身份号、图片地址、face token、关键点或分数。 - 保留期限、删除/匿名化期限和有权查看角色沿用已审批的 KYC 生物识别数据制度;若当前制度未明确,上线前必须由法务/安全/数据负责人给出配置并完成删除任务验证,不得默认永久保存。
8. 状态、错误与重试
| 场景 | 稳定错误码 | 处理 |
|---|---|---|
| 相机权限未授权 | FACE_CAMERA_PERMISSION_DENIED | 停留当前页并引导系统设置;保存失败尝试,不计在线调用次数 |
| SDK 初始化/授权失败 | FACE_SDK_INIT_FAILED | 保存 provider、SDK 版本、原始结果;按服务端降级配置决定是否新建备用尝试 |
| 未检测到人脸/多张人脸 | FACE_NOT_FOUND/FACE_MULTIPLE_FOUND | 提示重新现场采集,不调用在线服务 |
| SDK 质量不合格 | FACE_CAPTURE_QUALITY_FAILED | 展示针对性提示;保存全部质量字段,不调用在线服务 |
| 照片上传失败 | FACE_IMAGE_UPLOAD_FAILED | 保留本地临时记录并支持补传,不计在线调用次数 |
| KYC 证件人像不可用 | FACE_REFERENCE_IMAGE_UNAVAILABLE | 不调用百度,按风险规则补件/人审 |
| 人脸比对低于阈值 | FACE_MATCH_FAILED | 保存分数、阈值和响应;阻断或转人工复核 |
| 百度超时/结果不完整 | FACE_PROVIDER_RESULT_UNKNOWN | 状态置 UNKNOWN,查询原请求,不自动通过、不直接重复调用 |
| SDK 数据落库不完整 | FACE_SDK_DATA_INCOMPLETE | 当前尝试不得标记完成;App 补传或重新采集 |
| 审核白名单未命中/过期/撤销 | REVIEWER_BYPASS_NOT_ALLOWED | 按普通客户路径继续;不因查询失败放行 |
| 审核账号试图执行资金动作 | REVIEWER_FINANCIAL_ACTION_FORBIDDEN | 拒绝授信通过、合同、放款、真实扣款等动作并写审计 |
重试次数由现金贷后端按 uid/cust_id + business_key + scene 统一控制:仅 SDK 本地质量失败或未成功发起 CRS 人脸比对调用不计入次数;一旦供应商已受理,无论通过、失败或超时均计入,除非供应商明确未受理且未计费。切换 Google/百度、刷新页面、清理 App 数据或重新登录不得重置服务端计数。
9. 配置、监控与审计
| 配置项 | 规则 |
|---|---|
face_capture_provider | BAIDU_SDK/GOOGLE_ML_KIT;按现金贷产品、场景、App 版本、设备能力和灰度人群配置 |
face_match_provider | EXISTING_CRS/BAIDU_CLOUD;与采集路由组合由后端决定,不得由 App 改写 |
face_route_default | 后端默认完整路由 GOOGLE_EXISTING/BAIDU_CAPTURE_MATCH;默认路由不可用时失败关闭 |
face_route_rule_version | 每次路由决定固化命中规则版本,配置变更不回写历史记录 |
match_threshold | 服务端配置、版本化、按尝试固化;App 不持有最终阈值 |
match_quality_control/match_liveness_control/match_spoofing_control | 百度 1:1 比对请求的可选控制参数;如启用须随请求快照固化,不代表接入在线图片活体 V3 |
provider_fallback_enabled | 默认 false;开启时必须定义可降级错误白名单和关联新尝试规则 |
至少监控以下指标:按 SDK/版本/App 版本拆分的初始化成功率、采集成功率、质量失败率、上传成功率、SDK 数据完整率;百度 1:1 比对调用量、成功率、失败原因、UNKNOWN 率、耗时和余额/配额;Google 与百度的字段缺失率和原始数据入库失败率。
白名单需单独监控:有效规则数量、即将到期规则、每个规则/场景的命中量、各 bypass_scope 的调用量、被拒绝命中量、审核账号资金动作拦截量及异常高频重试。任何在生产环境新增/续期/撤销规则、命中未批准 scope、规则有效期异常或审核账号触发资金动作均须告警。
供应商路由、阈值、降级规则、数据查看、人工结果处置和数据删除均需记录操作者、时间、变更前后值、原因和关联工单。
10. 验收标准
- 现金贷 App 配置为百度时,能完成 SDK 初始化、现场照片采集、照片上传及服务端人脸 1:1 比对,App 内不包含百度云服务密钥。
- 百度采集成功、质量失败、动作失败、用户取消、权限拒绝、初始化失败和重试均能按会话与尝试查询到完整 SDK 原始字段及标准字段。
- 百度人脸比对记录可追溯到客户、业务申请、场景、采集会话、现场照片引用、KYC 证件人像引用、请求配置、原始响应、
score、实际阈值、规则版本和最终标准结果。 - 配置为 Google ML Kit 时,不改变现有采集主流程;SDK 当前实际返回的检测框、角度、关键点、轮廓、分类概率、tracking ID 等均按启用状态无损落库,失败和空结果也可查询。
- 未知 SDK/API 字段可以进入原始 JSON,不会被后端 DTO 丢弃;数组和点集不截断;原始记录不可被后续映射或重试覆盖。
- 图片 Base64、API 密钥、access token 不出现在业务表、普通日志、埋点和告警中;图片只以加密文件引用关联。
- KYC 证件人像缺失、供应商超时、响应缺字段、数据批次未落全时均不能得到
PASSED,也不会直接创建重复计费调用。 - 同一批次重复上传不产生重复事件;同一人脸比对请求重复提交返回原结果;供应商切换时新旧尝试均保留且关联可查。
- 监控可按百度/Google、SDK 版本、App 版本和场景查看采集漏斗、数据完整率、错误分布和百度服务耗时/成功率。
- 上线前完成百度正式授权、生产配额、阈值 UAT、典型 Android 机型兼容性、弱网补传、数据删除和降级回滚演练。
- 后端可按现金贷产品、场景、App 版本、设备能力和灰度规则分别下发
GOOGLE_EXISTING、BAIDU_CAPTURE_MATCH;同一有效会话重复查询保持路由一致。 - 路由查询失败、未知枚举或默认路由不可用时,新版 App 不再自动进入 Smileidentity、Google 或百度,且不能继续提交人脸成功结果。
- App 伪造/篡改
capture_provider、尝试指定match_provider或使用过期route_decision_id时,BNS 拒绝请求并保存审计记录。 - 后端触发供应商降级时,原路由、原尝试、新路由和新尝试均可关联查询,不覆盖失败记录且不重置服务端次数。
- 常见 360/390/411dp 宽设备上人脸采集框至少为
330dp × 330dp,Google/百度的示例图、预览、遮罩及检测坐标完全对齐;320dp 小屏和大字体模式无横向溢出、元素遮挡或主按钮不可达。 - 百度
BAIDU_CAPTURE_MATCH现金贷 KYC 路由中,仅在最终候选照片与 SDK 数据均已接收后调用/face/v3/match;可追溯比对请求、原始响应、score、实际阈值和路由版本,且无任何/face/v3/faceverify出站调用。 - 白名单仅能由已审批、未过期、包名/签名/Google Play 渠道/场景均匹配的服务端认证主体命中;App 不能查询、传入或篡改命中结果。
- 白名单命中后,采集、SDK 数据落库和本地质量校验仍执行;被豁免的校验记录为
BYPASSED + GOOGLE_REVIEWER_WHITELIST,不产生PASSED、伪造分数、False Successful或bvnMatch=true。 - 白名单账号尝试进入授信通过、合同、放款、真实绑卡/扣款等资金动作时,服务端阻断并生成审计与告警。
11. 上线前待确认项
以下事项不阻塞需求评审,但必须在开发联调或上线前闭环:
- 百度实际采购/交付的 Android SDK 产品包、版本、授权方式及完整回调字段清单。
- 人脸比对的正式阈值、
quality_control/liveness_control/spoofing_control级别及低分转人工区间。 - 现金贷 Android App 当前 Google 采集库的准确产品/版本(现有代码命名包含
firebaseFace,需确认是否已迁移为 Google ML Kit)、bundled/unbundled 模式及已启用的 landmark/contour/classification/tracking 配置。 - KYC 证件人像的权威来源、文件有效期、
face_type映射和无照片时的业务处置。 - 生物识别数据的正式保留期限、可查看角色、删除/匿名化策略及审批依据。
GOOGLE_EXISTING当前 CRS 实际比对供应商、real-call在各环境的配置及生产验收方式;不得以桩返回的matched=true/similarity=100作为真实联调通过。- Google Play 审核所需的精确页面范围,以及是否确实需要
BANK_CARD_CHECK_BYPASS、ACCOUNT_KYC_MATCH_BYPASS;未获明确审批的 scope 不创建。