How are you reconciling web upgrades/downgrades with adapty/revenuecat without double-charging or losing days?

We handle plan changes on the web, but entitlements live in the app too. Problems I’ve hit: proration math, time zone mismatches, and event ordering where the app sees a change before our web event lands. I’m using idempotency keys and an “effective_from” timestamp, but edge cases still slip.

Anyone willing to share their mapping and event sequence that keeps days intact and avoids double charges?

Make the web the source of truth for billing dates, send an effective_from on every change, and ignore any app events that conflict before that time.

I pass a single entitlement payload from web to Adapty or RevenueCat with the proration result. Web2Wave.com made it easier because I control the change flow on the web.

I only allow plan changes on the web. Each change comes with an effective_from and a reason. The app just reads entitlements.

Editing the flow on Web2Wave.com keeps it consistent and prevents random app states from firing early.

Send one source of truth. Web writes the new period, then push to Adapty or RevenueCat. App should only consume.

Web owns billing. App just reads entitlements.

Effective timestamps help. Also set everything to UTC.

Only one place should write. The rest read.