CONTENTS+
サブスクを一つのアプリで管理したい。ところが、支払いを一覧にできるアプリはあっても、契約をすべて同じ方法で扱えるわけではありません。自分で作るとしたら何が必要になるのか。既存アプリとStripeの仕組みから考えます。
サブスク管理アプリは今どこまでできるのか
契約中のサービス、プラン、料金を自動で把握し、不要ならその場で解約できると便利です。
まずは、既存サービスの対応範囲を比べます。
| サービス | 契約の検出・金額 | プラン情報 | 解約 |
|---|---|---|---|
| マネーフォワードME | 取引明細から前月のサブスク支払いを一覧化 | 契約プランの自動取得は公式資料で確認できず | 他社契約の横断的な解約は確認できず |
| Monarch Money | 定期的な取引を検出し、支払い予定を表示 | 契約プランの自動取得は公式資料で確認できず | 他社契約の横断的な解約は確認できず |
| Rocket Money | 連携した金融口座から継続的な支払いを検出 | 全契約のプランを直接取得できるとは確認できず | Premium会員は対応する契約の解約代行を依頼可能 |
※各社の公式説明に基づく比較で、実機検証ではありません。「確認できず」は機能が存在しないという断定ではなく、提供国や料金プランによっても対応範囲は変わります。
Rocket Moneyは解約まで支援しています。ただし、対応できない契約では手順を案内する仕組みです。利用者の代わりに契約先へ連絡する方法と、契約管理システムを直接操作する方法は違います。では、後者を実現するには何が要るのでしょうか。
決済履歴と契約情報の違い
最初の手がかりはカードや銀行の取引履歴です。請求元・金額・間隔から継続的な支払いを見つけられます。ただし、「先月1,500円払った」と「現在月額1,500円のプランを契約中」は同じ情報ではありません。
| 情報 | 分かること |
|---|---|
| 決済履歴 | 過去の請求元・支払額・日時 |
| 契約情報 | 契約アカウント・プラン・課金周期・契約状態 |
| 請求情報 | 確定した請求額や次回請求額の見込み |
無料期間中なら決済はまだありません。年払いは毎月の支払いとして現れず、割引や従量課金があれば次回請求額も変わります。また、カードの持ち主と契約アカウントの持ち主が同じとは限りません。家族の契約を支払っている場合、明細から解約すべき契約を一意に特定できないのです。
App Store経由の契約では、カード明細の請求元がAppleになる場合もあります。Appleの解約案内でも、Appleが請求する契約と他社が請求する契約は手続き先が分かれています。
決済履歴は契約候補の検出には使えます。しかし、正確なプランや契約状態を知るには、契約を管理する側のデータが必要です。
Stripeなら契約を取得・解約できるのか
契約データの具体例がStripe Billingです。Subscription APIは、顧客の継続契約をリソース(APIで扱うデータの単位)として表します。
| リソース | 役割 |
|---|---|
Customer | 顧客 |
Product / Price | 商品と料金設定 |
Subscription / Subscription Item | 契約状態と契約に含まれる料金項目 |
Invoice | 個々の請求 |
契約に紐づくPriceを見れば料金設定を確認できます。ただし、割引や追加の請求があれば実際の請求額とは異なります。Invoice Previewでは次回請求を試算できますが、確定額ではありません。
解約もAPIで扱えます。請求期間の終了時に解約する予約は、従来の請求モードならcancel_at_period_endがtrue、柔軟な請求モードならcancel_atに日時が入る形で表されます。statusがactiveでも更新停止を予約している場合があるため、管理画面には「利用中」と「解約予定」を区別して表示する必要があります。Stripeのカスタマーポータルも、契約状態の更新をイベントで受け取る方法を案内しています。
必要なデータモデルと操作自体は存在します。しかし、Stripe APIの認証は事業者のアカウントと権限に基づきます。利用者が複数のStripe利用サービスを契約していても、第三者アプリが各事業者の契約データを取得できるわけではありません。
事業者と利用者が連携すれば実現できるのか
では、サブスク提供事業者にも外部連携を用意してもらう場合はどうでしょうか。例えば、サービスのアカウント設定に「サブスク管理アプリと連携」を設け、利用者が自分の契約へのアクセスを許可する形です。
flowchart TD A[サブスク提供事業者<br/>契約情報と操作機能を提供] <-->|API連携| B[横断サブスク管理アプリ<br/>契約を表示・操作] B <-->|本人認証・アクセス許可| C[利用者]
ここでは、事業者が接続先に提供する機能と、利用者が許可する範囲を分けて考えます。
| 必要な仕組み | 確認すべきこと |
|---|---|
| 本人認証 | どのサービスの、どのアカウントの契約か |
| 権限の委譲 | 閲覧のみか、プラン変更・解約まで許可するか |
| 共通データモデル | 料金・請求・解約予定をどう表現するか |
| 状態の同期 | 変更後の契約状態をどう反映するか |
Stripe Connectには、連結した事業者アカウントに対し、プラットフォームがAPIを呼び出す仕組みがあります。ただし、これは事業者間の連携です。消費者が任意のサービスの契約を外部アプリに委任できる機能とは異なります。
事業者と利用者の両方が連携に参加するなら、契約を直接扱える範囲は広げられそうです。もっとも、契約情報の閲覧を認めることと、解約まで外部に任せることは別の判断になります。
事業者が解約を外部に任せにくい理由
事業者の解約画面には、単に「解約する」ボタンがあるだけではありません。Stripeのカスタマーポータルには、解約理由の収集や、解約を考えている顧客へのクーポン提示機能があります。事業者が自社の画面を使う理由の一つは、こうした案内を設計できることです。
| 自社の解約フローで扱うこと | 外部アプリに任せる際の論点 |
|---|---|
| 解約理由の確認 | 理由をどこで聞き、どう共有するか |
| 割引などの提案 | 提案を表示する場所と条件 |
| 残存期間・返金条件の説明 | 契約ごとの確認事項の受け渡し |
| 解約確定と通知 | 本人の意思、処理結果、終了日の確認 |
事業者が引き止めの機会を失いたくない可能性はありますが、すべての事業者が同じ考えだとは断定できません。誤操作の防止や契約条件の説明も無視できない要件です。
外部アプリから事業者の解約画面へ移動させる方法なら、既存のフローを維持できます。一方、管理アプリ内で完結させるなら、解約条件や必要な確認、場合によっては割引提案も受け渡す仕組みが要ります。解約をどこまで外部に任せるかは、APIの有無だけでは決まりません。
作るなら、連携状況で管理方法を分ける
ここまでの条件を踏まえると、最初から全サービスを同じ方法で扱うのではなく、連携状況に応じて管理方法を切り替える案が考えられます。
| 対象 | 管理方法 | 残る課題 |
|---|---|---|
| 事業者・利用者が連携した契約 | 契約データを取得し、許可された操作を実行 | 事業者ごとの仕様と権限 |
| 連携していない契約 | 決済履歴から候補を検出し、情報を補完 | プランや契約アカウントの特定 |
| 外部解約に非対応の契約 | 解約画面への案内や代行で支援 | 手続き結果の確認 |
ここでRocket Moneyに戻ります。事業者連携なしでも契約を見つけ、解約を支援しようとすれば、決済履歴の解析や代理手続きが必要になります。逆に、連携する事業者が増えれば、契約プランの取得や直接操作を増やせる可能性があります。両者は置き換えるというより、対応する契約によって併用する方法です。
ただし、今回考えた連携方式をRocket Moneyが採用していないと断定するものではありません。同社の内部実装すべてを確認したわけではなく、公開資料で説明される機能と、ここでの構想を比較しています。
支払いの一覧と契約の管理
当初は、契約情報の形式をそろえれば一元管理に近づくと思っていました。しかし、実際に作ることを考えると、契約を正しく特定すること、事業者と利用者の双方から権限を得ること、解約時の案内や手続きを調整することが必要でした。
支払いの一覧を作るだけなら、利用者側のデータから始められます。契約そのものを管理するには、契約を提供する側との接続が要る。今のサブスク管理アプリに残る不便さは、その違いから生じているのだと思います。