增值税发票在线查验 API 怎么接入?

简介: 本文介绍增值税发票在线查验接口的技术接入方式。支持通过 imgBase64 或 imgUrl 传入发票图片,服务端完成 OCR 识别并联网核验后返回发票代码、号码、金额、购销方信息等结构化字段。文中给出请求参数表、完整 JSON 返回样例、常见错误码排查方法,并提供 curl、Python、Node.js、Java、PHP 多语言示例,以及重试、缓存、限流等工程实践建议。

增值税发票在线查验 API 怎么接入:图片上传、返回字段与工程实践

一、技术简介

增值税发票在线查验接口支持通过图片(Base64 或 URL)传入发票凭证,由服务端完成 OCR 识别并联网核验票面信息,返回发票代码、号码、开票日期、金额、购销方信息、商品明细等结构化字段。适用于报销系统自动填单、财务对账数据校验、电子发票归档结构化存储等技术场景。

接口通过阿里云 API 网关接入,鉴权方式采用 APPCODE 简单身份认证(请求头 Authorization: APPCODE <appcode>),返回 JSON 格式。

本文所有调用地址、QPS 上限与收费规则以阿里云控制台实时配置为准。


二、能力概览

能力项 说明 适用情形
发票图片 OCR 识别 支持 JPG/PNG/BMP 等常见格式,提取票面文本 纸质发票拍照、电子发票 PDF 转图
联网核验真伪 对接税局底账数据进行状态校验 报销审核、财务入账前真伪确认
结构化字段返回 发票代码、号码、金额、购销方、商品明细等 系统自动填单、数据比对
Base64 / URL 双传参 二选一,支持本地文件转 Base64 或图片外链 内网环境与有公网访问条件的场景

三、适用场景

报销系统自动填单:员工上传发票图片后,系统自动调用接口提取票面字段,回填至报销表单,减少手工录入。

财务对账:批量核对销方、购方、价税合计等信息,与 ERP/财务系统账目比对。

电子发票归档:将纸质发票扫描件结构化存储,便于检索、审计与合规备查。


四、接入流程

4.1 请求参数表

字段名 类型 必填 说明
imgBase64 string 否 发票图片的 Base64 字符串,与 imgUrl 二选一
imgUrl string 否 发票图片的可访问下载地址,与 imgBase64 二选一

imgBase64 与 imgUrl 必须且只能传一个。建议优先使用 Base64,避免外链失效或被限制访问。

4.2 标准步骤

  1. 在阿里云控制台开通该 API,获取 APPCODE。
  2. 将发票图片转为 Base64(或准备可访问的图片 URL)。
  3. 构造 POST 请求,Header 携带 Authorization: APPCODE <appcode>。
  4. 发送请求,解析响应 JSON。
  5. 根据 ret_code 判断核验结果,处理业务逻辑。

五、调用示例与返回结构

5.1 完整返回结构

{
   
  "showapi_res_code": 0,
  "showapi_res_error": "",
  "showapi_res_id": "请求唯一标识",
  "showapi_res_body": {
   
    "ret_code": 0,
    "remark": "核验成功",
    "invoiceType": "增值税普通发票(电子)",
    "invoiceCode": "031*****411",
    "invoiceNo": "28*****251",
    "invoiceDate": "2019-01-01",
    "buyerName": "孟**",
    "buyerTaxNo": "",
    "buyerContact": "",
    "buyerBank": "",
    "salerName": "上海***有限公司",
    "salerTaxNo": "913*****40M",
    "salerContact": "上海市普陀区...",
    "salerBank": "",
    "invoiceAmt": "2891.98",
    "totalTaxAmt": "28.92",
    "totalAmt": "2920.90",
    "notes": "",
    "status": 1,
    "itemList": [
      {
   
        "name": "*信息技术服务*数据服务费",
        "spec": "API-AL",
        "unit": "项",
        "amount": "1.0",
        "taxRate": "0.01",
        "taxAmt": "28.92",
        "priceAmt": "2891.98",
        "priceUnit": "2891.980198019801980"
      }
    ]
  }
}

showapi_res_body 字段说明:

字段 类型 说明
ret_code int 业务结果,0 为成功,非 0 为失败
remark string 提示信息
invoiceType string 发票类型
invoiceCode string 发票代码
invoiceNo string 发票号码
invoiceDate string 开票日期(yyyy-MM-dd)
buyerName / salerName string 购方/销方名称
buyerTaxNo / salerTaxNo string 购方/销方税号
invoiceAmt string 合计金额(不含税)
totalTaxAmt string 合计税额
totalAmt string 价税合计
status int 发票状态:1 未作废、2 作废、3 红冲
itemList array 商品明细列表

