StripeはWebhookを利用して、様々なイベントをトリガーすることができます。そしてStripe CLIを利用することで、Webhookのデバッグや開発をよりスムーズに行うことができます。
v1.5.8時点では、stripe listen
とstripe trigger
がWebhook関連のコマンドとして用意されています。
Webhook commands:
listen Listen for webhook events
trigger Trigger test webhook events
stripe listen
でStripのWebhookイベントをモニタリングする
stripe listen
はStripe上でWebhookのイベントが発生したログを確認できるコマンドです。
stripe listen
コマンド概要
% stripe listen --help
The listen command watches and forwards webhook events from Stripe to your
local machine by connecting directly to Stripe's API. You can test the latest
API version, filter events, or even load your saved webhook endpoints from your
Stripe account.
Usage:
stripe listen [flags]
Examples:
stripe listen
stripe listen --events charge.captured,charge.updated \
--forward-to localhost:3000/events
Flags:
--connect-headers strings
A comma-separated list of custom
headers to forward for Connect
-e, --events strings
A comma-separated list of specific
events to listen for. For a list of
all possible events, see:
https://stripe.com/docs/api/events/types (default [*])
-c, --forward-connect-to string
The URL to forward Connect webhook
events to (default: same as normal
events)
-f, --forward-to string
The URL to forward webhook events to
-H, --headers strings
A comma-separated list of custom
headers to forward
-h, --help
help for listen
-l, --latest
Receive events formatted with the
latest API version (default: your
account's default API version)
--live
Receive live events (default: test)
-j, --print-json
Print full JSON objects to stdout
--print-secret
Only print the webhook signing
secret and exit
-s, --skip-update
Skip checking latest version of
Stripe CLI
--skip-verify
Skip certificate verification when
forwarding to HTTPS endpoints
-a, --use-configured-webhooks
Load webhook endpoint configuration
from the webhooks API/dashboard
listenコマンドでイベントの発生をモニタリングする
stripe listen
コマンドを実行すると、「いつ」「どのイベントが」「どのIDで」発生したかを確認できるようになります。
下のサンプルでは、2021/3/15 12:19:40びpayment_intent.created
のイベントが発生したことが確認できます。また、evt_xxx
を使ってStripe Dashboardで検索を行うと、イベントの内容や受け取ったレスポンスなどの記録が確認できます。
% stripe listen
> Ready! Your webhook signing secret is whsec_xxxxxxx (^C to quit)
2021-03-15 12:19:40 --> payment_intent.created [evt_1IV6xyDHnG67uihbNhTZyGQi]
--print-json
で詳細をJSON形式で確認する
E2Eテストやserverless invoke local
などでイベントをテストしたい場合、--print-json
オプションをつけて監視することで、Stripeから送られてくるWebhookイベントの内容をみることができます。
% stripe listen --print-json
{
"id": "evt_1IV7DpDHnG67uihbvtxwWKPY",
"object": "event",
"api_version": "2020-03-02",
"created": 1615779361,
"data": {
"object": {
"id": "pi_1IV7DpDHnG67uihbQsPJBGMl",
"object": "payment_intent",
"amount": 2000,
"amount_capturable": 0,
"amount_received": 0,
...
--live
で本番のイベントをモニタリングする
本番環境のイベントを追跡したい場合、--live
オプションを追加しましょう。
これで本番環境で発生したWebhookイベントをモニタリングできるようになります。
--events
で指定のイベントのみモニタリングする
規模の大きいアプリケーションなどでは、大量のイベントの中に調べたいイベントが埋もれてしまうこともあります。そんな場合は、--events charge.captured,payment_intent.created
のようにイベント名を指定すると便利です。
% stripe listen --events charge.captured,payment_intent.created
> Ready! Your webhook signing secret is whsec_xxxxxx (^C to quit)
2021-03-15 12:45:43 --> charge.captured [evt_1IV7NDDHnG67uihbhV4mIsBK]
2021-03-15 12:45:47 --> payment_intent.created [evt_1IV7NGDHnG67uihb5FNbkuF8]
stripe trigger
でWebhookイベントをトリガーする
Webhookを開発しても、実際にイベントが発生しないと動作確認ができません。イベントが発生することを待つか、Dashboardからイベントを手動で発行することのどちらかでデバッグを行うことが多いかと思いますが、Stripe CLIを使うことでイベント発行も行うことができます。
% stripe trigger --help
Trigger specific webhook events to be sent. Webhooks events created through
the trigger command will also create all necessary side-effect events that are
needed to create the triggered event as well as the corresponding API objects.
Supported events:
account.updated
balance.available
charge.captured
charge.dispute.created
charge.failed
charge.refunded
charge.succeeded
checkout.session.async_payment_failed
checkout.session.async_payment_succeeded
checkout.session.completed
customer.created
customer.deleted
customer.source.created
customer.source.updated
customer.subscription.created
customer.subscription.deleted
customer.subscription.updated
customer.updated
invoice.created
invoice.finalized
invoice.payment_failed
invoice.payment_succeeded
invoice.updated
issuing_authorization.request
issuing_card.created
issuing_cardholder.created
payment_intent.amount_capturable_updated
payment_intent.canceled
payment_intent.created
payment_intent.payment_failed
payment_intent.succeeded
payment_method.attached
plan.created
plan.deleted
plan.updated
product.created
product.deleted
product.updated
setup_intent.canceled
setup_intent.created
setup_intent.setup_failed
setup_intent.succeeded
subscription_schedule.canceled
subscription_schedule.created
subscription_schedule.released
subscription_schedule.updated
Usage:
stripe trigger <event> [flags]
Examples:
stripe trigger payment_intent.created
Flags:
-h, --help help for trigger
--stripe-account string Set a header
identifying the
connected account
customer.created
イベントを発行する
Dashboardからイベントを発行する時と同じように、発行したいイベント名を指定するだけで実行できます。
% stripe trigger customer.created
Setting up fixture for: customer
Trigger succeeded! Check dashboard for event details.
stripe listen
でモニタリングしている場合、customer.created
のイベントが発生したログが出力されます。
2021-03-15 12:52:53 --> customer.created [evt_1IV7U8DHnG67uihbTQSkyYg4]
stripe trigger
はデータ作成も行う点に注意
stripe trigger
コマンドは、現状不可能ですが、live環境向けに使うことは非推奨です。それは「実際にリソースを作成する」挙動を行うためです。
先ほどのstripe trigger customer.created
を実行したのち、Stripe Dashboardにアクセスすると、created by Stripe CLI
と記されたCustomerが作成されています。
この他、payment_intentやsubscriptionなども、実際に各APIを呼び出してリソースを作成し、それによってイベントを発行する動きをしています。
下のコマンドでは、Customer / Plan / Subscriptionが作成されています。
コマンドを実行するたびにリソースが作成されますので、もし「plans.listの結果をそのまま商品一覧として表示する」ような実装をアプリケーション側でされている場合には注意してください。
% stripe trigger customer.subscription.created
Setting up fixture for: customer
Setting up fixture for: plan
Setting up fixture for: subscription
Trigger succeeded! Check dashboard for event details.
stripe listen
を使ってローカル環境にWebhook APIサーバーをたてる
StripeのWebhook APIをローカルで開発する際、stripe listen
コマンドを利用することで、StripeからのWebhookイベントをローカル環境のAPIで受け取れるようにすることができます。
stripe sample
コマンドでWebhookのあるサンプルプロジェクトを作成する
[事前準備] 実際にWebhookを作成してもよいのですが、本筋から外れますので今回はStripeが用意しているサンプルを利用します。
placing-a-hold
など、Webhookの実装が含まれているサンプルプロジェクトを選んでstripe samples create
しましょう。
% stripe samples create placing-a-hold
A newer version of the Stripe CLI is available, please update to: v1.5.10
✔ Finished downloading
Use the arrow keys to navigate: ↓ ↑ → ←
? What type of integration would you like to use:
▸ using-webhooks
without-webhooks
? What server would you like to use:
java
▸ node
php
python
ruby
% cd placing-a-hold
続いてWebhook用のサーバーを立ち上げます。今回はNode.jsで作成していますので、npm
コマンドを利用します。また、実際には.env
ファイルにStripeのAPIキーなどを追加する必要がありますが、今回はリクエストが受け取れたらOKなので省略します。
% npm install --prefix server
% cp .env.example server/.env
% npm start --prefix server
Node server listening on port 4242!
curlコマンドでAPIにアクセスできるか試しておきましょう。
% curl http://localhost:4242/webhook -XPOST --verbose
* Trying ::1...
* TCP_NODELAY set
* Connected to localhost (::1) port 4242 (#0)
> POST /webhook HTTP/1.1
> Host: localhost:4242
> User-Agent: curl/7.64.1
> Accept: */*
>
< HTTP/1.1 400 Bad Request
< X-Powered-By: Express
< Content-Type: text/plain; charset=utf-8
< Content-Length: 11
< ETag: W/"b-EFiDB1U+dmqzx9Mo2UjcZ1SJPO8"
< Date: Mon, 15 Mar 2021 02:43:28 GMT
< Connection: keep-alive
<
* Connection #0 to host localhost left intact
Bad Request* Closing connection 0
もしアクセスできない場合は、以下のようにConnection refused
が表示されます。その場合、npm install
ができていないか、npm start
が失敗している可能性が高いです。
% curl http://localhost:4242/webhook -XPOST --verbose
* Trying ::1...
* TCP_NODELAY set
* Connection failed
* connect to ::1 port 4242 failed: Connection refused
* Trying 127.0.0.1...
* TCP_NODELAY set
* Connection failed
* connect to 127.0.0.1 port 4242 failed: Connection refused
* Failed to connect to localhost port 4242: Connection refused
* Closing connection 0
curl: (7) Failed to connect to localhost port 4242: Connection refused
stripe listen --forward-to
でStripeからのWebhookを受信する
通常localhostで稼働しているAPIにリクエストを飛ばすには、ngrokなどのサービスを使う必要があります。ですが、Stripe CLIを使っている場合、stripe listen
コマンドでforwardすることができます。
npm start
などでWebhookを受信するAPIサーバーを起動させた状態で、以下のコマンドを実行します。Portが4242以外を使用している場合は、都度書き換えましょう。
% stripe listen --forward-to localhost:4242/webhook
A newer version of the Stripe CLI is available, please update to: v1.5.10
> Ready! Your webhook signing secret is whsec_xxxxxxxxxxxxx (^C to quit)
Forwardに成功すると、CLIが待機中表示になります。
この状態で、新しくターミナル画面を追加し、stripe trigger
コマンドを実行してWebhookイベントを発生させてみましょう。
% stripe trigger payment_intent.created
Setting up fixture for: payment_intent
Trigger succeeded! Check dashboard for event details.
stripe listen
を実行している画面に、以下のようなログが表示されます。
2021-03-15 11:46:13 --> payment_intent.created [evt_1IV6RdDHnG67uihb8MVQQKGg]
2021-03-15 11:46:13 <-- [400] POST http://localhost:4242/webhook [evt_1IV6RdDHnG67uihb8MVQQKGg]
stripe listen
の実行結果をStripe Dashboardで確認する
Stripe CLIでforwardしたWebhookの送信ログも、Stripe Dashboardから確認できます。
ただし表示場所が[Webhook の試行]ではなく[Webhook CLI 応答]ですので注意してください。
Webhookを実際に使えるようにする
先ほどのログを見ますと、HTTP 400のBad Requestがレスポンスとして出力されています。これは、Stripe Webhookを受け取る際の署名チェックに失敗しているためです。
stripe listen
コマンドを実行した直後にYour webhook signing secret is whsec_xxxxxxxxxxxxx
という文言が表示されます。このwhsec_xxx
をserver/.env
ファイルのSTRIPE_WEBHOOK_SECRET
に設定して、再度npm start
でAPIサーバーを立ち上げてみましょう。
% vim server/.env
# Stripe keys
STRIPE_PUBLISHABLE_KEY=pk_12345
STRIPE_SECRET_KEY=sk_12345
# Required to run webhook
# See README on how to use the Stripe CLI to setup
STRIPE_WEBHOOK_SECRET=whsec_xxxxxxxxxxxxx
#Environment setup
STATIC_DIR=../../ client
% npm start --prefix server
Stripe Webhookの署名チェック用シークレットが正しく設定されたことで、再度stripe trigger payment_intent.created
を実行すると、WebhookのレスポンスがHTTP 200に変わります。
2021-03-15 11:56:17 --> payment_intent.created [evt_1IV6bNDHnG67uihbkrZPaKF8]
2021-03-15 11:56:17 <-- [200] POST http://localhost:4242/webhook [evt_1IV6bNDHnG67uihbkrZPaKF8]
デプロイ時はDashboardから署名チェック用シークレットを発行しよう
.env
に設定したSTRIPE_WEBHOOK_SECRET
は、Stripe CLIがWebhookの動作確認で利用するためのシークレットです。そのため、実際にデプロイして実行するアプリケーションには、登録したWebhook個別に発行されているシークレットを環境変数に設定するようにしましょう。
.env
をそのままGitでcommitすると、シークレットキーの漏洩だけでなく、意図せぬ挙動が起きる可能性も高まりますので要注意です。