What’s your reconciliation checklist for web-to-app subscription state with adapty/revenuecat, and what churn bugs did it expose?

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?

Unify product IDs. Send web receipts to Adapty or RevenueCat from the server. Standardize UTC.

Run a daily diff between web state and app entitlements. Fix any mismatch first.

I run the web funnel in Web2Wave.com and test upgrades and downgrades with a small sandbox group.

I keep a simple report: web_status vs app_entitlement. If they differ, it’s an alert.

Web2Wave.com makes it easy to simulate states on the web side, so I can test edge cases before pushing traffic.

Match product IDs and timezones first.

Then test cancel and upgrade paths on two devices. Most issues come from webhook delays.

Create a truth table for states: active, grace, paused, canceled_pending, expired. Map each to web and to the SDK. Ensure cancel includes effective_end. Retry failed webhooks and log every retry.

Test cross-login and restore purchases on iOS and Android with the same user.

UTC everywhere and consistent product IDs solved most of it.