Stripeサブスク解約の基本理解
まずは「Stripeのサブスクを解約する」と言ったときに、何が起きるのかを全体像として押さえておきましょう。Stripeでは、月額課金や年額課金などの継続課金は「Subscription(サブスクリプション)」オブジェクトとして管理されており、このSubscriptionが有効かどうかで、ユーザーがサービスを使えるかどうかを判断するのが一般的です。解約とは、このSubscriptionを「いつまで有効にするか/いつ無効にするか」をStripeに伝える操作だとイメージすると分かりやすくなります。
運営者として大事なのは、「解約ボタンを押した瞬間に使えなくなるのか」「請求期間の最後まで使えるのか」「その間のstatus(状態)は何になるのか」をきちんと理解しておくことです。これを知らないまま実装すると、ユーザーが「解約したのに請求された」「もう使えないのは困る」といった不満につながりやすくなります。Stripeには、即時解約と次回請求で解約を行うためのフラグやオプションが用意されているので、それぞれの挙動を整理していきましょう。
自動更新サイクルの仕組み
Stripeのサブスクは、基本的に「請求期間(billing cycle)」が一定間隔で繰り返される仕組みです。例えば月額プランであれば、契約開始日から1カ月ごとに請求が自動生成され、顧客が解約しない限りは自動更新され続けます。この自動更新のスケジュールは、Subscriptionに紐づくプラン(price)や、trial(無料期間)、billing_cycle_anchorなどの設定で決まります。
ポイントは、Stripe側は「次の請求日」を常に意識して動いている、ということです。次回請求日の直前になると請求書が発行され、支払いが成功すればそのまま次の期間に突入します。解約操作とは、この自動更新サイクルに対して「この日以降は更新しないで」と指示を出すイメージです。そのため、いつのタイミングで解約操作をするかによって、最後の請求日や有効期限が変わってきます。
解約の2種類:即時・次回請求で停止
Stripeでサブスクを止めるときの考え方は、大きく2パターンあります。ひとつは「即時解約(今すぐ停止)」で、解約した瞬間にSubscriptionを無効にしてしまう方法。もうひとつは「次回請求分から停止」で、今の請求期間の終わりまでは利用を許可し、それ以降は自動更新しないようにする方法です。Webサービスの多くは、ユーザー体験の観点から後者(次回請求で停止)を採用することが多いです。
StripeのAPIやダッシュボードでは、この2種類の解約を切り分けるためのオプションが用意されています。即時解約の場合は「今すぐキャンセル」、次回請求で停止する場合は「現在の期間の終了時にキャンセル」などの文言で表示され、内部的にはcancel_at_period_endというフラグで制御されます。運営者は、サービスのポリシー(返金の有無、日割りの有無)に合わせて、どちらのパターンをデフォルトとするか決めておく必要があります。
cancel_at_period_end の動作
Stripeで「今の請求期間の終了時に解約する」を実現するときに登場するのが、Subscriptionオブジェクトのcancel_at_period_endというフラグです。この値がtrueの場合、「現在の期間が終わったタイミングでサブスクをキャンセルする」という予約状態になります。逆にfalseのまま解約すると、「即時解約(キャンセルした瞬間に無効化)」という扱いになります。ダッシュボードから解約した場合も、どちらの挙動を選んだかによって、このフラグの値が変わります。
cancel_at_period_endを理解しておくと、「ユーザーは解約したつもりだが、期間の終わりまでは使える」という状態を、アプリ側で正しく表現できるようになります。例えば、マイページ上では「○月○日までは利用可能です」と表示しつつ、内部的には「更新予約なし」の状態として扱う、といった設計ができるようになります。ここからは、true/falseそれぞれの意味と、有効期限までの扱いを詳しく見ていきましょう。
true/false の意味
cancel_at_period_endがfalse(デフォルト)の場合、Subscriptionは通常の自動更新モードです。次回請求日が来るたびに請求が行われ、顧客が解約しない限りstatusはactiveのまま維持されます。この状態で「即時解約」を選ぶと、そのタイミングでSubscriptionはキャンセルされ、statusもcanceledなどの非アクティブな状態に変わり、以降の請求は行われません。
一方、cancel_at_period_endをtrueに設定して解約した場合は、「今はactiveだけれど、次の請求は発生させない」という予約状態になります。このときSubscriptionのstatus自体は、請求期間が終わるまではactiveのままです。ただし、Subscriptionオブジェクトを見るとcancel_atとcurrent_period_endが設定されており、「いつキャンセルされる予定か」「今の期間はいつまでか」が分かるようになっています。アプリ側では、この値を使って「解約予約済み」のフラグを持たせることが多いです。
有効期限までの期間中の扱い
cancel_at_period_endをtrueにした瞬間から、Subscriptionは「今は使えるが、次回からは更新しない」という状態になります。この期間中、Stripe上のstatusはactiveのままなので、単純にstatusだけで判断すると「解約されていない」と誤解しがちです。実装では、statusに加えてcancel_at_period_endの値やcurrent_period_endの日時もセットでチェックし、「active かつ cancel_at_period_end = true なら解約予約中」といったロジックを組むと安全です。
ユーザーへの表示としては、「解約済み(○月○日まで利用可)」のように、「もう更新はされないが、まだ使える」ことが伝わるメッセージにしておくとトラブルを防げます。また、current_period_endの日付を過ぎたタイミングでWebhook(customer.subscription.deleted など)が飛んでくるので、そのイベントをトリガーにしてアカウントの停止処理やプラン変更処理を行う、といった連携設計がよく使われます。こうすることで、「Stripe上の解約」と「アプリ上の停止」のタイミングをきれいに揃えられます。
status が変化するタイミング
StripeのSubscriptionは、契約のライフサイクルに応じて status(状態) が自動的に変化します。解約処理を正しく扱うためには、この状態遷移を理解しておくことが重要です。なぜなら、ユーザーの利用権限の切り替えや、社内システム側でのアクセス停止・通知処理などは、このstatus変化をトリガーに実行されることが多いためです。
Stripeのstatusには trialing / active / incomplete / incomplete_expired / past_due / canceling / canceled / unpaid などがありますが、解約運用で特に関係するのは active → canceling → canceled の流れです。cancel_at_period_endをtrueにした場合や、即時解約した場合などで変化のタイミングが異なるため、ここで整理しておきましょう。
active → canceling → canceled
まず、cancel_at_period_endをtrueにした場合、Subscriptionは「今は有効だが、次回更新はしない」という予約状態になります。このときstatusはactiveのままですが、内部的には「終了予定日」がセットされ、期間終了の直前に自動でcanceling状態に移行します。cancelingは「もうすぐキャンセルされる」ことを表す中間状態で、StripeのAPIレスポンス上のみ確認できます。
そして、current_period_endのタイミングになると、Subscriptionはcanceled状態に切り替わります。この瞬間、Webhook(customer.subscription.deleted)が送信されるため、運営側はこのイベントをキャッチしてユーザーの利用権限を停止する、メール通知を送る、プラン変更処理を行うなどの後続処理を行います。実践的には、アプリ側の停止処理はWebhookに合わせるのが最も安全です。
prorate(按分)と請求書の扱い
即時解約を行った場合、その月の残り期間に対して「日割り(prorate)」を返金するかどうかを選ぶことができます。prorateは「どれだけ利用したかに応じて差額を計算する」仕組みで、Stripeのprice設定や請求ロジックに応じて動作が変わります。日割りを適用する場合、差額はクレジットとして顧客に付与され、次回請求時に自動調整されます。
一方、次回請求で停止(cancel_at_period_end=true)の場合は、今の期間が満了するため返金は発生しません。ただし、期間終了直前には請求書や支払関連の処理が動かなくなるので、「解約したのに請求書が届いた」といった誤解は起きにくくなります。運営側としては、顧客への返金ポリシーと日割りの扱いを明確にしておくことが大切です。なお、金額周りは最新のStripe仕様に左右されるため、必要に応じて公式ドキュメント確認を推奨します。
即時解約(cancel now)の挙動
Stripeには「即時解約(Cancel now)」という操作があり、その名の通り、ボタンを押した瞬間にSubscriptionを無効化する方法です。cancel_at_period_endをfalseのまま解約するとこの即時解約扱いとなり、statusもすぐにcanceledへ遷移します。期間途中でも利用できなくなるため、学習サービス・コミュニティ・ツール利用権といった「即時停止が問題になりやすい」サービスを運営している場合は注意が必要です。
また、即時解約では、残り期間に対して返金を行うかどうかを選択できます。これはStripeのダッシュボードやAPIで「prorate(按分計算)」のオンオフを切り替えることで制御でき、返金した場合は顧客残高にクレジットとして付与されます。ただし、日割り計算の仕様は変わる可能性があるため、実際の運用前にテスト環境で動作確認しておくと安心です。
返金の考え方
即時解約時の返金は、サービスのポリシーによって異なります。SaaSでは一般に「即時解約=返金なし」とするケースが多いですが、ユーザー満足度の観点から日割り返金を採用する事例もあります。Stripeでは、残り期間分の金額を正確に計算して返金できるため、柔軟なポリシーを設定することが可能です。運営側としては、カスタマーサポート工数と顧客体験のバランスを考え、統一的なルールを決めておくとトラブルが減ります。
また、「返金した場合はどう会計処理すべきか?」といった疑問もよくあります。この点は事業規模や会計ルールにより扱いが変わるため、必要があれば税理士など専門家への確認が確実です。Stripeの返金ログはダッシュボードから確認できるため、管理面で迷うことは少ないでしょう。
Webhook で補足すべきイベント
即時解約を実装する際に重要なのは、「解約した瞬間に実行すべき処理」と「Stripe側でキャンセル処理が確定したときの処理」を正しく切り分けることです。基本的には、以下のWebhookイベントを補足しておくと安心です。
- customer.subscription.deleted:Subscriptionがキャンセルされたときに送信されるメインイベント
- invoice.payment_refunded:返金が発生したときに送られるイベント(即時解約+日割り返金時)
- customer.subscription.updated:状態変更があった場合の総合的な更新イベント
特にcustomer.subscription.deletedは、アプリ側の利用停止処理のトリガーとして最も信頼できます。運営側で任意のタイミングで実行するロジックではなく、「Stripeが確定処理したタイミング」に合わせることで、ズレや取り違えを防げます。Webhookイベントは突然仕様が変わることは少ないものの、重要な箇所なので定期的に公式ドキュメントをチェックすると安心です。
安心して解約運用するためのチェックリスト
ここまで解説したように、Stripeの解約は「即時か」「次回請求で停止か」「status 変化をどう扱うか」によって挙動が変わります。ここでは、運営者が安心してサブスク解約を提供するために、最低限チェックしておくべきポイントを整理します。特に Webhook や UI 表示など、アプリ側での連携設計が不十分だと「解約したのに利用できる」「請求が止まらない」などのトラブルになりやすいので、事前準備が重要です。
なお、Stripeの仕様はアップデートされる可能性があるため、運用前にはテスト環境(Test Mode)で動作確認し、必要に応じて公式ドキュメントも参照するようにしましょう。
ダッシュボードで確認すべき項目
Stripe ダッシュボードには、サブスクの状態を判断するための情報が豊富に揃っています。特に、解約運用においては以下の項目を必ず確認するようにしましょう。
- cancel_at_period_end:解約予約が設定されているかどうか
- current_period_end:いつまで利用できるかを示す有効期限
- status(active / canceling / canceled):現在の状態を判断
- cancel_at:実際にキャンセル処理が実行されるタイミング
- latest_invoice:直近の請求書と支払ステータス
特に cancel_at_period_end と current_period_end の組み合わせは「解約したのにまだ使える」期間を正しく管理するために重要です。ダッシュボードで状態を確認しつつ、ユーザーに表示するメッセージと一致しているかも合わせてチェックしておきましょう。
Webhook/アプリ側ロジックの注意点
Webhook は Stripe の状態変化を正確に補足するための重要な仕組みです。解約処理では、Subscription が削除されたタイミングを検出する customer.subscription.deleted が特に重要で、ここで利用停止処理を行うのが一般的です。また、prorate を使った返金処理を行う場合には、invoice.payment_refunded も補足しておくと安全です。
アプリ側では、status と cancel_at_period_end の両方を使って「まだ使えるのか」「解約予約中なのか」を判断するロジックが欠かせません。単純に status=active だけを見ると “解約されていない” と誤判定し、ユーザーに誤解を与える可能性があります。できれば、次回請求日(current_period_end)を UI に表示し、ユーザーに「いつまで使えるか」を分かりやすく伝えておくと安心です。
よくある質問(FAQ)とトラブル事例
ここでは、Stripeサブスク解約で運営者からよく寄せられる質問や、実際に起きやすいトラブルをまとめて紹介します。特に、cancel_at_period_end の誤解や Webhook 未設定に起因する問題はよく発生します。事前に理解しておくことで、ユーザー対応の工数を減らし、安定した運用が実現できます。
- Q1:解約したのに status が active のままなのはなぜ?
A:cancel_at_period_end=true の場合、期間の終了までは active です。current_period_end を確認し、UI 上で「解約予約中」と表示するのが安全です。 - Q2:即時解約したのに返金されないのは?
A:prorate(按分)が無効の場合、返金は行われません。返金ポリシーに従って、必要なら手動返金するケースもあります。 - Q3:解約後に請求書が届くことはある?
A:cancel_at_period_end=true の場合は原則なし。ただしタイミングによっては invoice が発行済みの場合もあるため、必ず最新の invoice ステータスを確認するようにしましょう。 - Q4:Webhook を設定していないとどうなる?
A:Subscription がキャンセルされてもアプリ側で利用停止処理が行われず、「解約後も使える」状態が発生します。必ず customer.subscription.deleted を設定してください。 - Q5:trial(無料期間)中に解約した場合の扱いは?
A:trial_end を過ぎるまでは請求が発生しません。解約しても trial 中は利用できるため、UI 表示に注意が必要です。
Stripe のサブスク解約は、基本的なロジックを理解してしまえば難しくありませんが、「期間の終わりまで使える」「即時に止まる」「status とフラグの意味が異なる」など、知っておくべき細かなポイントがあります。これらを押さえたうえで、自社サービスに合った解約運用を設計していくと、トラブルの少ない運営につながります。

コメント