
一、背景近期在做发票查验相关系统升级时发现新版 XXX税查验流程相比旧版本发生了明显变化。除了查验入口、验证码形式、参数结构有所调整外返回数据也变得更加完整包含查验结果、发票状态、购销方信息、明细项目、附加标签等多层级结构。为了适配新版查验流程我完成了一套新版发票查验能力的工程化改造主要包括新版验证码识别能力建设验证码样本训练与合成新旧版本查验流程兼容协议流程分析与适配返回结果标准化 JSON 输出单线程与多线程调用统一接入本文只介绍整体思路和落地效果不涉及具体接口细节、请求参数、加密逻辑、模型结构和绕过实现。二、目标本次改造的目标不是简单替换一个接口而是让系统具备完整的新版本适配能力。主要目标如下支持新版 XXX税查验流程。支持新版验证码的自动识别。支持按颜色提示提取对应字符。支持旧版与新版通过配置切换。支持单线程和多线程统一调用。返回结果改为标准 JSON 对象而不是字符串嵌套字符串。尽量降低 CPU 和内存占用保证服务稳定运行。三、整体流程新版查验流程可以抽象为以下几个阶段输入发票信息 ↓ 判断新旧版本 ↓ 获取查验区域与访问入口 ↓ 获取验证码 ↓ 识别指定颜色字符 ↓ 提交查验请求 ↓ 解析查验结果 ↓ 输出标准 JSON在工程实现上新版逻辑没有直接替换旧版而是通过配置项进行切换。这样可以在生产环境中逐步灰度不影响旧流程稳定性。四、新版验证码识别能力新版验证码相比旧版更复杂不再只是简单字符识别而是同时涉及字符识别颜色识别位置识别有效字符判断按提示颜色筛选字符例如查验流程中可能出现类似提示请输入红色字符 请输入黄色字符 请输入蓝色字符 请输入黑色字符因此模型不能只输出完整字符串还需要知道每个字符对应的颜色。最终识别流程可以理解为验证码图片 ↓ 模型识别每个位置的字符 ↓ 模型识别每个位置的颜色 ↓ 根据提示颜色筛选字符 ↓ 输出最终验证码这种方式相比传统单一 OCR 更适合新版验证码场景。五、训练与样本合成思路为了提升验证码识别稳定性我对样本构建做了专门处理。整体思路包括构建字符与颜色联合标注数据。对不同颜色、字体、位置、干扰样式进行覆盖。通过合成样本补充低频字符和低频颜色组合。训练时同时关注字符准确率和颜色准确率。推理时只保留业务需要的目标颜色字符。这里不展开具体训练脚本、模型结构和样本生成规则只说明最终目标让模型不仅知道“是什么字符”还知道“这个字符是什么颜色”。六、协议适配思路新版 XXX税查验流程与旧版本相比主要变化体现在查验入口选择逻辑不同。验证码获取方式不同。验证码提示字段存在变化。查验提交参数结构不同。返回数据结构更加复杂。返回结果中包含更多电子发票扩展信息。在适配时我没有把新版逻辑硬编码到旧流程里而是保留了版本判断new 0 走旧版流程 new 1 走新版流程这样单线程和多线程都可以根据配置自动选择对应流程。七、返回结果标准化新版查验成功后原始返回数据是一个多层 JSON。最开始如果直接把返回字符串塞进data字段会出现这种情况{ code: 7, msg: 请求成功, data: {\Response\:{\RequestId\:\...\}} }这种格式不利于前端或调用方解析因为data实际上是一个 JSON 字符串。优化后返回结果改为标准嵌套 JSON{ code: 7, msg: 请求成功, useTime: 478, data: { Response: { RequestId: ********, Data: { reCode: 00, CyjgDm: 7, CyjgMsg: 经查验发票信息一致, Cycs: 4, Cysj1: 2026-07-23 10:21:52, DzfpFpxxVO: { Fphm: ********, Kprq: 2025-12-29 12:45:57, Xsfmc: ********, Gmfmc: ********, Jshj: 160, Hjje: 150.94, Hjse: 9.06, MxzbList: [ { Xmmc: 餐饮服务, Je: 150.94, Se: 9.06, Slv: 0.060000 } ] } } } } }这样调用方可以直接访问data.Response.Data.CyjgMsg data.Response.Data.DzfpFpxxVO.Jshj data.Response.Data.DzfpFpxxVO.MxzbList不需要再做二次反序列化。八、关键返回字段说明常见字段含义如下字段含义code系统返回码msg系统返回消息useTime请求耗时单位毫秒RequestId本次查验请求流水号reCode接口处理结果码CyjgDm查验结果代码CyjgMsg查验结果描述Cycs查验次数Cysj1查验时间FpztDm发票状态代码DzfpFpxxVO电子发票主体信息Fphm发票号码Kprq开票日期Xsfmc销售方名称Gmfmc购买方名称Jshj价税合计Hjje合计金额Hjse合计税额MxzbList发票明细列表九、工程化处理为了让这套能力能够稳定运行我在工程层面重点处理了几件事模型本地化部署避免运行时依赖外部路径。验证码识别类独立封装方便服务层调用。控制模型推理并发避免 CPU 突然拉满。图片尺寸统一预处理减少不必要的缩放开销。新旧版本通过配置切换不影响原有流程。单线程和多线程调用路径保持一致。返回数据统一 JSON 化降低调用方解析成本。十、效果目前新版流程已经可以完成完整闭环获取验证码 识别指定颜色字符 提交查验 解析返回结果 输出标准 JSON一次成功查验的耗时示例约为useTime: 478ms实际耗时会受到网络环境、代理质量、服务响应速度、机器性能等因素影响。十一、总结这次新版 XXX税发票查验适配核心并不是某一个单点功能而是把验证码识别、协议适配、结果解析和工程稳定性整合到一起。最终实现了新版验证码自动识别颜色字符筛选新版查验流程适配标准 JSON 返回新旧版本兼容服务端批量调用支持后续还可以继续优化的方向包括提升复杂验证码场景下的识别稳定性增加更多异常返回码的归类对查验结果字段进行业务级结构化封装增加调用耗时、识别准确率、失败原因的监控统计本文仅作为项目实践记录所有能力均应在授权、合规、合法的业务场景中使用。