5.2 多语言调用示例

curl

curl -X POST '<调用地址>/ocrCheckVAT' \
  -H 'Authorization: APPCODE <YOUR_APPCODE>' \
  -H 'Content-Type: application/x-www-form-urlencoded' \
  --data-urlencode 'imgBase64=<BASE64_IMAGE_STRING>'

Python

import base64
import requests


def verify_invoice(image_path: str, appcode: str, endpoint: str):
    with open(image_path, "rb") as f:
        b64 = base64.b64encode(f.read()).decode("utf-8")

    url = f"{endpoint}/ocrCheckVAT"
    headers = {
   "Authorization": f"APPCODE {appcode}"}
    resp = requests.post(
        url, data={
   "imgBase64": b64}, headers=headers, timeout=30
    )
    return resp.json()


result = verify_invoice("invoice.jpg", "<YOUR_APPCODE>", "<调用地址>")
print(result["showapi_res_body"]["remark"])

Node.js

const fs = require('fs');
const axios = require('axios');

async function verifyInvoice(imagePath, appcode, endpoint) {
   
  const b64 = fs.readFileSync(imagePath, {
    encoding: 'base64' });
  const url = `${
     endpoint}/ocrCheckVAT`;
  const headers = {
    Authorization: `APPCODE ${
     appcode}` };
  const data = new URLSearchParams({
    imgBase64: b64 });
  const resp = await axios.post(url, data, {
    headers, timeout: 30000 });
  return resp.data;
}

Java(JDK 11+)

import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Base64;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;

public class InvoiceVerify {
   
    public static void main(String[] args) throws Exception {
   
        String imagePath = "invoice.jpg";
        String appcode = "<YOUR_APPCODE>";
        String endpoint = "<调用地址>";

        byte[] bytes = Files.readAllBytes(Paths.get(imagePath));
        String b64 = Base64.getEncoder().encodeToString(bytes);

        HttpClient client = HttpClient.newHttpClient();
        HttpRequest request = HttpRequest.newBuilder()
            .uri(URI.create(endpoint + "/ocrCheckVAT"))
            .header("Authorization", "APPCODE " + appcode)
            .header("Content-Type", "application/x-www-form-urlencoded")
            .POST(HttpRequest.BodyPublishers.ofString(
                "imgBase64=" + URLEncoder.encode(b64, StandardCharsets.UTF_8)))
            .build();

        HttpResponse<String> response = client.send(request,
            HttpResponse.BodyHandlers.ofString());
        System.out.println(response.body());
    }
}

PHP

<?php
$appcode = '<YOUR_APPCODE>';
$endpoint = '<调用地址>';
$imagePath = 'invoice.jpg';
$b64 = base64_encode(file_get_contents($imagePath));

$ch = curl_init("{$endpoint}/ocrCheckVAT");
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query(['imgBase64' => $b64]));
curl_setopt($ch, CURLOPT_HTTPHEADER, ["Authorization: APPCODE {$appcode}"]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);

$data = json_decode($response, true);
echo $data['showapi_res_body']['remark'];
?>


六、在线调试实录

6.1 请求参数设计

在阿里云控制台「API 调试」模块,选择 POST 方式,填入以下参数:

  • Header:Authorization: APPCODE <your_appcode>
  • Body(x-www-form-urlencoded):imgBase64=<发票图片Base64>

6.2 响应解读

  • showapi_res_code: 0 表示网关层调用成功。
  • showapi_res_body.ret_code: 0 表示业务核验成功。
  • status: 1 表示发票未作废(正常状态);2 为作废,3 为红冲。
  • itemList 为空数组时,表示该发票无商品明细(如定额发票)。

6.3 步骤追踪

  1. 准备发票图片 → 转为 Base64
  2. 构造 POST 请求 → 携带 APPCODE 鉴权头
  3. 发送请求 → 等待响应(通常 1~3 秒)
  4. 解析 JSON → 提取票面字段
  5. 业务逻辑处理 → 入库/填单/对账

七、接口调用限制与规范

