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

⑤ 查开票结果

把工行的 5 个原始状态翻成一个业务态,给你发票号 + 税额;带 withInvoice=true 时顺带把票文件也取回来。数据类接口。

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

接口(数据类)

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

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

请求参数

字段必填大白话说明
orderId必填你侧订单号(与④一致)
withInvoice选填true=顺带把发票文件一起取回
invoiceFormat选填票文件格式:1 ofd / 2 pdf / 3 xml(默认 2)
vendorId选填服务商ID
userId选填散户ID

请求示例

{
  "orderId": "ORD1",
  "withInvoice": true,
  "invoiceFormat": "2"
}

返回

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

返回参数(data)

字段大白话说明
status★业务状态。waiting_confirm 待散户确认 → waiting_pay 待付款 → invoicing 开票中 → done 已完成;failed 开票失败;cancelled 已取消(⑦取消开票之后的终态);done_upload_failed 开票完成但上传税局失败(票文件下载不到,看顶层 uploadFailReason,修复后调⑧的「上传重试」);processing 处理中
invoiceCode发票号码(开出来才有)
taxAmount合计税额(工行/税局算好的,不是我们算的)——这是发票票面上的增值税税额
taxRealAmount★实缴税费合计:工行实际代扣的全部税费总额,通常大于等于票面税额 taxAmount,差额是个税等非票面税费。财务对账用它
actuallyReceivedAmount★散户实际到手金额(付款金额扣完实缴税费后的净额,以工行返回为准)
invoiceLevyItemResponse★税费征收分项明细(数组):每项含征收项目/品目名称与代码、计税依据 taxBasis、税率 taxRate、应缴税额 taxPayable、应补退税额 taxCreditPayable、税款所属期。回答「这张票各税种各扣了多少」就靠它
payAmount合计金额(票面含税)
states.confirm工行原始:自然人确认状态 00 未确认 / 01 自然人已确认 / 02 全部确认完成
states.pay工行原始:支付状态 02 成功
states.invoice工行原始:开票状态 00 初始 / 01 开票中 / 02 成功 / 03 失败
states.upload工行原始:发票上传状态 04 上传成功
states.tax工行原始:缴税状态 04 缴税成功
invoice.byteDatabase64 编码的票文件(只有 withInvoice=true 且已开票成功时才有)
invoice.format票文件格式
raw工行预查询接口的原始全字段

返回示例(成功)

{
  "code": "CYT_00000",
  "msg": "success",
  "data": {
    "orderId": "ORD1",
    "status": "done",
    "invoiceCode": "26367200000123456789",
    "taxAmount": "42.81",
    "payAmount": "5018.35",
    "states": {
      "confirm": "02",
      "pay": "02",
      "invoice": "02",
      "upload": "04",
      "tax": "04"
    },
    "invoice": {
      "byteData": "JVBERi0xLjQK……(base64)",
      "format": "2"
    },
    "mock": false
  }
}

返回示例(失败 / 业务拦截)

// 开票失败
{
  "code": "CYT_00000",
  "data": {
    "orderId": "ORD1",
    "status": "failed",
    "states": { "invoice": "03" }
  }
}

异常与报错

情形含义与处理
status 长期停在 waiting_confirm散户还没在工行侧确认这一票,需要引导散户去确认
status 长期停在 waiting_pay老板还没付款。付款是扳机,不付不开票
status=failed看 raw 里工行给的失败原因。常见:企业忘了在电子税务局手动下载一次发票、额度不足
status=done_upload_failed / states.upload=05★票开出来了但上传税局失败,票文件下载不到。看顶层 uploadFailReason;典型:「他用或联用企业开票人未授权开票」=开票人没在电子税务局做乐企授权——授权补齐后调⑧的「上传重试」重新上传即可,不用重新开票
invoice 字段没有要么没传 withInvoice=true,要么还没开票成功

前端怎么用

// 轮询直到 data.status === 'done'
if (res.data.status === 'done') download(res.data.invoice.byteData);

税额是工行算好后取回的,平台不参与计算。五个原始状态都放在 states 里,排查时看它比看 status 更细。

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

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尚未配置工行凭据,返回的是演示数据、并未真调工行