Lemon Squeezy 用量计费适合 AI credits、插件调用次数、API 请求量、seat 之外的可变消耗。它的坑也很集中:后台看起来是订阅,代码里也成功创建了客户,但当前用量接口 404,或者客户页显示 12 次、Lemon Squeezy 只准备收 5 次。

排查时不要先改代码。先拿到 4 个证据:variant 是否启用 metered billing、subscription item id、最近一次 usage record 请求体、webhook 事件入库记录。

快速判断问题类型

现象最大概率原因查哪里关键证据
current usage 返回 404product/variant 未启用 usage-based billingProduct / Variant 设置「Usage is metered?」是否开启
usage record 201/200 但数值不对action 和 aggregation 错配usage record 请求体increment / set
checkout 金额是 0这是 metered billing 默认行为Checkout 测试订单是否有 setup fee
上报成功但应用里没同步webhook 入库或重放失败webhook 日志event id、签名、处理状态
客户权益对不上存了 subscription id,没存 subscription item id订单同步表subscription_item_id

Lemon Squeezy 帮助文档把 usage-based billing 也称为 metered billing。它启用在 product 或 variant 设置里,后续账单按你通过 API 上报的用量在下一次 renewal 处理。

current usage 返回 404 的原因

当前用量接口是:

GET /v1/subscription-items/:id/current-usage

Lemon Squeezy API 文档明确写了一个容易误判的行为:这个 endpoint 只用于启用 usage-based billing 的订阅;如果关联的 subscription product/variant 没有开启 usage-based billing,会返回 404 Not Found

注意,HTTP 404 本身只表示服务端找不到目标资源;在这个接口里,要按 Lemon Squeezy 的业务文档解释,不能把它直接等同于「客户没有用量」。

所以 404 的排查顺序是:

  1. 这个 :id 是不是 subscription item id,而不是 subscription id、variant id、customer id。
  2. 这个 subscription item 关联的 variant 是否开启 Usage is metered?
  3. 测试环境和生产环境的 variant 是否是同一个配置。
  4. 客户是不是从旧 checkout 买入,旧 variant 当时还没开 metered billing。
  5. 你是否在迁移产品后仍用老的 subscription item 查询。

如果只是当前周期没有用量,合理预期应该是能拿到当前周期 meta,并看到 quantity 为 0 或已聚合后的数值;文档里的 404 指向的是配置限制,不是「没用过」。

配置层要查的 5 个字段

打开 Lemon Squeezy 后台的 product/variant,不要从代码里猜。

配置项正确检查方式出错后果
Usage is metered?在 product/variant 设置里确认已开启current usage 404,usage 上报无法按预期计费
Pricing modelflat-rate、standard、package、volume、graduated 的组合价格阶梯和用量单位解释错
Usage aggregationSum、Most recent、Maximum 等action 选错后累计或覆盖异常
Setup fee是否需要 checkout 时立即收费客户看到 0 美元误以为免费
Variant id测试、生产、旧版本是否混用旧客户和新客户计费口径不一致

官方帮助页说明,usage-based billing 启用后,客户在 checkout 不会被立即收取用量费用,默认按钮会从 Pay 变成 Create subscription。除非你配置 setup fee,否则初始 charge 是 0;checkout 上传的 quantity 也会被忽略。

这对 AI 工具很重要。比如你卖「每 1,000 次调用按量计费」,用户开通当天不该因为 quantity=1000 被立即扣费;真正账单来自上一个 billing period 内的 usage records。

usage records 漏报排查

创建用量记录的 endpoint 是:

POST /v1/usage-records

核心字段只有几个,但每个都容易错:

字段文档含义排查口径
quantity正整数,用来表示上报的用量不能传负数;退款和冲正另做内部账
actionincrementset省略时默认 increment
subscription-item relationship这条用量属于哪个 subscription item不要传 subscription id
subscription_item_id返回对象里的订阅项编号存入内部 usage ledger

action 是漏报和重复计费的分水岭。

