SaaS订阅支付全链路拆解:shadcn-nextjs-boilerplate中Stripe从Checkout到Webhook同步的完整指南
【免费下载链接】shadcn-nextjs-boilerplateShadcn UI NextJS Boilerplate ⚡️ Free Open-source ChatGPT UI Admin Dashboard Template - Horizon AI Boilerplate项目地址: https://gitcode.com/gh_mirrors/sh/shadcn-nextjs-boilerplate
shadcn-nextjs-boilerplate(Horizon AI Boilerplate)是一个免费的开源Stripe 订阅支付SaaS 模板:Next.js + shadcn/ui + Supabase。它把 SaaS 产品最复杂的订阅支付链路封装成了三个可直接复用的模块——Stripe 客户端初始化、Checkout 会话创建、Webhook 事件同步,配合一套带 RLS 策略的数据库设计,让新手也能快速搭建自己的订阅计费系统。
一条链路:从用户付款到数据库同步
整个 Stripe 订阅支付链路可以概括为5 步:
- 配置密钥:在
.env.local.example中配置STRIPE_SECRET_KEY(服务端)与NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY(浏览器端) - 创建 Checkout 会话:服务端调用 Stripe API,生成支付页地址并跳转
- 用户在 Stripe Checkout 完成付款:Stripe 托管的收银台处理卡号、税务等敏感信息
- Stripe 发送 Webhook 事件:如
checkout.session.completed、customer.subscription.updated - Next.js API Route 验签后写入 Supabase:产品、价格、订阅状态同步到数据库
💡 上图为模板中内置的账户设置界面,用户可在此管理资料并接收「订阅即将到期」等通知,这正是订阅制产品常见的运营触点。
核心组件:三个文件看懂 Stripe 集成
1️⃣ 双端 Stripe 客户端
项目将 Stripe 拆成了服务端和浏览器端两个客户端,这是 SaaS 订阅支付集成的标准姿势:
- 服务端:
utils/stripe/config.ts— 用STRIPE_SECRET_KEY创建 Stripe 实例,支持LIVE/test双环境密钥切换,并注册了官方插件信息(appInfo) - 浏览器端:
utils/stripe/client.ts— 通过loadStripe加载@stripe/stripe-js,使用单例模式缓存 Promise,避免重复初始化
为什么必须拆开?因为 Secret Key 泄露意味着资金风险,绝不能出现在客户端。
2️⃣ Webhook 同步中枢
app/api/webhooks/route.ts是整个订阅支付链路的"心脏",它做了三件关键的事:
- 验签:用
stripe.webhooks.constructEvent校验Stripe-Signature头,防止伪造请求 - 事件过滤:只监听 7 类相关事件,忽略噪音
- 分发处理:按事件类型路由到不同的数据库操作
| Stripe 事件 | 触发时机 | 数据库动作 |
|---|---|---|
product.created/product.updated | Stripe 后台创建/修改产品 | upsert 到products表 |
price.created/price.updated | 定价变更(如月费 9.99 改 12.99) | upsert 到prices表 |
checkout.session.completed | 用户支付成功 | 写入订阅记录(mode === 'subscription'时) |
customer.subscription.created | 新建订阅 | 插入订阅 + 同步账单资料 |
customer.subscription.updated | 升级/降级/暂停 | 更新订阅状态 |
customer.subscription.deleted | 取消订阅 | 状态置为 canceled |
3️⃣ 数据库同步层
utils/supabase-admin.ts使用 Supabase 的 Service Role Key(仅服务端可用)完成四类操作:
createOrRetrieveCustomer:把 Supabase 用户 ID 映射到 Stripe Customer ID,写入customers映射表upsertProductRecord/upsertPriceRecord:产品与价格同步manageSubscriptionStatusChange:订阅状态变更的核心函数,拉取 Stripe 订阅详情后 upsert 到subscriptions表copyBillingDetailsToCustomer:新订阅时把卡信息、账单地址写回 Stripe Customer 和本地用户表
数据库设计:schema.sql 中的四张表
打开schema.sql,订阅支付相关的表设计得非常清晰,且全部启用了Row Level Security(RLS):
| 表 | 作用 | 权限策略 |
|---|---|---|
customers | Supabase 用户 ↔ Stripe Customer 映射 | 私有表,用户零访问 |
products | 产品(Stripe 为主数据源) | 公开只读 |
prices | 价格(支持one_time/recurring、day/week/month/year 周期) | 公开只读 |
subscriptions | 订阅状态(active/trialing/past_due/canceled等 8 种状态) | 仅本人可查 |
一个值得学习的设计:subscriptions表保存了cancel_at_period_end、trial_start、trial_end等完整时间轴字段,前端只需查询即可渲染"订阅还剩 5 天到期"这类提示。
📌 上图即基于本模板构建的 SaaS 产品主界面(AI Chat)。
users表中的credits/trial_credits字段,正是订阅权益与免费试用的扣费基础。
快速上手:三步跑通 Stripe 订阅支付
Step 1:配置环境变量
复制.env.local.example为.env.local,填入 Stripe Dashboard → API Keys 中的测试密钥:
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_test_xxx STRIPE_SECRET_KEY=sk_test_xxx STRIPE_WEBHOOK_SECRET=whsec_xxxStep 2:初始化数据库
将schema.sql在 Supabase SQL Editor 中执行,自动创建四张表、触发器和 RLS 策略。
Step 3:本地调试 Webhook
无需部署即可在本地调试:
stripe listen --forward-to localhost:3000/api/webhooksfixtures/stripe-fixtures.json提供了可直接导入 Stripe 测试环境的示例产品与定价数据,配合 Stripe 的测试卡号(4242 4242 4242 4242)即可完整走通一次订阅支付。
还能往哪扩展?
模板已预置了/dashboard/subscription路由(见components/routes.tsx),当前处于禁用状态——这正是留给你发挥的空间:
- ✅ 接入 Stripe Customer Portal,让用户自助管理/取消订阅
- ✅ 在 AI 功能(
app/api/chatAPI/)中加入订阅状态校验,实现"免费试用 3 次 → 付费解锁" - ✅ 利用
trial_credits字段实现试用额度扣减与到期降级 - ✅ 用
products/prices的 Realtime 订阅(schema 中已创建supabase_realtimepublication)实现定价页的实时刷新
总结
shadcn-nextjs-boilerplate 的 Stripe 集成示范了一条教科书级的 SaaS 订阅支付架构:密钥前后端分离、Webhook 验签、事件驱动同步、RLS 权限隔离。对于想上线订阅功能的 Next.js 开发者,这套从 Checkout 到 Webhook 的完整链路值得直接抄作业 ⚡
【免费下载链接】shadcn-nextjs-boilerplateShadcn UI NextJS Boilerplate ⚡️ Free Open-source ChatGPT UI Admin Dashboard Template - Horizon AI Boilerplate项目地址: https://gitcode.com/gh_mirrors/sh/shadcn-nextjs-boilerplate
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考