# Handle payment events with webhooks How to use webhooks to respond to offline payment events. *Webhook* (A webhook is a real-time push notification sent to your application as a JSON payload through HTTPS requests) は、Stripe からイベントを受信する HTTP エンドポイントです。 Webhook を使用すると、決済フロー外で発生する以下のような支払いイベントに関する通知を受け取ることができます。 - 成功した決済 (`payment_intent.succeeded`) - 不審請求の申し立てが行われた決済 (`charge.dispute.created`) - Stripe アカウントの利用可能な残高 (`balance.available`) ダッシュボードを支払いの返金や顧客情報の更新などの 1 回限りのアクションの用途に使用できるのに対して、Webhook は決済システムを拡張したり、ビジネスに影響する重要なイベントを大量に処理するのに役立ちます。 ## 独自の Webhook を構築する お客様独自のサーバーで Webhook ハンドラを構築し、オフラインのすべての決済フローを管理できます。まず、Stripe からのリクエストを受信できるエンドポイントを公開し、CLI を使用してシステムをローカルでテストします。Stripe からの各リクエストには [Event (イベント)](https://docs.stripe.com/api/events/object.md) オブジェクトと、修正された Stripe 上のオブジェクトへの参照が含まれます。 ## Webhook エンドポイントを作成 アプリケーションに新しいエンドポイントを追加します。リクエスト本文で送信されたイベントオブジェクトの `type` フィールドを確認することにより、特定のイベントに対応できます。次に、Webhook が機能していることを確認するため、標準的な出力を確認できます。 新しいエンドポイントを追加した後で、サーバを起動します。 #### Ruby ```ruby # Don't put any keys in code. See https://docs.stripe.com/keys-best-practices. # Find your keys at https://dashboard.stripe.com/apikeys. client = Stripe::StripeClient.new('<>') require 'stripe' require 'sinatra' require 'json' # Using the Sinatra framework set :port, 4242 post '/webhook' do payload = request.body.read event = nil begin event = Stripe::Event.construct_from( JSON.parse(payload, symbolize_names: true) ) rescue JSON::ParserError => e # Invalid payload status 400 return end # Handle the event case event.type when 'payment_intent.succeeded' payment_intent = event.data.object # contains a Stripe::PaymentIntent puts 'PaymentIntent was successful!' when 'payment_method.attached' payment_method = event.data.object # contains a Stripe::PaymentMethod puts 'PaymentMethod was attached to a Customer!' # ... handle other event types else puts "Unhandled event type: #{event.type}" end status 200 end ``` ## Stripe CLI をインストールして設定する その他のインストールオプションについては、[Stripe CLI を使ってみる](https://docs.stripe.com/stripe-cli.md)をご覧ください。 Stripe CLI をインストールしたら、コマンドラインで `stripe login` を実行して Stripe アカウントにリンクするためのペアリングコードを生成します。**Enter** キーを押してブラウザを立ち上げ、アクセスを許可する Stripe アカウントにログインします。生成された API キーは 90 日間有効です。ダッシュボードの [API キー](https://dashboard.stripe.com/apikeys)の下で、キーを修正したり削除したりできます。 > ログイン時、およびそのプロジェクトに対するコマンドを実行する際に、[–project-name](https://docs.stripe.com/cli/login#login-project-name) フラグを含めることで、プロジェクト固有の設定を作成できます。 テスト ```bash stripe login Your pairing code is: humour-nifty-finer-magic Press Enter to open up the browser (^C to quit) ``` 既存の API キーを使用する場合は、`--api-key` フラグを使用します。 ```bash stripe login --api-key <> Your pairing code is: humour-nifty-finer-magic Press Enter to open up the browser (^C to quit) ``` ## Webhook をローカルでテストする CLI を使用して、`listen` コマンドでローカル Webhook エンドポイントにイベントを転送します。 アプリケーションがポート 4242 で実行されていると仮定し、以下を実行します。 ```bash stripe listen --forward-to http://localhost:4242/webhook ``` 別の端末タブで、`trigger` CLI コマンドを使用して模擬 Webhook イベントをトリガーします。 ```bash stripe trigger payment_intent.succeeded ``` `listen` タブには次のイベントが表示されます。 ```bash [200 POST] OK payment_intent.succeeded ``` サーバーを実行中の terminal タブに「PaymentIntent was successful! (PaymentIntent は正常に処理されました)」と表示されます。 ## Optional: Webhook の署名を確認する Stripe は各イベントの `Stripe-Signature` ヘッダーに署名を含めます。これにより、イベントがサードパーティーではなく Stripe によって送信されたことを確認できます。Stripe の公式ライブラリを使用して署名を確認するか、自社のソリューションを使用して[手動で署名を確認](https://docs.stripe.com/webhooks.md#verify-manually)することができます。 最初に、Webhook エンドポイントのシークレットを特定し、それを `endpoint_secret` として Webhook ハンドラに追加します。ここではローカルでのエンドポイントの構築に引き続き Stripe CLI を使用しているため、`trigger` コマンドを使用して CLI から Webhook エンドポイントのシークレットを取得します。 ```bash stripe listen ``` Webhook エンドポイントのシークレットは `whsec_` で始まり、それに一連の数字と文字が続きます。この Webhook エンドポイントのシークレットは安全に保管し、決して公開しないようにしてください。 #### Ruby ```ruby # Don't put any keys in code. See https://docs.stripe.com/keys-best-practices. # Find your keys at https://dashboard.stripe.com/apikeys. client = Stripe::StripeClient.new('<>') require 'stripe' require 'sinatra' # 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 Dashboardendpoint_secret = 'whsec_...' # Using the Sinatra framework set :port, 4242 post '/my/webhook/url' do payload = request.body.readsig_header = request.env['HTTP_STRIPE_SIGNATURE'] event = nil beginevent = Stripe::Webhook.construct_event( payload, sig_header, endpoint_secret ) rescue JSON::ParserError => e # Invalid payload puts "Error parsing payload: #{e.message}" status 400 return rescue Stripe::SignatureVerificationError => e# Invalid signature puts "Error verifying webhook signature: #{e.message}" status 400 return end # Handle the event case event.type when 'payment_intent.succeeded' payment_intent = event.data.object # contains a Stripe::PaymentIntent puts 'PaymentIntent was successful!' when 'payment_method.attached' payment_method = event.data.object # contains a Stripe::PaymentMethod puts 'PaymentMethod was attached to a Customer!' # ... handle other event types else puts "Unhandled event type: #{event.type}" end status 200 end ``` ## Webhook エンドポイントをデプロイする Webhook エンドポイントを本番環境にデプロイする準備ができたら、以下を実行する必要があります。 1. テストキーではなく、[本番環境の API キー](https://docs.stripe.com/keys.md#test-live-modes)を使用してください。 1. Webhook エンドポイントを[ワークベンチ](https://docs.stripe.com/workbench.md)または API で設定します。 1. ワークベンチでエンドポイントを設定するには、[Webhook タブ](https://dashboard.stripe.com/workbench/webhooks)に移動します。 1. **送信先を追加**をクリックして、Stripe API のバージョンと、Stripe に送信させたい特定のイベントを入力します。**続行**をクリックし、使用可能な送信先タイプのリストから**Webhook エンドポイント**を選択します。**続行**をクリックし、エンドポイントの URL、オプションの名前、オプションの説明を入力します。**送信先を作成する**をクリックします。 1. アプリケーションの Webhook エンドポイントシークレットを、エンドポイントの Workbench の宛先詳細ビューに表示されている新しいシークレットに置き換えます。 これで、アプリケーションで本番イベントを受け入れられるようになりました。Webhook エンドポイントの設定については、[Webhook Endpoint](https://docs.stripe.com/api/webhook_endpoints.md) API のドキュメントで詳細をご確認ください。サンドボックスでのテスト方法については、[開発ガイドを参照してください](https://docs.stripe.com/webhooks.md)。