Syncing web subscriptions to the app was messier than I thought. Getting entitlements right exposed actual churn causes.
My checklist:
- Same product_ids across web and app, including periods and trial flags.
- Server-to-server: send the web receipt and start/end timestamps to Adapty/RevenueCat, then verify entitlement in the app.
- Webhooks: retry on failure and log every status change with a monotonic timestamp.
- Resolve timezones; I standardize to UTC everywhere.
- Diff report: daily compare web vs. app entitlement for active users and investigate mismatches.
Bugs found: a webhook timeout marked a few users as non-renewing in the app even though web was paid, which looked like churn. Also discovered a cancel flag sent without an effective_end_date, ending access too early.
How are you reconciling states and catching edge cases? Any tips for testing upgrades, downgrades, and cross-device logins without breaking entitlements or mislabeling churn?