前端对接开票
供应商上传发票校验
上传接口新增 uploadType:图片/PDF 走 OCR 抬头硬校验,二维码取票链接校验税务局域名;含报错文案速查与二维码解析前端职责
Markdown 原文(给 AI 用):https://doc.xfun.fun/supplier-invoice-upload-api.md
总览:改了什么
- 还是原来的上传接口
POST /invoice/task/upload,新增一个入参uploadType,前端改动很小。 - 图片/PDF 上传(原流程):后端会对发票做 OCR 识别,抬头与申请单不一致直接拦截,报错文案透出给供应商。数电票原生 PDF 也支持,直接传 PDF 的 OSS 地址即可。
- 新增二维码上传:供应商开完数电票后拿到的「扫码下载发票」二维码,前端解析出二维码里的链接后传给后端,后端校验链接是否为税务局域名。
- 金额、税号、重复上传均 不拦截,只拦抬头(产品拍板口径)。
- 「已开票」状态重新上传发票时,同样会过这套校验。
两种上传方式与前端职责
方式一:发票图片 / PDF(uploadType=1,或不传)
- 前端把发票文件(jpg/png/PDF)上传 OSS 拿到 URL,作为
invoiceUrl提交 —— 与现状完全一致。 - 后端 OCR 识别票面抬头(购买方名称),与申请单抬头比对,不一致返回报错。
注意
PDF 注意: OSS 上传时必须保留 .pdf 扩展名(后端按 URL 后缀区分 PDF 与图片识别通道)。如果上传组件会改文件名,确认生成的 URL 以 .pdf 结尾。
方式二:发票二维码(uploadType=2) 新增
- 供应商在税务 App 开票成功后有「扫码下载发票」二维码(往往是截图保存)。
- 前端负责解析二维码拿到其中的链接文本:拍照/相册选图后用二维码解码(小程序可用
wx.scanCode扫码,或选图后走解码库),把解析出来的 URL 字符串作为invoiceUrl提交。 - 后端只校验该链接是不是税务局域名(规则见下),不做 OCR。
说明
常见误区: uploadType=2 时 invoiceUrl 传的是 二维码内容里解析出的取票链接(https://…chinatax.gov.cn/…),不是二维码截图的 OSS 图片地址。传成图片地址会报「取票链接无效」。
接口定义
POST/invoice/task/upload入参变更
上传发票(原接口)。鉴权、Header 与现状一致。
请求参数
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
id | Long | 必填 | 开票申请单 ID |
invoiceUrl | String | 必填 | uploadType=1:发票图片/PDF 的 OSS 地址;uploadType=2:二维码解析出的税务局取票链接 |
uploadType | Integer | 可选 | 新增 1 = 发票图片/PDF(默认,不传按 1 处理);2 = 发票二维码取票链接 |
请求示例:图片 / PDF
{
"id": 123,
"invoiceUrl": "https://image-bulky.xunmengvip.com/supplier/invoice/dzfp_2611xxxx.pdf",
"uploadType": 1
}请求示例:二维码取票链接
{
"id": 123,
"invoiceUrl": "https://dppt.yunnan.chinatax.gov.cn/invoice-query/invoice-download?xxx",
"uploadType": 2
}响应
{ "code": 0, "msg": "success", "data": true }校验不通过时 code != 0,msg 为面向供应商的完整文案,直接 toast 展示即可,无需按 code 分支。
报错文案速查
| msg 文案 | 触发场景 | 前端处理建议 |
|---|---|---|
| 发票抬头“××”与申请单抬头“××”不一致,请核对后重新开具 | OCR 识别出的购买方名称与申请单抬头不一致(动态文案,含两边抬头) | toast / 弹窗展示,引导重新开票 |
| 发票识别失败,请确认图片清晰完整后重试 | 传的图不是发票(如二维码截图误走图片通道)、图片模糊不完整 | toast,引导重新拍摄/上传 |
| 发票识别失败,请稍后重试 | OCR 服务临时异常 | toast,可重试同一文件 |
| 取票链接无效,请上传税务局开具的取票二维码 | uploadType=2 且链接不是税务局域名(或误传了图片地址) | toast,检查是否解析对了二维码内容 |
| 当前状态不支持上传发票 | 申请单状态既非待开票/逾期,也非已完成重传 | toast 并刷新列表 |
| 申请单不存在 | id 错误或不属于当前供应商 | toast 并刷新列表 |
校验规则细节
抬头比对(uploadType=1)
- 比对前做归一化:忽略所有空白字符、全角括号()与半角括号 () 视为相同,其余必须完全一致。
- 例:申请单抬头「云南甲花卉(集团)有限公司」,票面「云南甲花卉(集团) 有限公司」→ 通过;票面「云南乙花卉有限公司」→ 拦截。
取票链接域名(uploadType=2)
- 必须是 https,且 host 为
chinatax.gov.cn或其子域(可带端口)。 - 合法:
https://inv-veri.chinatax.gov.cn/xxx、https://dppt.yunnan.chinatax.gov.cn:8443/xxx - 非法:
https://chinatax.gov.cn.evil.com/x、https://evil.com/chinatax.gov.cn、http://…(非 https)、OSS 图片地址
联调注意
- 测试环境已部署本功能;图片 OCR 校验由后端开关控制(
xm.invoice.ocr-check-enabled),联调前和后端确认测试环境开关已打开。二维码域名校验 不走开关,恒生效。 - OCR 校验对真实「电子发票(普通发票) PDF」已实测通过;测试时请用真实票面文件,随便找张图会命中「发票识别失败」。
- 上传方式的选择建议做成两个入口(对应原型「上传发票图片 / 上传发票二维码」),分别固定 uploadType=1 / 2。