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

① 开票

开一张数电发票。所有业务共用这一个接口——普通商品直接调,属于税局认定的特定业务时在基础字段之外多传一块即可。开票是异步的:本接口只返回受理号,票要用②查结果拿。

属「正向开票 · 腾讯联用」——开票通道的签名与加密全在开灵中台,你只调这一个。

接口

POST  https://openapi.kailingteck.com/api/v1/invoice/forward/create

鉴权:X-App-Key + X-Timestamp(Unix 秒) + X-Sign(= sha256(appKey + 时间戳 + 报文原文 + appSecret) 小写十六进制)。与开灵其它接口完全一致。

请求参数

⚠️

开票数据真实性与税务责任

  • 发票的全部票面要素——购销方名称与纳税人识别号、商品名称与税收分类编码、数量金额与税率、 支付流水号等——必须真实,并与实际发生的业务一致。
  • 开灵仅提供接口通道与报文转发,不对报文内容做真实性核验,也无从判断一笔业务是否真实发生。
  • 若因填报虚假、编造或与实际业务不符的数据(例如编造的支付流水号、不实的购方税号、 与真实交易不符的商品名称或税收分类编码)导致发票异常、被税务机关核查或稽查,相关法律责任与后果由开票方(销方)自行承担。
  • 两点建议:没有真实线上支付环节就不要传 pay_info, 留空即可;税收分类编码拿不准时,先与主管税务机关或开灵确认后再开,不要试错。
字段必填大白话说明
order_id必填你侧订单号,全局唯一。查结果、红冲都用它,不要复用
seller_taxpayer_num必填销方税号(开票方,即贵司税号)。★须与实际业务一致,虚假填报引发的税务责任由开票方承担。
terminal_code必填数电票规则:传销方税号,不是传统税盘号
invoice_type_code必填082 全电电子普票 / 081 全电电子专票
title_type必填抬头类型:1 个人或政府事业单位 / 2 企业
buyer_title必填购方名称。title_type=2 时 buyer_taxpayer_num 也必填。★须为真实购买方,不得虚构或代填他人抬头。
buyer_taxpayer_num条件购方税号,抬头类型为企业时必填。★须与实际业务一致,虚假填报引发的税务责任由开票方承担。
drawer必填开票人姓名,需与电子税务局登记一致。★不得填写他人姓名。
amount_has_tax必填含税总金额,元,两位小数。★须等于实际成交金额,★须与实际业务一致,虚假填报引发的税务责任由开票方承担。
amount_without_tax必填不含税总金额
tax_amount必填总税额。★须与金额、税率自洽(不含税金额+税额=含税金额),不得凑数。
items[].name必填商品名称,50 字内。不含 < > / & 等特殊符号。部分特定业务对名称写法另有要求,见下方对应的业务块。★须如实反映所售商品或服务,不得以其他品名替代。
items[].tax_code必填税收分类编码,见税局分类编码表。★须与商品或服务的实际属性匹配;拿不准的先与主管税务机关或开灵确认,不要试错。编码错配引发的税务责任由开票方承担。
items[].total_price必填该行不含税金额 = 含税金额 ÷(1+税率),两位小数
items[].tax_rate必填税率,最多三位小数。★须为该商品或服务适用的法定税率,不得自行调整。
items[].tax_amount必填该行税额 = 不含税金额 × 税率,两位小数
items[].total条件数量,最多 8 位小数。传了 price 就必填
items[].price条件不含税单价 = 不含税金额 ÷ 数量。传了 total 就必填
items[].unit选填商品单位,显示在票面「单位」栏,可填「个」「次」等。部分特定业务对单位取值有强制要求,见下方对应的业务块
items[].models选填规格型号,显示在票面「规格型号」栏
items[].discount选填含税折扣总金额,必须是负数
items[].preferential_policy_flag选填优惠政策标志
items[].zero_tax_flag选填零税率标识
pay_info[]选填支付信息集合。★开灵实测:不传也能开出票。但如果你的业务有真实线上支付环节(尤其成品油「支付即开票」),建议如实传——通道文档要求乐企联用传真实渠道流水号,编造的流水号在支付与发票匹配核验时有风险
pay_info[].pay_num选填★真实的渠道交易流水号(微信支付流水号以 420 开头)。没有线上支付环节就留空,不要编一个填进去——虚构流水号引发的税务风险由开票方承担
pay_info[].pay_channel_code选填交易渠道代码:001 现金 / 002 银行转账 / 003 票据 / 004 借记卡 / 005 信用卡 / 006 购物卡券 / 007 优惠券 / 008 商场积分 / 009 支付宝 / 010 微信支付 / 011 云闪付 / 012 Apple Pay / 013 Samsung Pay / 099 其他。★通道文档写明乐企联用只支持微信支付(010);实测传 001 现金也能开,但以真实支付方式为准
callback_url必填★开票结果回传地址——回调不用另外配置,就是随这个请求送过去的。开票状态一变,平台会 POST 推到这个地址;推送字段见下方「开票结果回调」块。不想轮询就靠它。红冲的回传地址在 ③ 的 invoices[].callback_url 里单独传
specific_business_code特定业务必填★特定业务代码——这是通往「特定业务」的入口。普通开票不填;做税局认定的特定业务时填对应代码,并在请求体顶层加上该代码对应的字段块。取值:01 成品油 / 03 建筑服务 / 04 货物运输 / 05 不动产销售 / 06 不动产经营租赁 / 09 旅客运输 / 13 拖拉机和联合收割机 / 15 数电二手车 / 51、52 二手车销售统一发票。★农产品收购(16)、自产农产品(12)、报废产品收购(24)不在本产品范围——这三类是收购方开给出售方的票,属于反向开票,请用平台的「反向开票」产品
special_invoice_kind选填特殊票种标识,普通开票传空或 00。做特定业务时按业务取值,具体取值见下方对应的业务块
e_extra_info选填特殊行业扩展信息,传 JSON 字符串(不是对象)。医疗服务住院(specific_business_code=10)/门诊(=11)时传病人信息;乐企微信支付拆分金额时传支付订单数据

