Skip to main content

Cross-platform entitlement sync if app is on both stores

ab-000410 · app-store-iap-subscriptions.restore-entitlements.cross-platform-sync
Severity: lowactive

Why it matters

A 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.

Severity rationale

Low because it only affects users who actively switch platforms, though impact per affected user is high.

Remediation

Configure both iOS and Android apps under a single RevenueCat (or Adapty/Qonversion) project using the same entitlement identifiers — the SDK then resolves entitlements against a unified customer profile automatically. For a custom backend, have both api/validate-apple.ts and api/validate-google.ts write to a single user_entitlements table keyed by your internal user_id, not by the platform-native purchase identifier, so a logged-in user sees the same is_premium = true on either device.

Detection

  • ID: app-store-iap-subscriptions.restore-entitlements.cross-platform-sync

  • Severity: low

  • What to look for: Count all relevant instances and enumerate each. If the app is distributed on BOTH iOS App Store and Google Play, determine how subscription entitlements are synchronized. A user who subscribes on iOS should ideally have their entitlement recognized if they switch to the Android version, and vice versa. Look for: (1) RevenueCat — handles this automatically if both iOS and Android are configured in the same RevenueCat project with the same entitlement IDs. (2) Adapty — same as RevenueCat if configured with cross-platform profiles. (3) Custom backend — look for an entitlement service that normalizes Apple and Google purchase records into a unified user-level premium flag stored in the database. The critical failure is a user subscribed on iOS who installs the Android app and finds their subscription not recognized. This is not a store rejection issue but a significant UX/churn risk.

  • Pass criteria: App is single-platform (skip), or cross-platform entitlement sync is handled via RevenueCat/Adapty/Qonversion (automatic), or a custom backend unifies entitlements. At least 1 implementation must be verified.

  • Fail criteria: App ships on both iOS and Android but iOS subscriptions are not recognized on Android and vice versa — entitlements are validated per-platform with no cross-reference to a unified user account.

  • Skip (N/A) when: App is iOS-only or Android-only; or cross-platform entitlement approach cannot be determined from codebase.

  • Detail on fail: "iOS purchase validation in api/validate-apple.ts and Android validation in api/validate-google.ts write to separate database tables with no shared user_id link — iOS subscribers are not recognized on Android"

  • Remediation: Use RevenueCat or Adapty and configure both iOS and Android apps under the same project — cross-platform entitlement sync is automatic with linked user identity. For custom backends, ensure both validation paths write a is_premium = true flag to the same user record.

    Review the configuration in src/ or app/ directory for implementation patterns.

  • Cross-reference: For related patterns and deeper analysis, see the corresponding checks in other AuditBuffet audits covering this domain.


Taxons

History