项目 说明
协议 HTTPS
调用方式 POST
请求体格式 application/x-www-form-urlencoded
鉴权方式 Authorization: APPCODE <appcode>
QPS 上限 以阿里云控制台实时配置为准
次数扣减规则 HTTP 200 时扣减,非 200 不扣减
图片格式 JPG / PNG / BMP 等常见格式
图片大小建议 压缩至 2MB 以内,避免超时

合规要求:发票图片属于敏感经营数据,传输请使用 HTTPS;日志中避免完整留存 Base64;核验结果仅用于业务校验,不作为唯一法律依据。


八、能力边界与免责声明

支持:增值税普通发票(电子)、增值税专用发票、机动车销售统一发票、增值税普通发票(纸质)等常见发票类型。

不支持:

  • 非发票类票据(如收据、门票、通行证)
  • 模糊、残缺、被遮挡的发票图片
  • 已过税务机关核验期限的历史发票

免责声明:本接口核验结果基于税局公开数据,仅供参考。因税局数据同步延迟、图片识别误差等原因导致的核验偏差,不承担业务决策责任。


九、错误码与排查指南

网关层 HTTP 状态码

状态码 含义 排查办法
400 请求参数错误 检查是否传入 imgBase64 或 imgUrl
401 身份校验失败 确认 APPCODE 有效且已授权该 API
403 请求被禁止 查看控制台余量与有效期
404 路径错误 核对路径 /ocrCheckVAT
500 服务端内部错误 稍后重试或联系平台
503 服务暂不可用 降低频率,稍后重试

业务层错误码

ret_code remark 排查办法
-1 查验不一致 票面信息与税局底账不一致,核对发票真伪
-2 查无此票 发票未同步至税局系统或 OCR 识别错误
-3 超过当日查验次数 单张发票当日查验已达上限,次日再试
-4 查验不成功,请重试 服务商端超时,指数退避重试 2~3 次


十、常见问题 FAQ

Q1:imgBase64 和 imgUrl 可以同时传吗?
不建议。两者二选一,同时传入可能造成请求体过大,服务端以其中一个为准。

Q2:图片格式有要求吗?
支持 JPG、PNG、BMP 等常见格式。建议上传清晰、完整的发票图片。

Q3:HTTP 200 但 ret_code 不为 0 是否扣次数?
是。HTTP 200 即视为一次成功调用,无论业务结果如何均扣减次数。

Q4:如何降低调用成本?
对高频重复场景做短时缓存(键:发票代码_发票号码,TTL 5~15 分钟);批量处理前做参数校验与去重;设置客户端限流。

Q5:为什么返回"查无此票"?
可能原因:发票尚未同步至税局系统;图片模糊导致 OCR 识别错误;发票状态异常。建议核对图片清晰度与票面信息。


十一、内容小结

本文围绕增值税发票在线查验接口,介绍了适用场景、请求参数、返回结构、错误码排查与多语言接入示例。接入时需注意:

  • imgBase64 与 imgUrl 二选一;
  • 使用 Authorization: APPCODE <appcode> 鉴权;
  • 完整调用地址、QPS 与收费规则以阿里云控制台为准;
  • 对敏感发票图片与核验结果做好传输加密、日志脱敏与缓存控制;
  • 失败时按指数退避重试,避免频繁触发限流。

合理运用重试、缓存与限流策略,可将该能力稳定集成到财务、报销或发票归档系统中。

