Bubble × Stripe Connect で作る!予約決済プラットフォームの作り方【第6回】Webhook設計
Bubble × Stripe Connect で作る!予約決済プラットフォームの作り方
第6回:Webhook設計 – 決済完了の検知とステータス更新
前回のおさらい
第5回では、サブスク課金を解説しました。
- 有料掲載・広告プランの実装
- Stripe Subscription の設定
- プロモーションコード「FIRST100」
今回は、決済システムの要である Webhook を解説します。
なぜ Webhook が必要か
問題: 決済完了をどう知るか
[ユーザー] → [Stripe決済画面] → [決済完了]
│
↓
ユーザーは success_url に戻る
│
↓
でも、本当に決済された?
success_url に戻ってきただけでは、実際に決済が完了したかは分かりません。
- ユーザーがURLを直接叩いた可能性
- 決済処理中にネットワークエラーが起きた可能性
- 不正なアクセスの可能性
解決策: Stripe からの通知を受け取る
[Stripe] → [Webhook] → [あなたのサーバー]
│
↓
「決済が完了しました」
│
↓
データベースを更新
Stripe が「決済完了しました」と教えてくれるので、確実に処理できます。
Webhook の仕組み
イベントの種類
| イベント | タイミング |
|---|---|
| checkout.session.completed | Checkout Session が完了 |
| payment_intent.succeeded | 支払いが成功 |
| invoice.paid | 請求書が支払われた(サブスク更新時) |
| customer.subscription.deleted | サブスクがキャンセルされた |
今回主に使うのは:
- checkout.session.completed: 決済完了時
- invoice.paid: サブスク更新時
- customer.subscription.deleted: サブスク解約時
Bubble での Webhook 設定
1. Backend Workflow の作成
Bubble の Settings → API → 「Enable Workflow API」をオン
Bubble の Backend workflows で新しいエンドポイントを作成:
Endpoint: stripe_webhook
Method: POST
このエンドポイントのURLは:
https://あなたのアプリ.bubbleapps.io/api/1.1/wf/stripe_webhook
2. Stripe ダッシュボードで登録
ダッシュボード → 開発者 → Webhook → 「エンドポイントを追加」
エンドポイントURL: https://xxx.bubbleapps.io/api/1.1/wf/stripe_webhook
イベント:
- checkout.session.completed
- invoice.paid
- customer.subscription.deleted
3. Webhook シークレットの取得
登録後、「署名シークレット」(whsec_xxx)が表示されます。
これは署名検証に使います(後述)。
受信データの構造
checkout.session.completed
{
"type": "checkout.session.completed",
"data": {
"object": {
"id": "cs_test_xxx",
"mode": "payment",
"payment_status": "paid",
"customer": "cus_xxx",
"amount_total": 3000,
"metadata": {
"reservation_id": "xxx",
"store_id": "xxx"
}
}
}
}
invoice.paid(サブスク更新)
{
"type": "invoice.paid",
"data": {
"object": {
"id": "in_xxx",
"customer": "cus_xxx",
"subscription": "sub_xxx",
"amount_paid": 55000
}
}
}
Bubble での処理フロー
予約決済の場合
[Webhook 受信]
│
↓
[type = checkout.session.completed ?]
│
├─→ No → 終了
│
└─→ Yes
│
↓
[mode = payment ?]
│
├─→ No(subscription)→ サブスク処理へ
│
└─→ Yes
│
↓
[metadata から reservation_id を取得]
│
↓
[予約を検索]
│
↓
[予約のステータスを「支払済み」に更新]
│
↓
[決済金額を保存]
Bubble の Backend Workflow
Trigger: stripe_webhook
Step 1: Only when
Request Data's type is "checkout.session.completed"
Request Data's data's object's mode is "payment"
Step 2: Search for 予約
reservation_id = Request Data's data's object's metadata's reservation_id
Step 3: Make changes to 予約
支払いステータス = 支払済み
決済金額 = Request Data's data's object's amount_total
stripe_payment_id = Request Data's data's object's id
署名検証
Webhook が本当に Stripe から来たものか確認する必要があります。
なぜ必要か
誰でもあなたのエンドポイントにPOSTできてしまいます:
[悪意のある人] → [偽の Webhook] → [あなたのサーバー]
│
↓
「決済完了しました」(嘘)
│
↓
不正に処理が実行される
検証方法
Stripe は Webhook 送信時に Stripe-Signature ヘッダーを付けます。
これと Webhook シークレット(whsec_xxx)を使って検証します。
Bubble での実装:
Bubble 標準では署名検証が難しいため、以下の方法があります:
1. Stripe プラグインを使う: 署名検証機能が含まれていることが多い
2. 検証を省略してリスク受容: テスト環境では許容できる場合も
3. サーバーサイドで検証: 外部サービス(Make.com など)を経由
実運用では検証を推奨しますが、小規模なら「metadata で二重チェック」でも対応可能:
[Webhook 受信]
│
↓
[reservation_id で予約を検索]
│
├─→ 見つからない → 無視
│
└─→ 見つかった
│
↓
[予約の金額と Webhook の金額が一致?]
│
├─→ 不一致 → 無視(ログに記録)
│
└─→ 一致 → 処理を実行
冪等性(べきとうせい)
同じ Webhook が複数回届くことがあります(Stripe のリトライ機能)。
問題
1回目: 予約を「支払済み」に更新
2回目: また「支払済み」に更新(問題なし)
3回目: ポイント付与 → これが重複すると困る!
対策
処理済みかどうかをチェック:
[Webhook 受信]
│
↓
[stripe_payment_id で履歴を検索]
│
├─→ 見つかった → 処理済み、スキップ
│
└─→ 見つからない → 処理を実行
│
↓
[処理完了後]
stripe_payment_id を保存
エラーハンドリング
Stripe へのレスポンス
Webhook を受け取ったら、200 OK を返す必要があります。
- 200 OK: Stripe は「届いた」と認識
- 4xx/5xx: Stripe はリトライする(最大3日間)
Bubble の Backend Workflow は正常終了すれば自動で 200 を返します。
エラー時のリトライ
処理中にエラーが起きても、Stripe が再送してくれます。
ただし、冪等性を担保していないと重複処理の原因に。
デバッグ方法
1. Stripe ダッシュボードで確認
開発者 → Webhook → イベント
各イベントの:
- 送信日時
- レスポンス(200 OK / エラー)
- リクエスト/レスポンスの詳細
2. 再送
同じイベントを再送できます。
デバッグに便利。
3. Stripe CLI(ローカル開発)
stripe listen --forward-to localhost:3000/webhook
ローカル環境でも Webhook を受け取れます。
次回予告
第7回(最終回)では、本番デプロイ を解説します。
- テスト環境から本番環境への切り替え
- Stripe 本番モードの設定
- 審査対策
お楽しみに!
このシリーズの目次
| 回 | タイトル | 内容 |
|---|---|---|
| 1 | イントロ | プラットフォーム決済の設計 |
| 2 | Stripe Connect設計 | Express アカウント、オンボーディング |
| 3 | 予約決済の実装 | Destination Charges、手数料計算 |
| 4 | クーポンの罠 | プロモコードが使えない問題と回避策 |
| 5 | サブスク課金 | 有料掲載・広告プランの実装 |
| 6 | Webhook設計 | ← 今ここ |
| 7 | 本番デプロイ | テスト→本番の切り替え、審査対策 |
いいね・フォローしていただけると励みになります!
実装のご相談
予約システム・サブスク決済の導入でお困りの方へ。
・Stripe / Stripe Connect の設計・実装
・Bubble / Make.com でのノーコード開発
・テスト環境→本番デプロイまで一貫対応
初期設定から運用まで、初心者の方にも丁寧にサポートします。