跳到正文
开灵科技 - 北京开灵科技有限公司API百宝箱

⑧ 下载发票

单独下载某张发票文件。日常查结果(⑤)带 withInvoice 就够了,这个用于补下载、单独取票。数据类接口。

属「工商银行 · 业务型接口」——底层编排 乐企直联原子接口,你只调这一个。

下载发票

接口 · 下载发票(数据类)

POST  https://openapi.kailingteck.com/api/v1/rinv/invoice/download

鉴权:X-App-Key + X-Timestamp + X-Sign(= sha256(appKey + 时间戳 + 报文 + appSecret))。

请求参数

字段必填大白话说明
orderId必填订单号
invoiceFormat选填格式:1 ofd / 2 pdf / 3 xml(默认 2)
isRedOrblue选填01 蓝票 / 02 红票(默认 01)

请求示例

{
  "orderId": "ORD1",
  "invoiceFormat": "2",
  "isRedOrblue": "01"
}

返回

所有接口都用同一层信封:code/msg/requestId/timestamp/data。业务字段都在 data 里,下表列的就是 data 的内容。code 为 CYT_00000 表示调用成功。

返回参数(data)

字段大白话说明
orderId回显订单号
byteData★票文件的 base64,解一次码就是文件本体(2026-09-16 起网关已把工行返回的双层编码解掉一层;此前自行按文件头做过双层兼容的接入方不受影响)
format票文件格式:1 ofd / 2 pdf / 3 xml
raw工行原始全字段

返回示例(成功)

{
  "code": "CYT_00000",
  "data": {
    "orderId": "ORD1",
    "byteData": "JVBERi0xLjQK……(base64)",
    "format": "2",
    "mock": false,
    "raw": { }
  }
}

异常与报错

情形含义与处理
byteData 为空这一单还没开票成功,先用⑤确认 status=done
要红票传 isRedOrblue=02;红冲后才有红票

前端怎么用

// data.byteData 是 base64,前端解码成文件下载
const blob = b64toBlob(res.data.byteData, 'application/pdf');

上传重试

接口 · 上传重试(数据类)

POST  https://openapi.kailingteck.com/api/v1/rinv/invoice/uploadRetry

鉴权:X-App-Key + X-Timestamp + X-Sign(= sha256(appKey + 时间戳 + 报文 + appSecret))。

请求参数

字段必填大白话说明
orderId必填上传失败那一单的订单号
userId选填收款散户ID(收方编号)。不传时平台按订单号自动查出来补上,一般不用传
vendorId选填企业子商户编号(付方编号)。不传时同上自动补齐,或取后台配置

请求示例

{
  "orderId": "ORD1"
}

返回

所有接口都用同一层信封:code/msg/requestId/timestamp/data。业务字段都在 data 里,下表列的就是 data 的内容。code 为 CYT_00000 表示调用成功。

返回参数(data)

字段大白话说明
accepted★true=重试已受理;false=没受理,看 uploadFailReason
uploadStatus工行上传状态:02 已受理 / 05 上传失败
uploadFailReason上传失败的原始原因(如「他用或联用企业开票人未授权开票」)
raw工行原始返回

返回示例(成功)

{
  "code": "CYT_00000",
  "msg": "success",
  "data": {
    "orderId": "ORD1",
    "accepted": true,
    "uploadStatus": "02",
    "mock": false
  }
}

前端怎么用

const r = await post('/api/v1/rinv/invoice/uploadRetry', { orderId });
if (!r.data.accepted) alert(r.data.uploadFailReason);   // 先修原因再重试

仅支持反向蓝票。场景:⑤查结果 status=done_upload_failed(states.upload=05,上传税局失败)时,先把失败原因修掉——最典型的是开票人没在电子税务局做乐企授权,授权补齐后调这里重新上传,不用重新开票;受理后用⑤轮询,upload 变 02、status 变 done 后即可下载票文件。

所有接口通用的报错(平台层)

HTTP / code含义与处理
400 · CYT_40001必填参数没传,data.hint 里写了缺哪个
401 · CYT_40100 / 40102缺鉴权头,或签名算错。签名 = sha256(appKey + 时间戳 + 报文原文 + appSecret),参与签名的报文必须与实际发送的逐字节一致
401 · CYT_40103时间戳与服务器相差超过 300 秒,校准本机时间后重试
403 · CYT_40301这把密钥的产品或渠道不对(工行接口需要「反向开票」产品 + 「工商银行」渠道)
429 · CYT_42901超过每分钟 120 次限流,稍后重试
502 · CYT_50200工行侧暂时不可达。注意工行测试环境每晚 19:00 后关闭、次日恢复,联调请排在工作时间
200 · data.mock=true尚未配置工行凭据,返回的是演示数据、并未真调工行