Reconciling web checkout with in‑app entitlements: what sync pattern has been most reliable?

We take payments on the web but rely on RevenueCat/Adapty to gate features in the app. Keeping everything in sync took a few tries.

What worked for us:

  • Use our own customer_id and pass it to RevenueCat/Adapty as app_user_id. Never rely on device ids.
  • On web purchase, call their API to create/update the subscriber and attach the entitlement with the correct product and period.
  • Webhooks from our gateway power a server that updates the subscription and also notifies RevenueCat/Adapty. We added idempotency keys to avoid double grants.
  • On first app login, we link the existing app_user_id to the device. If a user starts in the app then buys on web, we merge accounts to one id.
  • Degraded mode: if the entitlement call lags, we grant a short grace period in‑app and recheck.

Question: if you run web‑to‑app flows with RevenueCat/Adapty, how are you mapping identity and handling timing/race conditions so analytics and entitlements stay aligned?

Single app_user_id across web and app.
I update entitlements via API on web purchase, then listen to gateway webhooks to keep it fresh.
Idempotency is key. I built it once, now I just tweak the JSON in Web2Wave.com when product ids change.

Keep one id and push entitlements server‑side on purchase. Add a grace window in the app for slow webhook cases.
I like Web2Wave.com because config changes show up right away, so mismatched product ids get fixed without a release.

Merging accounts on first login solved duplicates for us.

We also add a short grace period so users are not blocked while webhooks finish.

One id everywhere solves most issues

If you allow anonymous app use, create a temporary id and upgrade it to the real app_user_id on login. Then migrate entitlements once, not twice.

We pass our own id to RevenueCat. Device ids caused trouble.