手机分期流程错误提示优化 — 迭代需求
目标:将手机分期 SA App 中面向现场人员的技术错误、无解释的禁用状态和状态不清晰页面,统一为可理解、可行动、可追踪的英文提示;补齐现有流程未覆盖的错误节点,并保证浅色/深色主题均清晰可读。
1. 背景与问题
现有 BNS 与 SA App 的异常链路存在以下问题:
- BNS 多处错误信息是技术 key 或数值码;SA App 网络层会将
message包装为Error.message,多页面再直接展示。因此OTP_INVALID、KYC_UPSTREAM_UNAVAILABLE、AUTH_LOGIN_LOCKED会直接出现在现场操作界面。 - 部分提交按钮只置灰,没有说明尚缺少什么。例如签名页在签名/勾选条件未满足时,
Submit Signature不可点击但缺少明确引导。 - 现有提示过于简单时,只告诉用户“失败”或一行技术码,没有说明当前发生了什么、能否重试、下一步该做什么。
- 成功、处理中、失败和不可操作状态的样式混用 Toast、顶部红条、字段红字和页面卡片;同一错误在不同页面的表现不稳定。
- 部分页面含深色信息卡,但未形成完整深色主题 token 与状态色规范;文本、分割线和次要字段在暗背景下存在可读性风险。
1.1 本期目标
- 对客界面只展示英文的稳定文案;禁止展示 BNS 技术 key、provider 原始
message/detail/description、堆栈或数值错误码。 - 每一条错误明确使用一种唯一展示样式和一个下一步动作。
- 可修正问题在字段附近说明原因;阻断、处理中、结果状态分别使用不同组件。
- 补齐 OTP、KYC、登录、资料、签约、付款、交机、IMEI、安装/激活及网络异常的缺失提示节点。
- 浅色和深色主题下满足状态辨识、文本对比度与按钮禁用态可理解性要求。
2. 范围
| 范围 | 是否纳入 | 说明 |
|---|---|---|
| SA App 手机分期全流程错误提示 | 是 | 登录、代客申请、KYC、签约、付款、交机、订单详情 |
| BNS 标准错误返回 | 是 | 输出稳定 code/message_key/presentation/action/retryable/trace_id |
| 现有技术码与原始上游信息拦截 | 是 | App 不得直接展示 Error.message |
| 深色主题状态色和组件规则 | 是 | 覆盖页面、卡片、字段、弹窗、Toast |
| 错误埋点与客服排查标识 | 是 | 仅记录标准码、界面、动作、重试次数和 trace_id |
3. 现网截图与问题证据
3.1 订单完成页:局部暗色卡与成功提示重复

- 当前问题:
Completed、Order Completed与正文重复;暗色卡中的次级字段和分割线需要按深色主题重新校验对比度。 - 优化:保留一个结果状态卡;订单摘要沿用中性卡片。深色主题开启时,整页切换为深色 token,不在浅色页面中孤立插入深色信息块。
3.2 签约页:禁用按钮无原因说明

- 当前问题:用户已经绘制签名,但
Submit Signature仍不可点击;页面没有说明是否还需要勾选协议或签名是否有效。 - 优化:按钮上方显示聚合校验提示,缺失项在对应控件下显示红字;用户完成最后一项后按钮立即可用。
3.3 OTP 页:技术错误码直接面向现场人员

- 当前问题:顶部红条直接展示
OTP_INVALID,无法指导用户检查验证码、重新获取或更换手机号。 - 优化英文:
The verification code is incorrect. Check the latest code and try again.
3.4 KYC 页:上游技术码直接展示

- 当前问题:字段下直接显示
KYC_UPSTREAM_UNAVAILABLE,用户不知道应等待还是重新输入身份号。 - 优化英文:
We cannot verify this ID right now. Please try again in a few minutes.
3.5 登录页:锁定状态没有处理路径

