Files
heicode-mananger/docs/integration/Heicode-Manager-PayPal支付接入与计费关系说明.md
chenchenandClaude Opus 4.8 0fe1d20d67 feat(agent): unify agnet→agent and implement client/runtime unification spec v0.1 core
按桌面客户端统一方案 v0.1 + agent_management Sub Mode Runtime 对接,强制全量统一,不留兼容。

命名统一(强制,无兼容):
- 全仓 agnet/Agnet/AGNET → agent/Agent/AGENT:后端 Go(路由 /api/agent/*、env AGENT_*、
  结构体/函数、19 个文件改名)、前端(agent-console/agent-hub、/api/agent 调用、i18n)、
  DB(表 agent_*、列 agent_id)、compose/.env、文档、脚本。
- DB 加幂等迁移 renameAgnetTablesToAgent():启动时 rename 老 agnet_* 表/列,保住生产数据。

统一方案核心(10 项):
- callback 统一 /api/agent/callbacks/runtime-events(路由/广播URL/函数名)。
- artifact 兜底判定改用 Runtime 权威信号 metadata.synthesized(§7.2)+ 结构化 artifact_type。
- Manager→Runtime 路径对齐 /api/agent/sub-agile/deployments(§2.2),{deployment_id} 回退 swarm_id。
- 状态裁决 display_status:Manager 唯一裁判,completed 无有效产物→needs_codegen/
  completed_without_deliverable(§10.6),接入 detail/timeline/workflow。
- GET /api/heicode/capabilities 能力发现(§6)。
- 模型策略 per_role(role_models)+ 收集 allowed_model_ids(§9)。
- resource_binding_id→secret_ref 服务端解析,客户端不再 inline secret_ref(§17.6)。
- 客户端统一路由层 /api/heicode/sub-agile|swarm/*(task≡deployment,复用控制面)+ workflow 投影。
- 日志分层 user_logs/debug_logs(§13)。

验证:go build ./... + go test(controller/router/model/middleware)全绿;前端 tsc -b + rsbuild build 通过。
待部署:VM .env 的 AGNET_*→AGENT_*;启动迁移自动 rename 表;其他三仓库需同步切到 /api/agent。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-01 23:45:10 +08:00

14 KiB
Raw Permalink Blame History

Heicode Manager PayPal 支付接入与计费关系说明

更新时间:2026-05-28

1. 结论

Heicode Manager 目前已经有余额充值、套餐订阅、订单、回调、补单、模型调用扣费和订阅扣费的基础能力。当前要接 PayPal,优先不要重做计费体系,而是在现有支付网关抽象中新增 paypal 支付提供方。

建议分两期:

阶段 范围 说明
第一期 PayPal Checkout 一次性支付 覆盖余额充值和 Heicode 内部订阅套餐购买。支付成功后沿用现有 top_ups、subscription_orders、user_subscriptions 逻辑。
第二期 PayPal 原生自动续订 只有业务明确需要自动续费时再做。需要新增 PayPal product / plan / subscription 映射、续费 webhook、取消和过期同步。

当前更稳妥的方案是第一期:用户通过 PayPal 支付一笔钱,Manager 在回调确认成功后给用户增加余额或开通一个 Heicode 内部订阅套餐。

2. 现有计费对象

对象 当前代码/表 作用
钱包余额 users.quota 用户模型调用的可用余额。
充值订单 top_ups 记录一次余额充值订单,成功后增加用户 quota。
订阅套餐 subscription_plans 管理员配置套餐价格、周期、总额度、重置周期、升级分组。
订阅订单 subscription_orders 用户购买套餐时生成订单,支付成功后创建用户订阅。
用户订阅 user_subscriptions 用户已购买的套餐实例,模型调用可优先从订阅额度扣。
订阅预扣记录 subscription_pre_consume_records 模型调用时对订阅额度做预扣、结算、失败退款。
模型调用日志 logs、task 相关表 记录模型、用量、扣费、请求状态。

3. 充值后模型费用怎么走

余额充值和模型扣费是两个独立阶段。

3.1 充值阶段

用户发起充值:

用户选择充值金额
-> Manager 创建支付订单
-> PayPal 创建 checkout order
-> 用户跳转 PayPal 支付
-> PayPal 回调 Manager
-> Manager 验证回调和订单状态
-> top_ups 标记 success
-> users.quota 增加对应额度
-> 记录充值日志

现有非 PayPal 代码里,充值金额换算逻辑大致是:

支付金额 = 用户选择的充值数量
       * Price
       * TopupGroupRatio
       * AmountDiscount

如果系统展示类型是 tokens,则会先按 QuotaPerUnit 换算成金额单位。当前生产公开状态中 quota_display_type=USD,quota_per_unit=500000,price=7.3,说明用户侧余额展示和内部 quota 之间已有换算关系。

PayPal 接入后也应复用同一套换算规则,不应单独发明 PayPal 专属余额单位。

3.2 模型调用扣费阶段

模型调用时不是从 PayPal 扣费,而是从 Heicode / NewAPI 的余额或订阅额度扣。

流程:

客户端/网页发起模型调用
-> Manager / NewAPI relay 计算模型费用
-> 根据用户计费偏好选择资金来源
-> 预扣额度
-> 请求上游模型
-> 根据真实 usage 结算差额
-> 成功记录日志,失败则退款预扣

当前资金来源有两类:

资金来源 代码标识 说明
钱包余额 wallet 从 users.quota 扣。
订阅额度 subscription 从 user_subscriptions.amount_used 扣。

用户计费偏好:

偏好 说明
subscription_first 默认。优先订阅额度,不足或无订阅时回退钱包。
wallet_first 优先钱包余额,不足时回退订阅。
subscription_only 只用订阅额度。
wallet_only 只用钱包余额。

因此 PayPal 只负责把钱变成 Heicode 的余额或订阅权益;后续模型费用仍由现有 NewAPI/Manager 计费链路处理。

4. NewAPI / CodeGW 的订阅模式

产品文档里 CodeGW / NewAPI 的定位是模型网关和计费服务。普通用户不进入 NewAPI 后台,只在 Heicode Manager / 客户端看模型、余额、额度、调用日志。

当前代码里的“订阅”不是 PayPal 原生订阅,而是 Heicode 内部套餐:

subscription_plans
-> 用户购买
-> subscription_orders
-> 支付成功
-> user_subscriptions
-> 模型调用扣订阅额度

套餐可配置:

字段 说明
price_amount 套餐展示价格。
duration_unit / duration_value 套餐有效期,如月、年、天。
total_amount 套餐总额度,0 可表示不限量。
quota_reset_period 额度重置周期,如 daily / weekly / monthly / never。
upgrade_group 购买后升级用户分组。
max_purchase_per_user 单用户购买上限。

PayPal 接入时有两种做法:

做法 推荐度 说明
PayPal 一次性支付购买内部套餐 高 最小改动,支付成功后创建 user_subscriptions。适合当前系统。
PayPal 原生订阅自动续费 中 需要维护 PayPal subscription 状态和续费 webhook,复杂度更高。

建议第一期先实现“一次性支付购买内部套餐”。这样不改变 NewAPI 订阅扣费逻辑,也不要求 PayPal 成为系统账本。

5. Agent 运行费用是否在项目设计文档里

有,但目前文档里表达的是“预算和用量上限”,不是已经完整落地的独立收费账本。

相关设计口径:

文档口径 含义
budget.max_tokens 本次 Agent / Agent 部署允许消耗的 token 上限。
budget.max_cost_usd 本次 Agent / Agent 部署允许消耗的美元成本上限。
budget.max_duration_sec 本次 Agent / Agent 部署允许运行的时间上限。
billing_context.provider = newapi 表示模型调用费用应映射到 NewAPI 用户、Token、Group 或 quota。
agent_runtime 表示子 Agent 角色、模型 profile、实例数,不能和 NewAPI 扣费对象混在一起。

产品文档明确:子 Agent 的运行模型属于 Agent 平台部署配置,不等同于 CodeGW 后台模型供应商配置。NewAPI 负责模型网关、余额、用量、日志和扣费;Agent 平台负责真实执行和运行态。

所以当前要分成两类费用:

费用类型 当前是否有闭环 说明
模型调用费用 有 通过 Manager/NewAPI 的 quota、subscription、usage 日志扣费。
Agent 运行预算 有字段和展示/回调基础 deployment payload 和事件里有 budget,但真实成本依赖 Agent Manager / Runtime 回传。
Agent 基础设施费用 未形成用户账本 CPU、内存、Pod、运行时资源成本目前不是 Manager 本地自动扣费项。

如果后续要把 Agent 运行也收费,需要 Agent Manager 回传真实用量:

{
  "deployment_id": "dep_xxx",
  "agent_instance_id": "agi_backend_001",
  "usage": {
    "model_tokens": 32000,
    "model_cost_usd": 4.21,
    "runtime_seconds": 930,
    "cpu_core_seconds": 1200,
    "memory_mb_seconds": 2048000
  },
  "billing_source": "newapi",
  "correlation_id": "corr_xxx"
}

没有 Runtime 真实回传前,Manager 不能把页面上的预算估算当成真实扣费依据。

6. PayPal 接入建议接口

PayPal 官方当前推荐一次性结账使用 Orders v2 API:创建订单后,用户批准,再 capture 订单。订阅自动续费使用 PayPal Subscriptions API 和订阅 webhook。

6.1 钱包充值

新增接口:

POST /api/user/paypal/pay

请求:

{
  "amount": 20,
  "success_url": "https://code.xinghanlab.com/console/topup?pay=success",
  "cancel_url": "https://code.xinghanlab.com/console/topup?pay=cancel"
}

响应:

{
  "message": "success",
  "data": {
    "approval_url": "https://www.paypal.com/checkoutnow?token=ORDER_ID",
    "order_id": "PAYPAL_ORDER_ID",
    "trade_no": "PPUSR1NO..."
  }
}

回调:

POST /api/paypal/webhook

处理规则:

  1. 验证 PayPal webhook 签名。
  2. 根据 PayPal order / capture id 找到本地 top_ups.trade_no 或 provider reference。
  3. 确认支付状态为完成。
  4. 幂等加锁,避免重复加余额。
  5. 将 top_ups.status 改为 success。
  6. 增加 users.quota。
  7. 记录充值日志。

6.2 内部订阅套餐购买

新增接口:

POST /api/subscription/paypal/pay

请求:

{
  "plan_id": 3,
  "success_url": "https://code.xinghanlab.com/console/topup?pay=success",
  "cancel_url": "https://code.xinghanlab.com/console/topup?pay=cancel"
}

响应:

{
  "message": "success",
  "data": {
    "approval_url": "https://www.paypal.com/checkoutnow?token=ORDER_ID",
    "order_id": "PAYPAL_ORDER_ID",
    "trade_no": "SUBPPUSR1NO..."
  }
}

支付成功后复用现有逻辑:

CompleteSubscriptionOrder(trade_no, provider_payload, "paypal", "")

最终效果:

subscription_orders.status = success
-> 创建 user_subscriptions
-> 可按 billing_preference 从订阅额度扣模型费用

7. 需要新增或调整的数据字段

最小实现可以复用现有字段:

表 字段 用途
top_ups.payment_provider paypal 标识支付提供方。
top_ups.payment_method paypal 标识支付方式。
top_ups.trade_no 本地订单号 本地幂等主键。
subscription_orders.payment_provider paypal 标识订阅订单来自 PayPal。
subscription_orders.provider_payload PayPal 回调摘要 保存脱敏后的回调信息。

建议新增字段或配置:

类型 名称 说明
Option PaypalClientId PayPal REST app client id。
Option PaypalClientSecret PayPal REST app secret,保存时不回显。
Option PaypalWebhookId PayPal webhook 验签需要。
Option PaypalEnvironment sandbox / live。
Option PaypalCurrency 默认 USD。
Option PaypalMinTopUp PayPal 最小充值金额。
Model const PaymentMethodPaypal 值为 paypal。
Model const PaymentProviderPaypal 值为 paypal。

如果第二期做 PayPal 原生自动续订,再新增:

字段 说明
subscription_plans.paypal_plan_id PayPal 端 plan id。
user_subscriptions.provider_subscription_id PayPal subscription id。
user_subscriptions.auto_renew 是否自动续费。
subscription_orders.provider_order_id PayPal order/capture/subscription 关联 ID。

8. 前端页面变化

钱包充值页:

  1. 充值方式增加 PayPal。
  2. 点击 PayPal 后调用 /api/user/paypal/pay。
  3. 成功后打开 approval_url。
  4. 回到 success_url 后刷新余额和充值记录。

套餐订阅页:

  1. 购买弹窗增加 PayPal。
  2. 点击后调用 /api/subscription/paypal/pay。
  3. 支付成功后刷新我的订阅。

管理员设置页:

  1. 支付设置增加 PayPal 配置块。
  2. Secret 类型字段保存后不回显原文。
  3. 展示 webhook 地址:https://code.xinghanlab.com/api/paypal/webhook。

9. 安全和幂等要求

要求 说明
webhook 必须验签 不能只信任前端 return URL。
本地订单必须先创建 不能收到 PayPal 回调才创建订单。
回调必须幂等 同一 trade_no 或 PayPal capture id 重复通知不能重复加余额或重复开通订阅。
支付金额必须二次校验 PayPal 回调金额、币种必须等于本地订单金额、币种。
支付提供方必须匹配 防止用其他支付网关回调完成 PayPal 订单。
密钥不进日志 client_secret、webhook 签名、access token 不得写日志。
退款先不自动扣回 第一期可只记录 PayPal refund/dispute 事件,由管理员人工处理;后续再做自动扣减。

10. 当前项目还缺什么

项 当前状态 PayPal 接入需要做
钱包充值闭环 已有,非 PayPal 新增 PayPal provider/controller/service。
内部订阅闭环 已有,非 PayPal 新增 PayPal 购买入口并复用 CompleteSubscriptionOrder。
模型费用扣费 已有 不需要因 PayPal 重写。
NewAPI/CodeGW 用户侧余额和日志 已有基础 PayPal 只影响充值入口,不影响模型计费规则。
Agent 运行预算 有字段和回调基础 真实收费需要 Agent Manager 回传真实 usage。
Agent 基础设施收费 未闭环 需要单独设计资源计价规则和 Runtime 用量回传。
PayPal 管理配置 未实现 新增系统设置项和前端配置。
PayPal webhook 未实现 新增 /api/paypal/webhook。

11. 建议实施顺序

  1. 新增 PayPal 配置项和支付 provider 常量。
  2. 实现 PayPal OAuth access token 获取和 Orders v2 create/capture 查询封装。
  3. 实现余额充值 PayPal 下单接口。
  4. 实现 PayPal webhook 验签和充值订单完成。
  5. 实现内部订阅套餐 PayPal 下单接口。
  6. webhook 成功后复用 CompleteSubscriptionOrder。
  7. 前端充值页和套餐购买弹窗增加 PayPal。
  8. 增加单测:金额校验、重复 webhook、provider mismatch、订单状态异常。
  9. Sandbox 冒烟:创建订单、支付、回调、余额增加、订阅开通、模型调用扣费。
  10. 生产上线前配置 live client、secret、webhook id、currency、回调域名。

12. 对外口径

可以这样向上级说明:

Heicode Manager 当前已有余额和订阅计费闭环。PayPal 接入不改变模型调用扣费规则,只作为新的收款渠道接入。

用户通过 PayPal 支付后,Manager 将支付结果转换为 Heicode 钱包余额或内部订阅套餐。模型调用仍由 NewAPI/CodeGW 计费链路按余额或订阅额度扣费。

项目设计文档中存在 Agent 运行预算字段,例如 token、美元成本和运行时长上限,但这目前是部署预算和审计约束,不等同于已完成的 Agent 基础设施收费账本。若要对 Agent 运行单独收费,需要 Agent Manager 回传真实模型用量、运行时长、CPU/内存等数据后再纳入扣费。

13. 参考资料

  • Heicode 产品资料包:docs/product-package/
  • NewAPI / CodeGW 边界:docs/heicode-runtime-auth-newapi-secret-design.md
  • Agent 请求契约:docs/integration/agent-platform-request-contract.md
  • PayPal Orders v2:https://developer.paypal.com/docs/api/orders/v2/
  • PayPal Subscriptions:https://developer.paypal.com/docs/subscriptions/reference/
  • PayPal Webhook 事件:https://developer.paypal.com/api/rest/webhooks/event-names