关于 rc-cancellations-pauses-winback
面向 Android 开发的 RevenueCat 技能,介绍如何处理订阅取消、暂停和挽回订阅。内容涵盖解析 CustomerInfo、打开 Google Play 管理页面,以及通过 REST API 获取暂停恢复日期。
主要功能
- 01检测仍可使用的已取消订阅
- 02识别账单问题与暂停状态
- 03打开 Google Play 管理页面
- 04通过 REST API 获取暂停恢复日期
- 05处理重新订阅与挽回事件
适用场景
- 01显示取消订阅后的访问截止时间
- 02提供订阅管理页面入口
- 03根据后端数据显示暂停恢复日期
- 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 且 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 查询暂停恢复日期
从后端调用订阅者端点,并读取订阅中的 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。
到期后重新订阅
到期后重新订阅会触发 RENEWAL webhook,而非 INITIAL_PURCHASE。在后端处理程序中,两个事件都应授予权益访问权限。
阶段 4:验证
| 检查项 | 方法 |
|---|---|
| 显示取消横幅 | 在 Play Store 中取消订阅,获取最新的 CustomerInfo,确认 unsubscribeDetectedAt != null 且 isActive == true |
| 管理深层链接可打开 | 点击链接,确认 Play 订阅页面打开的是正确产品 |
| 反映暂停状态 | 在 Play Store 沙盒中暂停订阅,确认 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中。