mcpField
R
rc-cancellations-pauses-winback

rc-cancellations-pauses-winback

github.com/revenuecat開発76628 回インストール1 日前に更新
リポジトリ

rc-cancellations-pauses-winback について

Android 開発向けの RevenueCat スキルで、サブスクリプションの解約、一時停止、再獲得の扱い方を説明します。CustomerInfo の判定、Google Play の管理画面への遷移、REST API による再開日の取得を扱います。

主な機能

  1. 01アクセス期間中の解約検出
  2. 02請求問題と一時停止の識別
  3. 03Google Play 管理画面を開く
  4. 04REST API による再開日の取得
  5. 05再登録と再獲得イベントの処理

活用シーン

  1. 01解約後のアクセス終了日を表示
  2. 02サブスクリプション管理画面への導線
  3. 03バックエンド情報に基づく再開日の表示
  4. 04更新 webhook 後のアクセス付与

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/revenuecat/ai-toolkit --skill rc-cancellations-pauses-winback

インストール後、Claude Code で/rc-cancellations-pauses-winbackを入力して読み込まれたか確認します。

詳細

解約、一時停止、復帰

CustomerInfo を読み取ることで、Android で解約、一時停止、復帰の状態を検出します。これらのイベントのほとんどは受動的なものです。アプリが開始するのではなく、状態を監視します。managementURL を使って Google Play の管理画面を開きます。一時停止からの再開日を REST API から取得します。

フェーズ 1:範囲を決める

ユーザーに表示する必要がある状態を決めます。

状態CustomerInfo のシグナル備考
解約済み、アクセス権は有効entitlement.unsubscribeDetectedAt != null and isActive == true「[expirationDate] に終了」と表示します
請求に関する問題(猶予期間または保留)entitlement.billingIssuesDetectedAt != null支払いに失敗し、復旧処理中です
一時停止中商品を引き続き所有しているが、entitlement.isActive == false再開日は REST API で取得する必要があります
有効で自動更新中entitlement.willRenew == true通常の状態です

バックエンドでの復帰キャンペーンのセグメント分けには、CANCELLATION webhook の cancel_reason フィールド(UNSUBSCRIBE、BILLING_ERROR、DEVELOPER_INITIATED、PRICE_INCREASE)を使用します。

フェーズ 2:準備する

Purchases.sharedInstance.getCustomerInfo(...) またはリスナーから、取得済みの CustomerInfo があることを確認します。setIncludeSuspendedSubscriptions(true) を指定して BillingClient.queryPurchasesAsync を呼び出す必要はありません。RevenueCat はサーバー側のサブスクリプション状態から一時停止状態を解決します。

ルール:

  • managementURL はすでに Uri? です。そのまま Intent に渡してください。Uri.parse(url.toString()) は呼び出さないでください。
  • expirationDate からアクセス権を手動で計算しないでください。isActive と willRenew を読み取ってください。
  • 一時停止からの再開日は SDK にありません。バックエンドで /v1/subscribers/{app_user_id} から取得してください。

フェーズ 3:実行する

アクセス権が残っている解約を検出する
val entitlement = customerInfo.entitlements["pro_access"]
if (entitlement?.unsubscribeDetectedAt != null && entitlement.isActive) {
    entitlement.expirationDate?.let { expiry ->
        showCancellationBanner(expiry)
    }
}

RevenueCat が SUBSCRIPTION_CANCELED RTDN を受け取ると、unsubscribeDetectedAt が設定されます。請求期間が終了するまでは、isActive は true のままです。

一時停止を検出する
val entitlement = customerInfo.entitlements["pro_access"]
val hasAccess = entitlement?.isActive == true
// When paused, isActive == false. Pause resume date is not in the SDK.
サブスクリプションの管理画面を開く
customerInfo.managementURL?.let { url ->
    startActivity(Intent(Intent.ACTION_VIEW, url))
}

managementURL の型は Uri? です。そのまま使用してください。Uri.parse(url.toString()) でラップするのは冗長であり、エラーの原因になります。

REST を使って一時停止からの再開日を取得する

バックエンドから subscribers エンドポイントを呼び出し、サブスクリプションの paused_expiration_time_ms を読み取ります。

curl -H "Authorization: Bearer $RC_SECRET_API_KEY" \
  https://api.revenuecat.com/v1/subscribers/$APP_USER_ID

一時停止中は、サブスクリプションオブジェクトに paused_expiration_time_ms が含まれます。独自のエンドポイントを通じて、この情報をクライアントに公開してください。

有効期限前に再登録する

Google の有効期限前再登録フローでは SUBSCRIPTION_RESTARTED が発生します。RevenueCat は unsubscribeDetectedAt をクリアし、willRenew = true に設定します。追加のコードは不要です。customerInfo を再読み込みするだけです。

有効期限後に再登録する

有効期限後の再登録では、INITIAL_PURCHASE ではなく RENEWAL webhook が発生します。バックエンドのハンドラーでは、どちらのイベントでもエンタイトルメントへのアクセス権を付与してください。

フェーズ 4:確認する

確認項目方法
解約バナーが表示されるPlay ストアで解約し、新しい CustomerInfo を取得して、unsubscribeDetectedAt != null および isActive == true を確認します
管理画面へのディープリンクが開くリンクをタップし、正しい商品に対応する Play のサブスクリプション画面が開くことを確認します
一時停止が反映されるPlay ストアのサンドボックスで一時停止し、entitlement.isActive == false を確認します
一時停止からの再開日/v1/subscribers/{id} を呼び出し、paused_expiration_time_ms が存在することを確認します
復帰が受け付けられるPlay で設定した復帰オファーを受け入れ、購入が CustomerInfo に通常のサブスクリプションとして表示されることを確認します

メモ

  • 延長と取り消しは、バックエンドから Google Play Developer API(purchases.subscriptionsv2.defer、purchases.subscriptionsv2.revoke)を通じて行います。RevenueCat は、その結果として発生する RTDN を処理し、CustomerInfo を自動的に更新します。
  • 復帰キャンペーンに SDK コードは必要ありません。Play Console または RevenueCat ダッシュボードで設定します。
  • RevenueCat は現在、一時停止専用の webhook を送信しません。Google Play RTDN の処理後、一時停止状態が CustomerInfo に反映されます。

References

コメント