最近、Netflix社のように「長期間利用がないユーザーの契約をキャンセルまたは請求停止する」サービスを耳にすることが増えてきました。
この記事では、このようなサービスを提供するために、Stripeでどのような実装ができるかを紹介します。
Stripeで、休眠アカウントに対してできるアクション
Stripeでサブスクリプションを契約中の「休眠アカウント」に対しては、2つのアクションがとれます。
- Netflixのように、サブスクリプションを自動解約する
- サブスクリプションは残し、請求だけを一時的に停止する
どちらも処理を実行したタイミングから、顧客に対する請求は停止します。
ですが後者の請求一時停止の場合、「サブスクリプションの契約データ」はそのまま残ります。
そのため、以下のようなケースでは解約ではなく一時停止を選択することができます。
- 復帰後に、前回と同じ契約(プラン・割引など)を提供したい場合
- 休会など、「期限付きの解約」を実現させたい場合
- 自動解約の前に猶予期間を設けたい場合
サブスクリプションを解約する方法
Stripeでサブスクリプションを解約する場合、「その場で解約」または「契約期間終了後に解約」の2つが選べます。
契約期間終了後に解約する
バッチ処理で休眠アカウントの判定を行う場合、顧客の契約期間が終了するタイミングで解約するのが親切です。
この場合、「サブスクリプションの更新」という形で解約を設定します。
await stripe.subscriptions.update(
'sub_xxx',
{
cancel_at_period_end: true,
}
);
契約期間が終了して、実際に解約されるまでの間であれば、cancel_at_period_end
をfalse
にすることで解約をキャンセルできます。
await stripe.subscriptions.update(
'sub_xxx',
{
cancel_at_period_end: false,
}
);
その場で解約する
その場で解約する場合は、Cancel a Subscription
のAPIを呼び出します。
await stripe.subscriptions.del(
'sub_xxx',
{
invoice_now: true,
}
);
この場合、従量課金の請求などの「未払いの請求」を処理するために、invoice_now: true
を設定しましょう。
実際には、usageRecordの最終集計などが必要になりますので、従量課金を含む場合はcancel_at_period_end
を使う方が手軽かもしれません。
サブスクリプションを一時停止する方法
一時停止する場合、「停止期間の請求をどう扱うか」と「いつまで一時停止するか」の2点を設定します。
サブスクリプション更新のAPIで、pause_collection
パラメータを渡しましょう。
await stripe.subscriptions.update('sub_xxx', {
pause_collection: {
behavior: 'void'
}
})
一時停止期間の請求書の扱い
Stripe Billingでは、一時停止期間中も請求書自体は作成されます。
発行された請求書のステータスを変更することで、顧客への請求を一時停止します。
請求書のステータスは「下書きkeep_as_draft
」「回収不可mark_uncollectible
」「無効void
」の3種類から選べます。
今回のような、「休眠アカウントに対して、請求とサービス提供を一時停止する」ケースでは、請求書を無効にする方法を推奨しています。
await stripe.subscriptions.update('sub_xxx', {
pause_collection: {
behavior: 'void'
}
})
「無効」を設定すると、その請求書で顧客に請求を行うことができません。
そのため、一時停止期間の請求を後日回収したい場合は、「下書き」を選択しましょう。
期限付きの一時停止措置
一時停止措置を期限付きで行いたい場合、pause_collection
にresumes_at
を追加します。
await stripe.subscriptions.update('sub_xxx', {
pause_collection: {
behavior: 'void',
resumes_at: dayjs().add(2, 'month').unix()
}
})
このサンプルでは、2ヶ月後にサブスクリプションを再開します。
一時停止措置の終了方法
顧客が再びサービスの利用を再開した場合、pause_collection
をnull
に変更することで請求を再開できます。
await stripe.subscriptions.update('sub_xxx', {
pause_collection: null
})
サブスクリプションが一時停止状態になったことを判別する方法
アプリケーション側で処理が必要な場合、customer.subscription.update
Webhookを利用します。
このイベントで更新後のSubscriptionデータがAPIに送信されますので、その中のpause_collection
属性をチェックしましょう。
ここの値がnull
ではない場合は、一時停止中のサブスクリプションです。
{
"id": "evt_1LE40qKlXtpaTqYx26p0Y3B6",
"object": "event",
"api_version": "2020-08-27",
"created": 1656044456,
"data": {
"object": {
"pause_collection": {
"behavior": "void",
"resumes_at": 1661314855
},
...
},
"previous_attributes": {
"pause_collection": {
"resumes_at": null
}
}
},
"livemode": false,
"type": "customer.subscription.updated"
}
previous_attributes
を併せてみることで、pause_collection
が変更されたかどうかの判別もできます。
同様に一時停止状態から復帰した場合についても、同じ値をチェックして処理を行いましょう。
ドキュメント
- https://stripe.com/docs/api/subscriptions/update#update_subscription-pause_collection
- https://stripe.com/docs/billing/subscriptions/pause
- https://stripe.com/docs/billing/subscriptions/cancel
[PR] Stripe開発者向け情報をQiitaにて配信中!
- [Stripe Updates]:開発者向けStripeアップデート紹介・解説
- ユースケース別のStripe製品や実装サンプルの紹介
- Stripeと外部サービス・OSSとの連携方法やTipsの紹介
- 初心者向けのチュートリアル(予定)
など、Stripeを利用してオンラインビジネスを始める方法について週に2〜3本ペースで更新中です。