When a subscription cancels on Google Play, most developers assume the user decided to leave. The billing infrastructure is Google’s problem, right? You build the product, Google handles the payments. If a charge doesn’t go through, that’s between the user and their bank.

The data tells a very different story.

In our 2026 State of Subscription Apps report – covering 115,000+ apps and over $16 billion in tracked revenue – 32.3% of all Google Play cancellations are involuntary billing errors. Not users churning. Not users who decided your app isn’t worth it. Users whose credit card expired, whose prepaid balance ran out, or whose bank flagged a routine charge. They wanted to keep paying. They just couldn’t.

On the App Store, that number is 15.2%. Still significant, but less than half the Google Play rate.

As we put it in the report: “The primary platform difference is not unsubscribe behavior – it’s billing reliability.”

For a $1M ARR Android app, a 32% involuntary cancellation rate translates to north of $300K/year walking out the door. And unlike voluntary churn – which requires product changes, retention experiments, and long feedback loops – involuntary churn is a recoverable revenue stream with well-documented playbooks and near-immediate ROI.

This is probably the highest-return retention work most Android developers aren’t doing. We’ll walk through why the gap exists, what Google Play gives you to fix it, what you need to build yourself, and what recovery actually looks like.

Why Google Play leaks more than Apple

The 2x gap between Google Play and the App Store isn’t a quality problem on Google’s end. It’s structural – a consequence of how each platform’s users interact with payments.

As Jacob Eiting discussed on the Sub Club podcast episode covering the report: “The Apple platform is way more oriented around keeping your credit card up to date. Everything is Apple Pay. You’ve got your Apple subscription to keep your photo library in the cloud. It feels like as a platform, they do kind of more strongly incentivize you to keep your billing updated, keep money flowing through their systems.”

Google Play users, particularly in developing markets, often don’t have that same web of tied services. Their Play Store payment method can go stale for months before they notice. Google also allows prepaid cards and carrier billing in markets where balances frequently run dry – payment methods that Apple doesn’t support at the same scale. As Jacob put it: “Your balance runs out and then the billing fails. The physics are just very different.”

Our report’s retention data reinforces this pattern. Jeff Morris Jr., writing in the expert commentary section, notes that the challenge in emerging markets isn’t long-term retention of a good user – it’s “overcoming initial billing or usage friction.” By the 3rd renewal cycle, all geographies converge to within a few percentage points of each other. The users are there, the payment infrastructure just isn’t keeping up.

The underlying decline categories tell you everything about why this is recoverable. The vast majority of billing failures are “soft” declines – generic declines, insufficient funds, expired cards – that are temporary, situational, and recoverable with retries and a little nudging. By some industry estimates, roughly a quarter to a third of US payment cards are reissued annually, creating a constant background rate of stale credentials even among engaged, willing-to-pay subscribers.

The user didn’t leave, their card did.

The practical upshot: Android developers have both a bigger problem and more granular tools to fix it. The question is whether they’ve configured those tools.

The 60-minute fix: platform tools most developers haven’t touched

Here’s the thing that makes involuntary churn different from almost every other retention problem: the highest-impact interventions are configuration changes, not code. Google provides a 60-day total recovery window with built-in retry logic, payment update prompts, and user notifications. But the default settings leave significant recovery on the table.

If you do nothing else after reading this post, do what’s in this section.

Grace periods: keep the user subscribed while Google retries

Google structures its recovery window into two phases. The grace period keeps the user subscribed with full access while Google retries the payment. If recovery fails during that window, the account hold suspends access but continues retry attempts. As of Google’s December 2025 policy change, the total window is capped at 60 days, with the account hold duration auto-calculated as 60 minus whatever grace period you configure.

Grace periods are now enabled by default on all auto-renewing base plans and can be set for up to 30 days (expanded from earlier limits at Google I/O 2025). During this period, Google retries the charge, emails the user, and sends notifications prompting a payment update. Your app still returns the subscription as active via queryPurchasesAsync(), meaning apps that check entitlements through the standard API handle grace periods automatically with no code changes. If payment recovers during the grace period, the original billing date is preserved – the user never knows anything went wrong.

Google’s published data on the impact is hard to argue with: enabling grace periods delivers a 57% higher recovery rate from renewal declines.

Account holds: the second-chance window