请求示例(基础字段,特定业务的完整报文见下方各业务块)

{
  "order_id": "REG1788017096448",
  "invoice_type_code": "082",
  "seller_taxpayer_num": "91110119MABQDU249D",
  "seller_name": "北京湛露科技有限公司",
  "seller_address": "北京市",
  "seller_tel": "01000000000",
  "seller_bank_name": "测试银行",
  "seller_bank_account": "1234567890",
  "title_type": 1,
  "buyer_title": "个人",
  "terminal_code": "91110119MABQDU249D",
  "drawer": "开灵测试",
  "callback_url": "https://你们的域名/invoice/callback",
  "template": 1,
  "amount_has_tax": "1.00",
  "amount_without_tax": "0.88",
  "tax_amount": "0.12",
  "taxpayer_confirmation": {
    "draw_with_nobuyer_flag": 1
  },
  "items": [
    {
      "name": "办公用品",
      "tax_code": "1080118000000000000",
      "unit": "个",
      "total": "1",
      "price": "0.88",
      "total_price": "0.88",
      "tax_rate": "0.13",
      "tax_amount": "0.12",
      "amount_has_tax": "1.00"
    }
  ]
}

上面那张是基础字段,所有票都要填。做税局认定的特定业务(运输、建筑、租赁、成品油…)时, 在同一个请求体里还要补两样:

  1. 把 specific_business_code 填成你这行的业务代码;
  2. 在请求体顶层(和 items 平级,不是塞进 items 里)加上该业务对应的那一块对象。
{
  "order_id": "...",
  "specific_business_code": "06",   ← ① 填业务代码(这里以不动产租赁为例)
  "items": [ ... ],
  "real_static_rent": {             ← ② 与 items 平级,加在顶层
    "property_num": "无",
    "location": "北京市大兴区",
    ...
  },
  "pay_info": [ ... ]
}

每一块都写清楚了什么时候触发、加在哪里, 并附一份已经把基础字段合并好的完整报文,不用自己拼。 每块只列额外要传的字段,基础字段看上面那张表。

⚠ 有 4 块不是由 specific_business_code 触发的(差额征税、销方/购方证件信息、冠名发票), 各自的触发条件写在块里,别照着业务代码找。

一、特定业务(由 specific_business_code 决定)

填了哪个业务代码,就在顶层加上对应的这一块。不做这行就都不用管。

二、按场景补充(和业务代码无关)

这几块不看业务代码,看的是主体性质、票种或模板—— 比如开给自然人要带证件信息、走差额征税要带扣除额。别照着 specific_business_code 找它们。

返回

统一信封 code/msg/requestId/timestamp/data,业务字段都在 data 里。code 为 CYT_00000 表示调用成功。

返回参数(data)

字段大白话说明
state受理状态,1 表示已受理、开票中
order_sn通道受理号。★查结果时可以用它,也可以用你自己的 order_id
invoice_id同 order_sn(值一样)
mocktrue=演示数据,未真实开票

返回示例(成功)

{
  "code": "CYT_00000",
  "msg": "success",
  "data": {
    "state": 1,
    "order_sn": "7499487274632001743",
    "invoice_id": "7499487274632001743",
    "mock": false
  }
}

返回示例(失败)

{
  "code": "CYT_50200",
  "data": {
    "upstreamCode": 1014,
    "upstreamMessage": "第1项商品明细中,开票明细金额校验失败"
  }
}

异常与报错

情形含义与处理
开票明细金额校验失败★最常见。要求 price × total 精确等于 total_price,且 total_price + tax_amount = amount_has_tax。用能整除的数字,别让小数除不尽
无法映射到「成品油单位」枚举★成品油的 unit 只能填 LITER 或 TON(英文大写)。填中文「升」「吨」会报这个错
企业开具成品油发票必须有成品油经销、生产资质销方企业没有成品油经营资质。这是税务资质问题,不是接口问题,需企业向主管税务机关办理
tax_code 不对税收分类编码要按油品/商品准确填,汽油为 1070101010100000000
order_id 重复同一个订单号不能重复开票

前端怎么用

const r = await post('/api/v1/invoice/forward/create', payload);
save(r.data.order_sn);      // 存下来,查结果要用
// 开票是异步的,接着轮询②查结果

所有业务共用这一个开票接口,区别只在于「除了基础字段,还要不要多传一块特定业务字段」。选你的场景,照那一块的完整报文改值即可。