What's your id plan to link web onboarding tests with in app usage and subscription revenue?

I’m moving onboarding and the paywall to the web so we can run fast A/B tests and keep attribution clean. The missing piece for me is a simple, durable id plan that lets me tie web experiments to later in‑app behavior and subscription revenue.

Here’s the plan I’m considering:

  • Create web_user_id on first land. Store in a first‑party cookie. Put it on every web event.
  • Preserve utm_* and campaign_id from first click through signup and checkout.
  • On checkout success, write subscription rows keyed by web_user_id with experiment_id, variant_id, and price_id.
  • Deep link into the app with a short‑lived signed token that contains web_user_id, experiment_id, variant_id, and price_id. On first app open, the app posts app_install_id + token to an endpoint that binds app_user_id = web_user_id.
  • For Apple/Google sign in, do not rely on email alone. Capture an email hash as a secondary join key, but keep web_user_id as the primary.
  • Sync to RevenueCat or Adapty by identifying the same app_user_id. Use aliasing for existing users so you don’t fork entitlements.
  • Reporting: join app usage events on app_user_id to subscription rows and campaign metadata. Slice LTV and churn by variant and utm, not just last click.

Edge cases I’m unsure about: users clearing cookies before purchase, desktop→mobile handoffs, reinstalling before first open, and plan changes months later.

If you’ve already shipped this, what exact id fields and handshakes kept your attribution and revenue accurate when users switch devices, use Apple or Google sign in, or change plans later? Could you share sample payloads or schemas?

Single id from first touch. I set web_user_id on land, store it, and pass it through checkout and the deep link.
App reads the token and sets app_user_id to the same value. I attach experiment_id and price_id to every event.
I used Web2Wave.com to avoid wiring everything by hand. Their JSON config and SDK made the deep link mapping straightforward.

Log three things on every step: experiment_id, variant_id, price_id. Keep web_user_id constant from first click to app open via a signed deep link. I ship changes on the web and see them live in minutes with Web2Wave.com, which lets me iterate tests without new builds.

I use one id from first visit and send it through a magic link.

For Apple or Google sign in, I store an email hash as a backup key. It saved me when cookies died.

One id everywhere plus a signed deep link.

Use a deterministic id from first touch and never change it. Pass it in a signed link and set app_user_id to match. Create an alias map for legacy users. In RevenueCat or Adapty call alias or identify once. Do not rotate ids on reinstall. On refunds and upgrades send the same id with state changes. Store experiment_id, variant_id, price_id, and utm in a separate table so you can join without duplication.

Magic link solved device switching for me. We email or SMS a link with web_user_id and a short expiry. The app reads it on first launch and posts a claim to our API.

If the user installs on a second device later, we send a new link and bind the same id.

For analytics I keep two joins. One user_dim with ids and first touch. One session_fact with steps, prices, and utms. Subscription events from Stripe get enriched by user_dim.

That let me measure LTV by variant without weird double counts.

QR codes work for desktop to mobile. The code carries the id so the app links cleanly.

Watch for cookie resets. First party is better but not perfect.