适用场景
出租车发票识别 API 核心价值是将机打发票上的结构化信息(车号、金额、里程等)转化为 JSON 数据,直接用于以下场景:
- 差旅费报销自动录入:员工拍照上传发票,系统自动提取金额、日期、车号,免去手工输入。
- 行程费用核对:财务或行政部门批量核对出租车发票与实际报销金额是否一致。
- 审计与合规检查:提取发票代码、号码、印章信息,验证发票真伪或归属。
该 API 仅识别全国出租车机打发票,手撕发票、收据等不在支持范围内。图片要求拍摄平整、清晰,避免反光、折叠或角度倾斜过大。
接口能力边界
| 维度 | 说明 |
|---|---|
| 支持输入方式 | URL 或 base64 编码 |
| 返回字段数 | 16 个(详见返回值部分) |
| 最大并发 QPS | 2 / s |
| 图片建议尺寸 | 长边不低于 500px,分辨率 ≥ 72dpi |
| 单次请求最大图片体积 | 以平台文档为准(建议小于 5MB) |
接口不会对图片进行裁剪或预处理,若发票区域占比过小,识别准确率可能下降。
鉴权与请求参数
鉴权方式
使用 HTTP Header 携带 API Key,素材给出了两种写法,本文以X-API-Key为例(可兼容Authorization: Bearer <key>的方式,具体以平台最新文档为准)。
X-API-Key: YOUR_API_KEY请求体参数
请求体为 JSON 对象,包含两个必填字段:
| 参数名 | 类型 | 必填 | 描述 |
|---|---|---|---|
input_type | string | 是 | 图片传输方式:url(公网图片链接)或base64(图片的 base64 编码) |
input_data | string | 是 | 当input_type=url时填完整图片链接;当input_type=base64时填 base64 字符串(可含data:image/xxx;base64,前缀) |
示例(URL 方式):
{ "input_type": "url", "input_data": "https://example.com/taxi-invoice.jpg" }curl 最小可运行示例
以下命令可直接复制后在终端运行,注意将YOUR_API_KEY替换为实际值,并将图片链接换成自己的发票图片:
curl -sS \ -X POST \ -H "X-API-Key: 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替换为编码字符串:
data=$(base64 -w0 /path/to/taxi-invoice.jpg) curl -sS -X POST \ -H "X-API-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d "{\"input_type\":\"base64\",\"input_data\":\"$data\"}" \ "https://v1.apizero.cn/api/ocr-taxi-invoice"注意:base64 编码时不要添加换行,建议使用
base64 -w0(Linux/macOS)或tr -d '\n'处理后传入。
Python 接入示例
对于后端开发者,使用requests库更为方便:
import requests import base64 API_URL = "https://v1.apizero.cn/api/ocr-taxi-invoice" API_KEY = "YOUR_API_KEY" # 方式一:URL def recognize_by_url(image_url): payload = { "input_type": "url", "input_data": image_url } headers = { "X-API-Key": API_KEY, "Content-Type": "application/json" } resp = requests.post(API_URL, json=payload, headers=headers) return resp.json() # 方式二:base64 def recognize_by_base64(image_path): with open(image_path, "rb") as f: b64_str = base64.b64encode(f.read()).decode("utf-8") payload = { "input_type": "base64", "input_data": b64_str } headers = { "X-API-Key": API_KEY, "Content-Type": "application/json" } resp = requests.post(API_URL, json=payload, headers=headers) return resp.json() # 示例调用 result = recognize_by_url("https://example.com/taxi-invoice.jpg") print(result)返回值解读
成功响应 HTTP 200,返回 JSON 格式,顶层包含code、msg、data、request_id。当code为 0 时表示成功。data对象包含以下字段:
基础信息
title_trial:发票标题,如“出租汽车发票”invoice_code:发票代码(12 位)invoice_no:发票号码(8 位)start_date:乘车日期(格式 yyyy-MM-dd)
车号与时间
car_number:出租车车牌号(含省份简称,如“沪A12345”)start_time:上车时间(HH:mm)end_time:下车时间(HH:mm)
费用明细
distance:行驶里程(公里,保留一位小数)price:单价(元/公里)total_amount:总金额(元)additional_fee:附加费(元,如燃油附加费)dispatch_fee:电召费(元,部分发票无此字段则为空字符串)
印章与归属
invoice_special_seal:发票专用章文字内容seller_name_in_seal:印章中的单位名称seller_taxpayer_no_in_seal:印章中的纳税人识别号is_sealed:是否已盖章(字符串“true”或“false”)
响应示例:
{ "code": 0, "msg": "成功", "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" }, "request_id": "req_abc123" }所有数值字段均为字符串类型,空字段返回空字符串而非 null。
常见错误与排查
| HTTP 状态码 | 错误码 | 常见原因 | 解决方案 |
|---|---|---|---|
| 401 | - | API Key 错误或缺失 | 检查X-API-Key请求头值是否正确 |
| 400 | 1001 | 请求参数格式错误 | 确认input_type为url或base64,且input_data非空 |
| 400 | 1002 | 图片无法访问(URL 方式) | 检查图片链接是否可公开访问,或使用 base64 |
| 400 | 1003 | base64 解码失败 | 确保编码字符串有效,不含非法字符 |
| 500 | 2000 | 服务内部错误 | 稍后重试,若持续失败请联系技术支持 |
若响应中code非 0,可通过msg字段获取错误描述。注意平台可能返回其他错误码,建议以实际响应为准。
工程化注意事项
1. 图片质量要求
- 平整度:发票应铺平拍摄,避免褶皱或弯曲导致字符扭曲。
- 光线均匀:避免强光直射或阴影遮挡关键区域(如发票代码、金额)。
- 分辨率:建议发票区域在图片中占比超过 60%,长边不低于 500px。
- 格式:主流格式(JPEG、PNG、BMP)均支持,推荐 JPEG 以减少体积。
2. QPS 限流处理
该接口 QPS 上限为 2,即每秒最多发起 2 次请求。批量场景下建议加入简单的令牌桶或固定间隔控制:
import time def batch_recognize(image_urls): results = [] for url in image_urls: result = recognize_by_url(url) results.append(result) time.sleep(0.5) # 确保不超过 2 QPS return results3. 重试策略
对于 5xx 错误或网络超时,建议使用指数退避重试(最大 3 次即可):
import requests from time import sleep def recognize_with_retry(image_url, max_retries=3): for attempt in range(max_retries): try: return recognize_by_url(image_url) except (requests.ConnectionError, requests.Timeout) as e: if attempt < max_retries - 1: sleep(2 ** attempt) else: raise4. 字段校验与容错
由于 OCR 识别的天然缺陷,个别字段可能识别错误或遗漏。建议业务代码中加入空值检查和人工复核逻辑:若total_amount为空,可标记为“人工确认”;若car_number不符合车牌号格式,则触发二次校验。
5. 数据存储建议
提取的字段建议统一存入数据库,并保留request_id用于追踪调用日志。字段类型可统一为varchar,便于容纳各种格式。
参考文档
- 官方文档页:https://apizero.cn/aidocs/ocr-taxi-invoice
- 原始接口定义:https://apizero.cn/aidocs/ocr-taxi-invoice/raw.md
以上文档包含完整的参数说明、更新记录及联系方式。