适用场景
银行卡识别是移动支付、金融科技和身份验证场景中的高频能力。当用户需要快速录入银行卡号或有效期时,手动输入容易出错,且体验不佳。以下场景可以直接复用该接口:
- 在线开户:用户上传银行卡照片,后台自动提取卡号和有效期,自动填入表单。
- 支付绑卡:APP中用户拍照或选择相册图片,实时识别并绑定银行卡。
- 卡号核对:将识别结果与用户手输信息交叉验证,降低人工审核维护复杂度。
- 后台单据处理:读取扫描件或截图中的银行卡信息,用于记账或清结算。
接口能力边界
在开始对接参数之前,需要了解该接口的约束条件,以避免传参不当导致失败。
| 属性 | 说明 |
|---|---|
| 接口地址 | POST https://v1.apizero.cn/api/ocr-bank-card |
| 请求方式 | POST |
| 图片格式 | jpg / png |
| 文件大小上限 | 10 MB |
| 输入方式 | 公网图片URL 或 Base64 编码字符串 |
| QPS 限制 | 2 次/秒 |
接口默认不返回银行卡发卡行、卡片类型等附带信息,如有需要可参考官方文档了解是否支持扩展参数。
鉴权与请求头
API 请求需要通过请求头传递身份凭证。根据实际测试,该接口支持两种鉴权方式,任选其一即可:
- 方式一(推荐):
Authorization: Bearer <你的API Key> - 方式二:
X-API-Key: <你的API Key>
建议在工程中使用方式一,符合 HTTP Bearer Token 标准,通用性更强。
请求头示例
Content-Type: application/json Authorization: Bearer sk_xxxxxxxxxxxxxxxx注意:Content-Type必须设置为application/json,请求体以 JSON 格式传递。
请求参数详解
接口请求体是一个 JSON 对象,包含两个必填字段。下面逐一说明每个字段的设计意图和最佳填法。
input_type(string,必填)
- 可选值:
"url"或"base64" - 作用:指明
input_data字段的编码格式。 - 最佳实践:
- 如果图片已经存储于可访问的公网地址(如对象存储、CDN),使用
url模式更简单,不需要额外编码。 - 如果图片来自客户端上传的二进制数据(例如 multipart 接收后读取字节流),优先使用
base64模式,避免中间环节存储临时文件。
- 如果图片已经存储于可访问的公网地址(如对象存储、CDN),使用
input_data(string,必填)
- 作用:承载图片的二进制数据或地址。
- 约束:
input_type=url时:必须是可以直接通过 HTTP/HTTPS 访问的图片链接,服务器会从该 URL 下载图片进行识别。图片大小不超过 10MB。input_type=base64时:填入图片二进制数据的 Base64 编码字符串。支持携带data:image/xxx;base64,前缀,也支持纯 Base64 内容。建议客户端拍完照后直接在前端用 FileReader 读取为 Base64,后端无需额外处理。
- 最佳实践:
- URL 模式下的图片链接务必确保公网可达,私有内网地址或需要鉴权的图片链接会被拒绝。
- Base64 字符串长度约为原始文件的 1.37 倍,10MB 图片产生的 Base64 约 13.7MB,需确保传输链路和 API 网关无大小限制。
- 图片尺寸过长或过宽会影响识别效果,建议保持卡面居中、无明显反光。可以拍摄时使用“辅助框”引导用户对齐。
请求体完整示例
{ "input_type": "url", "input_data": "https://storage.example.com/user_upload/bank_card_2025.jpg" }请求示例(curl & Python)
curl 请求(可直接复制测试,替换$API_KEY)
export API_KEY="your-api-key-here" curl -sS \ -X POST \ -H "Authorization: Bearer $API_KEY" \ -H "Content-Type: application/json" \ -d '{ "input_type": "url", "input_data": "https://example.com/bankcard.jpg" }' \ "https://v1.apizero.cn/api/ocr-bank-card"注意:示例中的“https://example.com/bankcard.jpg”请替换为真实的可访问图片地址。若使用 Base64,可以将
input_type改为"base64",input_data填入编码后字符串。
Python 请求示例(使用requests库)
import requests API_URL = "https://v1.apizero.cn/api/ocr-bank-card" API_KEY = "your-api-key-here" headers = { "Authorization": f"Bearer {API_KEY}", "Content-Type": "application/json" } def recognize_by_url(image_url: str) -> dict: payload = { "input_type": "url", "input_data": image_url } resp = requests.post(API_URL, headers=headers, json=payload) resp.raise_for_status() return resp.json() # 调用示例 result = recognize_by_url("https://example.com/bankcard.jpg") print(result)响应字段解析
成功响应的 HTTP 状态码为 200,响应体为 JSON 格式,顶层字段说明如下:
| 字段 | 类型 | 说明 |
|---|---|---|
code | integer | 业务状态码,0 表示成功,非 0 表示失败。 |
msg | string | 对应 code 的可读消息,成功时为“成功”。 |
request_id | string | 单次请求的唯一标识符,可用于日志追踪和问题反馈。 |
data | object | 识别结果,仅在 code=0 时存在。 |
data内部字段
| 字段 | 类型 | 示例 | 说明 |
|---|---|---|---|
card_number | string | "6222 0202 0001 5920 8" | 银行卡号,可能带有空格(便于人工阅读),实际使用时建议去除空格。 |
date_of_expiry | string | "12/28" | 卡片有效期,格式为MM/YY,如果没有有效期(如借记卡)可能返回空字符串。 |
注意:返回的card_number中的空格是文档示例格式,实际接口可能返回纯数字或带空格,请以实际响应为准。开发时应当通过replace(" ", "")去掉所有空格。
错误响应示例
{ "code": 401, "msg": "无效的API密钥或权限不足", "request_id": "req_err_xxxx", "data": null }错误处理与常见问题
| 错误现象 | 可能原因 | 排查步骤 |
|---|---|---|
| 401 Unauthorized | API Key 错误或未传递 | 确认请求头中的Authorization或X-API-Key,检查 Key 是否有效。 |
| 400 Bad Request | 请求体JSON格式错误或缺少必填字段 | 使用jq或在线 JSON 校验工具验证 payload。 |
| 图片识别失败(code≠0,msg含“识别失败”) | 图片过小、过模糊、卡面不全或格式不支持 | 确保图片分辨率不低于 300x200 像素,卡面占图片面积 70% 以上,避免反光/遮挡。 |
| 413 Request Entity Too Large | 图片超过 10MB | 压缩图片或限制上传文件大小。 |
| 429 Too Many Requests | 超过 QPS 2次/秒 | 加入本地队列或使用 token bucket 流控,建议间隔 500ms 以上。 |
| 耗时过长(>5秒) | 图片太大或网络链路慢 | 缩小图片宽高(建议最长边 2048px 以内),或改用 Base64 减少网络开销。 |
工程化注意事项
1. 并发控制与重试策略
由于接口 QPS 限制为 2,生产环境中建议使用信号量或令牌桶进行限流。对于失败请求(如 5xx 或超时),采用指数退避重试,最大重试 3 次,初始间隔 1s。
import time import requests from tenacity import retry, stop_after_attempt, wait_exponential, retry_if_exception_type @retry( stop=stop_after_attempt(3), wait=wait_exponential(multiplier=1, min=1, max=4), retry=retry_if_exception_type((requests.ConnectionError, requests.Timeout)) ) def robust_recognize(image_url: str): # 调用 recognize_by_url 并处理非200状态码 resp = requests.post(API_URL, headers=headers, json={ "input_type": "url", "input_data": image_url }, timeout=30) if resp.status_code == 429: time.sleep(1) raise requests.exceptions.RequestException("rate limited") resp.raise_for_status() return resp.json()2. 图片预处理
- 方向矫正:接口对旋转后的图片鲁棒性一般,建议在调用前自动检测图片 EXIF 方向并矫正。
- 亮度对比度:过暗或过亮图片可以先进行直方图均衡化。
- 裁剪:如果图片中包含多余背景,使用轮廓检测找到银行卡区域,裁剪后提交。
3. Base64 传输优化
- 客户端先压缩图片(例如将最长边缩放到 1024px,JPEG 质量 80%)再编码,可以显著降低传输延迟和失败率。
- 后端接收后无需二次处理,直接透传。
4. 缓存与幂等
- 同一张图片的识别结果在短时间内不会变化(除非更换卡面),建议按图片 MD5 哈希建立当日缓存,减少重复调用。
- 注意:有效期字段可能随批次不同而一致,但卡号通常是固定的,可缓存卡号。
5. 日志与监控
- 记录每次请求的
request_id、input_type、耗时、结果code。 - 对
code != 0的请求增加告警,便于及时排查接口可用性。
参考文档
- 接口文档页:https://apizero.cn/aidocs/ocr-bank-card
- 原始 Markdown 文档:https://apizero.cn/aidocs/ocr-bank-card/raw.md
本文所有参数与请求示例均来自官方文档,实际调用时请以最新版文档为准。