先日質問があった、Stripでサブスクリプションのキャンセルがあった場合のWebhook実装方法を解説します!
前提としてサブスクリプションの実装は完了しているものとします。
キャンセルの際にWebhookを使うので、今回はその解説となります。
なぜWebhookの実装が必要なのか、それは
- なんらかの理由でユーザーのカード引き落としができなくなった(カードの支払い拒否や有効期限切れ など)
- Stripe側で支払いがキャンセルされた
→この場合にBubble側に自動で通知が来ないから
つまり、Stripe側のキャンセル事情をBubbleアプリへ(Webhook)で知らせる必要があります。
この(Webhook)実装をしないと、Stripe側でキャンセルされたのにサービスが使用できてしまう、支払いがされていないのにサービスが利用できてしまう、ことになります。
Webhookの仕組み
Webhookとは
<Webhookとは>
あるイベントが発生した時に、指定したURLにPOSTリクエストする仕組みです。
この説明、APIを使用したことがある方には、なるほどね〜とわかると思いますが
ちょっと何を言っているかわからない… 方もいるはず。
わかりやすく言うと
☝️ 更新情報をBubbleアプリへ(リアルタイム)で伝える仕組みです。
図解すると以下になります↓
図1)BubbleとStripe連携し、毎月のサブスクリプションの支払いが実行される
図2)しかし何らかの理由でStripe側で支払いが実行されなくなる
がしかし、Bubble側には自動でその通知は行かない。Bubbleアプリ側では検知できない。
図3)Bubbleアプリ側に知らせる仕組みが「Webhook」
サブスクリプション(月額など)支払いが実行されない=>即時アプリへ知らせる
Bubbleアプリ側で(サービス非表示や再度支払いなど)できるようになる。
Webhookの仕組みがわかりましたでしょうか?
次に実際にBubbleでWebhookを使用する方法を解説します。
Webhookの設定
実はWebhook、はじめて設定する方にはややこしく感じます。
一体自分は何をどうしてるのか?全容が理解できないからです。
でも2~3回設定するうちに順番も何のためのものかも理解できるようになるので大丈夫です。今回はじめて設定する方は下の「その1〜その5」の手順に沿って進めてください。
その1:Bubble側の設定 – API workflow
まずはBubble側の設定です。
Backend workflowsを使用するのでStarterプラン($32/月の有料プラン)以上である必要があります。
有料プランにするとBackend workflowsが有効になるので、Enable workflow API and backend workflowsにチェックを入れます↓
Settings > API > Enable workflow API and backend workflows
上記のEnable workflow API and backend workflowsにチェックを入れることにより、ページ検索エリアをクリックすると一番下に Backend workflowsが表示されるようになります。
*チェックが入っていないとこの「Backend workflows」が表示されませんのでご注意ください。
Backend workflowsをクリックします↓
Backend workflowsのページが表示されたら
Click here to add a backend workflowのエリアをクリックし
General > New API workflow を選択します↓
New API workflowを選択すると、黒い設定画面が表示されます。設定を行います。
API workflow name | 任意の名前を付けます 例)stripe_webhook |
This workflow can be run without authentication | チェックを入れる |
Ignore privacy rules when running the workflow | チェックを入れる |
Parameter definition | Detect request date |
上記まで設定が完了したら、中央なかほどにある「Detect data」をクリックします↓
Detect dataをクリックするとPOPUPでこのような画面が開き、アプリ側が Detect=検出 をし始めます↓
このURLをコピーしてください。
赤色URL部分ををクリックすることで、URLをコピーすることができます。
そしてここがポイントですが、
この状態で、CANCELボタンを押さずに、ブラウザも閉じずに、このままの状態(検出させておくまま)、Stripeの管理ページを開いてください。
Stripeのページは別タブなどで開き、このBubble画面は触らないようにしてください。
この後の流れを少しだけ解説!
・コピーしたURLをStripe側に貼り付けます(Stripe側でキャンセルなどの発生があった場合に知らせるURLがコレです)
・イベント(支払いキャンセルなど)を1回実行し、無事検知がされるとデータが返ってきます。
上のポイント内容は今は全て理解できていなくてOKです。
URLをコピーしたら次の「その2」へ進んでください。
その2:Stripe側の設定 – エンドポイント
Stripeの管理画面を開き
テストを行う場合は「テスト環境」になっていることをしっかり確認してください。
開発者 > Webhook > エンドポイントを追加
をクリックします↓
Stripeイベントのリッスン ページに行くので
ここで先ほど
BubbleのPOPUP画面でコピーしたURLをそのまま丸っと貼り(ペーストし)ます。
URLを貼り付けたら、左下ボタン「+イベントを選択」から
何のイベントを検出したいか? を選択します。
Stripeはさまざまなイベントを用意してくれています↓
今回、Detect=検出 させたいのはサブスクリプションがキャンセルされたら
というイベントです↓
イベントCustomerの中にある
customer.subscription.deleted にチェックを入れます↓
今回検出する例)
customer.subscription.deleted
そして「イベントを追加」のボタンを押します↓
イベント追加のボタンを押すと以下の画面に戻るので↓
・リッスンするイベントの選択 が先ほどチェクを入れたものになっているのを確認し
「イベントを追加」ボタンを押し確定させます。
この画面になったらURL(エンドポイント)の設定は一旦成功です。
*あとでこの画面に戻り、URLを多少変更(一部削除)する必要がありますが…それは「その5」でお伝えします。
その3:Initialize(初期実行)をする
さて、ここまで来たら一度イベントを発生(Initialize)させなければいけません。
イベントを実行 → アプリ側へデータを返す(知らせる)
無事に検知されるかを、一度実際に実行しなければなりません。
今回検出させたいののは、サブスクリプションのキャンセル です。
そのため実行させるのは、「サブスクリプション契約しているものを Stripe側からキャンセル」することです。
以下のステップでキャンセルを発生させることができます。
- BubbleアプリでStripeのサブスクリプションを1例作っておく(今回の前提条件なので方法は省略します。)
- Stripe側から、そのサブスクを「キャンセル」する
Stripeの画面から
サブスクリプション > キャンセルを実行したいデータ(どれでも構いません)の「サブスクリプションをキャンセル」をクリックします
例では、user(stripe@example.jp)のサブスクリプションに対してキャセルを行っています。
確認POPUPが表示されるので、青色ボタン「サブスクリプションのキャンセル」をクリックします↓
Stripe側のステータスが「キャンセル済み」になったことがわかります↓
これでInitialize(初期実行)が完了しました!
一度キャンセルが実行されたので、アプリ側へデータが返っている(即時通知)はずです。
では、そのままにしているBubble画面を見てみましょう!
この1度イベントを発生させるInitialize、はじめて触る方にはわかりずらいのですが、、とりあえずStripe側が「検知できる」イベントを発生させないといけない。と覚えてください。
イベントを発生させたことで、Bubbleアプリと連携取れてるよ!Bubble側へ通知が行く「開門した!」ようなものと思ってください。
そのため、例でStripe側から user(stripe@example.jp)のサブスクリプションをキャンセルしましたが、この段階では開門されただけで、Bubble側データに変化はありません↓
この「active」を「canceled」に変更させるにはBackend workflowでactionの設定が必要です。これについては次のチャプター その4で解説をします。
その4:Bubble側の設定 – データが返ってくるのでSAVEしフローを組む
先ほどこの画面のままStripeのページに行きWebhookの設定とInitializeを行いました↓
無事Initializeがされたので、Bubble画面に戻ると、このように表示が変化しています↓
データが返ってきていることがわかります。
「SAVE」ボタンを押します。
*使用するデータで形式が異なっている場合は変更してください。
例えば日付のデータが「text」になっていて、そのデータを使用する(Dataに保存など)場合には「date」に変更してからSAVEボタンを押すようにしてください。
Stripe側から返って来るデータ形式の「保存」ができたので、値をWorkflowでも使うことができるようになります。
Workflowのaction設定で、Make change to thingからデータの更新を行います。
更新したいデータは「サブスクリプションのステータス」です。
Make change to thingから、変更させたいData typeを指定します。
<補足>
私の場合はData type「Billing」にStripeの情報を保持させているので↓
例)Dataをこのように組んでおり、変更させたいのはBillingのsubsc_status(サブスクのステータスを保存している)です
Things to change から Do a search for で Type「Billing」を選択↓
更にどのBillingかを制約(絞り込み)するために、Add a new constraint から以下を設定しました。
customer_id = Request Data ‘s object customer
object customer についての補足
object customerで絞り込みを行なっていますが、このobject customerはサブスクリプション作成時の「Stripe Customer ID」と同じです。
名称が異なっていますが、
Stripe Customer ID と Webhookで返って来た「object customer」は同じものを指しています。
以下スクリーンショットはBillingを新規作成時のもの。customer_id に「Stripe Customer ID」を入れています↓
Search for Billing には :first item を付け
「+Change another field」 でステータスの上書き(更新)を行います。
subsc_status = Request Data ‘s object status
上記でMake change to~の設定が完了しました。以降、Stripe側で支払いがキャンセルされると、Dataが自動で Make change(更新)され、ステータスが「canceled」に書き替わるようになります。
ただし最後にもう一つStirp側で行う重要なことがあります!
次の「その5」で解説をします。
その5:Stripe側の設定 – /initialize 部分を削除する
さて長くなりましたが、最後の設定です。
ここはシンプルです。
Stripe画面のWebhookページから、「その2」で設定したURL(エンドポイント)をクリックします。下図③をクリックします↓
詳細画面に遷移し
URLの右「・・・」3点リーダから「詳細情報の更新」をクリックします。
POPUPが表示されるので /initialize 部分を削除します↓
/initialize
を削除します。/から下「/initialize」をごっそり削除
削除したら青色ボタン「エンドポイントを更新」を押し、変更を完了させます。
さて長い〜長い〜設定もここまで!
これで完了です!!!
以降、Stripe側でキャンセルがあった場合にData の ステータスが自動で「canceled」に変更されるようになります↓
Webhookを使用したことにより、ステータスの変更が自動で行われるようになりました!
このステータスをアプリ側でどう使えば良いか?
それはステータスが「aactive」の場合だけサービス利用(表示など)ができるように組めば良いですね!
ステータスが即時反映されることにより、Dataのsubsc_statusが「canceled」になったら(の場合は)表示させないなどの設定が可能です。
まとめ:セキュリティについても注意!
今回もかなり〜長くなりました!
BubbleエディタとStripeの画面を行ったり来たり、今自分が一体何を設定しているのか?見失った方もいるかもしれません。
上のステップ「その1 〜 その5」に沿って数回試すことで理解できるようになります。
Bubble側で受け取るためのURLをStripeに登録する、そしてInitializeしちゃんと開門してあげる。
そのためのフローの設定でした。
====
✅ 最後に「重要な」セキュリティの話もしておきます!
セキュリティー的にはAPI workflow設定で以下3つ全てチェックを入れているので、割と危険な状態です。
それゆえ、URL(エンドポイント)は他人が知ることのないように管理しましょう。
またBubbleデフォルトで開示されている「Swagger」は見えない設定に、チェックを入れておく ことを推奨します。Swaggerが見えると全てのエンドポイントもわかってしまいます。
もう一点、Stripeから変更が返って来た際の条件も付けることをおすすめします!
Only whenに
返ってきた object customer が データに保存されている customer_idと一致した場合 だけこのworkflowを実行するように条件をつけます。
セキュリティに関しては奥が深く、追求に限りがありませんが一旦ここまで設定しておけば一安心です!
長くなりました。今回もお疲れ様でした!
知れば知るほど楽しくなるBubble!
今日も一歩前進、楽しんでいきましょう^^
Bubble構築のご相談や代行も承っております。
お気軽にご連絡ください。
お問い合わせはこちら