文件
hl-api-changelog/changelogs-v2/2026-06/25_4360_发票申请删amount+门槛放宽+开票核单门槛-修改接口-管理后台.md
T

12 KiB
原始文件 Blame 文件历史

发票申请删 amount · 门槛放宽 · 开票/重传核单门槛(管理后台)

  • 接口:POST /v3/admin/order/{orderId}/invoice/apply + PUT /v3/admin/order/invoice/{id}/issue + PUT /v3/admin/order/invoice/{id}/reupload
  • 变更类型:修改接口,破坏性变更(申请入参删 amount;新增错误码 581524/581525;门槛扩展)
  • 端类型:管理后台
  • 日期:2026-06-25
  • Issue:#4353
  • PR:#4360

本次三项改动:1. 申请入参删 amount,开票时后端自动算;2. 申请门槛放宽至定制中及以后;3. 开票/重传新增核单门槛。


1 接口背景

发票模块本次 PR #4360 三项改动:

  1. 申请入参删 amount:开票金额不再前端传入,开票时后端按规则自动计算(正常单=应收总额;取消单=净实收)。
  2. 申请门槛放宽:原仅允许 COMPLETED 订单申请;放宽为定制中及以后均可申请,同时支持已取消但净实收 > 0 的订单。
  3. 开票/重传新增核单门槛:完成开票(issue)和重新上传(reupload)操作要求订单核单完成(reviewStatus=COMPLETED),防止未结算的订单开出金额有误的发票。

2 变更清单

# 变更项 变更前 变更后
1 POST apply 入参 amount 必填字段,前端传开票金额 已删除,后端开票时自动算
2 POST apply 申请门槛(正常订单) 订单状态必须 COMPLETED 状态 ∈ {CUSTOMIZING / PENDING_DEPARTURE / TRAVELLING / COMPLETED} 均可申请
3 POST apply 申请门槛(取消订单) 不允许 CANCELLED 且净实收(已付 - 已退)> 0 时可申请
4 PUT issue 操作门槛 仅检查发票状态为 REQUESTED 增加:订单核单完成(reviewStatus=COMPLETED)才可开票,否则 581525
5 PUT reupload 操作门槛 仅检查发票状态为 ISSUED/PUSHED 增加:订单核单完成才可重传,否则 581525
6 新错误码 581524 无 INVOICE_ORDER_NOT_APPLICABLE:订单不满足申请条件
7 新错误码 581525 无 INVOICE_ORDER_NOT_REVIEWED:订单核单未完成,不可开票/重传

3 接口详情

3.1 代客申请发票

属性 值
方法 POST
路径 /v3/admin/order/{orderId}/invoice/apply
描述 财务或定制师代客提交开票申请(申请阶段不填金额,开票时后端自动算)
认证 Bearer JWT(管理员)
幂等性 非幂等,重复提交触发 581511(一单一票)
限流 无特殊限制

3.2 完成开票

属性 值
方法 PUT
路径 /v3/admin/order/invoice/{id}/issue
描述 财务上传发票 PDF 并完成开票,状态 REQUESTED -> ISSUED;需订单核单完成
认证 Bearer JWT(管理员)
幂等性 状态守卫,非幂等
限流 无特殊限制

3.3 重新上传发票

属性 值
方法 PUT
路径 /v3/admin/order/invoice/{id}/reupload
描述 财务重新上传发票文件(ISSUED/PUSHED 均可);需订单核单完成
认证 Bearer JWT(管理员)
幂等性 覆盖写,非幂等
限流 无特殊限制

4 接口入参

4.1 路径参数

接口 参数名 类型 必填 说明
POST apply orderId string(Long 雪花) 是 订单 ID
PUT issue id string(Long 雪花) 是 发票记录 ID
PUT reupload id string(Long 雪花) 是 发票记录 ID

4.2 请求体字段

POST /v3/admin/order/{orderId}/invoice/apply(AdminInvoiceApplyReqVO,⚠️ amount 已删)

当前完整字段列表(无 amount):

