easyai-ai-gateway/docs/billing-flow-v2.md
chengcheng 8beb8501fa
Some checks failed
ci / verify (pull_request) Failing after 8s
fix(billing): 封住发布前计费竞态
阻止上游提交状态不明的任务被租约接管后重复执行,并为人工复核保留可操作的结算记录。

将生产提交绑定到当前估价签名,统一复用预处理快照,并补强规则形状、定点溢出与历史规则兼容校验。

已通过 PostgreSQL 16 集成测试、Go 全量测试与静态检查、前端测试与构建、OpenAPI、依赖审计、镜像、迁移、流水线和 SemVer 门禁。
2026-07-21 10:23:58 +08:00

2.8 KiB
Raw Blame History

计费业务流程 v2

正常流程

sequenceDiagram
  participant UI as 前端
  participant API as Gateway API
  participant DB as PostgreSQL
  participant UP as 上游模型
  participant BW as 结算 Worker

  UI->>API: 参数变化后的只读估价
  API->>DB: 读取有效计价规则
  API-->>UI: 首选预计费用 + 候选最大冻结额
  UI->>API: 正式提交(可带 Idempotency-Key
  API->>DB: 重新计价、保存快照并冻结最大金额
  API->>DB: 领取执行租约
  API->>UP: 提交已预处理请求
  UP-->>API: 成功结果与实际用量
  API->>DB: 原子写 Attempt、任务成功、最终金额和 settle Outbox
  API-->>UI: succeeded + billingStatus=pending
  BW->>DB: SKIP LOCKED 领取 Outbox
  BW->>DB: 原子扣费、释放冻结、完成 Outbox

失败与取消

上游提交前失败、上游明确失败和用户取消均在任务终态事务内写入 release Outbox。Worker 使用冻结流水的幂等键释放资金。若上游请求已经进入 submitting,或成功响应已返回但任务终态尚未提交,租约接管必须停止自动执行;任务和对应 Outbox 转人工复核并保留冻结。

人工复核记录在管理端明确显示后续动作。上游结果不明的记录只能由 Manager 在完成外部核查后确认释放;历史成功未扣费且金额快照可用的记录可由 Manager 明确确认结算。两类操作均要求确认、Idempotency-Key 和审计记录,且不会再次调用上游。

即时估价

前端仅对影响计费的字段生成稳定签名,包括模型、生成模式、数量、质量、分辨率、时长、音频、参考素材和 Token 上限。签名变化后等待 350ms取消旧请求并用递增序号阻止乱序响应覆盖。

界面必须区分:

  • 计算中;
  • 显式免费;
  • 正常预计费用与冻结上限;
  • 价格不可用;
  • 估价请求失败。

价格不可用或估价失败时禁止生产生成;模拟模式仍允许执行并显示原因。

Worker 参数

  • 轮询间隔1 秒。
  • 单批数量50。
  • 处理锁过期120 秒。
  • 最大自动尝试20 次。
  • 退避上限15 分钟。

这些参数是安全默认值,可通过受控配置调整,但不得改变幂等键、快照和账务不变量。

发布与回滚

BILLING_ENGINE_MODE 支持:

  • observe:并行计算并记录差异,不改变旧路径账务结果。
  • enforce:启用 v2 缺价拒绝、冻结与结算闭环。
  • hold:在调用上游前拒绝新的生产任务,已有 Outbox 继续处理。

发布先运行 24 小时 observe补齐所有缺价和非法规则再以 10% 流量启用 enforce确认没有重复扣费、长期冻结和异常差额后扩大到 100%。回滚只切换到 hold不回滚数据库增量也不恢复隐式零价。