Webhook エンドポイントで Stripe イベントを受信する
Webhook エンドポイントの Stripe アカウントでイベントをリッスンし、実装で自動的にリアクションをトリガーできるようにします。
AWS アカウントにイベントを送信
イベントの送信先に Amazon EventBridge を指定してイベントを直接送信できるようになりました。
Stripe のシステムを構築する際、自社のアプリが Stripe アカウントで発生するイベントを受信できるようにすることをお勧めします。こうすることで、バックエンドシステムは適宜アクションを実行できます。
HTTPS Webhook エンドポイントでイベントを受信するためのイベントの送信先を作成します。Webhook エンドポイントを登録すると、Stripe は、Stripe アカウントで Event (イベント) が発生した際に、リアルタイムのイベントデータをアプリの Webhook エンドポイントにプッシュできます。Stripe は、HTTPS を使用して、Event オブジェクトを含む JSON ペイロードとして Webhook イベントをアプリに送信します。
Webhook イベントの受信は、顧客の銀行が支払いを確認したとき、顧客が支払いに不審請求を申請したとき、継続支払いが成功したときなど、非同期イベントに応答するのに役立ちます。
イベントの送信先を指定して Amazon EventBridge でイベントを受信することもできます。
始める
以下の手順を実行して、アプリで Webhook イベントの受信を開始します。
- Webhook エンドポイントハンドラを作成して、イベントデータの POST リクエストを受信します。
- Stripe CLI を使用して、ローカルで Webhook エンドポイントハンドラをテストします。
- Webhook エンドポイントに新しいイベントの送信先を作成します。
- Webhook エンドポイントを保護します。
1 つのエンドポイントを登録、作成して、複数のイベントタイプを同時に処理するか、特定のイベントに個別のエンドポイントを設定することができます。
組織のイベント送信先でサポートされていないイベントタイプの動作
Stripe はほとんどのイベントタイプを非同期で送信します。ただし、特定のイベントタイプに対しては、Stripe は応答を待ちます。イベントの送信先からの応答の有無は、これらの特定のイベントタイプに関する Stripe のアクションに直接影響を及ぼします。
組織のイベント送信先は、レスポンスを必要とするイベントタイプに対して限定的にサポートを提供しています。
- 組織のイベント送信先に
issuing_
を登録することはできません。代わりに、組織内の Stripe アカウントに Webhook エンドポイントを設定して、このイベントタイプを登録します。authorization. request issuing_
を使用して、購入リクエストをリアルタイムで承認します。authorization. request - 組織のイベント送信先に
checkout_
を登録できます。ただし、Checkout をウェブサイトに直接埋め込んだり、顧客を Stripe がホストする支払いページにリダイレクトしたりする場合、リダイレクト動作の処理は行われません。組織のイベント送信先にsessions. completed checkout_
イベントを配信しても、リダイレクトの動作には影響しません。Checkout のリダイレクト動作に影響を与えるには、組織内の Stripe アカウントで設定された Webhook エンドポイントを使用してこのイベントタイプを処理します。sessions. completed - 組織のイベント送信先の
invoice.
を登録できます。ただし、このイベントへの応答が失敗しても、自動回収時の請求書の自動確定には影響しません。Webhook エンドポイントのレスポンスを通じて請求書の自動確定に影響を与えるには、組織内の Stripe アカウントで設定された Webhook エンドポイントを使用してこのイベントタイプを処理します。created
ハンドラを作成する
POST メソッドを使用して、Webhook リクエストの受け付けが可能な HTTP または HTTPS エンドポイント関数を設定します。ローカルマシンでエンドポイント関数を開発中の場合、HTTP を使用できます。公開アクセスが可能になったら、Webhook エンドポイント関数は HTTPS を使用する必要があります。
エンドポイント関数を設定し、以下を行うようにします。
- Event オブジェクトで構成される JSON ペイロードを使用して、POST リクエストを処理します。
- 組織のイベントハンドラの場合、
context
値を調べて組織内のどのアカウントがイベントを生成したかを判断し、context
値に対応するStripe-Context
ヘッダーを設定します。 - タイムアウトを引き起こす可能性のある複雑なロジックの前に、成功ステータスコード (
2xx
) をすばやく返します。たとえば、会計システムで顧客の請求書を支払い済みとして更新する前に、200
のレスポンスを返す必要があります。
注
別の方法として、インタラクティブな Webhook エンドポイントビルダーを使用し、ご使用のプログラム言語で Webhook エンドポイント関数を構築することもできます。
エンドポイントの例
このコードスニペットは、Stripe アカウントから受信したイベントを確認し、イベントを処理して、200
レスポンスを返すように設定された Webhook 関数です。API v1 リソースを使用する場合はスナップショットイベントハンドラを参照し、API v2 リソースを使用する場合はシンイベントハンドラを参照します。
組織のハンドラサンプル
このコードスニペットは、組織全体で受信したイベントを確認し、イベントを処理して 200
レスポンスを返すように設定された Webhook エンドポイント関数です。ハンドラは、イベントのペイロードの context
フィールドをチェックして、受信したイベントがどのアカウントに適用されるかを確認し、アカウント内の後続の API コールに適切なアカウントの API キーを使用します。
このコードスニペットは、受信したイベントを確認し、該当する場合は元の口座を検出して、イベントを処理し、200
のレスポンスを返すよう設定された Webhook 関数です。
ハンドラをテストする
Webhook エンドポイント関数を本番環境に移行する前に、アプリケーションの連携をテストすることをお勧めします。これを行うには、自身のローカルマシンにイベントを送信するようローカスリスナーを設定し、テストイベントを送信します。テストには、CLI を使用する必要があります。
ローカルエンドポイントにイベントを転送する
ローカルエンドポイントにイベントを転送するには、CLI で次のコマンドを実行して、ローカルリスナーを設定します。--forward-to
フラグは、サンドボックス内のすべての Stripe イベントをローカルの Webhook エンドポイントに送信します。シンイベントとスナップショットイベントのどちらを使用するかに応じて、以下の適切な CLI コマンドを使用します。
注
stripe listen
を実行して Stripe Shell でイベントを確認することもできますが、シェルからローカルエンドポイントにイベントを転送することはできません。
ローカルリスナーでのテストに役立つ便利な設定として、以下のようなものがあります。
- HTTPS 証明書の検証を無効にするには、
--skip-verify
のオプションフラグを使用します。 - 特定のイベントのみを転送するには、
--events
のオプションフラグを使用して、カンマで区切ったイベントのリストを渡します。
- Stripe に登録済みの公開 Webhook エンドポイントからローカルの Webhook エンドポイントにイベントを転送するには、
--load-from-webhooks-api
のオプションフラグを使用します。これにより、登録されたエンドポイントにイベントが読み込まれ、パスとその登録イベントが解析され、そのパスが--forward-to path
のローカルの Webhook エンドポイントに関連付けられます。
- Webhook の署名を確認するには、リッスンコマンドの初期出力から
{{WEBHOOK_
を使用します。SIGNING_ SECRET}}
Ready! Your webhook signing secret is '{{WEBHOOK_SIGNING_SECRET}}' (^C to quit)
テストイベントをトリガーする
テストイベントを送信するには、Stripe ダッシュボードでオブジェクトを手動で作成し、イベントの送信先が登録されているイベントタイプをトリガーします。Stripe for VS Code を使用してイベントをトリガーする方法をご確認ください。
エンドポイントの登録
Webhook エンドポイント関数をテストしたら、Workbench の API または Webhooks タブで Webhook エンドポイントがアクセス可能な URL を登録します。そうすることで、Stripe はイベントの送信先を認識できます。最大 16 個の Webhook エンドポイントを Stripe に登録できます。登録済みの Webhook エンドポイントは、パブリックにアクセス可能な HTTPS URL である必要があります。
Webhook の URL 形式
Webhook エンドポイントを登録するための URL 形式は、次のとおりです。
https://<your-website>/<your-webhook-endpoint>
たとえば、ドメインが https://mycompanysite.
で、Webhook エンドポイントへのルートが @app.
の場合、エンドポイント URL に https://mycompanysite.
を指定します。
Webhook エンドポイントのイベント送信先を作成する
ダッシュボードで Workbench を使用するか、API を使用してプログラムでイベントの送信先を作成します。各 Stripe アカウントには、最大 16 個のイベント送信先を登録できます。
注
Workbench は、既存の開発者ダッシュボードに置き換わるツールです。開発者ダッシュボードをまだ使用されている場合は、新しい Webhook エンドポイントの作成方法をご覧ください。
エンドポイントのセキュリティ保護
ハンドラですべての Webhook リクエストが Stripe によって生成されたものであることを確認して、実装を保護する必要があります。公式ライブラリを使用して Webhook の署名を検証するか、手動で検証できます。
Webhook 連携のデバッグ
Webhook エンドポイントにイベントを送信する際に、以下のような複数のタイプの問題が発生することがあります。
- Stripe が Webhook エンドポイントにイベントを送信できない可能性がある
- Webhook エンドポイントで SSL の問題が発生している可能性がある
- ネットワーク接続が断続的である
- Webhook エンドポイントが、受信する予定のイベントを受信していない
イベント配信を表示する
イベント配信を表示するには、Webhook で Webhook エンドポイントを選択し、イベントタブを選択します。
イベント タブには、イベントのリストと、各イベントが Delivered
、Pending
、Failed
のいずれであるかが表示されます。イベントをクリックすると、配信試行の HTTP ステータスコードや保留中の配信時刻などのメタデータが表示されます。
HTTP ステータスコードを修正する
イベントにステータスコード 200
が表示されている場合は、Webhook エンドポイントへの送信が成功したことを示しています。200
以外のステータスコードを受信する場合もあります。次の表で、一般的な HTTP ステータスコードと推奨される解決方法の一覧をご覧ください。
保留中の Webhook ステータス | 説明 | 修正 |
---|---|---|
(接続不可) ERR | 宛先サーバーへの接続を確立できません。 | ホストドメインがインターネットで一般に公開されアクセス可能であることを確認します。 |
(302 ) ERR (またはその他の 3xx ステータス) | 宛先サーバーがリクエストを別の場所にリダイレクトしようとしました。Webhook リクエストへのリダイレクト応答は失敗と見なされます。 | Webhook エンドポイントの送信先を、リダイレクトによって解決される URL に設定します。 |
(400 ) ERR (またはその他の 4xx ステータス) | 宛先サーバーがリクエストを処理できないか、処理しません。これは、サーバーがエラーを検出した場合 (400 )、宛先 URL にアクセス制限が設定されている場合 (401 、403 )、または宛先 URL が存在しない (404 ) 場合に発生することがあります。 |
|
(500 ) ERR (またはその他の 5xx ステータス) | リクエストの処理中に、宛先サーバーでエラーが発生しました。 | アプリケーションのログを確認して、500 エラーが返されている理由を調べます。 |
(TLS エラー) ERR | 送信先サーバーへの安全な接続を確立できませんでした。通常、送信先サーバーの証明書チェーン内の SSL/TLS 証明書または中間証明書に問題があると、これらのエラーが発生します。Stripe には TLS バージョン v1. 以降が必要です。 | SSL サーバーテストを実行して、このエラーの原因となった可能性がある問題を見つけます。 |
(タイムアウト) ERR | 宛先サーバーで Webhook リクエストに応答するのに時間がかかりすぎました。 | Webhook 処理コードで複雑なロジックを延期して、成功を示すレスポンスを即時に返すようにしてください。 |
イベント送信の動作
このセクションは、Stripe が Webhook エンドポイントにイベントを送信する際に想定されるさまざまな動作を理解するのに役立ちます。
自動での再試行
本番環境では、Stripe は指数バックオフを使用して最長 3 日間、送信先へのイベントの配信を試行します。イベント送信先のイベントの配信タブで、該当がある場合、次回の再試行のタイミングを確認します。Stripe はサンドボックスで作成されたイベントの配信を数時間のうちに 3 回再試行します。Stripe が再試行するときに、送信先が無効化または削除されていた場合、そのイベントの以降の再試行は行われません。ただし、Stripe が再試行できるようになる前にイベントの送信先を無効にして、再び有効にした場合は、以降の再試行が引き続き行われます。
手動での再試行
Amazon EventBridge ではサポート対象外
Amazon EventBridge にイベントを手動で再送信することはできません。
イベントを手動で再試行するには、2 つの方法があります。
- Stripe ダッシュボードで、特定のイベントを確認しているときに 再送する をクリックします。これは、イベント作成後最大 15 日間機能します。
- Stripe CLI を使用して
stripe events resend <event_
コマンドを実行します。これは、イベント作成後最大 30 日間機能します。id> --webhook-endpoint=<endpoint_ id>
イベントの順序付け
Stripe は、イベントが生成された順序で配信されることを保証しません。たとえば、サブスクリプションを作成することで、次のイベントが生成されるとします。
customer.
subscription. created invoice.
created invoice.
paid charge.
(支払いが付随する場合)created
イベントの送信先が、特定の順序でのイベントの受信に左右されないようにしてください。配送を適切に管理できるように準備します。API を使用して不足しているオブジェクトを取得することもできます。たとえば、最初に受信したイベントが invoice.
であった場合は、それに含まれる情報を使用して請求書、支払い、サブスクリプションの各オブジェクトを取得できます。
API のバージョン管理
イベント発生時のアカウント設定の API バージョンによって API バージョンが決まり、さらに送信先に送られる Event (イベント) の構造が決まります。たとえば、アカウントで 2015-02-16 など、以前の API バージョンが設定されている場合、バージョン管理を使用して特定のリクエストの API バージョンを変更しても、生成され送信先に送られる Event (イベント) オブジェクトは、2015-02-16 の API バージョンに基づくものになります。Event (イベント) オブジェクトは、作成後に変更することはできません。たとえば、支払いを更新しても、元の支払いイベントは変更されません。そのため、アカウントの API バージョンを後から更新しても、既存の Event (イベント) オブジェクトがさかのぼって変更されることはありません。新しい API バージョンを使用して /v1/events
を呼び出すことで以前の Event (イベント) を取得しても、受信したイベントの構造には影響しません。テストイベントの送信先は、デフォルトの API バージョンか、最新の API バージョンのいずれかに設定できます。送信先に送られる Event (イベント) は、イベントの送信先で指定されているバージョンに従って構造化されます。
Webhook 使用のベストプラクティス
これらのベストプラクティスを見直し、Webhook エンドポイントがセキュリティで保護され、システムで適切に機能することを確認してください。
重複するイベントを処理する
Webhook エンドポイントは、同じイベントを複数回受信する可能性があります。処理したイベント ID をログに記録し、すでにログに記録したイベントを処理しないようにすることで、重複するイベントの受信に対処することができます。
場合によっては、2 つの Event オブジェクトが個別に生成・送信されます。これらの重複を識別するには、data.
のオブジェクト ID と event.
を使用します。
構築済みのシステムに必要なイベントタイプのみをリッスンする
Webhook エンドポイントは、お客様の実装で必要なイベントのタイプのみを受信するように設定します。その他のイベント (またはすべてのイベント) をリッスンすると、お客様のサーバーに過度の負荷がかかるため、お勧めしません。
ダッシュボードまたは API で、Webhook エンドポイントが受信するイベントを変更できます。
イベントを非同期で処理する
非同期キューで受信したイベントを処理するようにハンドラを設定します。非同期でイベントを処理することを選択した場合は、拡張性の問題が発生する可能性があります。Webhook の配信が急増すると (たとえば、すべてのサブスクリプションが更新される月初など)、エンドポイントホストが対処不可能になる場合があります。
非同期キューを使用することで、同時に発生するイベントをシステムが対応できる速度で処理できるようになります。
Webhook ルートを CSRF 保護から除外する
Rails、Django、その他のウェブフレームワークを使用している場合、貴社のサイトでは、すべての POST リクエストに 「CSRF トークン」が含まれていることを自動的に確認している可能性があります。これは、貴社とそのユーザーをクロスサイトリクエストフォージェリ の試行から保護するための重要なセキュリティ機能です。ただし、このセキュリティ対策は貴社サイトにおける正当なイベントの処理を妨げる可能性があります。この場合は、Webhook ルートを CSRF 保護から除外しなければならない可能性があります。
HTTPS サーバーでイベントを受信する
Webhook エンドポイント (本番環境で必要) に HTTPS URL を使用する場合、Stripe は Webhook データを送信する前に、お客様のサーバーへの接続が安全であることを確認します。これを機能させるには、お客様のサーバーが、有効なサーバー証明書で HTTPS をサポートするように正しく設定されている必要があります。Stripe の Webhook は、TLS バージョン v1.2 および v1.3 のみサポートしています。
エンドポイントの署名シークレットを定期的に取り消す
イベントが Stripe から送信されたことを確認するためのシークレットは、Workbench の Webhook タブで変更できます。シークレットを安全に保つために、定期的またはシークレットの侵害が疑われる場合にローテーション (変更) することをお勧めします。
シークレットを取り消すには、以下を行います。
- Workbench の Webhook タブで、シークレットをローテーションするエンドポイントをクリックします。
- オーバーフローメニュー () にアクセスし、シークレットの更新をクリックします。現在のシークレットキーをただちに有効期限切れにすることも、有効期限を最大 24 時間延長して、自社のサーバーの検証コードをご自身で更新する時間を確保することもできます。この間は、エンドポイントに対して複数のシークレットキーがアクティブになります。Stripe は、有効期限までシークレットキーごとに 1 つの署名を生成します。
イベントが Stripe から送信されたことを検証する
Stripe は、設定された IP アドレスリストから Webhook イベントを送信します。これらの IP アドレスから送信されたイベントのみを信頼してください。
また、Webhook の署名を検証して、受信したイベントが Stripe によって送信されたことを確認します。Stripe は、各イベントの Stripe-Signature
ヘッダーに署名を含めることで、エンドポイントに送信する Webhook イベントに署名します。これにより、イベントがサードパーティではなく Stripe によって送信されたことを確認できます。署名は、公式ライブラリを使用して確認するか、独自のソリューションを使用して手動で確認できます。
次のセクションでは、Webhook の署名を検証する方法を説明します。
- エンドポイントのシークレットを取得します。
- 署名を検証します。
エンドポイントのシークレットを取得する
Workbench の Webhook タブに移動し、すべてのエンドポイントを表示します。シークレットを取得するエンドポイントを選択し、クリックして表示をクリックします。
Stripe は、エンドポイントごとに一意のシークレットキーを生成します。テスト API キーと本番 API キーの両方に同じエンドポイントを使用する場合、シークレットはそれぞれ異なります。さらに、複数のエンドポイントを使用する場合は、署名を検証するエンドポイントごとにシークレットを取得する必要があります。この設定後、Stripe はエンドポイントに送信する各 Webhook への署名を開始します。
リプレイ攻撃を防止する
リプレイ攻撃とは、攻撃者が有効なペイロードとその署名を傍受し、それを再送信することを言います。そのような攻撃を低減するために、Stripe は Stripe-Signature
ヘッダーにタイムスタンプを含めています。このタイムスタンプは署名されたペイロードの一部であるため、署名によっても検証され、攻撃者は署名を無効にしなければタイムスタンプを変更できません。署名が有効でもタイムスタンプが古すぎる場合は、アプリケーションにペイロードを拒否させることができます。
Stripe のライブラリには、タイムスタンプと現在時刻の間に 5 分のデフォルトの許容範囲があります。この許容範囲は、署名を検証する際に追加のパラメーターを指定することで変更できます。ネットワークタイムプロトコル (NTP) を使用して、サーバーのクロックが正確であり、Stripe のサーバーの時間と同期していることを確認します。
よくある間違い
許容値 0
は使用しないでください。許容値 0
を使用すると、最新性チェックが完全に無効になります。
Stripe は、イベントをエンドポイントに送信するたびにタイムスタンプと署名を生成します。Stripe がイベントを再試行する場合 (たとえば、その前にエンドポイントが 2xx
以外のステータスコードで応答した場合)、新しい配信試行に対して新しい署名とタイムスタンプを生成します。
2xx レスポンスを素早く返す
エンドポイントは、タイムアウトの原因となる複雑なロジックを実行する前に、成功を示すステータスコード (2xx
) を速やかに返す必要があります。たとえば、会計システムで顧客の請求書を支払い済みとして更新する前に、200
のレスポンスを返さなければなりません。