发布于 2026-01-06 4 阅读
0

一次 API 调用即可完成身份验证和计费:值得信赖的模式 DEV 全球展示挑战赛,由 Mux 呈现:展示你的项目!

一次 API 调用即可完成身份验证和计费:值得尝试的模式

由 Mux 主办的 DEV 全球展示挑战赛:展示你的项目!

我在 Learnflow AI 上做出的第一个真正的后端决策,与速度、性能甚至语音逻辑都无关。

关键在于简洁

从一开始,我就知道两件事:

  • 每个用户都应该选择一个套餐(免费或专业版)。
  • 每个方案都应该明确定义用户可以访问哪些功能。

但问题在于:大多数工具将这些功能拆分到两个完全不同的服务中。一个 API 用于身份验证,另一个用于计费,第三个用于使用情况跟踪(通常是数据库)。最终,你不得不拼凑各种逻辑来回答像以下这样基本的问题:

“该用户现在可以开始会话吗?”

Learnflow AI 并非典型的 SaaS 应用。它采用基于使用量的付费模式,支持语音控制​​,并且限制会话时长。为了保证用户体验流畅,我不想让用户通过 3 个 API 进行 5 次查询。

所以我打了个赌:

如果计费和访问权限都来自同一数据源呢?

为什么这很重要(即使对于小型团队而言)

人工智能应用不仅仅是登录和点击几下那么简单,它们也会带来实际的成本。

Learnflow AI 每次会话都会启动一个语音助手。通话时间越长,费用越高。

所以:

  • 每个用户都需要使用限制。
  • 这些限制需要反映其定价层级。
  • 而且该应用程序需要实时执行这些规则。

这意味着我必须构建一个如下所示的流程:

第一波

如果授权系统和计费系统是分开的,那么这个系统就会很脆弱、速度很慢、容易出错。

所以,我选择了一个将它们合并的系统。

让我完成这一切的技术栈

  • Kinde提供身份验证和计划元数据(+ 使用情况跟踪)
  • 用于实时数据库存储会话的凸函数
  • Vapi用于语音会话编排

为什么选择 Kinde?

大多数身份验证提供商会返回一个令牌和一个用户 ID。仅此而已。

Kinde 更进一步:它允许您将计划信息存储在用户元数据中。

这意味着当用户登录时,我可以:

  • 显示或隐藏功能
  • 强制执行限制
  • 触发升级提示

这一切都无需调用单独的计费 API。

操作指南:一次 API 调用,即可实现完整访问逻辑

用户登录时,后台会发生以下情况:

1. 用户在注册时选择套餐

Kinde 支持托管定价表。因此,当用户注册时,他们会看到:

  • 免费计划
  • 专业版套餐($)

一旦他们选择了一个方案,Kinde 就会将该方案添加到他们的元数据中,然后我会将该元数据存储到我数据库中的用户表中。

无需运行 webhook 或后台同步。

2. 每次会话都会产生元数据

现在,用户每次登录时,其套餐信息都会被自动合并。

所以在 Convex 内部,我可以编写如下逻辑:

export const canStartSession = query({
  args: { userId: v.id("users") },
  handler: async (ctx, args) => {
    const user = await ctx.db.get(args.userId);
    const plan = user.plan;
    const credits = user.credits || 0;

    if (plan === "free" && credits <= 0) {
      return { allowed: false, reason: "out_of_credits" };
    }

    return { allowed: true };
  }
});

Enter fullscreen mode Exit fullscreen mode

就是这样。

一个电话,即可完成全面访问权限检查。

(在此模式出现之前)出了什么问题

错误1:将授权和计费视为两个独立的过程

我的第一个实现方案使用了单独的计费 API,并尝试通过 webhook 将计划数据同步到 Convex。

问题:

  • 比赛条件
  • 过时的计划信息
  • 同步失败时的复杂错误处理

错误 2:未在会话中存储计划信息

早期用户注册专业版后,会享受几分钟的免费使用体验。为什么?

因为应用程序直到后台同步完成后才读取计费元数据。

摩擦。混乱。下降。

错误三:隐藏使用直至失败

在添加积分计数器之前,用户根本不知道自己的积分快用完了。所以,有时候会话就会莫名其妙地失败。

我是如何解决的

  • 使用Kindle 的元数据 API作为计费数据源
  • 已将计划信息移至会话中
  • 在用户界面中显示积分计数器。

界面变更:

  • 仪表盘标题:You have 3 sessions left
  • 导师页面:This tutor requires Pro
  • 失败的模态:You're out of credits. Upgrade to continue.

全流

全流

为什么这种模式可以扩展

尽管 Learnflow AI 目前规模较小,但这种访问逻辑可以扩展到数千用户。

为什么?

  • 没有自定义计费后端
  • 无比赛条件
  • 每个计划决策都是可移植的。

此外,套餐升级会立即生效。

你可以从中借鉴什么

如果您正在构建一款采用按使用量计费的 AI 应用:

  • 选择一个允许您存储计划元数据的身份验证系统
  • 使用一个后端查询来决定访问权限
  • 尽早、经常地以视觉方式反映使用情况

不要把账单处理当作单独的问题。

产品逻辑。

最后想说

早期很容易过度设计。

你开始考虑规模问题、极端情况、支付失败、速率限制。

但在第一版中,用户只想知道:

  • 我可以用这个吗?
  • 我可以做什么?
  • 当我达到极限时会发生什么?

如果你能清晰地回答这些问题,就能赢得信任。

这种模式带给我的就是:默认的清晰度。

一次通话即可完成身份验证和计费。

值得关注的模式。

使用以下技术构建:

  • Kinde(身份验证 + 计费 + 元数据 + 使用量计量)
  • 凸(后端)
  • 瓦皮(语音会话)
  • Next.js 应用路由
文章来源:https://dev.to/sholajgede/auth-and-billing-in-one-api-call-a-pattern-worth-betting-on-57jl