FLARES LLC
FLARES LLC

Technical document

Stripe Webhookを冪等に処理する設計

決済連携では、画面遷移の成功だけを信じると状態がずれます。Stripe Webhookを中心に、重複や再送が起きても同じ結果になる処理を設計する必要があります。 Webhook処理では、イベントが一度だけ届く前提を捨てることが設計の出発点です。
決済 / Webhook約10分公開日 2026年7月5日更新日 2026年7月5日
Stripe Webhookを冪等に処理する設計のアイキャッチ

Summary

この文書の要点

  • Webhookは重複して届く前提で処理する。
  • 署名検証とイベントIDの保存を最初に行う。
  • イベント受信、署名検証、重複判定、業務反映、再処理を別の状態として管理する。
  • 決済状態はWebhook順序ではなく、外部側の現在状態を再取得して確定する。

どこが設計の難所か

決済完了後のリダイレクトだけで注文や契約を確定すると、ブラウザを閉じた場合や通信失敗時に状態がずれます。一方でWebhookは同じイベントが複数回届いたり、イベント順序が期待通りでないことがあります。

決済は金額、提供権限、請求状態に直結します。処理の二重実行や取り消し漏れは大きな問題になります。また、Webhook受信時に外部APIやメール送信まで同期実行すると、失敗時の扱いが難しくなります。

Stripe Webhookは決済連携の重要な入口ですが、同じイベントが複数回届いたり、順序が前後したり、処理途中でアプリ側だけ失敗したりします。単純にイベントを受け取って即DB更新すると、二重処理や状態巻き戻りが起きます。

境界をどう切るか

Webhook受信では、署名を検証し、イベントIDを保存し、未処理なら内部イベントとしてキューに積みます。決済状態の更新は、現在状態と受信イベントから許可される遷移だけを実行します。副作用はジョブに分けます。

設計では、Webhookを業務処理そのものではなく、外部イベントの受信記録として扱います。まずevent_idで一意に保存し、署名検証とイベント種別を確認し、その後に冪等なユースケースへ渡します。

実装で効く細部

DBには外部イベントテーブルと内部状態テーブルを分けて持ちます。イベントIDにユニーク制約を置き、重複受信時は成功として返します。状態更新では、決済待ち、確定、失敗、返金、取消などの遷移を明示します。

PostgreSQLには`webhook_events`テーブルを置き、event_id、type、payload_hash、received_at、processed_at、status、errorを保存します。業務反映側では、支払いIDやサブスクリプションIDごとに現在状態を確認し、すでに反映済みなら何もしないようにします。

  • event_idにユニーク制約を置き、重複受信は成功扱いで返せるようにする。
  • HTTP応答は短く返し、重い処理はキューへ渡して再試行できるようにする。
  • 状態更新時は外部APIで現在状態を確認し、古いイベントで巻き戻さない。

壊れ方を観測する

検証では、同一Webhookの複数回送信、順序逆転、署名不正、処理途中失敗、ジョブ再実行をテストします。Stripe CLIを使う場合も、実運用で起きる再送を想定したテストデータを用意します。

検証では、同一イベントの二重送信、順序逆転、処理途中例外、外部APIタイムアウトを再現します。テスト用イベントだけでなく、保存済みpayloadを使った再処理コマンドを持つと、障害時の復旧が現実的になります。

捨てた選択肢とトレードオフ

冪等性を厳密に扱うとテーブルや状態遷移が増えます。単発の簡易決済では重く見えるかもしれません。しかし、サブスクリプションや権限付与が絡む場合は、最初からイベント駆動で考える方が安全です。

すべてを同期処理にすると実装は単純ですが、タイムアウトや再送に弱くなります。キュー化すると状態管理は増えますが、再試行と調査がしやすくなります。決済では実装の短さより、二重反映しない構造を優先すべきです。

現場に残す判断軸

Stripe Webhookは通知ではなく、決済状態を確定するための重要な入力です。重複と順序逆転を前提に冪等な処理へ落とし込むことが、決済連携の基本になります。

Webhookの冪等性は、if文で重複を避けることではありません。受信イベントと業務状態を分け、何度実行しても同じ結果へ収束するように設計することです。

Technical documents

技術文書を増やしていきます。

AI、クラウド、業務アプリ開発、要件定義、運用設計に関する考え方を、今後も文書として整理します。

技術文書一覧へ