rc-payment-recovery について
RevenueCat を使う Android 開発者向けに、Google Play の更新失敗への対処を解説するガイドです。猶予期間やアカウント保留、アプリ内メッセージ、独自 UI、Webhook の検証を扱います。
主な機能
- 01猶予期間とアカウント保留の判別
- 02CustomerInfo から課金状態を取得
- 03自動または手動メッセージの設定
- 04支払い管理画面への誘導
- 05更新復旧状態のテスト
活用シーン
- 01猶予期間中の警告表示
- 02アカウント保留中のアクセス制限
- 03Webhook による復旧メール送信
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ revenuecat/ ai-toolkit --skill rc-payment-recoveryインストール後、Claude Code で/rc-payment-recoveryを入力して読み込まれたか確認します。
詳細
支払いの復旧
Google Play で更新に失敗すると、サブスクリプションは 2 つの状態を経由します。猶予期間(Google がカードへの再請求を試みている間もユーザーはアクセスを維持できます)と、アカウント保留(ユーザーが支払い方法を修正するまでアクセスが取り消されます)です。RevenueCat では、どちらの状態も自動的に CustomerInfo に反映され、Google のアプリ内メッセージがデフォルトで表示されます。
フェーズ 1:理解する
更新に失敗すると、次の 3 つのことが起こります。
| 状態 | アクセス | RevenueCat での表示方法 | ユーザーに表示される内容 |
|---|---|---|---|
| 猶予期間 | 維持 | entitlement.isActive == true かつ billingIssueDetectedAt != null | デフォルトでは Google のアプリ内スナックバー |
| アカウント保留 | 取り消し | entitlement.isActive == false かつ billingIssueDetectedAt != null | デフォルトでは Google のアプリ内スナックバー |
| 復旧 | 維持 | billingIssueDetectedAt == null | 何も表示されません |
SDK では、次の 2 つのシグナルが重要です。
EntitlementInfo.billingIssueDetectedAtは、Google が請求の問題を報告した時点から、ユーザーが解決するまで null 以外の値になります。EntitlementInfo.isActiveで、ユーザーが引き続きアクセスできるかどうかを確認できます。
バックエンドでは、状態が遷移するたびに BILLING_ISSUE ウェブフックが 1 回発火します。RTDN をデコードする必要はありません。
フェーズ 2:計画する
アプリのコードを書く前に、本当に必要なものを決めましょう。ほとんどのアプリでは、何もする必要はありません。
次の点を確認してください。
- デフォルトの Google アプリ内メッセージを表示しますか?表示する場合は、何もする必要はありません。SDK は BillingClient の接続時に
showInAppMessagesIfNeededを呼び出します。 - 独自のバナーやダイアログを表示しますか?表示する場合は、
CustomerInfoからbillingIssueDetectedAtを読み取り、isActiveに応じて処理を分岐します。 - 特定の画面でのみメッセージを表示しますか?表示する場合は、自動呼び出しを無効にし、独自に
showInAppMessagesIfNeeded(activity)を呼び出します。 - サーバー側のフラグ(たとえば、支払い復旧を促すメールを送信するためのもの)が必要ですか?必要な場合は、
BILLING_ISSUEウェブフックを処理します。アプリのコードは必要ありません。
デフォルトの動作だけでよい場合は、ここで終了です。
フェーズ 3:実行する
デフォルト(推奨)
アプリ内メッセージの自動表示を有効にしたままにします。これはデフォルトの設定です。
PurchasesConfiguration.Builder(context, apiKey)
.showInAppMessagesAutomatically(true)
.build()
手動で呼び出す
自動呼び出しを無効にし、選択したアクティビティからメッセージを表示します。
PurchasesConfiguration.Builder(context, apiKey)
.showInAppMessagesAutomatically(false)
.build()
Purchases.sharedInstance.showInAppMessagesIfNeeded(activity)
猶予期間中に独自の UI を表示する
エンタイトルメントを読み取り、両方のフラグに応じて処理を分岐します。
val entitlement = customerInfo.entitlements["pro_access"]
when {
entitlement == null || !entitlement.isActive ->
showSubscribeScreen()
entitlement.billingIssueDetectedAt != null && entitlement.isActive ->
showGracePeriodWarning()
entitlement.billingIssueDetectedAt != null && !entitlement.isActive ->
showAccountHoldScreen()
else ->
showPremiumContent()
}
ユーザーを支払い方法の修正画面に誘導する
CustomerInfo.managementURL は Google Play のサブスクリプションページを示します。
customerInfo.managementURL?.let { url ->
startActivity(Intent(Intent.ACTION_VIEW, url))
}
フェーズ 4:検証する
各状態遷移をテストします。
- 更新が拒否される Google Play テストカードを使い、サブスクリプションを猶予期間に移行させます。
entitlement.billingIssueDetectedAtが null 以外の値になり、isActiveがtrueのままであることを確認します。- アカウント保留になるまで待ち、
billingIssueDetectedAtが null 以外のまま、isActiveがfalseに変わることを確認します。 - 支払い方法を更新し、
billingIssueDetectedAtがnullに戻ることを確認します。 - バックエンドで、最初の状態遷移時に
BILLING_ISSUEウェブフックが発火することを確認します。