出租车发票识别 API 参数详解与工程化实践
适用场景:结构化提取发票字段,对接差旅与财务系统
出租车发票(出租车机打发票)在日常差旅报销、行程费用核对、财务审计等场景中广泛存在。传统人工录入方式耗时易错,通过 OCR 接口自动识别并结构化输出车号、上下车时间、里程、金额、发票代码/号码、单价、附加费、印章信息等 16 个字段,可极大提升处理效率。
典型落地场景包括:
- 企业差旅系統:员工上传出租车发票图片,系统自动识别关键字段并填入报销单。
- 财务审计:批量核对发票金额、发票号与行程是否匹配,辅助合规审计。
- 出行平台对账:司机端发票与平台订单数据自动比对。
接口能力边界:支持的字段与输入限制
出租车发票识别接口(slug:ocr-taxi-invoice)主要识别全国出租车机打发票(非手撕票或电子发票)。支持两种图片传输方式:url(公网可访问的图片链接)和base64(图片文件的 base64 编码字符串)。接口QPS 上限为 2 次/秒,超过该速率会返回频率限制错误。
识别字段覆盖:
- 车辆信息:车号(car_number)、里程(distance)
- 时间信息:上车时间(start_time,格式 HH:mm)、下车时间(end_time,格式 HH:mm)、日期(start_date,格式 yyyy-MM-dd)
- 金额信息:总金额(total_amount)、单价(price)、附加费(additional_fee)、调度费(dispatch_fee)
- 发票信息:发票代码(invoice_code)、发票号码(invoice_no)
- 印章信息:发票专用章内容(invoice_special_seal)、印章中公司名称(seller_name_in_seal)、印章中纳税人识别号(seller_taxpayer_no_in_seal)
- 其他:发票标题(title_trial)、是否加盖印章(is_sealed)
接口不承诺识别所有发票变种(如部分城市格式差异),建议图片平整、清晰、无遮挡。
请求参数与鉴权详解
基础 URL
POST https://v1.apizero.cn/api/ocr-taxi-invoiceHeader 参数
| 参数名 | 必填 | 类型 | 说明 |
|---|---|---|---|
| Authorization | 是 | string | Bearer <你的 API Key>,从控制台获取 |
| Content-Type | 否 | string | 请求体格式,推荐application/json |
注意:素材中 curl 示例使用的X-API-KeyHeader 与Authorization可能为等效鉴权方式,实际使用时请以最新文档为准。建议优先使用Authorization: Bearer <your_api_key>。
请求体(JSON Object)
| 字段 | 必填 | 类型 | 说明 |
|---|---|---|---|
| input_type | 是 | string | 图片传输方式,取值url或base64 |
| input_data | 是 | string | 图片内容。input_type=url时为完整 http/https 图片链接;input_type=base64时为图片的 base64 编码字符串(可含data:image/xxx;base64,前缀) |
请求体示例(URL 模式)
{ "input_type": "url", "input_data": "https://example.com/taxi-invoice.jpg" }请求体示例(base64 模式)
{ "input_type": "base64", "input_data": "data:image/jpeg;base64,/9j/4AAQ... (实际 base64 字符串)" }QPS 限制
接口每秒最多处理 2 个请求。如果并发超过此限制,将返回 HTTP 429 错误或由业务层返回频率限制提示。建议在批量场景下使用节流控制(如每 500ms 发送一次请求)或引入队列。
可复制的 curl 接入示例
以下示例使用Authorization头(请将$YOUR_API_KEY替换为真实 API Key):
curl -sS -X POST \ -H "Authorization: Bearer $YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "input_type": "url", "input_data": "https://example.com/taxi-invoice.jpg" }' \ "https://v1.apizero.cn/api/ocr-taxi-invoice"若需使用 base64 方式,将input_data中的 URL 替换为 base64 编码字符串即可。注意:base64 字符串可能很长,请确保 HTTP 客户端不截断。
返回值字段详解
成功响应(HTTP 200)格式如下:
{ "code": 0, "msg": "成功", "request_id": "req_abc123", "data": { "additional_fee": "1.00", "car_number": "沪A12345", "dispatch_fee": "", "distance": "12.3", "end_time": "10:05", "invoice_code": "31100000000", "invoice_no": "87654321", "invoice_special_seal": "XX出租汽车发票专用章", "is_sealed": "true", "price": "3.00", "seller_name_in_seal": "XX出租汽车有限公司", "seller_taxpayer_no_in_seal": "91310000XXXXXXXXXX", "start_date": "2024-01-15", "start_time": "09:30", "title_trial": "出租汽车发票", "total_amount": "38.50" } }字段说明(data 内)
| 字段 | 类型 | 说明 |
|---|---|---|
| car_number | string | 车牌号,如 "沪A12345" |
| start_date | string | 发票日期,格式 yyyy-MM-dd |
| start_time | string | 上车时间,格式 HH:mm |
| end_time | string | 下车时间,格式 HH:mm |
| distance | string | 里程,单位公里,如 "12.3" |
| total_amount | string | 总金额,单位元,如 "38.50" |
| price | string | 单价(每公里用量说明),单位元,如 "3.00" |
| additional_fee | string | 附加费,单位元 |
| dispatch_fee | string | 调度费,单位元,可能为空字符串 |
| invoice_code | string | 发票代码 |
| invoice_no | string | 发票号码 |
| invoice_special_seal | string | 发票专用章上印刷的文字 |
| is_sealed | string | 是否加盖印章,"true"或"false" |
| seller_name_in_seal | string | 印章中的企业名称 |
| seller_taxpayer_no_in_seal | string | 印章中的纳税人识别号 |
| title_trial | string | 发票标题文字,如 "出租汽车发票" |
注意:所有字段均为字符串,即使数值型也是字符串形式。空字段返回空字符串
""。未识别到的字段也返回空字符串,但不会缺少字段。
请求 ID
request_id字段可用于追踪单次请求,结合服务端日志排查问题。
常见错误与排查
| 错误表现 | 可能原因 | 排查建议 |
|---|---|---|
| HTTP 401 | Authorization 头缺失或无效 | 检查 API Key 是否正确,是否包含Bearer前缀 |
| HTTP 400 | 请求参数格式错误 | 确认 JSON 结构,input_type只能为url或base64,input_data非空 |
| HTTP 429 | 超过 QPS 限制 | 降低请求频率,每请求间隔至少 500ms |
| code != 0 | 图片质量差或非出租车发票 | 检查图片是否包含完整发票区域,是否倾斜/模糊/过曝 |
| 返回字段全部为空 | 未识别到任何内容 | 尝试更换图片,确保发票为机打发票而非手撕票或电子发票 |
图片质量最佳实践:
- 分辨率:建议宽度不低于 1000 像素。
- 拍摄:平铺拍摄,避免透视畸变;光线均匀,无阴影遮挡。
- 格式:支持 jpg、png,文件大小建议小于 10MB。
- 背景:发票主体占图片面积 70% 以上,避免背景杂乱。
工程化注意事项
1. 批量处理与重试策略
由于 QPS 为 2,批量处理时建议使用队列控制并发。例如 Python 中使用asyncio+aiohttp限制同时请求数为 1 或 2,并加入指数退避重试(遇到 HTTP 429 或 5xx 错误)。
Python 伪代码示例:
import requests import time from typing import List def recognize_taxi_invoice(api_key: str, image_url: str) -> dict: headers = { "Authorization": f"Bearer {api_key}", "Content-Type": "application/json" } body = { "input_type": "url", "input_data": image_url } try: resp = requests.post("https://v1.apizero.cn/api/ocr-taxi-invoice", headers=headers, json=body, timeout=30) resp.raise_for_status() return resp.json() except requests.exceptions.HTTPError as e: if resp.status_code == 429: time.sleep(1.0) # 简单等待后重试 # 实际应使用循环+退避 else: raise e2. 字段校验与空值处理
识别结果中部分字段(如dispatch_fee)可能为空字符串。在对接财务系统时,建议对空字段设置默认值(如0.00)或进行空值判断。
3. 多租户场景下的鉴权安全
API Key 应存储在服务端环境变量或密钥管理服务中,切勿硬编码在客户端代码或前端页面中。建议通过后端转发请求,外部用户不直接暴露 API Key。
4. 发票图片隐私合规
发票图片包含车号、金额等敏感信息。系统应在识别完成后及时删除原始图片或进行脱敏处理,避免数据泄漏。
5. 响应解析时的字段类型注意事项
所有字段均为字符串,如果需要进行数值运算,需要手动转换为float或Decimal,并处理空字符串转换异常。
参考文档
- 原始 API 文档(Markdown):https://apizero.cn/aidocs/ocr-taxi-invoice/raw.md
- 文档页面:https://apizero.cn/aidocs/ocr-taxi-invoice
