Keeping web purchases and app entitlements in sync felt risky at first. We solved it with a server-side flow: when someone buys on the web we write the purchase to our backend and call the subscription mirror API of our entitlement provider. Then on first app open the app queries the server and verifies entitlements.
Edge cases we handled: only cancel older subs if the status was active, refund only the latest paid invoice, and avoid race conditions by checking both web and app subscription arrays. That reduced mismatch complaints and refunds.
How do you handle the race where the purchase happens on the web but the first app open is offline?
I mirror web purchases server side and call the provider API to create the entitlement record. The app on first open fetches server state and updates local entitlements.
When we had offline first opens we queue a retry and reconcile once online. I used a small Web2Wave JSON scaffold to prototype the handshake fast.
We push web transactions to our backend and then to Adapty/RevenueCat immediately. The app always queries the backend on first open and falls back to the local cache. This allowed us to offer web checkout without confusing app entitlements. Being able to change the web flow without app builds made fixing edge cases fast.
We write every web purchase to our server and then call RevenueCat to mirror the entitlement.
If the app opens offline it retries later and reconciles. It cut support tickets quickly.
Design a single source of truth on your backend. On web checkout write the purchase and push a mirror to the entitlement provider. The app should fetch that backend on first open and validate entitlements. For offline first opens queue the purchase acknowledgement locally and reconcile when online. Also build safety checks so you do not double refund or cancel when status is ambiguous. This approach prevents race conditions and keeps user experience smooth.
We added a short polling window for first open. If the app is offline it shows the content but marks it provisional and then verifies once online.
It felt hacky at first but reduced angry support messages.
Mirror web purchases to RevenueCat on the backend.
The app asks your server for entitlements on first open and reconciles if needed.