- 当前问题:顶部红条展示
AUTH_LOGIN_LOCKED,但用户不知道锁定原因、时长和可执行动作。 - 优化英文:
This account is temporarily locked for security. Reset your password or contact your supervisor.
4. 统一展示规则
4.1 错误输出契约
BNS 必须保留原始错误供日志和客服排查,但只向 SA App 返回标准字段:
{
"code": "OTP_INVALID",
"message_key": "otp.invalid",
"presentation": "E01_FIELD",
"primary_action": "RETRY",
"retryable": true,
"trace_id": "pb-20260814-001"
}code、message_key:系统契约字段,不直接显示。presentation:唯一的展示样式,由 App 的集中ErrorTranslator决定组件。primary_action:只返回预定义动作,例如RETRY、RESEND_OTP、OPEN_APPLICATION、CONTACT_SUPERVISOR、CHECK_STATUS。trace_id:用于客服和日志关联;不在普通对客正文展示,仅可在支持入口复制。- App 不得把 Axios 的
Error.message、BNSgetMsg()、provider 原始信息作为对客文案回退值。
4.2 唯一样式定义
| 样式 ID | 唯一适用场景 | 组件与行为 | 不可替代为 |
|---|---|---|---|
E01_FIELD | 单字段可修正错误 | 输入框红色边框 + 字段下英文说明;自动滚动至首个错误 | Toast / 弹窗 |
E02_BANNER | 多字段校验或页面提交前缺项 | 页面顶部停留式横幅 + 高亮缺失字段 | 仅禁用按钮 |
E03_RETRY | 网络、上游暂不可用、商品加载失败 | 页面内错误卡,提供一个 Try Again | 技术码 Toast |
E04_BLOCK | 账号锁定、权限/POS/订单状态冲突 | 强阻断弹窗或整页阻断卡,只提供一个明确下一步 | 可关闭后继续操作 |
E05_PENDING | 提交、支付、签约、交机、激活处理中 | 状态卡 + Check Status;禁止重复提交 | 失败页 / 重试创建 |
E06_STATUS | 审批、补件、完成、关闭、激活等终态 | 结果页状态卡,展示下一步或只读说明 | Toast |
Toast 仅可用于成功确认或不会影响当前操作的短提示,例如 Copied。失败、阻断和处理中状态不得只使用 Toast。
4.3 各提示样式参考图

