适用场景:为什么需要结构化提取发票数据
在二手车交易、财务报销、税务核算等业务中,机动车销售发票是关键原始凭证。传统人工录入不仅耗时,还容易因笔误导致数据差异。通过API将发票图片转化为结构化JSON,可以直接对接OA、ERP或税务系统,减少人工核对环节。典型的应用场景包括:
- 二手车交易核验:自动读取车辆VIN码、车辆型号和查看文档方信息,辅助真实性核验。
- 企业财务报销自动化:OCR结果直接填入报销单金额、税额、开票日期等字段。
- 税务核对:将价税合计、税率与申报系统比对,提升抵扣效率。
接口能力边界
调用前需要明确当前API能做什么、不能做什么:
- 支持的图片格式:jpg / png,单张文件大小不超过10 MB。
- 传输方式:支持通过公网图片URL传输,或使用Base64编码后的图片数据。
- 返回字段:最多可提取20个结构化字段,包括发票代码、发票号码、开票日期、查看文档方/销售方名称及识别号、车辆类型、VIN码、价税合计、税率等。
- 注意事项:发票需要平整、拍摄清晰、无遮挡;过长的连拍或严重倾斜的图片可能影响识别准确率。
- QPS限制:每秒最多2次请求,超出后可能会收到限流响应(以实际返回码为准)。
参数与鉴权
Header参数
每个POST请求必须携带以下Header:
| 参数名 | 是否必须 | 类型 | 说明 |
|---|---|---|---|
| Authorization | 是 | string | 格式为Bearer <你的API Key>,用于身份验证。 |
| Content-Type | 否 | string | 请求体格式,通常为application/json;不设置时默认也可能被接受。 |
API Key 一般需要从服务商的管理后台获取,请妥善保管,避免泄露到公共代码仓库中。
请求体参数
请求体为一个JSON对象,包含两个必填字段:
{ "input_type": "url", "input_data": "https://example.com/vehicle-invoice.jpg" }| 字段名 | 类型 | 必填 | 说明 |
|---|---|---|---|
input_type | string | 是 | 图片传输方式:url表示公网图片地址,base64表示图片的Base64编码。 |
input_data | string | 是 | 当input_type=url时,填写图片的 http/https 链接;当input_type=base64时,填写Base64字符串(可含data:image/xxx;base64,前缀,也可不含)。 |
注意:如果使用
base64方式,建议将图片大小控制在8MB以内(编码后约10.6MB),避免请求体过大导致的超时或截断。
最小可运行 curl 示例
下面提供一个可直接复制的curl命令。请将YOUR_API_KEY替换为你自己的真实API Key,并将图片URL替换为你想要测试的发票图片链接。
curl -sS \ -X POST \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "input_type": "url", "input_data": "https://example.com/vehicle-invoice.jpg" }' \ "https://v1.apizero.cn/api/ocr-vehicle-invoice"如果图片上传到公网不方便,也可以使用Base64方式:
# 先对本地图片做Base64编码(假设图片为 test.jpg) # Linux/macOS: IMAGE_BASE64=$(base64 -w0 test.jpg) # Windows (PowerShell): # $imageBase64 = [Convert]::ToBase64String([IO.File]::ReadAllBytes("test.jpg")) curl -sS \ -X POST \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d "{ \"input_type\": \"base64\", \"input_data\": \"$IMAGE_BASE64\" }" \ "https://v1.apizero.cn/api/ocr-vehicle-invoice"建议:首次测试尽量使用一张清晰、发票区域占比大的JPEG图片,URL方式出错概率低;待确认脚本流程正确后,再切换到Base64方式以便集成到后端代码中。
返回值逐字段解读
成功时API返回如下结构的JSON(已格式化):
{ "code": 0, "data": { "buyer_id": "", "buyer_name": "张三", "certificate_num": "LSXXXXXXXXXXXXX", "date": "2024年01月15日", "invoice_code": "31100000000", "invoice_num": "12345678", "machine_num": "499098765432", "price": "156055.05", "print_code": "", "print_num": "", "product_model": "丰田/CAMRY", "saler_addr": "上海市XX路XX号 021-XXXXXXXX", "saler_id": "91310000XXXXXXXXXX", "saler_name": "XX汽车销售有限公司", "tax": "13944.95", "tax_rate": "9%", "total_price": "壹拾柒万元整", "total_price_little": "170000.00", "vehicle_type": "小型轿车", "vin": "4A123456" }, "msg": "成功", "request_id": "req_abc123" }顶层字段说明
| 字段名 | 类型 | 含义 |
|---|---|---|
code | number | 业务状态码:0表示请求成功并识别完成;非零值表示异常。 |
msg | string | 业务提示信息,通常为“成功”或错误描述。 |
data | object | 识别结果的核心数据对象。 |
request_id | string | 本次请求的唯一标识,可用于排查日志。 |
data 对象各字段速览
| 字段名 | 类型 | 对应发票区域 | 说明 |
|---|---|---|---|
invoice_code | string | 发票代码 | 如果未能识别,可能为空字符串""。 |
invoice_num | string | 发票号码 | —— |
date | string | 开票日期 | 示例格式2024年01月15日。 |
buyer_name | string | 查看文档方名称 | —— |
buyer_id | string | 查看文档方识别号 | 企业为统一社会信用代码,个人可能为空。 |
saler_name | string | 销售方名称 | —— |
saler_id | string | 销售方识别号 | —— |
saler_addr | string | 销售方地址及电话 | 包含地址+电话,部分发票可能只有地址。 |
vehicle_type | string | 车辆类型 | 如“小型轿车”。 |
product_model | string | 厂牌型号 | 品牌/型号信息。 |
vin | string | 车辆识别代号/车架号 | —— |
certificate_num | string | 合格证号 | —— |
machine_num | string | 机器编号 | —— |
price | string | 不含税价 | 数值字符串,如156055.05。 |
tax | string | 增值税额 | —— |
tax_rate | string | 增值税税率 | 含百分号,如9%。 |
total_price | string | 价税合计(大写) | 中文大写。 |
total_price_little | string | 价税合计(小写) | 数值字符串,如170000.00。 |
print_code | string | 打印在发票上的代码 | 部分省份不呈现此字段,可能返回空。 |
print_num | string | 打印在发票上的号码 | 同上。 |
注意:当
code != 0时,data可能缺失或为null,此时应以msg中的文字提示为准。
常见错误排查
1. 400 Bad Request
- 可能原因:请求体格式不正确,如JSON语法错误、图片URL不是有效格式。
- 检查方法:使用
jq .验证JSON是否合法;确保URL可公网访问,且以http://或https://开头。
2. 401 Unauthorized
- 可能原因:
AuthorizationHeader 格式错误或API Key无效。 - 检查方法:确认前缀为
Bearer(注意空格);测试Key是否已过期;检查是否误将Key放入请求体。
3. 413 Request Entity Too Large
- 可能原因:Base64后的图片数据超过服务端限制。
- 检查方法:将图片压缩至8MB以内,或改用URL方式传输。
4. 非200状态码
- 500:服务端内部错误,可重试或稍后调用。
- 503:服务暂不可用,常见于QPS超限或临时维护。
5. 返回code != 0的常见情况
- 识别失败:图片不清晰、发票倾斜严重、背景杂乱等。建议重新拍照并保证发票占据画面60%以上。
- 图片无法解析:尝试使用
base64方式代替URL,排除网络下载故障。
工程化注意事项
- 并发控制:QPS上限为2次/秒,建议在代码中实现退避或本地队列,避免触发限流。
- 重试策略:对5xx响应采用指数退避(如第一次等待1秒,第二次2秒,第三次4秒);对4xx响应不重试,直接记录日志。
- 图片预处理:在调用前端做高宽比校正、旋转校正和降噪,能显著提升识别率。
- 数据校验:返回的
total_price_little应与price + tax基本一致(考虑浮点误差);若发现偏差较大,建议人工介入。 - 隐私与合规:发票中包含查看文档方、销售方及车辆信息,传输和存储时应采用HTTPS加密,并在数据库中做脱敏或加密存储。
参考文档
- 机动车发票识别API文档
- 原始Markdown文档