字段 类型 必填条件 说明
invoiceType string 始终必填 发票类型,只有 VAT_NORMAL / VAT_SPECIAL 两值
titleType string 始终必填 抬头类型:COMPANY(单位)/ PERSONAL(个人);VAT_SPECIAL 只能 COMPANY
titleName string 始终必填 发票抬头(企业全称或个人姓名)
taxNo string titleType=COMPANY 或 invoiceType=VAT_SPECIAL 时必填 纳税人识别号
bankName string invoiceType=VAT_SPECIAL 时必填 开户银行名称
bankAccount string invoiceType=VAT_SPECIAL 时必填 银行账号
registAddress string invoiceType=VAT_SPECIAL 时必填 注册地址
registPhone string invoiceType=VAT_SPECIAL 时必填 注册电话
email string 始终必填 收件邮箱,需通过邮箱格式校验
remark string 选填 申请备注

PUT /v3/admin/order/invoice/{id}/issue

字段 类型 必填 说明
fileUrl string 是 upload 接口返回的 OSS 地址
pdfName string 否 PDF 文件名(展示用)
pdfSize Long 否 PDF 文件大小(字节)
invoiceNo string 否 发票号码

PUT /v3/admin/order/invoice/{id}/reupload

字段 类型 必填 说明
fileUrl string 是 新发票 PDF 的 OSS 地址
pdfName string 否 新 PDF 文件名
pdfSize Long 否 新 PDF 文件大小(字节)

5 出参字段

POST apply 响应:成功返回新建发票 ID(字符串,雪花 ID)。

PUT issue / reupload 响应:操作成功返回 HTTP 200,data 为 null。


6 枚举 / 数据字典

6.1 发票类型(invoiceType)

code 说明
VAT_NORMAL 增值税普通发票
VAT_SPECIAL 增值税专用发票

6.2 抬头类型(titleType)

code 说明 限制
COMPANY 单位 普票/专票均可
PERSONAL 个人 只能选 VAT_NORMAL;选 VAT_SPECIAL 返回 581523

6.3 订单状态与可申请关系

订单状态(code) 中文 可申请? 说明
CUSTOMIZING 定制中 是 放宽新增
PENDING_DEPARTURE 待出行 是 放宽新增
TRAVELLING 出行中 是 放宽新增
COMPLETED 已完成 是 原有
CANCELLED 已取消 条件是 净实收(已付 - 已退)> 0 时可申请
其他状态 - 否 报 581524

6.4 开票时金额自动计算规则

订单类型 金额计算公式 说明
正常单(非 CANCELLED) 应收总额 = 订单总价 + 增项 - 优惠 申请时不确定,开票时算
取消单(CANCELLED) 净实收 = 已付金额 - 已退金额 净实收 = 0 则拒绝申请

7 错误码

错误码 常量 触发场景
581502 INVOICE_CANNOT_ISSUE 发票状态非 REQUESTED,不允许开票
581503 INVOICE_CANNOT_REUPLOAD 发票状态非 ISSUED/PUSHED,不允许重新上传
581511 INVOICE_ALREADY_EXISTS 该订单已有有效发票,不可重复申请(一单一票)
581513 INVOICE_TYPE_INVALID 发票类型枚举值非法
581514 INVOICE_TAX_NO_REQUIRED 公司抬头/专票时税号为必填
581515 INVOICE_VAT_SPECIAL_FIELDS_REQUIRED 专票时开户行/银行账号/注册地址/注册电话为必填
581516 INVOICE_EMAIL_REQUIRED 收件邮箱为必填或格式错误(HTTP 400)
581523 INVOICE_VAT_SPECIAL_PERSONAL_FORBIDDEN 专票只能开给单位
581524 INVOICE_ORDER_NOT_APPLICABLE ✨ 新增:订单状态不在可申请集合内,或取消单净实收为 0
581525 INVOICE_ORDER_NOT_REVIEWED ✨ 新增:开票/重传时订单核单未完成(reviewStatus != COMPLETED)

8 示例

8.1 典型成功——普票申请(无 amount 字段)

请求

POST /v3/admin/order/1920000000000000001/invoice/apply
Authorization: Bearer <token>
Content-Type: application/json
{
  "invoiceType": "VAT_NORMAL",
  "titleType": "PERSONAL",
  "titleName": "李四",
  "email": "lisi@example.com",
  "remark": "报销使用"
}

响应

{"code": 200, "msg": "success", "data": "1934567890123456789"}

