すべての記事
StripeStripe Connectmarketplacewebhook debugging

Stripe Connect Webhook:ローカルテストガイド

Stripe Connect は通常の Stripe とは別の Webhook エコシステムです。署名の数学は同じ。それ以外はすべて違います。Connect ハンドラーが account.application.deauthorized を静かに無視する理由を探していたなら、この記事はあなたのためのものです。

Connect は受信するイベントを変える

通常の Stripe Webhook はプラットフォームアカウントから来ます:charge、customer、subscription。Connect Webhook は接続アカウントと、プラットフォーム上の Connect 固有のライフサイクルイベントから来ます。リストは大きく重なりますが、Connect 有効時のみ見えるイベントを含みます:

  • account.updated — 検証ステータス、capability、要件
  • account.application.deauthorized — 接続アカウントがあなたのアクセスを取り消した
  • capability.updated — payout/transfer の有効化状態
  • person.createdperson.updated — Custom と Express アカウント向け
  • payout.failedpayout.paid — 接続アカウント上、プラットフォームではない

ほとんどのチームはデプロイ後にこれに気づきます。ローカルテストなら数分で問題が表面化します。

Stripe-Account ヘッダーがすべてを変える

イベントが接続アカウントで起こると、Stripe は接続アカウントの ID(acct_xxx)を持つ Stripe-Account ヘッダーを付けます。ハンドラーは payload の中身ではなく、そのヘッダーでルーティングする必要があります。

const connectedAccountId = req.headers['stripe-account'];
const event = stripe.webhooks.constructEvent(
  rawBody,
  req.headers['stripe-signature'],
  endpointSecret,
);

// Now process the event in the context of connectedAccountId
await handleConnectEvent(event, connectedAccountId);

ヘッダーの読み込みを忘れると、ハンドラーはすべての Connect イベントをプラットフォームで起きたかのように扱います。このパターンのバグは通常「payout が間違ったマーチャントに表示される」として現れます。

PortPreview で Connect をローカルテスト

セットアップは通常の Stripe ローカルテストと同じ、プラス追加 1 ステップ:

  1. プラットフォームアプリをローカル実行。
  2. トンネルを起動:npx portpreview 3000
  3. Stripe ダッシュボードでトンネル URL を Webhook エンドポイントとして追加し、さらに Events on Connected accounts オプションにチェック。これがイベントストリーム全体を変えるトグルです。
  4. テスト用 Express または Custom 接続アカウントを使う。Stripe のテストモードは現実的なイベントを発火する偽の「Jenny Rosen」アカウント作成者を含みます。
  5. Connect テストインターフェイスからイベントをトリガー:オンボーディング完了、payout 要求、アカウントの認可解除。

認可解除フローが難しい

接続アカウントがあなたのアプリのアクセスを取り消すと、Stripe は account.application.deauthorized をちょうど 1 回発火します。ハンドラーがクラッシュ、5xx を返す、または時間内に確認しないと、Stripe はリトライしますが、接続アカウントはすでに消えています。そのアカウントへの以降の API 呼び出しは 401 を返します。

認可解除フローは慎重にテスト。Connect テストモードでテストアカウントを認可解除し、Webhook をキャプチャし、キャプチャした payload に対してクリーンアップロジックを走らせます。パスが鉄壁になるまでリプレイ

Express 対 Standard 対 Custom

アカウントタイプは受信する person/capability イベントを変えます。Express と Custom アカウントは person.* イベントを出します。プラットフォームがオンボーディング完了を助けるからです。Standard アカウントは Stripe ホスト画面で自身のオンボーディングを処理するので、見えるイベントは少ない。プロジェクト途中でアカウントタイプを切り替えると——実際にやる人がいます——Webhook ハンドラーは調整が必要です。

私たちが実際にやること

プラットフォームレベルの分析とマーチャント別レポートを持つ本物のマーケットプレイスでは、初日から 2 つの別個のハンドラーパスを作ります:1 つはプラットフォームイベント用(Stripe-Account ヘッダーなし)、1 つは接続アカウントイベント用。関数の先頭でルーティング。これで後の「これは私たち向けかマーチャント向けか」バグの 90% を回避します。

Connect Webhook は Stripe の署名スキームを共有するので、検証の仕組みは通常の Stripe Webhook テストと同一です。プロバイダー間の署名数学の背景は署名検証ガイドを参照。キャプチャとリプレイ内蔵で Connect をテストするには PortPreview のウェイトリストへ。

よくある質問

Stripe Connect Webhook は通常の Stripe Webhook とどう違う?
Connect イベントは接続アカウントから来て、どのアカウントがイベントを発火したかを示す Stripe-Account ヘッダーを持ちます。署名の仕組みは通常の Stripe と同じですが、ダッシュボードで Events on Connected accounts を有効にし、ハンドラーでヘッダーによりルーティングする必要があります。
Stripe-Account ヘッダーは何に使う?
イベントをトリガーした接続アカウントを識別します。同じイベントタイプがプラットフォームでも接続アカウントでも発火し得て、ビジネスロジックが異なるため、ハンドラーは処理前に読むべきです。
認可解除 Webhook をローカルでどうテストする?
トンネルで Connect エンドポイントを設定し、テスト用 Express または Custom アカウントを接続し、Connect テストインターフェイスから認可解除します。account.application.deauthorized イベントがローカルハンドラーに届きます——クリーンアップロジックを調整しながら必要に応じてリプレイします。