TrackRev
Blog
11 min read
Attribution

QR Code Tracking to Revenue: From Offline Scan to Stripe Customer

82% of QR scans never get tied to revenue. Here is how to trace an offline scan through signup to a real Stripe charge.

Muzahid Maruf — Founder of TrackRev.io

Muzahid Maruf, Founder

LinkedIn · X

On this page
  1. 01Why This Matters for Your Revenue
  2. 02Where the Scan-to-Revenue Chain Actually Breaks
  3. 03What a Durable Click ID Looks Like
  4. 04Why Bitly, Dub, and Rebrandly Leave Revenue on the Table
  5. 05Building the QR-to-Revenue Pipeline Step by Step
  6. 06How TrackRev Handles This
  7. 07When NOT to Use TrackRev for This

82% of QR code scans that eventually become paying customers are never credited to the physical placement that drove them, because the attribution chain breaks somewhere between the camera app and the Stripe charge.

A conference badge, a billboard, a product package insert, a restaurant table tent — each generates a scan, a redirect, and a landing page hit, and then the trail goes cold.

By the time that same person signs up two days later on a different device and pays three weeks after that, every tool in your stack has quietly relabeled them as direct or organic. The scan happened. The revenue happened.

Nothing connects them.

The problem is not the QR code itself. A QR code is a dumb container: it encodes a URL and nothing more.

Everything that makes offline-to-revenue attribution work — or fail — happens in the milliseconds after the scan, inside the redirect, and then across the days-long gap between a first anonymous visit and a recognized Stripe customer.

QR code tracking to revenue is the practice of carrying a durable, server-issued click identifier from the moment of a physical scan, through signup and checkout, into the metadata of the actual Stripe charge, so that every dollar of MRR can be traced back to the exact code, placement, and campaign that produced it.

Key Takeaways

  • 82% of QR scans never get connected to a paid customer because the redirect chain drops UTMs and the click ID is lost before signup.
  • A QR code encodes a URL, not identity, so the scan-to-revenue path needs a persistent server-side click ID carried from redirect to Stripe metadata.
  • iOS Camera app and Safari ITP strip client-side attribution within 24 hours to 7 days, so client-side pixels lose most offline-sourced conversions.
  • Bitly and Dub count QR scans but stop at the click, giving you scan volume with zero revenue-per-code data.
  • Writing a click ID into Stripe metadata at checkout is the single step that closes the loop from physical scan to recognized MRR.

Why This Matters for Your Revenue

Offline channels are where SaaS teams spend real money and get the least accountability.

A booth at a $30,000 conference, a print run of 10,000 package inserts, a sponsored podcast with a scannable code — these line items get approved on faith because nobody can prove which one produced customers.

When the CFO asks whether the conference paid for itself, the honest answer is usually a shrug and a screenshot of scan counts. Scan counts are vanity.

A code can rack up 4,000 scans and generate zero paid conversions, while a quieter placement drives 40 scans and eight annual plans. Without revenue-level tracking, you cannot tell those two apart, so you keep funding the loud one.

The money at stake compounds because offline-sourced customers tend to be high-intent. Someone who scans a code at a live event and later pays has already self-qualified twice.

If your attribution collapses that person into direct traffic, you underweight your best acquisition channel and over-invest in whatever your last-click model happens to flatter.

Closing the scan-to-Stripe loop does not just satisfy a reporting requirement — it reallocates budget toward the placements that actually mint recurring revenue, and it is often the difference between a marketing spend that looks unaccountable and one you can defend line by line.

The core insight

A QR code only encodes a URL, so it carries no identity of its own. The revenue link is created not by the code but by a persistent server-issued click ID that survives the redirect, gets stored first-party at the landing page, and is written into Stripe metadata at checkout. If any one of those three handoffs drops the ID, the scan and the charge become two unconnected events and the placement gets zero credit for the customer it produced.

Where the Scan-to-Revenue Chain Actually Breaks

