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. 02Stripe 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 エンドポイントで署名検証が行われている
  • 処理の前にイベントがログに記録されている(insert-before-process パターン)
  • 本番環境へのデプロイ前に Go-live チェックリストが完了している </success_criteria>

<essential_principles>

基本原則

  1. 冪等性は譲れない

    • すべての Webhook ハンドラーはデータベースベースの冪等性を使用しなければならない
    • インメモリの Set を決して使用しない(サーバーレスのコールドスタートで失われる)
    • イベントレコードは処理の後にではなく、前に挿入する
  2. テストモード/ライブモードの分離

    • すべてのキーに環境変数を使用する(決してハードコードしない)
    • テストキー: sk_test_、pk_test_、whsec_test_
    • ライブキー: sk_live_、pk_live_、whsec_live_
    • 製品/価格はライブモードで再作成する必要がある
  3. 共有 Stripe アカウント

    • すべての NetZero Suite プロジェクトは 1 つの Stripe アカウントを共有する
    • 同じ Webhook シークレットをプロジェクト間で使用できる
    • 各プロジェクトは独自の Webhook エンドポイント URL を持つ
  4. クライアントの遅延初期化

    • モジュールレベルで Stripe を初期化しない(ビルドエラーの原因になる)
    • サーバーサイドクライアントにはファクトリー関数パターンを使用する
    • インスタンスを作成する前に API キーの存在を確認する

</essential_principles>

何を構築していますか?

進める前に、ユースケースを特定してください:

ユースケースワークフロー説明
新規プロジェクトsetup-new-project.mdゼロからの Stripe 統合
Webhook の追加add-webhook-handler.md既存プロジェクトへの Webhook ハンドラーの追加
サブスクリプションimplement-subscriptions.mdプランによる定期課金
クレジットシステムadd-credit-system.md従量課金制のクレジット
Go livego-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 ルートにランタイム/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.tsWebhook ルート全体(コピー&ペースト用)
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.mdStripe を新規に統合
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" を使用します。

コメント