Attribution Data Discrepancy: Why Your SaaS Tools Disagree on Where Revenue Came From
40-60% gaps between GA4, Stripe, and your ad platforms are normal. Here's why SaaS attribution tools disagree and how to reconcile them.
Muzahid Maruf, Founder · TrackRev.io & Contant.io
On this page
Roughly 40-60% of SaaS teams find their attribution tools disagree by more than a third on where revenue came from, and most never reconcile the numbers because they assume one dashboard must be lying. It isn't.
GA4 says paid search drove 120 signups, Meta Ads Manager claims 90 conversions on its own, your Stripe dashboard shows 74 new subscriptions, and your BI tool attributes 61 of them to organic.
None of these numbers are wrong in isolation. They are answers to four different questions, measured with four different identity models, over four different time windows, filtered by four different definitions of a 'conversion.'
The discrepancy isn't a bug you can patch. It is the predictable result of stacking measurement systems that were never designed to agree, then reading them as if they were.
Once you understand exactly where each number diverges, the gaps stop being alarming and become diagnosable.
An attribution data discrepancy is the measurable difference between two or more systems reporting on the same revenue event, caused by mismatched identity resolution, attribution windows, event definitions, and data loss between the click and the charge.
Key Takeaways
- GA4, ad platforms, and Stripe routinely disagree by 40-60% because each measures a different event with a different identity model and a different attribution window.
- Client-side pixels lose 20-35% of conversions to ad blockers, ITP cookie expiry, and iOS Link Tracking Protection before the data ever reaches a report.
- Ad platforms self-attribute using their own view-through and click windows, so summing Meta, Google, and TikTok 'conversions' will always exceed your real Stripe revenue.
- The only reconcilable source of truth is the payment processor: a Stripe charge is a single, deduplicated, dollar-denominated event that every tool should be forced to map back to.
- First-party server-side attribution that writes the marketing source onto the Stripe charge closes most of the gap because it stops depending on cookies that browsers now delete.
Why This Matters for Your Revenue
When your tools disagree by 40%, every downstream budget decision inherits that error.
If Meta claims 90 conversions and Stripe recorded 74 new subscriptions attributable to paid social, you are either over-crediting Meta by 22% and about to raise its budget, or you are under-counting because a third of those conversions were stripped before Stripe ever saw a UTM.
Guess wrong and you scale the wrong channel. On a $30,000 monthly ad budget, a 30% misattribution moves roughly $9,000 to a channel that didn't earn it.
The cost compounds in subscription businesses because attribution errors don't just misprice acquisition — they misprice lifetime value. A channel that looks expensive on first-payment attribution may deliver customers who upgrade and stay 18 months.
If your discrepancy hides that, you cut the channel with the best channel LTV and keep the one that churns in month two.
Reconciling the discrepancy is the difference between a CFO who trusts your marketing numbers and one who quietly discounts everything you report.
The core reason your dashboards never match
GA4, ad platforms, and your payment processor are not measuring the same thing. GA4 measures sessions tied to a browser cookie. Ad platforms measure clicks and view-throughs credited to their own users. Stripe measures deduplicated dollars. A number that is correct in one system is structurally incomparable to a number in another — reconciliation means mapping every source back to a single Stripe charge, not forcing the dashboards to agree.
The Four Systems That Never Agree
Before you can fix a discrepancy you have to name the systems producing it. In a typical SaaS stack, four independent measurement layers report on the same funnel, and each one is optimized to answer a different question.
Web analytics measures sessions, not customers
GA4 counts events tied to a client-side identifier — the _ga cookie or a Measurement Protocol client ID.
When Safari's Intelligent Tracking Prevention caps that cookie at 7 days, a visitor who clicks an ad on Monday and pays the following week returns as a brand-new user with no memory of the ad.
GA4 then files that revenue under Direct or Organic. This is why GA4 frequently fails to show revenue by channel at all, and why its channel report drifts further from reality every quarter as browser privacy tightens.
Ad platforms self-attribute in their own favor
Meta, Google Ads, and TikTok each run a private attribution engine that credits conversions to their own platform whenever their pixel or a logged-in match can claim the user.
Meta's default is a 7-day click plus 1-day view window; Google Ads uses data-driven attribution across a 30-day window; TikTok defaults to 7-day click and 1-day view.
A single customer who saw a Meta ad, searched your brand on Google, then clicked a TikTok ad will be counted as a conversion by all three.
Sum them and you will always exceed your actual Stripe revenue, sometimes by 150% or more.
- View-through inflation: Meta can credit a conversion to an impression the user never clicked, which no other system in your stack will ever see.
- Modeled conversions: when the pixel is blocked, ad platforms estimate conversions statistically and report them as real — you cannot reconcile a number that was never observed.
- Deduplication gaps: the same purchase fired from both a browser pixel and the Conversions API can double-count if the event ID isn't matched.
The payment processor is the only ground truth
A Stripe, Paddle, Polar, or Lemon Squeezy charge is the one event in your entire stack that is real money, deduplicated, and denominated in dollars. It cannot be modeled, blocked, or inflated by a view-through.
This is why any serious reconciliation treats the payment processor as the anchor and forces every other system to map its claimed conversions back to actual charges.
If you take one architectural principle from this article, it is that Stripe revenue is the denominator and everything else is an attribution hypothesis about it.
Your product database counts a fourth thing
Your app's own database records signups and activations, which rarely line up 1:1 with either sessions or charges.
A free trial signup is not a customer, and in PLG models the gap between trial and paid is where most attribution is lost.
If you don't persist the marketing source from the moment of signup through to conversion, the channel that drove the trial is orphaned by the time the card is charged weeks later.
This is the specific failure covered in free trial signup attribution.
| System | What it counts | Identity model | Default window | Typical inflation vs Stripe |
|---|---|---|---|---|
| GA4 | Sessions with conversion event | Client-side cookie / client ID | Data-driven, up to 90 days | -25% to -40% (undercounts) |
| Meta Ads Manager | Clicks + view-throughs | Logged-in user match + pixel | 7-day click, 1-day view | +30% to +90% (overcounts) |
| Google Ads | Ad-attributed conversions | Google identity + gclid | 30-day, data-driven | +20% to +60% (overcounts) |
| Stripe | Deduplicated charges | Customer + charge ID | N/A (the event itself) | Baseline (ground truth) |
| Product DB | Signups / activations | Internal user ID | Whatever you persist | Varies with trial-to-paid lag |
The same funnel measured five ways. Inflation figures are typical ranges observed across mid-market B2B SaaS; your exact spread depends on channel mix and privacy exposure.
Where the Data Actually Leaks
Systemic disagreement explains the direction of the gaps. Data loss explains their size. Between the moment a user clicks and the moment Stripe fires a charge, four distinct leaks quietly delete attribution.
Ad blockers delete the pixel before it fires
Between 20% and 35% of B2B SaaS traffic runs an ad blocker or privacy extension that blocks connect.facebook.net, googletagmanager.com, and similar client-side scripts outright.
The conversion happens, the money is real, but the pixel never fires, so the ad platform and GA4 both lose it. Developer-heavy audiences skew far higher — some infra tools see 50%+ blocking.
We break the revenue math down in detail in the guide on ad blocker attribution loss.
Brave and uBlock block by default
Brave ships with Shields enabled out of the box, and uBlock Origin sits in millions of Chrome installs — both strip the Meta and Google pixels before page load. Neither prompts the user, so the conversion vanishes with no client-side fallback.
Safari ITP expires the cookie before conversion
Apple's Intelligent Tracking Prevention caps client-side script-set cookies at 7 days, and JavaScript-set first-party cookies at 24 hours in some contexts.
For any SaaS with a sales cycle longer than a week — which is most of B2B — the attribution cookie is dead before the customer decides to pay. The click is orphaned and the revenue lands in Direct.
See Safari ITP and attribution for the full mechanism.
UTM parameters get stripped in transit
Attribution can die before the user even lands. iOS 17 Link Tracking Protection strips known tracking parameters from URLs in Messages, Mail, and private browsing. Link shorteners drop query strings on redirect. Email clients rewrite URLs.
If your utm_source never survives to your landing page, no downstream system can attribute the visit — the data was destroyed upstream of your analytics. This is the mechanism behind why UTM parameters get stripped.
The identity breaks at the checkout domain boundary
When your marketing site is www.yoursaas.com and your app is app.yoursaas.com, or when checkout redirects to a Stripe-hosted or Paddle-hosted page on a different domain, the browser treats them as separate origins.
Cookies set on one don't travel to the other.
Unless you explicitly pass the attribution identity across the boundary — via a query parameter, a shared subdomain cookie, or server-side session — the click context is lost exactly at the moment of payment.
This is the cross-subdomain tracking problem, and it is one of the most common silent causes of an inflated Direct channel.
Cross-device clicks land as separate people
A prospect clicks your ad on their phone during a commute, then buys from their laptop at their desk. Two devices, two cookies, zero shared identity unless you resolve them through a logged-in account.
Client-side tools count this as two visitors and attribute the revenue to whichever device saw the checkout — usually filed as Direct on desktop. Resolving it requires stitching identity through your own login, covered in cross-device attribution for SaaS.
The reconciliation math most teams never run
Start with 100 real Stripe conversions. Ad blockers erase 25 from the pixel-based tools. ITP cookie expiry misfiles 20 more as Direct. UTM stripping kills the source on 10 before landing. Cross-device and cross-subdomain breaks scatter another 15. That leaves client-side analytics correctly attributing about 30 of 100 conversions — a 70% attribution loss — while ad platforms simultaneously over-report through view-through and modeling. The two errors run in opposite directions, which is exactly why the dashboards can never meet in the middle.
How to Reconcile the Numbers
You will never make GA4 and Meta agree, and chasing that is wasted effort. Reconciliation means picking one anchor, mapping everything to it, and quantifying each gap so you know which number to trust for which decision.
Anchor on the payment processor
Make Stripe (or Paddle, Polar, Lemon Squeezy) the denominator for every attribution report.
Instead of asking 'how many conversions does Meta claim,' ask 'of the 74 charges Stripe recorded this month, which marketing source is written on each one.' A charge either has a verifiable source or it doesn't; there is no view-through to argue about.
The practical way to guarantee this is to store the marketing source in Stripe metadata on every charge at checkout time.
Backfill source onto historical charges
You can retroactively tag past charges by joining Stripe's charge export to your server access logs on email and timestamp. It won't recover a lost UTM, but it reassigns logged-in sessions, typically reclaiming 10-15% of charges previously dumped into Direct.
Move the tracking server-side
Every leak above shares one root cause: the attribution logic runs in the browser, where blockers, ITP, and parameter stripping have jurisdiction.
Move the capture to a first-party server endpoint and most of the loss disappears, because a server request from your own domain isn't blocked and isn't subject to the 7-day cookie cap.
The tradeoffs are laid out in server-side click tracking vs client-side pixels. This is not a marginal improvement — it is the difference between attributing 30% and 90% of your revenue.
Quantify each gap instead of hiding it
A reconciled report should show, per channel, the raw platform-reported number, the Stripe-verified number, and the delta with a labeled reason.
When Meta reports 90 and Stripe verifies 61, the 29-conversion gap isn't error to be embarrassed about — it's the sum of view-through credit and modeled conversions, and you can name it.
The forensic version of this exercise is covered in why your attribution data is wrong.
Decide which number governs which decision
Use the payment-anchored number to allocate budget and report to finance. Use the ad-platform number only inside that platform's own optimizer, where its view-through model actually helps the algorithm learn.
Never mix them in one spreadsheet and sum them — that is the original sin that produces impossible 150%-of-revenue attribution totals.
| Symptom | Root cause | Reconciliation fix | Recoverable revenue |
|---|---|---|---|
| Direct traffic is 40%+ of revenue | ITP + cross-device + stripped UTMs dumping into Direct | First-party server-side capture, persist source to charge | 15-30% of total |
| Ad platforms sum to >100% of Stripe | View-through + modeled conversions overlapping | Anchor on Stripe, use platform numbers only in-platform | Prevents overspend, not lost revenue |
| GA4 undercounts vs Stripe by 30% | Ad blockers killing gtag before it fires | Server-side event capture on your own domain | 20-35% of conversions |
| Trial converts weeks later, source lost | No persisted attribution across the trial gap | Write source at signup, read it at charge | All delayed-conversion revenue |
| Checkout on separate domain loses context | Cross-origin cookie boundary | Pass identity across boundary server-side | 10-20% of paid revenue |
A diagnostic map from symptom to fix. Recoverable revenue percentages are typical for B2B SaaS with sales cycles over one week and Safari share above 30%.
How TrackRev Handles This
TrackRev Revenue Attribution is a first-party attribution platform built for SaaS — a Triple Whale and HYROS alternative without the e-commerce assumptions or ad-spend minimum. Connects Stripe, Paddle, Polar, and Lemon Squeezy. $19/month.
The reconciliation architecture described above is exactly the product. TrackRev captures the marketing source server-side on your own domain, so ad blockers, ITP cookie caps, and iOS Link Tracking Protection never get a vote.
It persists that source from first click through free trial to the eventual charge, then writes it onto the Stripe, Paddle, Polar, or Lemon Squeezy transaction itself.
Your source of truth becomes the deduplicated payment event, not a browser cookie that Safari deleted six days ago.
Because the payment processor is the anchor, TrackRev reports are inherently reconcilable: every dollar of revenue maps to one verified source, and delayed conversions in long B2B cycles stay attributed instead of collapsing into Direct.
It also credits recurring revenue correctly, so a channel gets ongoing credit for the customers it brought, not just the first payment — the model detailed in subscription LTV attribution.
Why the ad-native tools can't reconcile this
Triple Whale and Northbeam are built around e-commerce and paid-media spend, and they assume a Shopify-style purchase model with a large, always-on ad budget.
Point them at a $19-plan B2B SaaS with a three-week trial and a Stripe backend and their core assumptions break: there is no ad-spend floor to model against, and the conversion happens far outside their pixel-friendly window.
HYROS leans on client-side tracking and long attribution windows that still depend on cookies browsers now expire. GA4, as covered above and in attributing revenue without GA4, undercounts structurally because it lives in the browser.
Link-shortener-first tools like ClickMagick and PixelMe track the click well but were never architected to read a Stripe charge and reconcile it back to source, so they leave the most important half of the funnel — the money — unmeasured.
When NOT to Use TrackRev for This
If you run a high-volume e-commerce store on Shopify with a six-figure monthly ad budget and same-session purchases, a media-buying platform like Triple Whale or Northbeam will serve you better — they are built to model ad spend at that scale and to feed conversion signals back into ad optimizers, which TrackRev deliberately doesn't try to replace.
Likewise, if your entire funnel is a single-domain, cookie-friendly, sub-24-hour purchase with no trial and no Safari exposure, the discrepancy you're trying to fix may be small enough that any first-party pixel closes it, and adding another tool isn't worth the setup.
TrackRev earns its place when revenue lives in Stripe, Paddle, Polar, or Lemon Squeezy, when sales cycles outlast the ITP cookie window, and when 'Direct' has quietly eaten a third of your reporting.
If none of that describes you, spend your effort elsewhere.
Found this useful? Share it.
Frequently asked questions
- GA4 undercounts because it tracks conversions with a client-side browser cookie that ad blockers delete and Safari's Intelligent Tracking Prevention expires within seven days. Stripe records the actual deduplicated charge regardless of browser state, so it captures conversions GA4 loses. A 25-40% gap where GA4 is lower than Stripe is normal for SaaS, not a tracking bug.
- Ad platforms like Meta and Google self-attribute using view-through credit and statistically modeled conversions that no other system observes. Each platform also claims the same customer independently, so summing them exceeds real revenue. Meta's default 7-day-click plus 1-day-view window credits impressions a user never clicked, which inflates its number well above your verified Stripe charges.
- Trust the payment processor. A Stripe, Paddle, Polar, or Lemon Squeezy charge is real money, deduplicated, and impossible to inflate with view-throughs or modeling. Use ad-platform numbers only inside that platform's own optimizer, and use your payment-anchored, source-tagged revenue for budget decisions and finance reporting. Never sum platform numbers together, because that double-counts shared customers.
- For B2B SaaS with sales cycles longer than a week and meaningful Safari traffic, client-side tools typically attribute correctly on only 30-40% of conversions. Ad blockers erase roughly a quarter, ITP cookie expiry misfiles about a fifth as Direct, and UTM stripping plus cross-device breaks account for the rest. Server-side first-party capture recovers most of that loss.
- Only if the tool you pick anchors on the payment processor and captures the source server-side. Picking a client-side tool and ignoring the rest keeps you inside the same cookie-dependent blind spot. The durable fix is to make the deduplicated Stripe charge your denominator and write the marketing source onto it, so every dollar maps to one verifiable source.

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.