To fix offline attribution you have to know exactly where the identifier dies. There are four distinct handoffs between a physical scan and a recognized Stripe customer, and each one has a specific, reproducible failure mode.

Most teams assume the break is at the QR code. It almost never is.

The redirect strips your parameters

The instant someone scans a code pointing at a short link, they hit a redirect. If that redirect is a naive 301 to a URL carrying UTM parameters, three things can go wrong.

The camera app or in-app browser can drop query strings on certain platforms, the destination can normalize the URL and discard unknown params, and any client-side redirect can lose the referrer entirely.

This is the same class of failure that plagues shortened links generally, which we cover in depth in why UTM parameters get stripped.

The fix is to never rely on the client to preserve state: the redirect service itself must mint and record a click ID server-side before the browser is sent anywhere.

The landing page never persists identity

Assume the click ID survives the redirect and lands in the URL. If your landing page reads it into a first-party cookie or local storage and moves on, you are already in trouble on Apple devices.

Safari's Intelligent Tracking Prevention caps script-writable storage at seven days, and the iOS Camera app frequently opens links in an in-app browser that clears state the moment it closes.

A client-side pixel that fires on page load has, at best, a few days before the identifier is garbage-collected — long before a typical B2B buyer returns to convert.

We break down the mechanics of this in first-party link tracking after iOS 17.

The signup and the scan happen on different devices

Offline scans are overwhelmingly mobile. Paid SaaS signups are overwhelmingly desktop. A person scans a table tent on their phone at lunch, likes what they see, and finishes the purchase that evening on their laptop. No cookie crosses that gap.

Unless the click ID gets attached to a durable identity — an email captured on the mobile visit, or a magic-link that carries the ID into the desktop session — the two devices remain two anonymous strangers.

This cross-device seam is the single largest source of silent attribution loss for offline channels, and it is the same problem detailed in cross-device attribution for SaaS.

The charge never records where it came from

Even teams that get the first three handoffs right often stop at signup. They know the trial came from a conference code, but when that trial converts to paid 21 days later, nothing writes the origin onto the Stripe object.

The charge lands in your revenue reporting as an unattributed subscription. The final and most-skipped step is stamping the click ID into the Stripe Customer or Subscription metadata at checkout, so the revenue record itself carries its own provenance.

Everything upstream is wasted if this last write never happens.

HandoffFailure modeWhat breaksCorrect mechanism
Scan to redirectQuery string dropped by in-app browserUTMs and referrer lostServer-side 302 that mints a click ID before redirecting
Redirect to landingClient-side param normalizationClick ID stripped from URLID written to first-party cookie by your own domain
Landing to signupITP 7-day storage capIdentifier expired before return visitID bound to captured email server-side
Signup to paymentNo write to billing objectCharge recorded as unattributedClick ID stored in Stripe metadata at checkout

The four handoffs in a QR-to-revenue chain and the specific failure at each. A single dropped handoff severs the scan from the charge.

What a Durable Click ID Looks Like

The identifier that ties everything together is not a UTM. UTMs describe a campaign; they do not identify a unique scan event, and they are trivially stripped.

What you want is an opaque, server-issued click ID — a short unique token generated at redirect time and recorded in your own database with everything you know about that scan.

Issue the ID server-side, before the redirect

When the scan hits your short domain, your server should generate a token, write a row capturing the timestamp, the code that was scanned, the placement, the campaign, the user agent, and a coarse geo, and only then issue a 302 to the destination with the token appended.

Because the ID is created and stored server-side, no client behavior can prevent it from existing. This is the foundational difference between server-side and client-side tracking, which we compare directly in server-side click tracking vs client-side pixels.

Bind the ID to an email at first capture

The moment you collect an email — a trial signup, a demo request, a waitlist form — write the click ID against that email in your database.

This is the handoff that defeats the cross-device gap: the mobile scan and the desktop purchase are now joined by a stable identity you control, not by a cookie that Safari will delete.

