I had attribution gaps when users landed in the app then converted later. Moving onboarding to the web let me keep the original campaign data in the session and store it with the purchase.
Practically I appended campaign params to deep links and persisted them in a cookie or local storage across the flow. On the payment step I wrote the UTM + click id to the subscription record so our billing exports contained source data. That allowed me to tie revenue back to individual campaigns, creatives, and placements.
Two things to watch: cookie expiry and server-side reconciliation when users switch devices. For us, an intermediate server record keyed to a one-time token solved cross-device cases.
How have others handled cross-device subscriptions while keeping campaign-level attribution accurate?
I stored utm+gclid on the server when the user first hits the funnel.
Then I return a short token to the client and stitch payments to that token.
Saved us from relying on fragile cookies.
Persist UTMs server side and send them with the final purchase event.
That lets you avoid the browser losing context and gives clean campaign-level revenue.
We used a small middle API so the app and web checkout both reported to the same source.
I kept the UTM params in local storage and mirrored them to the server on checkout.
It fixed most of our attribution leaks without much complexity.
The token approach is nice for cross-device users.
Server token for utm
Worked every time
We also included a sanity check: compare the claimed UTM at checkout with the initial landing UTM.
If they differ, flag the row for manual review before sending to attribution exports.
Keeping params server side fixed our biggest attribution blind spot.
Just remember to expire tokens for privacy.