NewHuxly MCP — Connect Claude, Cursor & Codex.Learn more
How to Handle Failed Payments in a Subscription App
Back to Blog
GuideNov 1, 20267 min read

How to Handle Failed Payments in a Subscription App

Contents

A card expiring does not mean a customer chose to leave. Subscription platforms may retry a failed charge, place the account in a grace period, or change entitlement status later.

If your app treats every billing issue as immediate cancellation, it can lock out a customer who still has access.

The first rule is to separate payment events from access decisions. Your app should show current entitlement accurately, explain what the customer can do, and avoid promising a recovery date it does not control.

Key takeaway:

A failed charge does not always end access immediately. Check current entitlement, show the correct payment-recovery path, and test recovery as well as failure.

Know who bills the customer

An iOS or Android in-app subscription is governed by the respective store's billing lifecycle. A web subscription through Stripe has a different one.

Diagram showing distinct paths for App Store, Google Play, and web subscription billing sources.

If you use RevenueCat, it can provide a normalized view of entitlements across supported stores, but the app still needs to handle each product's business rules.

Map each purchase source in your system: App Store, Google Play, or web. Record customer ID, product or plan, entitlement, current status, and source. Do not tell an App Store customer to update a card in your Stripe portal.

Review current store rules and integration documentation when shipping billing changes. Platform retry and grace behavior can be configured and can evolve.

Separate billing issue from loss of access

A billing issue is a signal that the renewal payment has a problem. It is not necessarily proof that the paid feature should be disabled now.

With a configured grace period, the customer's entitlement may remain active while the store retries the charge.

RevenueCat's billing issues and grace periods guide explains how billing-issue events and entitlement status interact. Its entitlements documentation describes how an app checks the current access state.

Use the current entitlement status for gating paid features. Use billing events to trigger support and messaging workflows. A webhook is a notification of a change, not an instruction to override a newer entitlement snapshot.

Map access from the current entitlement

Use current entitlement to decide whether paid features are available. Use billing events to explain a problem and guide recovery. RevenueCat's billing issues and grace periods guide explains this distinction.

Current provider statePaid featuresWhat the customer sees
Active, no billing issueAvailableNormal account state
Billing issue, entitlement still activeAvailableA quiet banner and the recovery path for their billing source
Canceled, but entitlement still active until period endAvailable until the entitlement expiresThe confirmed end date, where provided
Entitlement inactive after expiryFollow the product's access policyHow to restore access and what happens to saved work
Active again after recoveryAvailableThe old failure message removed

For an active subscriber with a billing issue, a banner might say: "There's a problem with your renewal. Check your payment method to keep access." Link to the correct store or web billing path.

Do not copy a fixed grace-period length into the message or send a store-billed customer to a web card form. Use the actual state returned for that billing source.

Decide which features remain after expiry and how saved content is retained. A failed renewal should not silently delete the customer's work.

Test these states with provider sandbox events. A delayed billing-issue event must not lock an account that has already recovered.

Handle asynchronous events safely

Billing systems can deliver events more than once or out of order. Deduplicate by event identifier where available, record received time and effective time, and refresh authoritative customer status before making an irreversible access change.

Abstract visual of asynchronous billing events being reordered and reconciled along a timeline.

Suppose a payment recovery event is processed before a delayed billing-issue event. If you simply apply the latest received message, the account can incorrectly fall back into failure. Reconcile against current entitlement or provider state.

If the app has both device-side and server-side access checks, ensure they agree on the entitlement identity. A stale client cache should have a clear refresh path when the customer restores or updates payment.

Write recovery messages that help

A useful email or in-app message states the issue plainly, identifies the subscription, tells the customer where to update payment, and avoids claiming their account has been canceled while a grace period is active.

Limit message frequency. Repeated payment-failure alerts across push, email, and SMS can feel punitive. Schedule one initial notice and a sensible reminder if the issue persists, respecting the platform's own communications and user preferences.

Use account-specific deep links only if they land in the correct purchase source. Do not request card details in your own app for a store-billed subscription.

Plan grace period and access expiry

A grace period can protect a subscriber's experience, but its exact availability and configuration depend on the store and your setup. Keep your product copy based on status and a known expiry date, if provided, instead of hard-coding "You have three days."

Decide how the app behaves when offline and cached entitlement appears active. Cache can be useful for continuity, but do not claim a failed renewal has been resolved before verification.

Define how long cached access lasts and how a later status refresh is handled.

Once the provider confirms payment recovery, refresh the entitlement, restore any access that expired, and remove the billing banner. An active entitlement during a grace period does not by itself mean the payment issue is resolved.

Build support visibility

Support staff need to see billing source, current entitlement, recent billing events, last refresh time, and whether a notice was sent. Keep payment card details with the billing provider; your support screen should not expose sensitive payment data it does not need.

Give support a way to guide store customers to the platform's subscription management screen and web customers to your billing portal. A refund, cancellation, and billing failure need different help instructions.

For general subscription setup, see how to build a subscription mobile app with RevenueCat. For business decisions about tiers, see how to price a subscription app.

Test the lifecycle end to end

Use store sandbox and provider test tools for failed renewal, retry, grace period, recovery, cancellation, expiration, and restore. Confirm which events arrive and what current entitlement says at each stage. Send a duplicated and out-of-order webhook to your backend test environment.

Two synchronized test mobile devices displaying subscription lifecycle states in a sandbox test.

Check the app on two devices logged into the same account. Verify feature access, banners, and support status converge after a refresh. Review copy for each billing source so customers are sent to the right place.

Build payment recovery with Huxly

Use Huxly to build the account states and recovery screens around your billing provider. Specify that current entitlement controls access and that each subscriber must see the recovery path for their billing source.

Start building with Huxly, then test failure, grace, recovery, and expiry with provider test events. Check the saved work and access state as well as the banner.

FAQ

Should I lock a user out as soon as a payment fails?

Usually not without checking the current entitlement. Retry and grace behavior can keep access active after a billing issue.

What is a grace period?

It is a configured period during which a subscription can remain entitled while the billing platform retries a failed charge. Exact behavior depends on the platform and setup.

Can I update an App Store subscriber's card inside my app?

Send the person to the appropriate store-managed billing path. The store controls the payment method for store-billed subscriptions.

Why did I receive the same webhook twice?

Many event systems retry delivery. Process each event only once and check current entitlement before changing access.

What if a payment recovers after access expires?

Refresh status, restore the applicable entitlement, clear failure messages, and show the updated access state promptly.

How much should I email about failed payments?

Send enough to help the customer recover, without repeated redundant alerts. Coordinate with the billing platform's own messages.

Keep reading