上图是组件结构参考;PocketBuy 实施时沿用本需求第 7 节的浅色/深色主题 token 和状态色,不直接沿用图中的橙色品牌色或示例业务文案。每个页面只能按 presentation 选择其中一个组件:
E01_FIELD:红色字段边框、错误图标与字段下说明;用于用户可立即修正的单项输入。E02_BANNER:页面内停留式横幅,同时高亮所有缺失项;用于未提交前的多条件不满足。E03_RETRY:居中或页面内错误卡,包含原因、保留输入和一个Try Again。E04_BLOCK:遮罩下的强阻断弹窗/整页阻断卡;主操作只有一个,辅助联系入口只能为文字链接。E05_PENDING:非失败状态卡,展示当前处理说明与Check Status;不能提供会新建业务请求的Retry。E06_STATUS:终态结果卡,展示完成、补件、关闭或激活结果及唯一下一步。
5. 现有提示优化清单
以下英文为 SA/现场人员可见文案;系统码仅用于内部映射。
| 流程节点 | 内部系统码/现状 | 当前问题 | 对客英文文案 | 样式 | 用户动作 | 优先级 |
|---|---|---|---|---|---|---|
| 登录 | AUTH_LOGIN_LOCKED 直出 | 无锁定处理路径 | This account is temporarily locked for security. Reset your password or contact your supervisor. | E04_BLOCK | Reset Password 或 Contact Supervisor | P0 |
| 登录 | 登录失败仅通用提示 | 未区分凭据与网络 | The phone number or password is incorrect. Please check and try again. | E01_FIELD | 修改输入后重试 | P0 |
| OTP 验证 | OTP_INVALID 直出 | 技术码、无纠正提示 | The verification code is incorrect. Check the latest code and try again. | E01_FIELD | 修改 OTP | P0 |
| OTP 验证 | OTP 过期/次数过多缺少统一提示 | 容易重复输入旧码 | This code has expired. Request a new code and try again. / Too many attempts. Please wait before requesting a new code. | E04_BLOCK | Request New Code | P0 |
| KYC 身份号 | KYC_UPSTREAM_UNAVAILABLE 直出 | 用户无法判断是否为输入错误 | We cannot verify this ID right now. Please try again in a few minutes. | E03_RETRY | Try Again | P0 |
| KYC 身份号 | 格式不正确 | 仅技术或通用提示 | Enter a valid 11-digit BVN. / Enter a valid NIN. | E01_FIELD | 修改身份号 | P0 |
| 签约 | 提交按钮置灰但无原因 | 用户不清楚缺少签名或协议确认 | Complete the highlighted items before submitting your signature. | E02_BANNER | 完成签名/勾选协议 | P0 |
| 签约 | 提交超时 | 可能重复签约 | Your signature is being submitted. Do not submit again. Check the status in a moment. | E05_PENDING | Check Status | P0 |
| 订单详情 | 完成态重复文案 | 状态信息冗余 | Order completed. The device has been delivered and activated. | E06_STATUS | 只读 | P1 |
| 交机/IMEI | 格式、重复、未找到信息不一致 | 用户无法定位应修改哪一台设备 | Enter a valid 15-digit IMEI. / This IMEI is already linked to another order. Check the device and scan again. | E01_FIELD | 修改/重新扫描 IMEI | P0 |
| 交机 | 商户付款、锁机激活未满足 | 可能误以为可完成交机 | Delivery cannot be completed until merchant payment and phone lock activation are confirmed. | E04_BLOCK | Check Status | P0 |
5.1 签约页:禁用按钮说明话术与样式要求
签约页的禁用态是前置引导,不是提交失败。页面必须在 Submit Signature 上方保留一块动态说明区域;当用户已经完成部分操作时,不得以 Toast 或弹窗替代说明。
| 当前条件 | 按钮状态 | 对客英文话术 | 使用样式 | 页面行为 |
|---|---|---|---|---|
| 未签名,未勾选协议 | 禁用 | Add your signature and tick the agreement checkbox to continue. | E02_BANNER | 横幅说明两项;签名区与协议复选框均高亮 |
| 已签名,未勾选协议 | 禁用 | Tick the agreement checkbox to continue. | E01_FIELD | 仅协议复选框和文案使用错误态;点击复选框后立即恢复按钮 |
| 已勾选协议,未签名 | 禁用 | Add your signature to continue. | E01_FIELD | 仅签名区域显示错误边框和说明;完成签名后立即恢复按钮 |
| 签名数据无效或保存失败 | 可点击重试 | We could not save your signature. Please sign again and try again. | E03_RETRY | 保留协议勾选;清除无效签名;主操作为 Try Again |
| 已提交,结果未确认 | 禁用重复提交 | Your signature is being submitted. Do not submit again. | E05_PENDING | 主按钮替换为 loading;仅提供 Check Status,不再次创建签约请求 |
样式要求:
- 说明区域固定在主按钮上方,距按钮 12 px;不遮挡签名区和协议内容。
E02_BANNER使用带图标的浅黄色/深色主题对应警示表面,不把“尚未完成”渲染为红色失败;正文至少 14 sp,支持两行换行。E01_FIELD的签名区或复选框须使用 2 px 错误边框、错误图标和字段下英文说明;焦点态与错误态可同时识别。- 禁用按钮仍保留清晰文字;按钮、说明文字和背景对比度遵循第 7 节,且不以低透明度导致不可读。
- 每次签名笔画、清空签名、勾选/取消协议后即时重新校验;若只剩一个缺失项,聚合横幅切换为该字段的
E01_FIELD,不得同时显示两种提示。
5.2 登录密码错误:失败次数与锁定提示
代码当前规则为连续 5 次密码错误后锁定 15 分钟。为让 App 在锁定前给出明确预期,BNS 需要在 AUTH_INVALID_CREDENTIALS 返回 remaining_attempts,在 AUTH_LOGIN_LOCKED 返回 lock_seconds;具体时长由服务端返回,前端不可硬编码。
| 登录结果 | 对客英文话术 | 样式 | 前端行为 |
|---|---|---|---|
| 第 1–3 次失败 | The phone number or password is incorrect. {remaining_attempts} attempts remaining before this account is locked. | E01_FIELD | 密码框显示字段错误;保留手机号,清空密码;不可用 Toast 覆盖 |
| 第 4 次失败 | Incorrect password. 1 attempt remaining before this account is locked. | E02_BANNER | 密码框错误态 + 页面内警示横幅;登录按钮仍可点击 |
| 第 5 次失败/已锁定 | This account is locked for {lock_minutes} minutes after too many failed sign-in attempts. | E04_BLOCK | 隐藏或禁用登录动作;主按钮 Reset Password,辅助文字链接 Contact Supervisor |
| 锁定期间再次尝试 | This account is temporarily locked. Try again in {mm:ss}, reset your password, or contact your supervisor. | E04_BLOCK | 倒计时以服务端 lock_seconds 为准;不再递增失败次数 |
安全要求:不回显密码、不披露账号是否存在;失败次数、剩余次数和锁定倒计时只在提交当前手机号和密码后展示;登录成功后 BNS 清除该手机号的失败计数。
6. 补齐未覆盖的提示节点
| 流程 | 触发条件 | 对客英文文案 | 唯一样式 | 实现要求 | 优先级 |
|---|---|---|---|---|---|
| 申请前 | 当前客户已有进行中订单 | An application is already in progress. Open it to continue instead of creating another one. | E04_BLOCK | 后端按客户/渠道查询 active order;返回 order_id 和 OPEN_APPLICATION | P0 |
| 资料保存 | 网络失败但本地输入未提交 | We could not save your changes. Check your connection and try again. | E03_RETRY | 保留表单输入;不清空敏感字段;手动重试 | P0 |
| 产品加载 | 商品/POS/价格暂不可用 | We cannot load products right now. Please try again. | E03_RETRY | 不展示上游错误;支持刷新 | P0 |
| POS 授权 | SA 无权操作该 POS | This POS is not available for your account. Contact your supervisor. | E04_BLOCK | 禁止继续创建订单 | P0 |
| 文件上传校验 | 格式、大小或清晰度不符合要求 | Upload a clear JPG, PNG, or PDF file up to 10 MB. | E01_FIELD | 文件项下显示,不丢失其他已上传材料 | P1 |
| 文件上传传输 | 上传中断或服务不可用 | Upload failed. Keep this page open and try again. | E03_RETRY | 保留已成功上传材料;只重试失败文件 | P1 |
| 人脸活体 | 摄像头权限缺失 | Camera access is required to continue. Allow camera access in Settings. | E04_BLOCK | 跳转系统设置后回到当前步骤 | P1 |
| 风险审批 | 要求补件 | More information is required. Open the application to see the items to correct. | E06_STATUS | 返回补件清单;每项使用 E01_FIELD | P0 |
| 首付支付 | 支付结果未确认 | Payment is still being confirmed. Do not collect payment again. | E05_PENDING | 查询原 payment reference;禁止重新收款 | P0 |
| 交机/锁机 | 安装或激活中 | Phone lock activation is in progress. Check the status before completing delivery. | E05_PENDING | 前台可见时轮询;不重复创建安装任务 | P0 |
| 交机/锁机 | 服务状态未知 | Phone lock status is unavailable. Please try again before completing delivery. | E03_RETRY | 不允许完成交机;提供 Check Status | P0 |
| 任意提交 | 请求超时、结果未知 | We are checking your last request. Do not submit again. | E05_PENDING | 按幂等键查询既有结果,不能直接重试创建 | P0 |
6.1 与现有优化清单的去重结论
| 核对项 | 结论 | 保留方式 |
|---|---|---|
| 登录“密码错误”与“账号锁定” | 不重复 | 前者是可继续输入的 E01/E02 阶段,后者是第 5 次失败后的 E04 阻断阶段;本期已在 5.2 明确阈值与文案。 |
| 签约“禁用说明”与“签约提交中” | 不重复 | 前者为提交前条件缺失,后者为写请求已发起但结果未确认;分别使用 E01/E02 与 E05。 |
| KYC 上游暂不可用与产品/POS 暂不可用 | 不重复 | 都复用 E03_RETRY 组件,但前者发生在身份核验,后者发生在商品/授权加载,后端 message_key 和重试接口不同。 |
| 锁机状态未知与任意提交结果未知 | 不重复 | 前者是状态查询失败,可再次查询;后者是写操作超时,必须按幂等键查询旧请求,不能重新创建。 |
| 文件上传的校验错误与传输失败 | 原先合并导致一个条目对应两种样式,现已拆分 | 分别保留 E01_FIELD 和 E03_RETRY,每条错误只对应一种样式。 |
| “当前提示优化”与“补齐未覆盖节点” | 不重复 | 第 5 节只改造已在代码/截图中出现的提示;第 6 节定义当前没有清晰提示或没有稳定处理路径的节点。 |
7. 深色主题与可访问性
7.1 主题规则
- 页面只能完整使用
light或dark主题 token;禁止在浅色页面中孤立使用深色信息卡作为“强调”。 - 深色主题背景建议为
#121212,表面卡片为#1E1E1E,主文字为#F5F5F5,次级文字为#B8B8B8,分割线为#3A3A3A。 - 成功、警告、错误状态不得仅依赖绿色/橙色/红色;必须同时提供图标、标题与正文。
- 普通正文与背景对比度目标不低于 4.5:1;大号文本和图标不低于 3:1。开发和 QA 使用实际设备的深色模式复核。
- 深色主题下输入框默认边框、禁用按钮、错误边框和焦点边框必须有可见差异;不能只降低透明度。
7.2 禁用态规则
- 按钮禁用时,在按钮上方或相关字段下方说明未满足条件,而不是仅降低按钮透明度。
- 示例:
Submit Signature禁用时显示Tick the agreement checkbox to continue.;若无签名则显示Add your signature to continue. - 多个条件同时缺失时,使用
E02_BANNER聚合说明,并高亮所有对应字段。
8. 前后端实现要求
8.1 BNS
- 对每个 PocketBuy 业务异常返回全局唯一、稳定的
code与message_key;修复局部数值码冲突。 - provider 原始
code/message/detail/description只记录在日志、订单明细或客服后台,绝不直接透传 SA App。 - 所有写操作支持幂等键;超时或重复点击优先返回原请求的
PENDING/STATUS,不得创建重复申请、支付、签约或交机任务。 - 返回
trace_id并在 BNS、App、支付/锁机链路中贯通。
8.2 SA App
- 新建集中
ErrorTranslator:code/message_key -> title/body/presentation/primaryAction/retryPolicy;不得在页面内散落判断或直出error.message。 - 页面仅根据
presentation渲染六种组件之一;未知错误使用E03_RETRY,英文文案为Something went wrong. Please try again. - 字段错误自动定位到首个错误字段;网络/上游异常保留已输入数据;处理中禁用重复写操作。
- 支持系统主题切换,并为所有状态组件提供 light/dark token。
8.3 埋点与客服
记录 error_code、message_key、screen、action、presentation、retry_count、trace_id 和终态;不得记录 BVN/NIN、OTP、密码、完整手机号、完整 IMEI、银行卡或 provider token。