はじめに
前回の動画ではStripe決済のワークフローを解説しました。今回はその続きとして、Webhookの役割と、購入後にレッスンへアクセスする仕組みについて解説します。
なぜWebhookを利用するのか
今回の実装では、Webhookをバックアップ用に利用しています。決済周りは確実に機能しなければならない部分であるため、成功ページでのチェックに加えて、Webhookによるサーバーサイドでの二重チェックを行っています。
設定はやや面倒ですが、より確実に動作させるために、決済の購入が完了したらStripe側からNext.jsのサーバーに対してコールバックURLを呼び出す仕組みになっています。
Webhookの仕組み
Stripeから送信されるWebhookは、/api/stripeのエンドポイント(route.ts)で受け取ります。このAPIは以下のような処理を行います。
- Stripeからのイベントを受け取る
- 決済が成功したことを確認する
- データベースからユーザーの現在の状態を検索する
- 必要に応じてユーザーのロールを更新する
二重チェックの構造
決済の検証は2段階で行われています。
1つ目のチェック:成功ページ
前回の動画で解説した通り、成功ページ(サーバーコンポーネント)でStripeのセッションIDをもとに決済状態を確認し、データベースのユーザーロールをプレミアムに更新します。
2つ目のチェック:Webhook API
Stripeからのコールバックでroute.tsが呼び出され、サーバー経由で再度ユーザーの状態を確認・更新します。ユーザーがまだノーマルユーザーであればプレミアムに更新し、既にプレミアムユーザーであればスキップします。
Stripe公式でもこの二重チェックの方法が推奨されています。
べき等性(Idempotency)とは
Webhookの実装で重要な概念がべき等性です。これはプログラミングの用語で、同じ操作を何回繰り返しても結果が変わらないようにするという意味です。
今回の実装では、Webhookの処理内で「既にプレミアムユーザーの場合はスキップする」というチェックが入っています。これがべき等性のチェックです。
なぜべき等性が重要なのか
今回はロールの更新だけなので、プレミアムユーザーを再度プレミアムに更新しても実害はありません。しかし、例えばポイント付与の実装では、べき等性がなければ同じWebhookが二度処理されたときにポイントが二重に付与されてしまう可能性があります。
特にサブスクリプション(月額課金)で月次更新するときなど、べき等性のチェックは欠かせません。
この概念を知っているだけで、Claude Codeへの指示出しも的確になります。例えば「べき等性はチェックできていますか?」といった確認ができるようになります。
購入後のレッスンアクセスの仕組み
プレミアムユーザーになった後、有料レッスンにアクセスする際の流れは以下の通りです。
- クライアント側にはセッションIDだけがクッキーに保存されている
- レッスンページにアクセスするたびに、セッションIDを使ってデータベースに問い合わせる
- データベースでプレミアムユーザーであることを確認する
- 確認が取れたら動画を閲覧できる
ここで重要なのは、クッキーに保存されているのはセッションIDだけであり、ロール(権限)の情報は保存していない点です。そのため、以前の課金していない状態のロール情報が返されるようなことはありません。毎回データベースに最新の状態を確認しに行くため、決済完了後は正しくプレミアムユーザーとして認識されます。
これは一般的なセッションの扱い方であり、セキュリティ的にも問題のない設計です。
まとめ
今回の補足動画で解説した内容はWebの基礎知識が多く含まれています。セッション、クッキー、Webhook、べき等性など、これらの概念を理解しておくことで、決済以外の実装でも応用が効きます。より深く学びたい方は、Claude Codeに質問して学習を深めてみてください。