mcpField
S
stripe-stack

stripe-stack

github.com/scientiacapital开发2886 次安装3 周前更新
代码仓库

关于 stripe-stack

stripe-stack 是面向 Next.js 和 Supabase 项目的 Stripe 支付集成技能,提供 Webhook、订阅与积分系统的工作流和模板,并强调幂等处理及安全切换测试与正式环境。

主要功能

  1. 01Next.js 与 Supabase 集成工作流
  2. 02基于数据库的 Webhook 幂等处理
  3. 03Webhook 签名验证
  4. 04订阅与积分系统模式
  5. 05测试转正式环境检查清单

适用场景

  1. 01在新建的 Next.js 项目中接入 Stripe
  2. 02可靠地处理 Stripe Webhook
  3. 03实现周期性订阅
  4. 04构建按量付费积分

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/scientiacapital/skills --skill stripe-stack

安装后在 Claude Code 中输入/stripe-stack确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

config.json
reference/
common-errors.md
environment-vars.md
pricing-models.md
webhook-patterns.md
templates/
env-example.txt
idempotency-migration.sql
plans-config.ts
stripe-client.ts
webhook-handler-nextjs.ts
webhook-handler.test.ts
workflows/
add-credit-system.md
add-webhook-handler.md
go-live-checklist.md
implement-subscriptions.md
setup-new-project.md

详细介绍

为 Next.js + Supabase 项目提供 Stripe 支付集成指南,涵盖 Webhook、订阅和积分系统的生产就绪模式。确保具备幂等性、正确区分测试模式与正式模式,并安全处理密钥。

<quick_start> 为 Next.js + Supabase 项目添加支付功能:

  1. 安装 Stripe:npm install stripe @stripe/stripe-js
  2. 添加环境变量(参见下方的 quick_reference)
  3. 创建幂等性表(参见下方的架构)
  4. 选择工作流:setup-new-project.md 或 add-webhook-handler.md
// Lazy-loaded Stripe client
import Stripe from 'stripe';
let _stripe: Stripe | null = null;
export function getStripe(): Stripe {
  if (!_stripe) {
    _stripe = new Stripe(process.env.STRIPE_SECRET_KEY!, { apiVersion: '2025-12-15.clover' });
  }
  return _stripe;
}

</quick_start>

<success_criteria> 集成成功的标准:

  • Webhook 处理程序使用基于数据库的幂等性机制(而非内存机制)
  • 所有密钥都存储在环境变量中(绝不硬编码)
  • 在部署任何正式模式配置前,测试模式已全面正常运行
  • 所有 Webhook 端点都进行签名验证
  • 处理事件前记录事件(先插入、后处理模式)
  • 正式上线检查清单已完成 </success_criteria>

<essential_principles>

核心原则

  1. 幂等性不可妥协

    • 所有 Webhook 处理程序都必须使用基于数据库的幂等性机制
    • 绝不使用内存中的 Set(无服务器冷启动时会丢失)
    • 处理事件前插入事件记录,而不是处理后插入
  2. 测试模式与正式模式分离

    • 所有密钥都使用环境变量(绝不硬编码)
    • 测试密钥:sk_test_、pk_test_、whsec_test_
    • 正式密钥:sk_live_、pk_live_、whsec_live_
    • 产品和价格必须在正式模式下重新创建
  3. 共享 Stripe 账户

    • 所有 NetZero Suite 项目共用一个 Stripe 账户
    • 多个项目可以使用同一个 Webhook 密钥
    • 每个项目都有自己的 Webhook 端点 URL
  4. 延迟初始化客户端

    • 绝不在模块级别初始化 Stripe(会导致构建错误)
    • 服务端客户端使用工厂函数模式
    • 创建实例前检查 API 密钥

</essential_principles>

你要构建什么?

继续前,请确定你的使用场景:

使用场景工作流描述
新项目setup-new-project.md从头开始集成 Stripe
添加 Webhookadd-webhook-handler.md为现有项目添加 Webhook 处理程序
订阅implement-subscriptions.md使用套餐进行周期性计费
积分系统add-credit-system.md按需付费积分
正式上线go-live-checklist.md从测试模式迁移到正式模式

工作流路由

如果要在新项目中设置 Stripe: → 阅读 workflows/setup-new-project.md → 然后阅读 reference/environment-vars.md → 使用 templates/stripe-client.ts 和 templates/env-example.txt

如果要添加 Webhook 处理: → 阅读 workflows/add-webhook-handler.md → 然后阅读 reference/webhook-patterns.md → 使用 templates/webhook-handler-nextjs.ts 和 templates/idempotency-migration.sql

如果要实现订阅计费: → 阅读 workflows/implement-subscriptions.md → 然后阅读 reference/pricing-models.md → 使用 templates/plans-config.ts