Account holds kick in when the grace period expires. The user loses access, the subscription state shifts to SUBSCRIPTION_STATE_ON_HOLD, and queryPurchasesAsync() stops returning the subscription. This is important – you need to explicitly check for the on-hold state to show the right messaging in your app. Google continues retrying in the background for the remainder of the 60-day window. If the user fixes their payment during account hold, access resumes but the billing date resets to the recovery date.

Google reports that adding account hold on top of grace periods produces 35% higher payment decline recovery and 8% lower involuntary churn. In early cohort data, combining grace period and account hold tripled the decline recovery rate from roughly 10% to 33%.

The In-App Messaging API: two lines of code, 2x recovery

Now, the tool that almost nobody uses. The In-App Messaging API is a single call – BillingClient.showInAppMessages() with InAppMessageCategoryId.TRANSACTIONAL – that displays a Google-rendered snackbar when a user in grace period or account hold opens your app. It shows once per day, includes a direct link to fix payment on Google Play, and requires no custom UI work on your end.

Google’s data shows this produces a 2x increase in user recovery and growth in overall subscriber spend. Two lines of code. Call it on every app launch. If you implement one thing from this post, make it this.

If you’re using RevenueCat, this is already handled – the SDK shows Google Play’s In-App Messages automatically starting in v7. No additional code needed. You can disable it via .showInAppMessagesAutomatically(false) if you want to manage it yourself, but for most apps, the default behavior is exactly what you want.

What about Apple?

The App Store’s involuntary churn rate is less than half of Google Play’s, and more of the recovery happens automatically – billing retry is always on for all auto-renewable subscriptions, and since iOS 16.4, Apple shows a Billing Problem Message to users without any API call on your end. The one thing you should actively opt into is the Billing Grace Period in App Store Connect – set it to 28 days. Apple’s own data shows 90% of billing issues resolve within that window. That’s it for iOS. The rest of this post focuses on Google Play, where the problem is bigger and the developer toolkit is more hands-on.

The Google Play configuration checklist

The total time investment here is about an hour: verify grace periods are enabled and set to the maximum appropriate duration for each base plan (up to 30 days), confirm account hold is set to auto-calculated for a full 60-day window, and add the In-App Messaging API call to your app launch flow.

That’s it. You’ve just recovered a meaningful chunk of your involuntary churn.

If you’re using RevenueCat, grace period and account hold states configured in the Play Console are detected automatically – subscriptions in a grace period remain “active” in your entitlement checks, and a BILLING_ISSUE event fires to your webhooks and connected integrations the moment a payment fails. The Subscription Status chart in the dashboard also surfaces a dedicated “Billing Issue” status, so you can see at a glance what percentage of your active MRR is currently at risk from payment failures. It’s a useful gut check after you’ve made configuration changes – you can watch the billing issue cohort shrink in real time.

Subscription Status chart in RevenueCat

But platform-level tools are a floor, not a ceiling.

Once you’ve configured the platform defaults, the next layer of recovery comes from developer-side dunning – the industry term for communicating with users about failed payments and prompting them to fix it. This is where you move from “configuration” to “engineering investment,” but the ROI remains strong.

Push notifications and in-app messaging

The timing cadence matters more than the copy. Fire the first push notification on Day 0 when the decline is detected via Google’s Real-Time Developer Notifications (RTDN). Follow up on Days 1–3, then Day 7, then Day 14. After that, diminishing returns set in.

Keep the tone helpful, not alarming. “We’re having trouble renewing your subscription – tap to update your payment method” works better than anything that sounds like a warning siren. The user didn’t do anything wrong; their card did.

Calibrate your in-app messaging to the subscription state. During the grace period, the user still has access – a non-blocking banner or snackbar is appropriate. During account hold, escalate to a more prominent modal explaining that access is suspended, with a clear call-to-action.

Google’s In-App Messaging API already handles a once-daily in-app prompt during grace period and account hold, so your developer-side push notifications serve as a complementary channel – catching users who haven’t opened the app.

To trigger all of this, you need Real-Time Developer Notifications set up via Google Cloud Pub/Sub. The billing-related notification types to handle are SUBSCRIPTION_IN_GRACE_PERIOD (type 6), SUBSCRIPTION_ON_HOLD (type 5), SUBSCRIPTION_RECOVERED (type 1), and SUBSCRIPTION_EXPIRED (type 13). After receiving any RTDN, call purchases.subscriptionsv2.get to fetch the full subscription state – RTDNs signal that something changed but don’t carry complete details.