相关文章
|
1月前
|
缓存 JSON 自然语言处理
企业工商信息查询接口技术解析:接入流程、返回结构与工程实践
本文以统一社会信用代码查询企业工商数据接口为样例,梳理 RESTful 数据查询接口的通用接入方式。内容涵盖接口概览(HTTPS GET、APPCODE 鉴权、调用地址与请求参数)、返回结构(showapi_res_body 字段与两层返回码解析)、错误排查(HTTP 状态码与业务 ret_code)、频控与合规(限流、缓存 TTL、敏感信息脱敏)、多语言接入示例(curl/Python/Java/Node.js/PHP),以及重试、幂等、密钥安全等工程实践要点。适用于金融风控、商户资质审核、合规审查等需核验企业工商登记信息的场景。
215 0
企业工商信息查询接口技术解析:接入流程、返回结构与工程实践
|
23天前
全国 31 省今日油价数据一览,你的省份 92# 汽油多少钱?
2026-09-24 全国 31 省区市今日油价数据梳理:92/95/98 号汽油与 0 号柴油各省零售参考价明细,海南 92# 汽油 9.41 元/升居全国最高,新疆 8.07 元/升最低,全国均价约 8.35 元/升。
196 0
|
27天前
2026-09-21 全国 31 省区市今日油价数据解析
本文整理 2026-09-21 全国 31 省区市今日油价数据,覆盖 89/92/95/98 号汽油与 0 号柴油明细,并梳理 92 号汽油区域价差等关键特征。
149 0
2026-09-21 全国 31 省区市今日油价数据解析
|
1月前
|
缓存 文字识别 自然语言处理
行驶证正副页 OCR 识别接口技术解析:接入流程、参数设计与工程化实践
本文以阿里云云市场上架的一款行驶证正副页 OCR 识别接口为样例,系统梳理其接入方法与工程化要点。内容覆盖接口能力、请求参数(img_base64 / img_url / side)、返回字段结构(正页 front_result 与副页 back_result)、业务状态码 ret_code 与网关 HTTP 错误排查,并提供 curl / Python / Java / PHP / Node.js 多语言调用示例。同时给出限流、重试、超时、结果缓存、密钥安全等接入工程实践,帮助开发者把结构化识别接口稳定地接进业务系统。文中字段与调用地址均取自官方调试面板,接入思路可迁移至同类 OCR 接口。
125 0
行驶证正副页 OCR 识别接口技术解析:接入流程、参数设计与工程化实践
|
1月前
|
缓存 JSON 自然语言处理
增值税发票在线查验 API 怎么接入:Base64 图片上传、返回字段与工程实践
本文介绍阿里云市场增值税发票在线查验接口的技术接入方式:支持通过 imgBase64 或 imgUrl 传入发票图片,服务端完成 OCR 识别并联网核验后返回发票代码、号码、金额、购销方信息等结构化字段。文中给出请求参数表、完整 JSON 返回样例、常见 HTTP 与业务错误码排查方法,并提供 curl、Python、Node.js、Java、PHP 多语言示例,以及重试、缓存、限流等工程实践建议。
193 0
增值税发票在线查验 API 怎么接入:Base64 图片上传、返回字段与工程实践
|
1月前
|
缓存 JSON 自然语言处理
HTML 转 Markdown 接口技术解析:异步接入流程、参数设计与轮询实践
本文以阿里云云市场的一个 HTML 转 Markdown 接口为例,讲解异步任务模型的接入方式。接口采用 APPCODE 鉴权,提供提交转换(/html2md)、查询任务(/task_detail)与历史查询(/task_history)三个操作,通过 task_id 串联提交、轮询、取回流程。文章给出完整的请求参数、返回结构、错误排查表,以及 Python、Java、PHP、Node.js、curl 多语言示例,并梳理重试退避、结果缓存、频控限流与密钥安全等工程要点,适用于内容迁移、文档整理与数据采集场景。
173 0
HTML 转 Markdown 接口技术解析:异步接入流程、参数设计与轮询实践
|
1月前
|
存储 人工智能 缓存
AI 人像景点打卡照生成接口的异步接入与工程化实践
本文以阿里云云市场上的 AI 人像景点打卡照生成接口为样例,介绍其请求参数、异步任务返回结构、状态轮询机制与多语言接入示例,并给出重试退避、结果缓存、并发节流与密钥安全的工程化实践,帮助开发者快速把「提交任务 → 轮询取图」模式落地到同类图像生成 API 接入中。
139 0
AI 人像景点打卡照生成接口的异步接入与工程化实践
|
1月前
|
缓存 自然语言处理 安全
智能问答 API 接入实践:从请求设计到重试缓存
本文以阿里云 API 网关上一个智能问答接口为样例,整理其接入方式、请求参数、返回结构与错误处理,并给出 Java / Python / PHP / curl 多语言代码示例;在此基础上总结生产接入中的工程化要点,包括重试退避、令牌桶限流、本地缓存、熔断降级与凭据安全管理。文末附 10 条技术 FAQ。
184 0
智能问答 API 接入实践:从请求设计到重试缓存
|
监控 搜索推荐 API
动物识别-图片动物识别-动物图像识别API-AI动物检测-动物种类识别
支持上传图片(Base64/文件/URL),自动识别物种并返回名称及置信度。适用于生态保护、宠物服务、科普教育等场景,助力高效智能分类与管理。
20 0
|
24天前
28 家主流金店 2026-09-24 金店参考价数据解析
2026 年 9 月 24 日 28 家主流金店黄金、铂金参考价数据汇总与分布解析,数据每日同步。
97 0