如果要添加积分/用量计费系统: → 阅读 workflows/add-credit-system.md → 然后阅读 reference/pricing-models.md

如果要从测试模式迁移到正式模式: → 阅读 workflows/go-live-checklist.md

<quick_reference>

快速参考

环境变量(标准)
# Server-side (never expose to client)
STRIPE_SECRET_KEY=sk_test_...
STRIPE_WEBHOOK_SECRET=whsec_...

# Client-side (safe to expose)
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_test_...

# Optional: Price IDs (for test→live switching)
STRIPE_PRICE_STARTER_MONTHLY=price_...
STRIPE_PRICE_PRO_MONTHLY=price_...
常见 Webhook 事件
事件触发时机操作
checkout.session.completed客户完成结账创建订阅记录
customer.subscription.created新订阅开始初始化用户限额
customer.subscription.updated套餐变更、续订更新套餐/限额
customer.subscription.deleted取消订阅降级为免费套餐
invoice.paid月度续订成功重置用量计数器
invoice.payment_failed支付失败标记为 past_due
Stripe 客户端模式
let _stripe: Stripe | null = null;

export function getStripe(): Stripe {
  if (!_stripe) {
    const key = process.env.STRIPE_SECRET_KEY;
    if (!key) throw new Error('STRIPE_SECRET_KEY not configured');
    _stripe = new Stripe(key, {
      apiVersion: '2025-12-15.clover',
      typescript: true
    });
  }
  return _stripe;
}
### 幂等性表结构
CREATE TABLE stripe_webhook_events (
  id TEXT PRIMARY KEY,           -- Use Stripe event ID directly
  type TEXT NOT NULL,            -- Event type
  data JSONB NOT NULL,           -- Full event payload
  processed_at TIMESTAMPTZ DEFAULT NOW()
);
Webhook 处理器结构
export async function POST(request: NextRequest) {
  const body = await request.text();
  const signature = request.headers.get('stripe-signature');

  // 1. Verify signature
  const event = stripe.webhooks.constructEvent(body, signature, webhookSecret);

  // 2. Check idempotency (BEFORE processing)
  const { data: existing } = await supabase
    .from('stripe_webhook_events')
    .select('id')
    .eq('id', event.id)
    .single();

  if (existing) return NextResponse.json({ duplicate: true });

  // 3. Log event (INSERT before processing)
  await supabase.from('stripe_webhook_events').insert({
    id: event.id,
    type: event.type,
    data: event,
  });

  // 4. Process event
  switch (event.type) {
    case 'checkout.session.completed':
      await handleCheckout(event.data.object);
      break;
    // ... other handlers
  }

  return NextResponse.json({ received: true });
}

</quick_reference>

<integration_notes>

集成说明

兼容
  • Supabase:Webhook 处理器使用服务角色客户端(绕过 RLS)
  • Prisma:Supabase 幂等性表的替代方案
  • Vercel:为 Webhook 路由添加 runtime/maxDuration 配置
  • Next.js App Router:使用 request.text() 获取原始请求体
相关技能
  • supabase-sql-skill - 用于数据库迁移
  • create-hooks-skill - 用于部署后的通知
GitHub 仓库

可获取私有模板和示例: github.com/ScientiaCapital/stripe-stack

</integration_notes>

<reference_index>

参考文件

文件用途
reference/webhook-patterns.md幂等性、事件处理、错误恢复
reference/pricing-models.md套餐、额度与按使用量计费
reference/environment-vars.md标准环境变量约定
reference/common-errors.md故障排查指南

模板文件

文件用途
templates/webhook-handler-nextjs.ts完整的 Webhook 路由(复制粘贴即可使用)
templates/stripe-client.ts延迟加载的客户端工厂
templates/plans-config.ts订阅套餐定义
templates/idempotency-migration.sqlSupabase 迁移
templates/webhook-handler.test.ts测试模板
templates/env-example.txt标准 .env 模板

工作流文件

文件用途
workflows/setup-new-project.md全新 Stripe 集成
workflows/add-webhook-handler.md为现有项目添加 Webhook
workflows/implement-subscriptions.md订阅计费
workflows/add-credit-system.md按需付费额度
workflows/go-live-checklist.md测试 → 生产环境迁移

</reference_index>

输出结果旁文件

最后一步,将内容写入 ~/.claude/skill-analytics/last-outcome-stripe-stack.json:

{"ts":"[UTC ISO8601]","skill":"stripe-stack","version":"1.0.0","variant":"default",
 "status":"[success|partial|error]","runtime_ms":[estimated ms from start],
 "metrics":{"webhooks_configured":[n],"products_created":[n],"checkout_flows_built":[n]},
 "error":null,"session_id":"[YYYY-MM-DD]"}

如果部分阶段失败但已生成结果,请使用状态 "partial"。仅当未生成任何输出时,才使用 "error"。

评论

支持 Markdown