How affiliate attribution actually works — and why most tools get it wrong
Attribution is the whole job of an affiliate platform: credit the affiliate who genuinely drove an install, and only that affiliate. On Shopify it's deceptively hard — and the common shortcut quietly pays the wrong person. Here's what's really going on, and how to do it right.
The problem: Shopify strips your query params
The obvious approach is to tag the affiliate's link with a code — ?ref=CODE — and read it back when the merchant installs your app. It seems simple. It doesn't work on its own.
When a merchant installs a Shopify app, the flow passes through the App Store and Shopify's OAuth. Along the way, Shopify strips arbitrary query parameters. By the time your app's install callback runs, that ?ref=CODE is gone. The affiliate's code never reaches the moment where you'd record the referral.
The shortcut most tools take (and why it misattributes)
Because the code is lost, many affiliate tools fall back to a heuristic: when a new install shows up, look back ~30 days for any affiliate click for that app and credit the most recent one.
The trouble is that a click carries no shop identifier — it happens before the install, in a different browser context. So "the most recent click for this app" is a guess. If two affiliates promoted you in the same window, the last click wins, even if the other one drove the install. Worse, a single stray click — say, an affiliate testing their own link — can capture an entirely unrelated install and pay it to the wrong person.
The right way: carry the code through the install
You don't fight Shopify's redirect — you use the one field it's required to preserve: the OAuth state parameter. It's the CSRF nonce your app already sends, and Shopify hands it back to your callback untouched. So you tuck the affiliate code inside it:
- The affiliate link routes the merchant to your install URL carrying
?ref=CODE. - At install start, you read
refand pack it into the signedstatenonce. - Shopify returns
stateto your OAuth callback intact. - You unpack
refand record the install against the exact affiliate — with the shop domain.
That shop domain + affiliate code pairing is the whole point: it identifies precisely which install came from which affiliate. No guessing, no cookies, no 30-day window. It's deterministic.
Using Shopify managed installation / token exchange (no developer-controlled OAuth redirect)? Same idea — you read ref from your app's first load instead of from state, and record it the same way.
What about existing Mantle-style links?
Mantle-style programs use a direct App Store link with ?mref=CODE. The same principle applies — the app forwards the mref code. A well-built platform treats ref, mref, and utm_source as the same thing: they all resolve to one affiliate code, so migrating between tools doesn't break a single affiliate's link.
How PartnerDock does it
PartnerDock is built around deterministic attribution. Exact matches — where the merchant demonstrably came through the affiliate's link — are credited automatically. Anything uncertain (an install with no forwarded code, matched only by the last-click window) is never auto-approved; it waits for the founder to confirm, so a stray click can't quietly pay out.
Setup is a one-time, ~10-minute integration, with copy-paste examples for Remix, Next.js, Express, Gadget and more — and a dashboard status that flips to Verified the moment a real install carries a code end to end. Existing App Store and redirect links keep working throughout.
Run an affiliate program on numbers you can trust
PartnerDock gives Shopify app founders deterministic attribution, commission tiers, automated payouts, and a done-for-you affiliate portal — with free migration from Mantle.
