結論
Stripe Billing は 時間軸のある課金(プラン・更新・請求書) をプロダクト側に持たせるための層です。
単発の PaymentIntent だけでは表現しづらい「次回請求」「試用終了」「座席数変更」を扱うときに効きます。
このテーマで判断すべき軸
- 課金単位(月額固定 / 従量 / 複合プラン)
- 誰がカードを更新するか(自社サポートか、顧客自身か)→ Customer Portal
- 請求書の要否(B2B でインボイス必須か)→ Invoice
- 試用・クーポン・税 の扱い → Stripe Tax との組み合わせ
実装の基本フロー
- Customer を自社アカウントと紐づけて一意に保つ
- Price / Product でプランを表現し、Subscription で契約状態を持つ
- 請求タイミングでは Invoice が生成・更新される前提で、Webhook で請求結果を取り込む
- カード失効時は回収メール・ポータル導線・社内オペをセットで設計する
オブジェクトの役割分担
| オブジェクト | 役割 | 内部モデルで分ける理由 |
|---|---|---|
| Customer | 顧客の箱 | ユーザー退会や統合時に参照の起点になる |
| Subscription | 契約の継続状態 | 契約有効か、変更予約があるかを表す |
| Invoice | 請求書と回収状態 | 未払い、回収済み、回収不能を分けて扱える |
| PaymentIntent | 個別請求の決済状態 | 支払い処理そのものの成否を追える |
| Customer Portal | 顧客セルフサーブ | CS で抱える作業を減らせる |
ここを混ぜると、「契約は有効だが今月分の請求は失敗」や「請求書は発行済みだがカードは未更新」のような現実の状態が表せなくなります。
失敗しやすい点
- 「サブスク=PaymentIntent を毎月叩く」で代用し、リトライ・猶予・請求書再発行 を自前実装で積み上げる
- 社内の「契約ID」と Stripe の Subscription ID の同期を後回しにし、解約・プラン変更で不整合が残る
- Webhook を請求確定の正とせず、ダッシュボードの画面操作だけで状態を信じる
customer.subscription.updatedだけ追い、invoice.paidやinvoice.payment_failedを見ない
先に決めておくと楽になる運用ルール
- 契約有効判定は
Subscription基準か、請求回収完了基準か - 一時的な回収失敗時に即停止するか、猶予期間を置くか
- プラン変更を即時反映するか、次回請求から反映するか
- 請求書 PDF やカード更新を顧客セルフサービスに寄せるか
運用で見る指標
- 更新成功率(失敗理由の内訳:残高・期限・3DS 等)
- 猶予期間中の解約・更新コンバージョン
- 請求書の未払い件数と回収までの日数
次に読む記事
用語の短い定義は 用語集一覧 から辿れます。
よくある質問
Customer Portal は必須ですか?
必須ではありませんが、カード更新や請求書DLを自前で全部作るより運用コストが下がることが多いです。
単発決済と併用できますか?
可能です。境界を決めずに混ぜると状態管理が複雑になるため、注文ドメインで役割を分けてください。