LINE Bot と ChatGPT を組み合わせた有料Botを開発している。
Stripeで課金を受け取ったり、解約・プラン変更をトリガーにしてLINEへ通知を送る仕組みを実装中だ。
Stripeから送られてくるWebhookを受け取る処理の中で、どういう分岐をしているかを整理しておく。
全体の流れ
Stripeでの決済やプラン変更が行われると、
Stripeは設定してある Webhook URL(GASのdoPost)にイベント情報を送ってくる。
そのイベントの種類ごとに処理を分けている。
Stripe → GAS(doPost)
├── checkout.session.completed 決済完了
├── customer.subscription.updated プラン変更
└── customer.subscription.deleted 解約
それぞれのイベントで、
スプレッドシートを更新したり、LINEでユーザーに通知を送ったりする。
⸻
Stripe Webhookのメイン処理
Webhookを受け取るエントリーポイントは doPost(e)。
ここで event.type に応じて分岐している。
function doPost(e) {
const event = JSON.parse(e.postData.contents);
if (event.type === 'checkout.session.completed') {
// 決済完了イベント
} else if (event.type === 'customer.subscription.updated') {
// プラン変更イベント
} else if (event.type === 'customer.subscription.deleted') {
// 解約イベント
}
}
1. checkout.session.completed
決済が完了した時に発火
Stripeの決済が完了すると、このイベントが送られる。
ここでは「ユーザーが有料プランに入った」ことを検知する。
if (event.type === 'checkout.session.completed') {
const object = event.data.object;
// 支払いステータスを確認
if (object.payment_status !== 'paid') return;
const userId = object.client_reference_id; // LINEユーザーID
const customerId = object.customer; // Stripeの顧客ID
const email = object.customer_details.email;
const subscriptionId = object.subscription;
// LINEにメッセージ送信
sendTextMessage(◯,◯)); //独自メソッド
}
処理の目的
- 決済済みであることを確認
- 顧客情報を「顧客シート」に登録
- 有料プラン情報を「ユーザープランシート」に記録
- LINEで「ご契約ありがとうございます」メッセージを送信
client_reference_idにLINEのIDを仕込むと
client_reference_id にLINEのuserIdを仕込んでおくことで、
Stripe→GAS→LINEの紐付けが自動でできる。
⸻
2. customer.subscription.updated
プラン変更時(アップグレード/ダウングレード)
ユーザーがStripeのカスタマーポータルなどでプランを変更した場合に発火する。
else if (event.type === 'customer.subscription.updated') {
const subscription = event.data.object;
const customerId = subscription.customer;
// キャンセル予約があるか
if (subscription.cancel_at_period_end === true) {
// 期限までの解約予約
}
// schedule が存在する場合 → 次回請求日からの変更
if (subscription.schedule) {
// 予約変更(翌月反映)
} else {
// 即時変更(今すぐ切り替え)
}
}
ケース別の動作
cancel_at_period_end === true
「今月末で解約予定」として、キャンセル予約メッセージを送信
subscription.schedule が存在
翌月からプラン変更 → ユーザープランシートに「pending」として予約情報を記録
上記どちらもなし
即時プラン変更 → プランタイプを即時更新、LINEで変更完了通知
⸻
具体的な例:翌月変更のスケジュール
if (subscription.schedule) {
const billingCycleAnchor = subscription.billing_cycle_anchor;
const effectiveDate = Utilities.formatDate(
new Date(billingCycleAnchor * 1000), 'Asia/Tokyo', 'yyyy/MM/dd'
);
処理の目的
- 解約予約・変更予約を検知し、ユーザーにわかりやすく加工する
3. customer.subscription.deleted
解約完了時
ユーザーがプランを完全に解約したときに発火する。
else if (event.type === 'customer.subscription.deleted') {
const object = event.data.object;
const customerId = object.customer;
分岐はハマった。未来の自分が迷わないようにメモを残す。