消费前一卡通单人信息校验设计

目标

消费模式第一次完整读卡成功后,不再使用读卡器返回的卡状态判断消费资格。终端必须先按读卡账号向一卡通服务器查询单人信息,以服务端返回的卡号、卡状态、卡序号和姓名形成权威人员快照;只有服务端状态为 1 时,零元核验或正金额扣款才能继续。

范围

不修改业务订单查询协议、一卡通扣款算法和既有服务端上报字段契约;没有明确协议字段时,不向现有上报接口擅自增加姓名。

方案选择

采用“交易执行器前置校验门禁”方案:在读卡器串行交易流程中,把服务端单人查询放在首次完整读卡与零元分支/扣款分支之间,并通过独立网关和解析器隔离网络及字段规则。

未采用 Activity 普通异步回调方案,因为页面回调与扣款线程分离后容易出现查询尚未结束而交易继续的竞态;未采用本地人员快照替代方案,因为本地快照可能关闭、过期或尚未同步,不能满足消费前实时校验要求。

组件职责

单人信息模型与解析

新增只表达服务端权威人员字段的模型,包含账号、卡号、卡序号、状态和姓名。解析器从 SOAP 响应读取 CUSTOMERID、CARDNO、CARDSN、STATUS、NAME。

服务端查询网关

查询网关冻结本次交易使用的一卡通服务器地址和 AppID,直接发起 GetInfoByCustID,不额外调用 GetCustomerCount。网络异常、SOAP Fault、查无人员、账号不一致和字段解析失败统一转换为“人员卡信息同步失败”。

卡片权威信息合并

UID、账号、钱包余额、消费计数和原始响应继续来源于读卡器;卡号、卡序号、卡状态和姓名由服务端覆盖,原始读卡值保留为诊断字段。正金额订单第二次读卡提供最新余额和计数,并在 UID、账号未变化后继承服务端身份字段。

状态规则

消费资格只使用服务端状态。异常状态发生在扣款前,因此保留当前订单;移卡后允许换卡重试。

查询失败与人工重试

  1. 结束本次扣款前尝试,不执行成功反馈、扣款、消费后读卡或一卡通流水上传。
  2. 保存失败结果和错误分类,并展示“同步人员卡信息失败”确认弹框。
  3. 确认后对当前订单和当前卡片重新执行首次完整读卡及单人查询;成功后才继续交易。
  4. 取消后关闭弹框,保留订单并等待移卡;移卡后可重新放卡处理。
  5. 不执行无限自动重试。

页面、日志与数据库

并发与生命周期

测试

验收标准

  1. 服务端查询完成前没有任何扣款指令。
  2. 服务端状态只有 1 能继续,其他状态均在扣款前拦截。
  3. 查询失败弹出“同步人员卡信息失败”;确认可重试,取消后移卡可重新处理。
  4. 卡号、卡序号、状态和姓名来自服务端单人信息。
  5. 页面、流程日志和本地快照记录服务端姓名,前后快照身份一致。
  6. 失败、异常状态、重复确认和页面退出不会导致重复扣款。
  7. 单元测试和 Debug 构建通过;现场补充真实 SOAP 与真机扣款验收。