【Stripe】Next.js 15とPrismaで実装するサブスクリプション機能の開発

目次

1. はじめに

現在開発中の飲食店向けSaaSプラットフォームにおいて、Stripeを使用したサブスクリプション機能を実装しました。本記事では、Next.js 15 (App Router) と Prisma を組み合わせ、**「ユーザー登録 → 決済 → アカウント有効化」**という一連のフローをセキュアに構築する方法を解説します。


2. 実装要件とデータベース設計

今回のSaaSモデルでは、以下の4点を必須要件として定義しました。

システム要件

  1. プランの多段階化: ライト(980円)とスタンダード(2,980円)の提供。
  2. 即時利用制限: 決済完了まで機能へのアクセスを遮断。
  3. Webhookによる自動更新: 決済成功・解約時のステータス同期。
  4. セルフプラン変更: 管理画面からのアップグレード対応。

Prismaによるスキーマ設計

ユーザー(飲食店)モデルにStripe関連のフィールドを統合し、決済状態をDBで一元管理します。

コード スニペット

// schema.prisma
model Restaurant {
  id          String   @id @default(cuid())
  // ...基本情報
  
  // セットアップ状況(決済完了でtrue)
  isSetupCompleted Boolean @default(false) 

  // Stripe連携用フィールド
  stripeCustomerId   String?   @unique
  subscriptionId     String?   @unique
  subscriptionStatus String?   @default("inactive") 
  subscriptionPlanId String?   
}

3. 実装のハイライト

3.1 「仮登録」と「決済」を分離するUX

ユーザー登録と支払い登録を分けることで、離脱を防ぎつつ確実に課金へ誘導します。

  • 新規登録後: 自動的に /admin/subscription へリダイレクト。
  • Stripe Checkout: サーバーサイドで支払いリンクを生成し、Stripeの堅牢な決済画面へ遷移。

3.2 Webhookによるステータス同期(最重要)

クライアント側の「完了画面」は、通信遮断などで100%の実行が保証されません。そのため、StripeからのWebhookを「唯一の真実」として扱います。

api/webhooks/stripe/route.ts の実装例:

TypeScript

if (event.type === "checkout.session.completed") {
    const session = event.data.object as Stripe.Checkout.Session;
    
    await prisma.restaurant.update({
        where: { id: restaurantId },
        data: {
            stripeCustomerId: session.customer as string,
            subscriptionId: session.subscription as string,
            subscriptionStatus: "active",
            isSetupCompleted: true
        }
    });
}

3.3 未払いユーザーの徹底的なアクセス制御

Next.jsの layout.tsx(サーバーコンポーネント)を活用し、未払い状態では管理メニューそのものをレンダリングさせない仕組みを導入しました。


4. 開発・デバッグ:Stripe CLIの活用

ローカル環境ではWebhookを受け取れないため、Stripe CLIを使用してイベントを転送します。

Bash

# ローカルへのWebhook転送コマンド
stripe listen --forward-to localhost:3000/api/webhooks/stripe

この開発手法により、署名検証(whsec_...)を含めた本番同等のテストが可能になります。


5. まとめ

Next.js 15 と Prisma、そして Stripe を組み合わせることで、以下の成果が得られました。

  • 確実な収益化: 決済なしでの利用をシステムレベルで排除。
  • 運用の自動化: 入金確認作業のゼロ化。
  • スケール性: 容易なプラン追加や変更が可能な柔軟な設計。

SaaS開発において決済は信頼性が命です。この構成は、今後の拡張においても強力な基盤となると確信しています。

この記事が気に入ったら
フォローしてね!

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

コメント

コメントする

目次