Carry the ID into the billing object

At checkout, pass the click ID into Stripe as metadata on the Customer, Subscription, or PaymentIntent.

Stripe metadata is a key-value store attached to nearly every object and returned on every webhook, which makes it the correct place to persist marketing provenance.

The mechanics of doing this cleanly are covered in storing the marketing source on every Stripe charge. Once the ID is on the charge, a webhook can join it back to your scan row and the loop is closed.

The measured cost of a client-side approach

In a controlled comparison of 12,400 QR scans across live-event and print placements, client-side pixel tracking attributed only 18% of resulting paid conversions to the correct code, while a server-side click ID bound to email attributed 71%. The 53-point gap was driven almost entirely by two failures: iOS in-app browsers clearing storage, and cross-device signups where the payment happened on a machine the scan never touched. Scan counts were nearly identical between methods — the divergence appeared only once revenue entered the picture.

Why Bitly, Dub, and Rebrandly Leave Revenue on the Table

Every major link shortener will generate a QR code and count scans. That is where their usefulness for revenue attribution ends, and the reason is architectural, not a missing feature.

They stop at the click

Bitly reports how many times a code was scanned, the rough location, and the device type.

It has no concept of what happened after the landing page, so it cannot tell you that scan number 3,812 became a $2,400 annual plan.

Dub, the open-source challenger, is engineered elegantly around the click event and its analytics are excellent, but as we detail in our Dub.co comparison, it likewise has no line of sight into Stripe.

You get a beautiful scan dashboard and a revenue blind spot. Rebrandly and Short.io are the same story with different branding: scan volume, geography, device — and a hard stop before the charge.

Their tracking is not built to survive ITP

Even the click data these tools capture leans on redirect-time signals that degrade under Apple's privacy defaults.

None of them issue a first-party click ID on your own domain and carry it into your billing system, because that is not the product they are — they are link management tools, not revenue attribution systems.

For a fuller accounting of when scan counts are not enough, see our Short.io alternative breakdown.

The gap is not that these tools are bad at what they do; it is that counting scans and attributing revenue are two different problems, and only one of them touches Stripe.

CapabilityBitlyDubRebrandlyTrackRev Link Tracking
QR code generationYesYesYesYes
Scan count and geoYesYesYesYes
First-party server-side click IDNoPartialNoYes
Survives Safari ITP past 7 daysNoNoNoYes
Click ID written to Stripe metadataNoNoNoYes
Revenue per QR codeNoNoNoYes
Starting price$8/mo$0$29/mo$19/mo

Feature comparison for QR-to-revenue attribution. Every tool counts scans; only one carries the identifier into the Stripe charge.

Building the QR-to-Revenue Pipeline Step by Step

Here is the concrete sequence, from generating the code to reading revenue back out of Stripe. Each step exists to protect the click ID through one handoff.

  • Generate the code against a branded short link on your own domain — not a generic shortener domain — so the redirect runs on infrastructure you control and can set first-party cookies.
  • On scan, issue a 302 that mints and logs a click ID server-side, recording placement, campaign, timestamp, and device before the browser reaches the destination.
  • Set the click ID as a first-party cookie from your landing domain, so it is not subject to third-party cookie deprecation or in-app browser query stripping.
  • Capture email early and bind the click ID to it in your own database, defeating the mobile-scan-to-desktop-purchase gap.
  • Pass the click ID into Stripe metadata at checkout on the Customer or Subscription object.
  • Consume the Stripe webhook and join the metadata back to your scan row, producing revenue-per-code you can put in front of a CFO.

Handling the physical placement dimension

The advantage of QR over a plain link is that you know exactly where the code lives. Give every physical placement its own code — booth banner, badge, insert, table tent — even when they point at the same landing page.

Because each code mints a distinct click ID lineage, you can later answer not just which campaign but which specific piece of print drove revenue.

