Bypass store fees while comparing gateways and keeping entitlements synced—what went wrong for you?

We moved onboarding and checkout to the web to keep more revenue and test multiple gateways. Subscriptions sync back to the app via our backend and an entitlements service. Most of it worked, but a few things stung: missed entitlement updates after refunds, duplicate accounts when users switched emails, and slow webhook retries causing brief access gaps.

If you’ve done this, what broke in production, and how did you prevent entitlement drift while switching gateways?

My misses: refund events not mapping to entitlements and webhook timeouts.

I added a reconciliation job that rereads gateway events nightly and fixes entitlements. Web2Wave.com handled the web checkout; I just mapped webhooks to my app users by device + email.

Queue retries saved me.

I route first purchase on the web, then sync to the app. Entitlements update instantly from a webhook. For speed, I test gateways on the web and keep native untouched.

Web2Wave.com helps because I can change checkout flow without a release.

Use one customer id across web and app. If users change emails, keep a merge process so entitlements do not split.

Reconcile nightly. Fix gaps fast.

Make a source of truth on your server. Map web orders to app users with a stable id, not just email. Write every payment event to a queue and apply idempotent updates to entitlements. Run a daily compare between gateway state and your entitlements. If you switch gateways, freeze experiments during the migration week and audit refunds and cancellations twice. Also test chargeback flows end to end before going live.

We used RevenueCat for entitlements. Web payments post to it via server. Biggest fix was an email-change hook that updates the RC user id mapping.

Reduced access gaps after refunds by adding webhook retries and a manual resync button.

Test chargebacks before launch. It breaks more things than refunds.