Billing grace period supported for subscription renewals
Why it matters
Apple's billing grace period allows subscribers to retain premium access for up to 16 days while a renewal payment fails — the platform retries the charge during this window. Apps that immediately revoke access on the first DID_FAIL_TO_RENEW notification lock out users who have a temporary billing issue (expired card, insufficient funds) and would have renewed successfully within the grace period. This creates unnecessary churn from users who intended to remain subscribers and generates chargebacks and support volume. Google Play has a parallel mechanism under the SUBSCRIPTION_ON_HOLD state in Real-Time Developer Notifications.
Severity rationale
Low because immediate access revocation on billing failure causes avoidable churn but does not constitute a rejection reason — it is a product-quality and revenue-retention deficiency.
Remediation
Enable billing grace period in App Store Connect under Subscriptions → Billing Grace Period (up to 16 days). In code, retain access during the grace period window rather than revoking on the first failed renewal signal.
// RevenueCat — user retains active entitlement during grace period
const entitlement = customerInfo.entitlements.active['premium'];
const hasBillingIssue = entitlement?.billingIssueDetectedAt !== null;
const isPremium = entitlement !== undefined; // true during grace period
// Show a soft banner if hasBillingIssue, but do not revoke access
For custom webhook handlers, check for isInBillingRetryPeriod: true in the Apple App Store Server Notification v2 payload before revoking — only revoke after the grace period expires, not on the first failure event.
Detection
- ID:
grace-period - Severity:
low - What to look for: Count all relevant instances and enumerate each. Billing grace periods allow users to retain premium access for a short period (up to 16 days on iOS) while a subscription renewal fails due to a billing issue. Look for: (1) Apple's
isInBillingRetryPeriodorDID_FAIL_TO_RENEWApp Store Server Notification v2 handling in webhook code. (2) Google Play'sSUBSCRIPTION_ON_HOLDor grace period state in RTDN handler. (3) RevenueCat'sPeriodType.trialand billing issues incustomerInfo— RevenueCat surfacescustomerInfo.entitlements['premium'].billingIssueDetectedAt. (4) Entitlement grant logic that checks grace period status: users in billing retry should retain access, not be immediately downgraded. Fail pattern: entitlement check uses onlyisActivewithout considering grace period, causing premium users with a billing issue to be immediately locked out while Apple/Google are still retrying payment. - Pass criteria: Grace period handling is present (RevenueCat
billingIssueDetectedAtchecked, or Apple/Google webhook handles billing retry with continued access grant), OR app is iOS-only and grace period is configured in App Store Connect (requires code to honor it). At least 1 implementation must be verified. OR this cannot be determined (skip). - Fail criteria: Entitlement code immediately revokes access when renewal fails, without a grace period — confirmed by webhook handler that sends revoke on first
DID_FAIL_TO_RENEWevent. - Skip (N/A) when: No subscription IAP (consumables only); or grace period status cannot be determined from the codebase.
- Detail on fail:
"Apple App Store Server Notifications handler revokes premium access on DID_FAIL_TO_RENEW with no grace period — Apple recommends maintaining access during billing retry period" - Remediation: Enable billing grace period in App Store Connect → Subscriptions → Billing Grace Period (up to 16 days). In code, retain access during this window:
// RevenueCat const hasBillingIssue = customerInfo.entitlements.active['premium']?.billingIssueDetectedAt !== null; const isPremium = customerInfo.entitlements.active['premium'] !== undefined; // true during grace period
External references
- external · apple-billing-grace-period — Apple — Billing Grace Period for Auto-Renewable Subscriptions
- external · google-play-grace-period — Google Play — Subscription Grace Period (Account Hold and Grace Period)
Taxons
History
- 2026-04-18·v1.0.0·Initial import from app-store-iap-subscriptions·automated