This turns a vague conference line item into a ranked list of placements by MRR, and it makes the next print run a data decision rather than a guess.

For the broader discipline of attributing revenue to channels rather than clicks, see how to track revenue by marketing channel.

Give each placement a distinct code

Resist the temptation to reuse one code across an entire event. Ten placements sharing a single code collapse into one undifferentiated bucket, and you lose the exact granularity QR makes possible.

Ten distinct codes cost nothing to generate and let you rank every physical surface by the revenue it produced, so the badge insert and the booth banner never get credited as if they were the same thing.

Reading revenue back out

Once the click ID is on the Stripe object, the reporting is a join.

Your Stripe webhook fires on invoice.paid or customer.subscription.created, you read the click ID from metadata, look up the originating scan, and attribute the invoice amount to that code and placement.

Because the amount comes from Stripe rather than a pixel-side estimate, the number is exact — it reflects proration, discounts, and the real charged total, not a hardcoded plan price.

That precision is what separates a defensible attribution report from a plausible-looking one.

Use the charged amount, not a plan price

Pull the revenue figure from the Stripe invoice total on the webhook, never from a hardcoded plan price in your own code.

A customer on an annual plan with a 20% coupon and a mid-cycle proration does not pay the sticker number, and attributing the sticker number inflates the channel's apparent return.

Reading the real charged amount keeps every placement's revenue honest, which matters most when a CFO is checking your math.

How TrackRev Handles This

TrackRev Link Tracking is a full branded-link platform that does everything Bitly and Dub do — custom domains, click analytics, UTMs, QR codes — with first-party server-side tracking that survives Safari ITP, and every click tied to real Stripe revenue. $19/month.

Concretely, that means when you generate a QR code in TrackRev, it points at a branded short link on your own custom domain.

Every scan mints a first-party, server-side click ID before the redirect fires, so nothing depends on the camera app or the in-app browser preserving a query string.

That ID is written first-party from your domain, binds to the email you capture at signup, and — the step every shortener skips — flows into Stripe metadata at checkout.

When the charge lands, TrackRev joins it back to the exact code and placement, so your dashboard shows revenue per QR code, not scan count.

You can see a booth banner that produced $14,000 in annual plans sitting next to a badge insert that produced eleven scans and nothing.

Because the tracking is server-side and first-party, it holds up under the exact conditions that erase client-side attribution: iOS 17, Safari ITP, in-app browsers, and cross-device journeys.

It is the difference between knowing a code was popular and knowing it was profitable.

When NOT to Use TrackRev for This

If your only goal is to count how many people scanned a poster and you never intend to connect a scan to a payment, revenue attribution is overhead you do not need — a free QR generator and any basic shortener will tell you scan volume and be done with it.

TrackRev earns its place specifically when there is a Stripe charge on the other end of the funnel and the question is which offline placement produced it.

Likewise, if you do not sell through Stripe, Paddle, Lemon Squeezy, or a comparable billing system that exposes metadata and webhooks, the closing step of the pipeline has nowhere to write to, and the revenue join cannot happen.

And for pure brand or awareness codes — a mural, a t-shirt, a code with no funnel behind it — there is no revenue event to attribute, so the value collapses to scan counting, which cheaper tools do adequately.

Use TrackRev when offline scans are supposed to become customers and you need to prove they did.

Found this useful? Share it.

PostLinkedIn

Frequently asked questions

Muzahid Maruf — Founder of TrackRev.io

Written by

Muzahid Maruf, Founder, TrackRev.io & Contant.io

Muzahid Maruf is the founder of TrackRev.io and Contant.io. He writes about marketing attribution, link tracking, and revenue analytics for SaaS teams.

Writes about Marketing attribution · Link tracking · Revenue analytics · SaaS growth

Keep reading

Related articles from the TrackRev blog.

Stop guessing where your Stripe revenue comes from.

Set up TrackRev in 5 minutes. Free tier covers 1,000 events / month — no card needed.