If you’re using RevenueCat, this plumbing is already done for you. The BILLING_ISSUE event fires automatically to your connected integrations – Braze, OneSignal, Iterable, Customer.io, and others – so you can trigger dunning campaigns directly from the tools you’re already using without building your own RTDN processing pipeline. The event includes grace_period_expiration_at, giving your campaigns the exact deadline to work with.

Deep linking to payment settings

Every extra tap between your dunning message and the payment update screen costs you recovered subscribers. The best recovery flows route users directly to the right screen with a single tap.

On Android, link to: https://play.google.com/store/account/subscriptions?package={packageName}&sku={skuId} – this takes users directly to their specific subscription on Google Play.

On iOS (for your cross-platform setup), use AppStore.showManageSubscriptions(in:) in StoreKit 2 (iOS 15+) to display the subscription management sheet without leaving your app.

If you’re using RevenueCat, the managementURL property on CustomerInfo returns the correct platform-specific URL automatically. This means your in-app billing error UI can include a one-tap “Fix payment” button that works across both stores without hardcoding store-specific URLs or maintaining platform branching logic.

Email dunning sequences

Email catches users who aren’t opening your app or aren’t seeing push notifications. A 3–5 message sequence over 14–28 days works well, shifting from friendly notification (“Heads up – we couldn’t process your payment”) to urgency (“Your subscription is at risk”) to final warning (“Last chance to keep your subscription”). Personalize with the user’s name and the specific features they’ll lose access to. Make the call-to-action button prominent and link directly to payment update.

One nuance worth flagging: pre-dunning emails that warn about upcoming card expirations – sent before a failure happens – sound good in theory but can backfire in practice. They can prompt users to reconsider whether they want the subscription at all, especially if the app isn’t top-of-mind. For active users, in-app prompts about expiring cards tend to be safer than email.

Recovery benchmarks: what to expect

Recovery rates vary based on how many of these tools you actually activate. Here’s what Google’s published data suggests, supplemented by their developer case studies:

  • Platform defaults only (no grace period optimization, no developer intervention): roughly 10–15% recovery of failed payments. This is where most apps sit today.
  • Optimized grace periods + account holds + In-App Messaging API (about an hour of configuration): roughly 30–35% recovery on Google Play. Google’s published data shows the combined effect of grace period and account hold triples recovery from the baseline. The In-App Messaging API doubles user recovery on top of that.
  • Full dunning stack (push notifications + email sequences + deep links on top of the platform tools): the incremental gains from each channel compound. In Google’s published Truecaller case study, implementing RTDN-triggered messaging alongside grace periods and account hold recovered 40% of at-risk subscribers – up from 15% before the changes.

Now consider what a recovered subscriber is actually worth. Our 2026 State of Subscription Apps data shows that a subscriber who survives their 1st monthly renewal has a 73–82% chance of making it to their 3rd. Every billing failure you recover in cycle 1 is a subscriber who gets the chance to become one of those high-retention renewals. Conversely, our reactivation data shows that once a monthly subscriber actually churns, only about 20% come back within a year – and for annual subscribers, it’s a dismal 5%. Preventing the loss is dramatically more valuable than winning the user back later.

Whichever tier you’re operating at, make sure you’re measuring the impact. Track your billing error cancellation rate by platform (RevenueCat’s Subscription Retention chart excludes unresolved grace period transactions, so your retention numbers reflect actual recovered subscribers). Compare cohorts before and after you extend grace periods. The feedback loop here is fast – you should see movement within a single billing cycle.

Fix billing before you buy more users

Involuntary churn is one of those rare problems where the diagnosis is clear, the tools already exist, and the returns are immediate. The instinct to treat billing failures as the platform’s problem is understandable – but the data is unambiguous. A third of your Google Play cancellations are subscribers who wanted to keep paying.

The highest-impact work is configuration, not code. Extend your grace periods. Enable account hold. Add Google’s In-App Messaging API. That’s an afternoon of work that recovers real revenue starting the next billing cycle.

Fix billing before you buy more users.