All 23 checks with why-it-matters prose, severity, and cross-references to related audits.
Apple guideline 3.1.1 and Google Play Billing Policy both require that all digital goods sold within an app — subscriptions, consumables, non-consumables — are transacted exclusively through the platform's official billing API (StoreKit on iOS, Play Billing Library on Android). Routing a digital goods purchase through Stripe, Paddle, PayPal, or any other third-party processor via a webview or external link is not a gray area: it results in immediate rejection and, for repeat violations, developer account termination. Apple has removed apps and banned developer accounts for this specific violation. The business impact is severe: an app rejected during review has zero revenue until resubmitted, a process that takes days to weeks and requires removing the violating payment flow entirely.
Why this severity: Critical because violation results in immediate App Store rejection and potential permanent developer account termination with no warning period.
app-store-iap-subscriptions.iap-integration.storekit-billingSee full patternPlaceholder product IDs like `com.example.app.monthly` or counts that do not match the paywall UI mean purchases fail at the store layer before revenue is ever collected. The StoreKit or Play Billing call returns an unknown-product error, the paywall renders a broken CTA, and every install that reaches the purchase screen churns out with zero attribution. This is pure reference-integrity and placeholder-hygiene failure — the code and the App Store Connect / Play Console records must agree exactly or the integration is dead on arrival.
Why this severity: High because placeholder or mismatched IDs silently break every purchase attempt, destroying conversion before any revenue lands.
app-store-iap-subscriptions.iap-integration.product-idsSee full patternEvery IAP submission is exercised by an Apple reviewer who will attempt to cancel the OS payment sheet. CWE-755 (Improper Handling of Exceptional Conditions) applies directly: an unhandled cancellation error that surfaces a crash or an error dialog is an automatic rejection under Apple guideline 3.1.1. Beyond review, a purchase flow that crashes or shows a confusing error when a user declines to buy drives uninstalls and negative reviews — user cancellation is a normal event, not an error state. A broken purchase error flow also risks leaving entitlement state inconsistent: the user may be charged by the platform but denied access by the app if the success path is never reached.
Why this severity: High because a crash or error dialog on user cancellation causes immediate App Store rejection and is exercised by every reviewer examining an IAP app.
app-store-iap-subscriptions.iap-integration.purchase-errorsSee full patternShipping IAP with no sandbox configuration means the purchase flow has never actually run end-to-end without a real card charge. Any regression in product ID casing, entitlement mapping, receipt validation, or SDK key selection ships straight to production, where the first signal is a user support ticket or a drop in activation-to-subscription conversion. A `.storekit` file or an environment-split RevenueCat/Adapty/Qonversion key turns this into a local test that runs on every build instead of a launch-week fire.
Why this severity: Low because sandbox gaps cause launch-time regressions rather than runtime failures for paying users in production.
app-store-iap-subscriptions.iap-integration.sandbox-testingSee full patternClient-side receipt validation is trivially bypassed: any user with a proxy tool (Charles Proxy, mitmproxy) can intercept the platform's receipt response and return a forged success. This is OWASP A07 (Identification & Authentication Failures) applied to entitlement decisions — the access control check runs in an environment the attacker fully controls. CWE-345 (Insufficient Verification of Data Authenticity) is the direct mapping. The business consequence is that paid features become free for any motivated user. Apple deprecated the legacy `/verifyReceipt` endpoint in favor of App Store Server API v2 (JWT-signed transactions, `api.storekit.itunes.apple.com`) — apps still using the legacy endpoint face a compounding validation gap as it is phased out.
Why this severity: High because client-side receipt validation is bypassable by any user with a network proxy, allowing paid features to be unlocked without payment.
app-store-iap-subscriptions.iap-integration.receipt-validationSee full patternApple guideline 3.1.1 prohibits directing users to external payment flows for digital goods — and enforcement is not limited to rejection. Apple has terminated developer accounts for this violation and retroactively removed apps from the store. Google Play Billing Policy carries equivalent restrictions. The damage extends beyond the individual app: a terminated developer account means every app under that account is removed simultaneously. Unlike most rejection reasons which allow a resubmit with a fix, account termination has no straightforward appeal path. This is the highest-severity policy violation in the entire IAP compliance surface.
Why this severity: Critical because external payment links for digital goods are the single most severe App Store policy violation, causing immediate rejection and potential permanent developer account termination.
app-store-iap-subscriptions.iap-integration.no-external-paymentSee full patternApple guideline 3.1.1 explicitly requires a "Restore Purchases" mechanism for all non-consumable IAP and subscriptions. Its absence is a rejection reason — but the practical impact compounds post-launch: users who delete and reinstall the app, upgrade to a new device, or restore from backup lose access to content they paid for. These users generate support tickets, file chargebacks with their bank or credit card company, and leave one-star reviews. Chargebacks damage the developer's payment processor standing even though Apple actually processed the payment. A functional restore path prevents all of this at minimal implementation cost.
Why this severity: Critical because Apple guideline 3.1.1 explicitly mandates a restore mechanism, and its absence causes immediate rejection — not a warning.
app-store-iap-subscriptions.restore-entitlements.restore-purchasesSee full patternUsers who reinstall an app or transfer to a new device lose any premium state stored only in local storage (`AsyncStorage`, `SharedPreferences`, `UserDefaults`, MMKV). CWE-311 (Missing Encryption of Sensitive Data) is a related vector — but the core failure here is data-integrity: the entitlement record does not survive the lifecycle events it must. The business consequence is straightforward: paying users who lose their subscription after a reinstall file chargebacks directly with their bank or credit card company, which harms the developer's payment standing. They also leave negative reviews and generate disproportionate support volume. ISO/IEC 25010 reliability requirements apply — a subscription entitlement is a durable system state that must survive device lifecycle events.
Why this severity: High because entitlement loss after reinstall causes paying users to file chargebacks and leave negative reviews, with direct financial and reputational impact.
app-store-iap-subscriptions.restore-entitlements.reinstall-survivalSee full patternWhen Family Sharing is enabled for an IAP subscription in App Store Connect, up to five family members share the entitlement. A family member's receipt carries `inAppOwnershipType == .familyShared` rather than `.purchased`. Apps that validate receipts without handling this ownership type will incorrectly deny access to paying family members — users who legitimately share the subscription but are treated as non-subscribers. Apple's Family Sharing IAP documentation specifies that apps must handle `FAMILY_SHARED_MEMBER_JOINED` App Store Server Notification v2 events when Family Sharing is enabled. The check is low severity because Family Sharing is disabled by default and most apps do not enable it.
Why this severity: Low because it only applies when Family Sharing is explicitly enabled in App Store Connect, which is not the default configuration for most apps.
app-store-iap-subscriptions.restore-entitlements.family-sharingSee full patternApple'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.
Why this severity: 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.
app-store-iap-subscriptions.restore-entitlements.grace-periodSee full patternA user who subscribes on iOS, reinstalls on Android, and discovers their subscription is not recognized will either double-pay or churn. Validating Apple receipts into one database table and Google purchase tokens into another with no shared `user_id` link splits a single paying customer into two half-customers — and the data-integrity hit compounds when refunds, cancellations, or plan changes arrive on one platform but never reach the other. Cross-platform sync is a churn and support-load problem, not a store policy one.
Why this severity: Low because it only affects users who actively switch platforms, though impact per affected user is high.
app-store-iap-subscriptions.restore-entitlements.cross-platform-syncSee full patternApple guideline 3.1.2 and the FTC Negative Option Rule both require that subscription price, billing period, auto-renewal disclosure, and cancellation mechanism are clearly displayed before the user initiates a purchase. Apps that bury auto-renewal disclosures in Terms of Service links or show only a price without a billing period have been rejected under these requirements. Beyond policy, the FTC Negative Option Rule (updated 2023) applies to recurring charges to US consumers regardless of platform — companies that violate it face FTC enforcement actions. Google Play Subscription Policy carries equivalent disclosure requirements.
Why this severity: High because missing auto-renewal disclosure is one of the most consistent subscription-app rejection reasons under Apple guideline 3.1.2, and also triggers FTC Negative Option Rule compliance exposure.
app-store-iap-subscriptions.subscription-lifecycle.subscription-termsSee full patternApple reviewers test IAP apps on physical devices, including small-screen models like the iPhone SE (667 logical points of usable height). A paywall that requires scrolling to see the price, auto-renewal terms, or the subscribe button fails Apple guideline 3.1.2's requirement that subscription terms are clearly displayed before purchase. Beyond review, a paywall where the subscribe button is below the fold on smaller devices creates a real conversion drop for users who never see it — large hero images or feature lists that push the CTA off-screen reduce paid conversions from the segment most likely to be budget-conscious.
Why this severity: High because a paywall requiring scroll to reveal the price or CTA fails Apple guideline 3.1.2 on physical device review and reduces conversion on smaller screens.
app-store-iap-subscriptions.subscription-lifecycle.paywall-elementsSee full patternApple guideline 3.1.2(b) and the FTC Negative Option Rule both require that free trial terms — duration and post-trial price — are clearly disclosed before the user initiates the trial. A paywall that shows "Start Free Trial" without disclosing what the user will be charged after the trial is one of the most common subscription rejection reasons Apple cites. The FTC Negative Option Rule (effective 2024) extends this obligation to US consumers in digital subscription flows: failure to disclose post-trial pricing is an unfair or deceptive act regardless of where the purchase occurs. The compliance risk applies to the developer directly, not only to the platform relationship.
Why this severity: High because missing post-trial price disclosure is one of the most cited subscription rejection reasons under Apple guideline 3.1.2(b) and also triggers FTC Negative Option Rule exposure for US users.
app-store-iap-subscriptions.subscription-lifecycle.free-trial-termsSee full patternA "Free Trial" toggle that flips the CTA between trial and full-price products treats trial eligibility as a user choice — but Apple and Google determine eligibility server-side based on prior introductory offer usage. Non-eligible users tapping "Start Free Trial" get charged immediately with no warning, which generates refund requests, chargebacks, and 1-star reviews citing deceptive billing. This also puts the paywall in the crosshairs of App Store Review Guideline 3.1.2(a) on subscription clarity and equivalent Play Store policies on misleading pricing.
Why this severity: Medium because deceptive trial UI drives chargebacks and store rejections but does not halt shipping outright.
app-store-iap-subscriptions.subscription-lifecycle.no-trial-toggleSee full patterniOS subscriptions are cancelled through device Settings → Apple ID → Subscriptions; Android subscriptions through Google Play. The app cannot provide a direct cancel button, but it must communicate the cancellation path — users who cannot figure out how to cancel file chargebacks, which cost the developer $15–$25 per dispute plus chargeback ratio penalties. Apple guideline 3.1.2 requires that users are informed of how to cancel, and the FTC Negative Option Rule requires that cancellation be "simple." A paywall that says "Cancel anytime" without providing any actual cancellation instructions is deceptive under this standard.
Why this severity: Medium because absent cancellation instructions generate chargebacks and FTC Negative Option Rule exposure, even though the omission alone is not always an immediate rejection trigger.
app-store-iap-subscriptions.subscription-lifecycle.cancellation-instructionsSee full patternA paying subscriber who cannot see their renewal date, current tier, or next charge amount inside the app has to dig through App Store or Play Store settings to answer basic billing questions — and many will just email support or dispute the charge instead. Hiding subscription status is also a common trigger for App Store Review Guideline 3.1.2 rejections on subscription transparency. The data is already in `customerInfo.entitlements.active[...]` on every launch; not surfacing it is pure UX negligence.
Why this severity: Medium because missing status UI drives support load and chargebacks without blocking the purchase flow itself.
app-store-iap-subscriptions.subscription-lifecycle.subscription-statusSee full patternManually calling `cancelSubscription()` followed by `purchaseSubscription()` to move a Monthly subscriber to Annual creates a coverage gap, risks double-charging the user during the transition, and can trigger Play Store purchase rejections because Google expects proration via `SubscriptionUpdateParams`. The error-resilience cost is high: failed upgrades strand users between plans with unclear entitlement state and drive refund requests. Both platforms ship a first-class upgrade/downgrade path — bypassing it is the failure mode here.
Why this severity: Low because it only affects users actively changing tiers, though each affected user risks a double charge.
app-store-iap-subscriptions.subscription-lifecycle.upgrade-downgradeSee full patternHardcoded price strings like `"$9.99/month"` display the wrong currency and wrong amount to users in other countries — App Store pricing tiers mean a US $9.99 subscription may be priced at £7.99, €9.99, ¥1,500, or A$14.99 depending on the market. Showing a US price to an Australian user who is actually charged A$14.99 is a misrepresentation of the cost that violates both Apple guideline 3.1.1 and consumer protection laws in many jurisdictions. Apple's and Google's IAP SDKs return a `localizedPrice` string already formatted in the user's local currency — there is no reason to hardcode prices.
Why this severity: Low because hardcoded prices cause incorrect currency display in non-US markets but are unlikely to trigger rejection on their own — however they do expose the developer to consumer protection complaints.
app-store-iap-subscriptions.pricing-compliance.price-localizationSee full patternDisplaying an annual plan as `"$4.17/month"` in 24pt font with `"$49.99 billed annually"` in 10pt gray text misrepresents the actual charge in a way that triggers Apple App Store Review Guidelines, the FTC Negative Option Rule, and EU Digital Services Act provisions on dark patterns. Countdown timers with no genuine time-limited offer attached are classified as manipulative urgency patterns under multiple regulatory frameworks. Beyond regulatory risk, misleading pricing erodes user trust: users who feel deceived by a pricing screen leave negative reviews and request refunds at higher rates, directly impacting the app's store rating and refund ratio.
Why this severity: High because misleading pricing presentation triggers Apple guideline 3.1.2 rejection and regulatory exposure under the FTC Negative Option Rule and EU dark-patterns provisions.
app-store-iap-subscriptions.pricing-compliance.no-misleading-pricingSee full patternApple and Google both process refunds for IAP purchases at their discretion — the developer cannot override platform refund policy. Terms of Service language stating "all sales are final" or "no refunds" contradicts the platform's actual refund policy and misleads users who are legally entitled to request a platform refund. This misrepresentation is actionable under consumer protection law in most jurisdictions. Beyond legal risk, users who encounter "no refunds" language and cannot find a refund path file chargebacks directly with their bank, which costs the developer $15–$25 per dispute and, at high rates, risks merchant account suspension.
Why this severity: Low because the defect is informational and does not cause immediate rejection, but it creates consumer protection legal exposure and directly drives chargeback rates.
app-store-iap-subscriptions.pricing-compliance.refund-policySee full patternApple Promotional Offers are only valid for users who have previously subscribed to the product — presenting them to first-time users generates an invalid purchase attempt that fails at the platform level. An offer identifier string that does not match exactly what is configured in App Store Connect causes the same failure. Both scenarios result in a purchase error that the user experiences as a broken "Subscribe" button. Apple's promotional offer system requires server-side signature generation to prevent unauthorized use, so a mismatch between the code's offer identifier and App Store Connect configuration breaks the entire offer flow silently.
Why this severity: Low because misconfigured promotional offers break the discount flow for targeted users but do not affect the primary subscription purchase path for new subscribers.
app-store-iap-subscriptions.pricing-compliance.promo-offersSee full patternThe post-Epic v. Apple regulatory environment has produced jurisdiction-specific carve-outs to the rule that all digital goods must be sold through the platform store. For EU iOS apps under the Digital Markets Act, Apple must permit alternative payment methods for Core Technology Fee-registered developers. For US iOS apps following the 2024 court order, Apple allows apps to link to external purchase — subject to a 27% commission on purchases within 7 days. Developers who implement alternative billing without understanding these jurisdiction-specific rules, eligibility requirements, and commission structures risk building a payment flow that is simultaneously policy-compliant in one market and a violation in another. Regulatory-conformance is the directly applicable taxon.
Why this severity: Info because the regulatory landscape is actively changing and the check surfaces awareness signals only — it never produces a scored failure.
app-store-iap-subscriptions.risk-indicators.alternative-billing-rulesSee full patternRun this audit in your AI coding tool (Claude Code, Cursor, Bolt, etc.) and submit results here for scoring and benchmarks.
Open App Store IAP & Subscriptions Audit