跳转到正文
生产环境文档契约 1.5.169
正在核对线上版本…

错误处理与重试 ​

两套错误结构 ​

标准 REST 错误 ​

/api/v1/channel/*、/api/v2/channel/*,以及数据接口的鉴权、权限和交付异常使用 HTTP 状态码。 通常返回以下 Body;税务请求大小/整包并发限制的中间件错误可省略 details:

json
{
  "code": "CHANNEL_ORDER_NOT_FOUND",
  "message": "Channel order not found",
  "details": {}
}

code 是固定的字符串常量,程序里用它做分支判断;message 是给人看的,仅供排查。

PDF、同源 HTML 和发票分片签名下载的 403/404 可能只返回 {"detail":"..."},没有 code;仍按 HTTP 状态处理。该区别不适用于所有下载接口,具体以各接口参考为准。

校验失败时 details.errors 列出具体字段:

json
{
  "code": "VALIDATION_ERROR",
  "message": "Request validation failed",
  "details": {
    "errors": [
      { "type": "value_error", "loc": ["body"], "msg": "at least one collection type is required" }
    ]
  }
}

业务码信封 ​

业务码信封使用 HTTP 200,结果在 success / code 里;该路径下的鉴权、权限、请求大小、限流和交付异常仍可返回非 2xx。先处理 HTTP 错误,再判断信封。 见获取数据。

业务码 ​

code含义处理
0 / 200成功——
60003采集、加工或交付准备中15–30 秒后重试当前查询
60002失败或无可交付数据查询订单/产品的错误信息
10000任务不存在核对渠道编码与两类订单号
10001参数、输出范围或发票汇总处理状态data.errorCode=INVOICE_RESULT_NOT_READY 表示汇总准备中,可等待重查;其他汇总处理错误按 errorCode、msg 联系平台处理来源或后台任务;参数和授权范围错误则修正请求

60002 有两种含义

「采集失败」和「查询无数据」都是 60002,msg 会给出具体原因 (如「查询无数据」「税务数据未匹配到已配置表单」「本任务未申请 PDF 报告」)。 需要区分时回到产品查询看 state 与 error_code。

HTTP 状态码 ​

状态典型 code处理
400INVOICE_CURSOR_INVALID、INVOICE_SCHEMA_RETIRED、ACK_BATCH_INVALID、LARGE_CHUNK_INVALID按对应交付规则修正参数或重新开始读取
413TAX_REQUEST_TOO_LARGE缩小请求体;税务 ALL 请求上限为 1 MiB
416RANGE_INVALID、RANGE_REQUIRED使用单个显式起点的 Range,每次不超过 4 MiB
429TAX_WHOLE_RESPONSE_LIMIT、TAX_READ_LIMIT遵循 Retry-After(如有),降低并发,整包可改用分页
503DELIVERY_NOT_READY、PART_INTEGRITY_FAILED等待当前交付准备或修复,再重试同一读取
401CHANNEL_AUTH_REQUIRED、INVALID_CHANNEL_KEY、CHANNEL_SIGNATURE_REQUIRED、INVALID_CHANNEL_SIGNATURE、CHANNEL_TIMESTAMP_EXPIRED核对认证头、时钟与 canonical,见鉴权与签名
403CHANNEL_ORDER_FORBIDDEN、REPORT_NOT_ENTITLED渠道与订单不匹配,或未获定制报告授权
404CHANNEL_ORDER_NOT_FOUND、PRODUCT_NOT_REQUESTED、RAW_ARTIFACT_NOT_AVAILABLE、HTML_REPORT_NOT_FOUND、HTML_REPORT_NOT_READY、INVOICE_ORDER_NOT_FOUND核对订单号;确认本单申请过该产品
409EXTERNAL_ORDER_CONFLICT、AGREEMENT_NOT_CONFIGURED、TAX_URL_MISSING、CHANNEL_REQUEST_REPLAYED、INVOICE_DELIVERY_MODE_MISMATCH、INVOICE_*_NOT_READY、INVOICE_*_EXPIRED读 code 再决定,不要盲目重试
403RAW_ARTIFACT_LINK_EXPIRED原始文件签名缺失、不完整、无效或过期;鉴权查询订单取得完整新链接
410RAW_ARTIFACT_EXPIRED、HTML_REPORT_EXPIRED、PUBLIC_RESULT_ACCESS_EXPIRED、ORDER_DATA_ACCESS_EXPIRED、ORDER_DATA_ACCESS_REVOKED、REPORT_DATA_EXPIRED、INVOICE_DATASET_EXPIRED按 code 区分文件或快照已清理、分享到期、资料到期及权限撤销;刷新链接不会延长资料期限
422INVALID_ACCESS_LIFETIME修正三类期限及其组合,分享天数不能超过资料保留天数
422VALIDATION_ERROR、INVALID_PRODUCT、INVALID_CALLBACK_URL、SUCCESS_URL_POINTS_TO_MANAGEMENT、EXIT_URL_POINTS_TO_MANAGEMENT、REPORT_TYPE_UNSUPPORTED修正请求

每个接口能返回哪些 code 是写在契约里的

接口参考每个接口的每个错误响应都列出了该接口实际可能返回的 code 及其含义, 本页是跨接口的汇总,以接口页为准;客户端应保留无法识别的 code 和 message,避免将新增错误码当成成功。

发票交付专属错误 ​

/invoice/standard 或 /invoice/results 请求 STANDARD 时,异步汇总未就绪或失败会返回 HTTP 200、code=10001、success=false,具体代码位于 data.errorCode。只有 INVOICE_RESULT_NOT_READY 表示继续等待;INVOICE_RESULT_STORAGE_LIMIT、INVOICE_STANDARD_SOURCE_MISSING、INVOICE_RESULT_BUILD_FAILED 等应交平台处理存储、来源或任务,不能靠修改请求参数恢复。

普通 /invoice/all 使用页码分页,参数错误也可返回 HTTP 200、code=10001,data 为 null。Compatible_V1 的协议错误代码位于响应顶层 errorCode,不要与 STANDARD 的 data.errorCode 混淆。

分片清单返回 INVOICE_SCHEMA_RETIRED 时重新查询包状态;游标无效时从首次游标请求重新读取。

税务分页确认的 ACK_PAGES_INCOMPLETE 表示尚有页面未读,ACK_MANIFEST_MISMATCH 表示快照或哈希不匹配, ACK_BATCH_MISMATCH 表示已由其他接收批次确认。处理流程见税务分页交付。

code含义处理
INVOICE_DELIVERY_MODE_MISMATCH本单未申请该交付模式用申请时选择的模式取数
INVOICE_DATASET_NOT_READY发票快照未就绪等产品成功后重试
INVOICE_DATASET_EXPIRED快照已过期联系平台
INVOICE_CURSOR_INVALID游标不属于本数据集从头重新拉取
INVOICE_CURSOR_EXPIRED游标令牌过期(默认 24 小时)在资料与快照仍有效时省略 cursor 从首请求重读;按新一轮读取去重,不拼接两次结果
INVOICE_EXPORT_NOT_FOUNDexportId 不属于本订单重新查询 package/status
INVOICE_EXPORT_NOT_READY分片包未就绪继续查询 package/status
INVOICE_EXPORT_EXPIRED分片包已过期联系平台
INVOICE_NOT_REQUESTED本单未采集发票用申请时选择的范围取数
INVOICE_EXPORT_COUNT_MISMATCH分片记录数与快照不一致平台会重建分片包,稍后重查状态
INVOICE_EXPORT_PATH_INVALID分片包存储路径异常联系平台

重试决策 ​

mermaid
flowchart TD
  A[收到错误] --> B{哪一层}
  B -->|HTTP 401| C[修认证, 不要重试]
  B -->|HTTP 409| D[读 code]
  D -->|*_NOT_READY| E[等一段时间再重试]
  D -->|EXTERNAL_ORDER_CONFLICT| F[换订单号或改回原请求]
  D -->|CHANNEL_REQUEST_REPLAYED| G[换新 Nonce 重发]
  B -->|HTTP 422| H[修参数, 不要重试]
  B -->|业务码 60003| E
  B -->|业务码 60002| I[查产品状态定位原因]
  B -->|业务码 10001| J{data.errorCode}
  J -->|INVOICE_RESULT_NOT_READY| E
  J -->|其他汇总处理错误| K[联系平台处理来源或后台任务]
  J -->|无处理错误代码| L[核对参数和授权范围]

恢复方式 ​

场景做法
PROCESS 或 60003继续等待同一任务,不要重新创建授权
平台系统重试沿用 authorization_code 和 job_id,attempt_id 会变
税局会话失效,授权页要求重新录入凭据使用平台提供的当前授权入口继续,跟踪最新 attempt_id
TAX_ACCOUNT_RESTRICTED先按税局提示解除账号限制,不循环提交密码
BROWSER_START_FAILED / BROWSER_CLOSE_TIMEOUT属于采集环境恢复,由平台处理,不要求客户反复重新授权
INVOICE_COLLECTION_INCOMPLETE已取得部分文件但采集区间未完整完成;使用平台提供的重新授权入口,保留旧批次证据
INVOICE_DOWNLOAD_QUOTA_EXHAUSTED / INVOICE_EXPORT_QUOTA_EXHAUSTED税局额度受限,按平台恢复提示处理;重复授权不能恢复税局当日额度
INVOICE_VERIFICATION_POLICY_NOT_APPLIED按当前响应区分诊断警告与阻断失败;只有最终失败且要求系统重试时由平台检查节点,不循环提交企业凭据
VAT_INVOICE_REVENUE_MISMATCH收入核验差异率达到 40%,按 REAUTHORIZE 重新授权采集,不将已有产品可取数解释为整单通过
REVENUE_CHECK_ERROR收入核验执行异常,按 CONTACT_SUPPORT 联系平台
ORDER_FULFILLMENT_FAILED采集已完成但本单交付生成失败,由平台处理结果生成,无需重复采集
AUTHORIZATION_EXPIRED当前未提交授权已到期,重新生成后使用新的授权链接
AUTHORIZATION_SUPERSEDED链接已被下一代替换,停止使用旧链接
平台明确创建新授权代次authorization_code 会变,按新代次继续处理

不要因部分质量警告重建订单

state=SUCCESS 且 qualityStatus=WARNING / collectionResult=COMPLETED_WITH_WARNINGS 表示已有数据可用但覆盖不完整。保存 qualityIssues 与 dataQuality,按业务规则处理; 不要把它当成 60003 循环重试,也不要自动创建新的外部订单。

CONTACT_SUPPORT

平台提示恢复动作 CONTACT_SUPPORT 时停止自动重试, 保留错误码、external_order_id、job_id、attempt_id 联系平台。

哪些请求可以放心重试 ​

重试安全(术语叫「幂等」)的意思是:同一个请求重发多次,结果和只发一次一样, 不会产生重复数据或重复动作。

接口重试是否安全说明
创建授权✅ 业务参数一致时比对授权范围、企业、地址等;授权有效秒数和废弃模块筛选不参与已有授权冲突比对,详见创建授权说明
订单/产品查询✅只读
数据接口(Key 模式)✅只读
数据接口(签名模式)⚠️ 必须换新 Nonce复用 Nonce → 409 CHANNEL_REQUEST_REPLAYED
V2 游标⚠️ 换新 Nonce;同一 cursor 可重复请求以订单、执行批次、响应 datasetId 和请求游标保存读取进度
V2 分片包状态⚠️ 换新 Nonce;接口本身可安全重复调用会触发/推进准备流程
文件下载✅仅返回 Accept-Ranges: bytes 的接口支持 Range;普通 HTML 下载不保证支持

建议的重试节奏 ​

失败后不要立刻重试:先等一小段时间,每失败一次就把等待时间拉长(术语叫「指数退避」)。

错误类型首次等待上限最多次数
60003 / *_NOT_READY20 秒5 分钟按业务超时(如 2 小时)
429先遵循 Retry-After,无该头时降低并发并退避按业务超时按业务超时
5xx / 网络超时2 秒起,每次翻倍;状态轮询仍不少于 15 秒60 秒5
401 / 422不重试————

轮询下限

状态查询间隔不得低于 15 秒。更密集的轮询不会让采集更快, 只会增加客户端和服务端负担。税务容量限制返回 429 时,以实际 code 和 Retry-After 为准。

建议留存的排查信息 ​

无论走回调还是轮询,客户端都应把下面这些记录下来:

  • external_order_id、authorization_code、job_id、attempt_id
  • 每次请求的 X-Channel-Nonce 与响应的 code / message
  • 回调的 event_id 与 X-RPA-Delivery

排查时把这几项一起提供给平台,可以直接定位到具体采集尝试。

文档契约 API 1.5.169