在线续费开票接口
本文档包含在线续费流程中供前端使用的五个开票接口:开票抬头查询、开票申请提交、单订单及批量开票进度查询和电子发票下载。
通用约定
- 接口前缀:
/v3/console/package-renewal-order - 接口需要使用控制台现有的登录态调用。用户身份和订单归属由服务端从登录态取得,无需且不能在请求中传入
unionId。 POST请求的Content-Type为application/json。- 成功响应统一为:
{ "code": 200, "status": "success", "data": ... }。 - 失败响应的
status为error,错误详情位于error.code和error.desc。前端应使用status === "success"判断业务成功。
订单列表开票资格字段
GET /v3/console/package-renewal-order/list 的每个订单项新增以下字段:
| 字段 | 类型 | 说明 |
|---|---|---|
canApplyInvoice |
Boolean | 是否可申请在线发票。仅当订单为 live_console 在线续费订单、支付状态为支付成功,且创建时间不早于 ONLINE_INVOICE_LAUNCH_AT 配置的上线时间时为 true。 |
invoiceApplicationStatus |
String | 当前发票申请状态。canApplyInvoice=false 时为 null;可开票但未申请时为 NOT_APPLIED;已申请时为 PROCESSING(处理中)、ISSUED(已开票)或 FAILED(申请失败)。 |
前端仅对 canApplyInvoice=true 的订单处理发票入口:NOT_APPLIED 显示“申请开票”,ISSUED 显示“下载发票”,其余状态展示申请进度。批量查询接口可用于局部刷新状态。
服务端状态同步
客户提交申请后,申请状态先为 PROCESSING。支付服务会按 ONLINE_INVOICE_POLL_INTERVAL_SECONDS 配置周期轮询 PCS/CRM,并将 ISSUED、FAILED、发票号码、PDF 地址和失败原因写回申请表;终态不再轮询。轮询采用数据库租约,避免多实例重复更新同一申请。前端不需要依赖页面刷新来推进状态。
1. 查询历史开票抬头
按公司名称查询 CRM 中已有的开票抬头,用于自动回填纳税人识别号。未查询到记录时返回空数组,不代表请求失败。
请求
GET /v3/console/package-renewal-order/invoice-title
| 参数 | 位置 | 类型 | 必填 | 说明 |
|---|---|---|---|---|
companyName |
Query | String | 是 | 公司名称;按完整名称查询。 |
请求示例:
GET /v3/console/package-renewal-order/invoice-title?companyName=广州保利云科技有限公司
响应数据
data 为数组:
| 字段 | 类型 | 说明 |
|---|---|---|
companyName |
String | 开票抬头(公司名称)。 |
taxpayerId |
String | 纳税人识别号。 |
响应示例:
{
"code": 200,
"status": "success",
"data": [
{
"companyName": "广州保利云科技有限公司",
"taxpayerId": "91440101MA5XXXXXXX"
}
]
}
前端建议在用户完成公司名称输入后调用;若返回多条记录,允许用户选择对应的纳税人识别号。
2. 提交开票申请
为当前登录用户的在线续费订单提交电子发票申请。服务端会校验订单归属及可开票条件,并对同一订单的重复提交进行幂等处理。
请求
POST /v3/console/package-renewal-order/invoice-application
请求体字段:
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
orderId |
String | 是 | 在线续费订单 ID。 |
invoiceType |
String | 是 | 发票类型:VAT_SPECIAL(增值税专用发票)或 VAT_NORMAL(增值税普通发票)。 |
companyName |
String | 是 | 开票抬头(公司名称),不能为空。 |
taxpayerId |
String | 是 | 纳税人识别号,不能为空。 |
请求示例:
{
"orderId": "renewal_order_123456",
"invoiceType": "VAT_NORMAL",
"companyName": "广州保利云科技有限公司",
"taxpayerId": "91440101MA5XXXXXXX"
}
响应数据
data 为开票申请信息:
| 字段 | 类型 | 说明 |
|---|---|---|
orderId |
String | 续费订单 ID。 |
requestNo |
String | 开票申请流水号,用于关联本次申请。 |
invoiceType |
String | 发票类型,取值同请求参数。 |
companyName |
String | 开票抬头。 |
taxpayerId |
String | 纳税人识别号。 |
amountCent |
Long | 开票金额,单位为分;展示金额需除以 100。 |
status |
Integer | 开票状态码;状态枚举以服务端返回为准。 |
statusName |
String | 开票状态名称,前端可直接用于展示。 |
invoiceApplicationStatus |
String | 与订单列表一致的状态枚举:NOT_APPLIED、PROCESSING、ISSUED、FAILED。有申请记录时不会返回 NOT_APPLIED。 |
invoiceNo |
String | 发票号码;未开票时可能为空。 |
pdfUrl |
String | 电子发票 PDF 地址;未开票时可能为空。 |
failureReason |
String | 开票失败原因;仅失败时可能返回。 |
响应示例:
{
"code": 200,
"status": "success",
"data": {
"orderId": "renewal_order_123456",
"requestNo": "invoice_request_123456",
"invoiceType": "VAT_NORMAL",
"companyName": "广州保利云科技有限公司",
"taxpayerId": "91440101MA5XXXXXXX",
"amountCent": 99800
}
}
示例仅展示核心字段;实际响应会按上表返回开票状态及发票信息。提交前应禁用重复点击;即使因网络重试重复提交,服务端也会按订单处理幂等。申请提交成功仅表示申请已受理。
3. 查询开票进度
查询当前登录用户指定续费订单的开票申请状态。接口会同步 CRM 中的最新状态,适合在申请提交后或订单详情页刷新时调用。
请求
GET /v3/console/package-renewal-order/invoice-application
| 参数 | 位置 | 类型 | 必填 | 说明 |
|---|---|---|---|---|
orderId |
Query | String | 是 | 在线续费订单 ID。 |
请求示例:
GET /v3/console/package-renewal-order/invoice-application?orderId=renewal_order_123456
响应数据
data 的完整字段与第 2 节“提交开票申请”的响应数据一致。重点关注以下字段:
| 字段 | 类型 | 说明 |
|---|---|---|
status |
Integer | 开票状态码;状态枚举以服务端返回为准。 |
statusName |
String | 开票状态名称,可直接用于页面展示。 |
invoiceApplicationStatus |
String | 与订单列表一致的申请状态:未申请时为 NOT_APPLIED,已申请时为 PROCESSING、ISSUED 或 FAILED。 |
invoiceNo |
String | 已开票时返回发票号码。 |
pdfUrl |
String | 已生成电子发票时返回 PDF 地址。 |
failureReason |
String | 开票失败时返回失败原因。 |
响应示例:
{
"code": 200,
"status": "success",
"data": {
"orderId": "renewal_order_123456",
"requestNo": "invoice_request_123456",
"statusName": "开票中",
"invoiceApplicationStatus": "PROCESSING"
}
}
订单尚未申请时,接口返回:
{
"code": 200,
"status": "success",
"data": {
"orderId": "renewal_order_123456",
"invoiceApplicationStatus": "NOT_APPLIED"
}
}
4. 批量查询开票进度
用于订单列表批量判断操作项。接口仅接受当前登录用户的、已支付且支持在线开票的续费订单;任一订单不满足条件时,整个请求返回业务失败。
请求
POST /v3/console/package-renewal-order/invoice-application/batch
请求体字段:
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
orderIds |
String[] | 是 | 订单 ID 列表,不能为空,单次最多 100 个;重复 ID 会自动去重。 |
请求示例:
{
"orderIds": [
"renewal_order_123456",
"renewal_order_654321"
]
}
响应数据
data 为以订单 ID 为键的对象。每个值均含有 invoiceApplicationStatus,其取值与订单列表字段一致;未申请的订单仅返回 orderId 和 invoiceApplicationStatus=NOT_APPLIED。
{
"code": 200,
"status": "success",
"data": {
"renewal_order_123456": {
"orderId": "renewal_order_123456",
"statusName": "已开票",
"invoiceApplicationStatus": "ISSUED",
"invoiceNo": "1234567890",
"pdfUrl": "https://example.com/invoices/invoice_request_123456.pdf"
},
"renewal_order_654321": {
"orderId": "renewal_order_654321",
"invoiceApplicationStatus": "NOT_APPLIED"
}
}
}
订单列表展示规则:invoiceApplicationStatus=NOT_APPLIED 时显示“申请开票”;ISSUED 时显示“下载发票”;其他状态展示申请进度。不要使用 status 数值做前端分支。
5. 获取电子发票 PDF 下载地址
获取当前登录用户已开票续费订单的电子发票 PDF 地址。订单尚未开票时,服务端会返回业务失败响应。
请求
GET /v3/console/package-renewal-order/invoice-download
| 参数 | 位置 | 类型 | 必填 | 说明 |
|---|---|---|---|---|
orderId |
Query | String | 是 | 在线续费订单 ID。 |
请求示例:
GET /v3/console/package-renewal-order/invoice-download?orderId=renewal_order_123456
响应数据
data 的完整字段与第 2 节“提交开票申请”的响应数据一致,其中 pdfUrl 为本接口的核心字段。前端取得 pdfUrl 后可在新窗口打开或按现有下载策略处理。
响应示例:
{
"code": 200,
"status": "success",
"data": {
"orderId": "renewal_order_123456",
"requestNo": "invoice_request_123456",
"invoiceNo": "1234567890",
"pdfUrl": "https://example.com/invoices/invoice_request_123456.pdf"
}
}
推荐调用顺序
- 用户填写公司名称后,调用“查询历史开票抬头”回填或选择纳税人识别号。
- 用户确认开票信息后,调用“提交开票申请”。
- 在订单列表调用“批量查询开票进度”;在订单详情页或申请结果页调用“查询开票进度”,并依据
statusName、failureReason展示状态。 - 已开票后调用“获取电子发票 PDF 下载地址”,使用返回的
pdfUrl下载或预览发票。
