# Connect Webhook Connect で Webhook を使用して Stripe アクティビティの通知を受ける方法をご紹介します。 アカウントでイベントが発生すると、Stripe は *Webhook* (A webhook is a real-time push notification sent to your application as a JSON payload through HTTPS requests) を使用してアプリケーションに通知します。すべての *Connect* (Connect is Stripe's solution for multi-party businesses, such as marketplace or software platforms, to route payments between sellers, customers, and other recipients) の組み込みでは、[Webhook エンドポイント](https://dashboard.stripe.com/account/webhooks)を設定して、Connect イベントをリッスンする必要があります。 ## Connect Webhook Connect プラットフォームは、次の 2 種類の Webhook を使用します。 - 「Account」Webhook は、自身のアカウントでのアクティビティー用です (たとえば、API キーを使用して、[別の Stripe アカウントとしての認証](https://docs.stripe.com/connect/authentication.md)なしで行われるほとんどのリクエスト)。これには、連結アカウントで直接行われたものを除き、すべてのタイプの支払いが含まれます。 - 「Connect」Webhook は、連結アカウントでのアクティビティー用です。Stripe は、連結アカウントに関するすべてのイベント (アカウントの更新とダイレクト支払いを含む) を Connect Webhook に送信します。 Connect Webhook を作成する際は、Connect Webhook イベントを受信するように設定する必要があります。[ダッシュボード](https://dashboard.stripe.com/test/webhooks)で作成する場合は、**リッスン対象**で**連結アカウントでのイベント**を選択します。API を使用して作成する場合は、[connect パラメーター](https://docs.stripe.com/api/webhook_endpoints/create.md#create_webhook_endpoint-connect)を true に設定します。 ![Stripe ダッシュボードでの Webhook 設定](https://b.stripecdn.com/docs-statics-srv/assets/webhooks.ac3d6c19a5281fbbd2b85a335cd887b3.png) Connect Webhook の場合、開発環境の Webhook URL はテスト用 Webhook のみを受信しますが、本番環境の Webhook URL は本番環境とテスト環境の両方の Webhook を受信します。これは、本番環境アプリケーションでは本番環境の取引とテスト取引の両方を実行できるためです。イベントの Webhook を受信したら `livemode` の値を確認して、ユーザーによる対応が必要かどうかを判断することをお勧めします。 [サンドボックス](https://docs.stripe.com/sandboxes.md) アカウントのイベントを受信するには、そのアカウント用に個別の webhook エンドポイントを定義する必要があります。 連結アカウントの各イベントには、連結アカウントを識別する最上位の `account` プロパティが含まれます。連結アカウントは[イベントをトリガーしたオブジェクト](https://docs.stripe.com/api/events/object.md#event_object-data-object)を所有しているため、[連結アカウントとして](https://docs.stripe.com/connect/authentication.md)、そのオブジェクトに対して API リクエストを行う必要があります。 ```json { "id": ""{{EVENT_ID}}"", "livemode": true, "object": "event", "type": "customer.created", "account": ""{{CONNECTED_ACCOUNT_ID}}"", "pending_webhooks": 2, "created": 1349654313, "data": {...} } ``` 次の表は、連結アカウントに関連する最も一般的で重要なイベントのいくつかについて説明したものです。 | イベント | data.object 型 | 説明 | | ---------------------------------- | ------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `account.application.deauthorized` | `application` | 連結アカウントがプラットフォームへの連結を解除すると発生します。これを使用して、サーバーでクリーンアップをトリガーできます。Stripe ダッシュボードにアクセスできる連結アカウント ([Standard アカウント](https://docs.stripe.com/connect/standard-accounts.md)を含む) で利用できます。 | | `account.external_account.updated` | `card` や `bank_account` などの外部口座 | [連結アカウントに関連付けられた銀行口座またはデビットカードが更新された](https://docs.stripe.com/connect/payouts-bank-accounts.md)場合に発生し、入金に影響することがあります。プラットフォームが管理する連結アカウントに適用されます。これには、Custom アカウントと Express アカウント、および[プラットフォーム管理](https://docs.stripe.com/connect/platform-controls-for-stripe-dashboard-accounts.md)が有効な Standard アカウントが含まれます。 | | `account.updated` | `account` | 連結アカウントの要件の変化やステータスの変化を監視できます。すべての連結アカウントで利用可能です。 | | `balance.available` | `balance` | お客様の Stripe 残高が更新されたときに発生します。例えば、[銀行口座から追加した資金](https://docs.stripe.com/connect/top-ups.md)が連結アカウントに送金できるようになったときなどです。 | | `payment_intent.succeeded` | `payment_intent` | 支払いインテントで支払いが成功した場合に発生します。[デスティネーション支払い](https://docs.stripe.com/connect/destination-charges.md)と[ダイレクト支払い](https://docs.stripe.com/connect/direct-charges.md)を含むすべての支払いで利用可能です。 | | `payout.failed` | `payout` | [入金が失敗した](https://docs.stripe.com/connect/payouts-connected-accounts.md#webhooks)場合に発生します。入金が失敗すると、関連する外部口座は無効になり、外部口座が更新されるまで自動でも手動でも入金を行うことはできません。 | | `person.updated` | `person` | `Account` に関連付けられている `Person` が更新されたときに発生します。[Persons API を利用して確認要件に対処する](https://docs.stripe.com/connect/handling-api-verification.md#verification-process)場合は、個人の要件の変化やステータスの変化を監視します。プラットフォームが管理する連結アカウントに適用されます。これには、Custom アカウントと Express アカウント、および[プラットフォーム管理](https://docs.stripe.com/connect/platform-controls-for-stripe-dashboard-accounts.md)が有効な Standard アカウントが含まれます。 | #### イベント - account.application.deauthorized #### Ruby ```ruby # Using Sinatra. require 'sinatra' require 'stripe' set :port, 4242 # Don't put any keys in code. See https://docs.stripe.com/keys-best-practices. # Find your keys at https://dashboard.stripe.com/apikeys. Stripe.api_key = '<>' # If you're testing your webhook locally with the Stripe CLI, you # can find the endpoint's secret by running `stripe listen` # Otherwise, find your endpoint's secret in your webhook settings in # the Developer Dashboard endpoint_secret = 'whsec_...' post '/webhook' do payload = request.body.read sig_header = request.env['HTTP_STRIPE_SIGNATURE'] event = nil # Verify webhook signature and extract the event. # See https://stripe.com/docs/webhooks#verify-events for more information. begin event = Stripe::Webhook.construct_event( payload, sig_header, endpoint_secret ) rescue JSON::ParserError => e # Invalid payload. status 400 return rescue Stripe::SignatureVerificationError => e # Invalid Signature. status 400 return end if event['type'] == 'account.application.deauthorized' application = event['data']['object'] connected_account_id = event['account'] handle_deauthorization(connected_account_id, application) end status 200 end def handle_deauthorization(connected_account_id, application) # Clean up account state. puts 'Connected account ID: ' + connected_account_id puts application.to_s end ``` #### イベント - account.updated #### Ruby ```ruby # Using Sinatra. require 'sinatra' require 'stripe' set :port, 4242 # Don't put any keys in code. See https://docs.stripe.com/keys-best-practices. # Find your keys at https://dashboard.stripe.com/apikeys. Stripe.api_key = '<>' # If you're testing your webhook locally with the Stripe CLI, you # can find the endpoint's secret by running `stripe listen` # Otherwise, find your endpoint's secret in your webhook settings in # the Developer Dashboard endpoint_secret = 'whsec_...' post '/webhook' do payload = request.body.read sig_header = request.env['HTTP_STRIPE_SIGNATURE'] event = nil # Verify webhook signature and extract the event. # See https://stripe.com/docs/webhooks#verify-events for more information. begin event = Stripe::Webhook.construct_event( payload, sig_header, endpoint_secret ) rescue JSON::ParserError => e # Invalid payload. status 400 return rescue Stripe::SignatureVerificationError => e # Invalid Signature. status 400 return end if event['type'] == 'account.updated' account = event['data']['object'] handle_account_update(account) end status 200 end def handle_account_update(account) # Collect more required information puts account.to_s end ``` #### イベント - person.updated #### Ruby ```ruby # Using Sinatra. require 'sinatra' require 'stripe' set :port, 4242 # Don't put any keys in code. See https://docs.stripe.com/keys-best-practices. # Find your keys at https://dashboard.stripe.com/apikeys. Stripe.api_key = '<>' # If you're testing your webhook locally with the Stripe CLI, you # can find the endpoint's secret by running `stripe listen` # Otherwise, find your endpoint's secret in your webhook settings in # the Developer Dashboard endpoint_secret = 'whsec_...' post '/webhook' do payload = request.body.read sig_header = request.env['HTTP_STRIPE_SIGNATURE'] event = nil # Verify webhook signature and extract the event. # See https://stripe.com/docs/webhooks#verify-events for more information. begin event = Stripe::Webhook.construct_event( payload, sig_header, endpoint_secret ) rescue JSON::ParserError => e # Invalid payload. status 400 return rescue Stripe::SignatureVerificationError => e # Invalid Signature. status 400 return end if event['type'] == 'person.updated' person = event['data']['object'] connected_account_id = event['account'] handle_person_update(connected_account_id, person) end status 200 end def handle_person_update(connected_account_id, person) # Collect more required information puts 'Connected account ID: ' + connected_account_id puts person.to_s end ``` #### イベント - payment_intent.succeeded、ダイレクト支払い #### Ruby ```ruby # Using Sinatra. require 'sinatra' require 'stripe' set :port, 4242 # Don't put any keys in code. See https://docs.stripe.com/keys-best-practices. # Find your keys at https://dashboard.stripe.com/apikeys. Stripe.api_key = '<>' # If you are testing your webhook locally with the Stripe CLI you # can find the endpoint's secret by running `stripe listen` # Otherwise, find your endpoint's secret in your webhook settings in # the Developer Dashboard endpoint_secret = 'whsec_...' post '/webhook' do payload = request.body.read sig_header = request.env['HTTP_STRIPE_SIGNATURE'] event = nil # Verify webhook signature and extract the event. # See https://stripe.com/docs/webhooks#verify-events for more information. begin event = Stripe::Webhook.construct_event( payload, sig_header, endpoint_secret ) rescue JSON::ParserError => e # Invalid payload. status 400 return rescue Stripe::SignatureVerificationError => e # Invalid Signature. status 400 return end if event['type'] == 'payment_intent.succeeded' payment_intent = event['data']['object'] connected_account_id = event['account'] handle_successful_payment_intent(connected_account_id, payment_intent) end status 200 end def handle_successful_payment_intent(connected_account_id, payment_intent) # Fulfill the purchase puts 'Connected account ID: ' + connected_account_id puts payment_intent.to_s end ``` #### イベント - payment_intent.succeeded、ダイレクト支払い以外 #### Ruby ```ruby # Using Sinatra. require 'sinatra' require 'stripe' set :port, 4242 # Don't put any keys in code. See https://docs.stripe.com/keys-best-practices. # Find your keys at https://dashboard.stripe.com/apikeys. Stripe.api_key = '<>' # If you are testing your webhook locally with the Stripe CLI you # can find the endpoint's secret by running `stripe listen` # Otherwise, find your endpoint's secret in your webhook settings in # the Developer Dashboard endpoint_secret = 'whsec_...' post '/webhook' do payload = request.body.read sig_header = request.env['HTTP_STRIPE_SIGNATURE'] event = nil # Verify webhook signature and extract the event. # See https://stripe.com/docs/webhooks#verify-events for more information. begin event = Stripe::Webhook.construct_event( payload, sig_header, endpoint_secret ) rescue JSON::ParserError => e # Invalid payload. status 400 return rescue Stripe::SignatureVerificationError => e # Invalid Signature. status 400 return end if event['type'] == 'payment_intent.succeeded' payment_intent = event['data']['object'] handle_successful_payment_intent(payment_intent) end status 200 end def handle_successful_payment_intent(payment_intent) # Fulfill the purchase puts payment_intent.to_s end ``` #### イベント - balance.available #### Ruby ```ruby # Using Sinatra. require 'sinatra' require 'stripe' set :port, 4242 # Don't put any keys in code. See https://docs.stripe.com/keys-best-practices. # Find your keys at https://dashboard.stripe.com/apikeys. Stripe.api_key = '<>' # If you're testing your webhook locally with the Stripe CLI, you # can find the endpoint's secret by running `stripe listen` # Otherwise, find your endpoint's secret in your webhook settings in # the Developer Dashboard endpoint_secret = 'whsec_...' post '/webhook' do payload = request.body.read sig_header = request.env['HTTP_STRIPE_SIGNATURE'] event = nil # Verify webhook signature and extract the event. # See https://stripe.com/docs/webhooks#verify-events for more information. begin event = Stripe::Webhook.construct_event( payload, sig_header, endpoint_secret ) rescue JSON::ParserError => e # Invalid payload. status 400 return rescue Stripe::SignatureVerificationError => e # Invalid Signature. status 400 return end if event['type'] == 'balance.available' balance = event['data']['object'] handle_available_balance(balance) end status 200 end def handle_available_balance(balance) # Transfer funds to a connected account puts balance.to_s end ``` #### イベント - account.external_account.updated #### Ruby ```ruby # Using Sinatra. require 'sinatra' require 'stripe' set :port, 4242 # Don't put any keys in code. See https://docs.stripe.com/keys-best-practices. # Find your keys at https://dashboard.stripe.com/apikeys. Stripe.api_key = '<>' # If you're testing your webhook locally with the Stripe CLI, you # can find the endpoint's secret by running `stripe listen` # Otherwise, find your endpoint's secret in your webhook settings in # the Developer Dashboard endpoint_secret = 'whsec_...' post '/webhook' do payload = request.body.read sig_header = request.env['HTTP_STRIPE_SIGNATURE'] event = nil # Verify webhook signature and extract the event. # See https://stripe.com/docs/webhooks#verify-events for more information. begin event = Stripe::Webhook.construct_event( payload, sig_header, endpoint_secret ) rescue JSON::ParserError => e # Invalid payload. status 400 return rescue Stripe::SignatureVerificationError => e # Invalid Signature. status 400 return end if event['type'] == 'account.external_account.updated' external_account = event['data']['object'] connected_account_id = event['account'] handle_external_account_update(connected_account_id, external_account) end status 200 end def handle_external_account_update(connected_account_id, external_account) # Transfer funds to a connected account puts 'Connected account ID: ' + connected_account_id puts external_account.to_s end ``` #### イベント - payout.failed #### Ruby ```ruby # Using Sinatra. require 'sinatra' require 'stripe' set :port, 4242 # Don't put any keys in code. See https://docs.stripe.com/keys-best-practices. # Find your keys at https://dashboard.stripe.com/apikeys. Stripe.api_key = '<>' # If you're testing your webhook locally with the Stripe CLI, you # can find the endpoint's secret by running `stripe listen` # Otherwise, find your endpoint's secret in your webhook settings in # the Developer Dashboard endpoint_secret = 'whsec_...' post '/webhook' do payload = request.body.read sig_header = request.env['HTTP_STRIPE_SIGNATURE'] event = nil # Verify webhook signature and extract the event. # See https://stripe.com/docs/webhooks#verify-events for more information. begin event = Stripe::Webhook.construct_event( payload, sig_header, endpoint_secret ) rescue JSON::ParserError => e # Invalid payload. status 400 return rescue Stripe::SignatureVerificationError => e # Invalid Signature. status 400 return end if event['type'] == 'payout.failed' payout = event['data']['object'] connected_account_id = event['account'] handle_failed_payout(connected_account_id, payout) end status 200 end def handle_failed_payout(connected_account_id, payout) # Re-collect bank account required information puts 'Connected account ID: ' + connected_account_id puts payout.to_s end ``` ## Webhook をローカルでテストする Stripe CLI を使用して、Webhook をローカルでテストできます。 1. まだインストールしていない場合は、[Stripe CLI をマシンにインストール](https://docs.stripe.com/stripe-cli/install.md)してください。 1. Stripe アカウントにログインし、コマンドラインで `stripe login` を実行して CLI を設定します。 1. 1 つの端末ウィンドウで `stripe listen --forward-to localhost:{PORT}/webhook` を実行し、別の端末ウィンドウで `stripe trigger {{EVENT_NAME}}` を実行することにより、ローカルホストがシミュレーションされたイベントを連結アカウントで受信できるようにします。 > Connect Webhook では、`stripe listen` で [–forward-connect-to](https://docs.stripe.com/cli/listen#listen-forward-connect-to) を使用し、`stripe trigger` で [–stripe-account](https://docs.stripe.com/cli/trigger#trigger-stripe_account) を使用します。 ## See also - [Webhook に関するドキュメント](https://docs.stripe.com/webhooks.md) - [Event オブジェクトのリファレンス](https://docs.stripe.com/api.md#events)