8.2 边界情况——取消订单且净实收 > 0 可申请

说明:订单已取消,实付 3000 元、退款 1000 元,净实收 2000 元 > 0,申请通过。开票时金额自动计算为净实收 2000 元。

请求(结构同 8.1,orderId 换为该取消订单 ID)

响应

{"code": 200, "msg": "success", "data": "1934567890123456700"}

8.3 业务失败——订单核单未完成,完成开票被拒

请求

PUT /v3/admin/order/invoice/1934567890123456789/issue
Authorization: Bearer <token>
Content-Type: application/json
{
  "fileUrl": "https://oss.example.com/invoice/2026/06/xxx.pdf",
  "pdfName": "发票_北京科技.pdf",
  "invoiceNo": "12345678"
}

响应(订单 reviewStatus 非 COMPLETED)

{"code": 581525, "msg": "订单核单未完成,不可开具发票", "data": null}

9 业务边界

适用:

  • POST apply:订单状态 ∈ {CUSTOMIZING / PENDING_DEPARTURE / TRAVELLING / COMPLETED},或 CANCELLED 且净实收 > 0
  • PUT issue:发票状态为 REQUESTED,且订单 reviewStatus = COMPLETED
  • PUT reupload:发票状态为 ISSUED/PUSHED,且订单 reviewStatus = COMPLETED

不适用:

  • POST apply:订单为 PAID(已支付但未进入定制阶段)、或 CANCELLED 且净实收 = 0,报 581524
  • PUT issue/reupload:订单核单未完成(reviewStatus != COMPLETED),报 581525

特殊边界:

  • 取消单开票金额 = 净实收(已付 - 已退),不是订单总价;正常单 = 应收总额
  • 一单一票:同一订单只允许一张有效发票(REQUESTED/ISSUED/PUSHED 状态),若已有则报 581511

10 修改前后对比

apply 入参字段对比

字段 变更前 变更后
amount 始终必填,JSON number,单位元 ⚠️ 已删除,后端开票时自动算

apply 申请门槛对比

场景 变更前 变更后
正常订单 仅 COMPLETED 可申请,其余报 581510 CUSTOMIZING / PENDING_DEPARTURE / TRAVELLING / COMPLETED 均可申请
取消订单 不允许 净实收 > 0 时可申请,= 0 报 581524
不满足时错误码 581510 INVOICE_ORDER_NOT_COMPLETED(已废弃) 581524 INVOICE_ORDER_NOT_APPLICABLE(新增)

issue / reupload 门槛对比

操作 变更前 变更后
PUT issue 仅检查发票状态为 REQUESTED 增加:订单核单完成(reviewStatus=COMPLETED),否则 581525
PUT reupload 仅检查发票状态为 ISSUED/PUSHED 增加:订单核单完成,否则 581525

11 影响评估 / 回滚

破坏兼容性:是

  • 前端申请表单必须删除开票金额输入框,不再传 amount 字段
  • 前端申请成功弹窗/提示中不展示金额(金额在开票时才确定)
  • 财务点击「完成开票」,若订单未核单则收到 581525,前端需展示「订单核单未完成,不可开票」提示

前端同步上线:申请表单删 amount 必须在本次后端部署后同步更新;财务开票侧 581525 错误提示须同步适配。

回滚方案:回滚后端至 #4360 前版本,amount 字段恢复必填,申请门槛收回到仅 COMPLETED,581524/581525 不再存在。


12 注意事项

  1. amount 字段已删:前端申请表单必须移除金额输入框,不传 amount。传入后端会忽略,导致用户困惑(以为填了金额实际无效)。
  2. 开票时金额自动写入:发票金额由后端在 issue 操作时根据订单类型自动计算,财务无需手填金额。
  3. 申请门槛放宽的注意点:定制中/待出行/出行中提前申请的发票,开票时(issue)后端按当时应收总额计算金额。财务须在核单完成后再开票(581525 已强制保证)。
  4. 核单门槛(581525):完成开票和重传均要求核单完成。财务若收到此错误,需先在核单管理页完成核单,再回来开票。
  5. 取消单申请:CANCELLED 订单申请发票,开票金额为净实收(已付 - 已退)。若净实收为 0,申请被 581524 拒绝。

13 关联 / 联系人