如果 aggregation 是 Sum of usage during period,increment 才合理。你每次上报 quantity=1,Lemon Squeezy 会把当前周期内的记录加总。

如果 aggregation 是 Most recent usage during a period 或 Most recent usage,应该用 set。这表示「当前总用量是 500」,不是「再增加 500」。把 increment 用在这类场景,会把 dashboard 里的总量越推越高。

一个最小请求体应该长这样:

{
  "data": {
    "type": "usage-records",
    "attributes": {
      "quantity": 1,
      "action": "increment"
    },
    "relationships": {
      "subscription-item": {
        "data": {
          "type": "subscription-items",
          "id": "1"
        }
      }
    }
  }
}

生产环境建议给每次上报留 5 列日志:内部用户 id、subscription_item_id、quantity、action、Lemon Squeezy usage record id。只存「接口成功」四个字,月底无法解释为什么少收 27 次调用。

当前用量与自有用量表的对账

开发者指南说明,current usage 的 quantity 会在你发送 usage record 后更新,并反映下一张 invoice 会使用的 billable usage;它会按照你配置的 aggregation 计算。

这句话有两个含义。

第一,current usage 不是原始流水表。它是 Lemon Squeezy 算完聚合后的结果。你自己的 usage ledger 仍然要保存每次 API 调用、消息生成、插件运行或 credit 扣减。

第二,current usage 是和 subscription item 绑定的。一个客户如果从 Basic 升到 Pro,或者从旧 variant 迁移到新 variant,你要把旧 subscription item 和新 subscription item 分开对账。

推荐对账方式:

你的系统Lemon Squeezy对账频率
原始调用日志不直接对应实时写入
内部 usage ledgerusage records每次上报后记录返回 id
客户用量页current usage meta.quantity每次刷新或定时同步
月度收入表subscription invoicerenewal 后对账

如果客户投诉「页面显示 100,账单只收 80」,看 aggregation。Maximum usage during period、Most recent usage、Sum during period 得出的 billable usage 本来就不同。

webhook 重放与环境问题处理

用量上报本身靠 usage records API,webhook 负责把 Lemon Squeezy 的订阅、客户、发票状态同步回你的系统。2026-02-25 API changelog 新增了 customer_updated webhook event,用来监听 customer profile updates 并同步到应用。

这类更新不改变 usage record 的字段,但会暴露同一个工程问题:你的 webhook 不能只「收到就改库」,还要能查重、重放、分环境。

建议每个 webhook event 入库时保存:event id、event type、test/live 环境、关联 customer id、subscription id、subscription item id、原始 payload、处理状态、错误信息。

如果你在本地、预发、生产之间频繁切换回调地址,后台登录、API key、webhook secret、Cloudflare 或 GitHub 部署环境也会变多。团队多人处理付款和订阅事故时,把核心后台放在固定设备和固定网络规范下,用海外银行 + Stripe + AI 工具全场景承载这些高风险操作,至少能减少「谁在什么环境改了 webhook」这类追查成本。

排查 webhook 时按这个顺序:

  1. Lemon Squeezy 后台是否真的发出了对应 event。
  2. 你的 endpoint 是否返回 2xx。
  3. 签名校验失败有没有被记录,而不是直接丢弃。
  4. event id 是否被幂等逻辑误判为已处理。
  5. test mode 和 live mode 是否写进了同一张客户表。
  6. 重放后是否只更新状态,不重复发放权益。

重新建 variant 还是继续打补丁

这几种情况建议新建 variant,并把旧客户留在旧口径里,别硬改:

  • 旧 variant 原来不是 usage-based,已经有客户购买。
  • 你从 quantity-based billing 改成 usage-based billing。
  • aggregation 从 Sum 改成 Most recent,历史账单解释会变。
  • 单位从「次」改成「千 token」或「credit」。
  • setup fee 逻辑发生变化。

重新建 variant 的好处是账单历史清楚。坏处是迁移要写 customer communication、权益映射和内部报表备注。对已经收过钱的订阅产品,清楚比省事重要。

相关阅读