Stripe で決済を扱うアプリにとって、Webhook は「あれば便利」ではなく実装上の必須要素だ。カード決済やサブスクの状態は Stripe 側で非同期に確定するため、その結果を確実に受け取る経路がなければアプリの状態と決済の状態がずれてしまう。

何を通知するか

支払いの成功・失敗、サブスクリプションの作成・更新・終了、返金やチャージバック、請求書の発行と支払い完了——課金まわりで起きるイベントが一通り飛んでくる。たとえば「決済完了 Webhook を受けて初めてアカウントを有効化する」といった設計にすれば、クライアント側の通信断や離脱でも整合性が崩れない。

実装で外せない 2 点

ひとつは署名検証。受信したリクエストが本当に Stripe からのものかを検証しないと、偽のイベントで不正にアカウントを有効化される余地が生まれる。もうひとつはリトライへの対応で、Stripe は配信失敗時に再送するため、ハンドラは同じイベントが複数回届いても結果が変わらない冪等な作りにする必要がある。

イベント順序と遅延という落とし穴

Webhook は必ずしも発生順に届くとは限らず、たとえば invoice.paid より先に customer.subscription.updated が届くこともある。アプリ側で「イベントが来た順に状態を更新する」設計にしていると不整合を招く。確定状態は Webhook の到着順ではなく、必要に応じて API で現在の状態を取り直して判断するのが堅い。テスト時は Stripe CLI でローカルにイベントを転送できるので、本番前に異常系の挙動を一通り確認しておきたい。

コストと範囲

Webhook 自体は無料で、Stripe の決済手数料とは別枠だ。当然ながら Stripe 以外の決済プロバイダのイベントは扱えない。Stripe を採用した時点でセットで設計に組み込むべき仕組みと考えてよい。