TrackRev
Blog
11 min read
Attribution

GA4 Not Showing Revenue by Channel? Here's Why and How to Fix It

68% of SaaS teams see wrong or missing revenue-by-channel data in GA4. Here's why Stripe revenue never lands in your channel report and how to fix it.

Muzahid Maruf — Founder of TrackRev.io

Muzahid Maruf, Founder

LinkedIn · X

On this page
  1. 01Why This Matters for Your Revenue
  2. 02The Six Reasons Revenue Never Reaches Your Channel Report
  3. 03How To Diagnose Which Cause Is Hitting You
  4. 04What You Can Actually Fix Inside GA4 (And What You Can't)
  5. 05How TrackRev Handles This
  6. 06When NOT to use TrackRev for this

Roughly 68% of B2B SaaS teams that connect Stripe to Google Analytics report that GA4 either shows no revenue by channel at all or shows numbers that contradict their Stripe dashboard by 20% or more.

You open the Traffic acquisition or User acquisition report expecting to see MRR split cleanly across Google, LinkedIn, newsletter, and affiliate, and instead you get a wall of 'Direct' and '(not set)', a revenue column that reads $0.00 for channels you know converted, or a total that is a third of what Stripe actually collected.

The instinct is to assume a broken tag. Usually the tag is fine. The problem is architectural: GA4 was built to measure e-commerce transactions that complete inside a single browser session, and SaaS revenue simply does not behave that way.

Every symptom in this article traces back to one root cause.

GA4 not showing revenue by channel is what happens when a browser-session analytics tool is asked to attribute revenue that is actually created server-side in your billing system, across multiple sessions, devices, and days it can never observe.

Key Takeaways

  • GA4's Default Channel Grouping buckets 30-45% of paid SaaS revenue into 'Direct' or '(not set)' because subscription payments settle server-side in Stripe, outside any browser session GA4 can measure.
  • GA4 only records revenue from a purchase event fired in the browser; recurring MRR, upgrades, and off-session renewals never fire that event, so they never appear in any channel row.
  • Cross-domain hops to Stripe Checkout or a billing subdomain reset the GA4 session and reassign the conversion to 'Direct' unless you configure cross-domain measurement precisely.
  • The 24-72 hour lag between a trial signup and the first paid charge routinely exceeds GA4's session window, breaking the link between the acquisition channel and the eventual revenue.
  • A first-party attribution platform that reads Stripe as the source of truth ties every charge, renewal, and expansion back to the original UTM, which GA4's event model structurally cannot do.

Why This Matters for Your Revenue

When 30-45% of your paid revenue collapses into 'Direct', you are not just missing a report row. You are making budget decisions on inverted data.

The channel that GA4 credits with the most 'Direct' revenue is frequently the one you underfund, because 'Direct' looks like free demand nobody paid to create.

Meanwhile the paid channel that actually drove those signups shows a cost with no revenue beside it, so it gets cut in the next planning cycle.

Teams routinely kill their best-performing acquisition source because GA4 filed its revenue under a bucket that means 'we don't know'.

The money impact compounds because the mislabeled revenue is recurring. A misattributed $400/month subscription is not a $400 mistake, it is a $4,800 annual mistake, and every renewal reinforces the wrong conclusion.

If you spend $30,000 a month across four channels and GA4 hides which channel generates the LTV, your cost-per-acquisition math is fiction.

You cannot compute payback period, you cannot defend spend to a CFO, and you cannot tell whether a channel is profitable until months after you have already reallocated the budget away from it.

The core reason GA4 can't show your channel revenue

GA4 attributes revenue only when a purchase event fires inside a browser session it can see. SaaS revenue is created in Stripe: recurring renewals, off-session upgrades, and payments that settle 24-72 hours after the click never fire that browser event, so GA4 has no revenue to assign to any channel and defaults it to 'Direct' or '(not set)'.

The Six Reasons Revenue Never Reaches Your Channel Report

GA4's channel report fails for SaaS in six distinct, diagnosable ways. Most teams have three or four of them running at once, which is why the numbers look randomly wrong rather than wrong in a consistent direction.

Work through each one against your own setup before you blame the pixel.

1. The purchase event never fires for recurring revenue

GA4 can only credit revenue to a channel if a purchase event carries a monetary value into a session. The first checkout might fire that event.

The second month's renewal fires nothing, because no browser is involved when Stripe charges the saved card. Every renewal, every off-session upgrade, and every usage-based invoice is invisible to GA4 by design.

For a subscription business where 70-80% of annual revenue is renewal revenue, this alone means GA4 can never see the majority of the money, let alone attribute it to a channel.

This is the difference between tracking a signup and tracking revenue. If you want the channel that drives lifetime value rather than the channel that drove one browser transaction, GA4's event model is the wrong instrument.

We break this down further in our guide to crediting lifetime revenue, not just the first payment.

The tell: a spike in brand-search revenue

When renewal and multi-session revenue can't find their real source, GA4 disproportionately credits 'Organic Search' for your brand name, because that's what people type when they return to log in and get charged.

If your branded-search channel shows more revenue than your entire paid program, that's not organic demand, it's misattributed subscription revenue leaking into the one channel returning users happen to touch.

2. Cross-domain hops to Stripe Checkout reset the session

When a visitor clicks a Google ad, lands on yoursite.com, then gets redirected to checkout.stripe.com or your own app.yoursite.com to pay, GA4 starts a brand-new session on the return unless cross-domain measurement is configured to a fault.

The referrer on the way back is Stripe, GA4 sees an inbound visit from a domain it doesn't recognize as yours, and the conversion gets reassigned to 'Direct' or to 'stripe.com / referral'.

The original Google click is severed from the payment.

This is one of the most common single causes of a GA4 revenue column full of zeros next to your paid channels.

The cure is real cross-domain configuration, and the failure mode is subtle enough that we cover it separately in why attribution breaks between www and app.

How to confirm it's a cross-domain reset

Add Session source / medium as a secondary dimension to your conversions and look for stripe.com / referral or checkout.stripe.com sitting next to your purchase events.

If it's there, the return trip from checkout is minting a fresh session and stealing credit from the real acquisition channel. It's a five-minute check that instantly separates this cause from the others.

3. The trial-to-paid lag exceeds the session window

A prospect clicks your LinkedIn ad on Tuesday, starts a 14-day trial, and converts to paid on day 12. GA4's default session timeout is 30 minutes and its acquisition attribution leans on the session that produced the conversion.

Twelve days later, the browser session that fires the paid event has no memory of the LinkedIn click, so the revenue is credited to whatever brought the user back that day, usually 'Direct' or an organic search for your brand name.

Longer sales cycles make this worse, not better. A B2B deal with a 45-day evaluation guarantees the acquisition touch and the revenue event live in completely different sessions. See how long sales cycles break standard tracking for the full mechanism.

4. UTM parameters get stripped before the conversion

GA4 derives its channel grouping from UTM parameters and referrer. If the UTMs are lost between the ad click and the signup, GA4 has nothing to group on and defaults to 'Direct'.

UTMs get stripped by redirect chains, by iOS 17 Link Tracking Protection, by ad blockers, and by short-link services that drop query strings on the final hop.

This is a mechanical data-loss problem, not a reporting problem, and it is bigger than most teams estimate. Our breakdown of why UTM parameters get stripped lists every point in the chain where the string can vanish.

Short-link services and QR redirects are frequent offenders: many drop the query string on the final hop, so a click that carried five UTM parameters arrives at your site naked. GA4 then has nothing to group on.

If your newsletter or social links route through a shortener, test one end to end and watch whether the UTMs survive the last redirect before you trust any channel row.

Under GA4 Consent Mode, a visitor who declines analytics cookies produces a modeled or discarded conversion. Ad blockers go further and prevent gtag.js from loading at all, so the purchase event never fires even when a purchase happened.

On a technical SaaS audience, ad-blocker penetration commonly runs 25-40%, which means a quarter to nearly half of your real conversions are simply absent from GA4 before any attribution logic even runs.

6. Default Channel Grouping mislabels what does get through

Even the revenue that survives can land in the wrong row. GA4's Default Channel Grouping applies rigid rules: a utm_medium that isn't exactly cpc, email, social, or one of the other reserved values gets dumped into 'Unassigned'.

A newsletter tagged utm_medium=newsletter instead of email disappears from the Email channel. Paid social tagged utm_medium=paid-social instead of the expected value falls out of the Paid Social bucket.

The revenue is technically present but filed under a label that makes it useless for decisions.

Symptom in GA4Root causeTypical revenue affectedFixable in GA4?
Revenue column shows $0.00 for paid channelsPurchase event fires on a domain GA4 didn't measure40-60% of paid conversionsPartially, with cross-domain setup
Most revenue attributed to 'Direct'UTMs stripped or session expired before payment30-45% of totalNo, structural
Renewals and upgrades missing entirelyNo browser event fires for recurring charges70-80% of ARRNo, structural
Channel shows in 'Unassigned' / '(not set)'utm_medium not a reserved GA4 value5-15% of tagged trafficYes, with custom grouping
GA4 total is far below Stripe totalAd blockers and declined consent drop gtag.js25-40% of conversionsNo, client-side limit

The five most common 'GA4 not showing revenue by channel' symptoms mapped to their root cause and whether GA4 configuration alone can fix them. Figures are typical ranges observed across B2B SaaS accounts connecting Stripe to GA4.

How To Diagnose Which Cause Is Hitting You

You can isolate most of these causes in under an hour with three checks. Do them in order, because each rules out a class of problem and narrows what's left.

Check 1: Reconcile GA4 revenue against Stripe for one week

Pull total revenue from Stripe for a fixed seven-day window and compare it to GA4's total purchase revenue for the same dates. If GA4 is materially lower, you have an event-firing or data-loss problem, not an attribution-grouping problem.

The size of the gap tells you how much is missing before you even ask which channel earned it.

  • GA4 within 5% of Stripe: your event fires reliably; your problem is channel grouping, not data loss.
  • GA4 20-40% below Stripe: ad blockers, consent, or cross-domain session resets are dropping events.
  • GA4 more than 50% below Stripe: recurring revenue and off-session charges aren't firing any event at all.

Check 2: Inspect the referrer on your converting sessions

In the GA4 Traffic acquisition report, add Session source / medium as a secondary dimension and look at what's driving your purchase conversions.

If you see stripe.com / referral, checkout.stripe.com, or an unexpectedly large (direct) / (none), your checkout redirect is severing the session. That is a cross-domain configuration failure, and it is fixable, though the fix is fragile.

Check 3: Audit your utm_medium values against GA4's reserved list

Export the distinct utm_medium values your campaigns use and compare them to GA4's Default Channel Grouping rules. Any medium that isn't a reserved keyword is silently rerouting revenue into 'Unassigned'.

This is the one cause you can fully fix inside GA4 by building a custom channel group, and it's worth doing regardless of what else you deploy.

The measurement gap in numbers

In a reconciliation of 40 B2B SaaS Stripe accounts against GA4, GA4 captured a median of 61% of actual Stripe revenue and correctly attributed only 44% of it to a non-Direct channel. That means for every $100,000 Stripe collected, GA4 could confidently tie roughly $27,000 to a specific marketing channel. The remaining $73,000 was either missing or filed under 'Direct' and '(not set)'.

What You Can Actually Fix Inside GA4 (And What You Can't)

Some of these problems have GA4-native fixes. Most don't, because they stem from the boundary between a browser-session tool and a server-side billing system.

Be honest with yourself about which bucket each of your symptoms falls into before you spend a week on GA4 configuration that can't reach the root cause.

The fixes that work

  • Custom channel groups: remap non-standard utm_medium values so 'Unassigned' revenue lands in the right channel.
  • Cross-domain measurement: add your app and checkout domains to GA4's configured domains so the return trip doesn't reset the session.
  • Server-side GTM: route the purchase event through a server container to survive some ad blockers, at meaningful setup cost.
  • Referral exclusions: exclude stripe.com from referral traffic so returning payers don't overwrite the acquisition source.

The failures no GA4 setting can reach

No GA4 configuration fires a browser event when Stripe silently renews a subscription off-session. No setting recovers the LinkedIn click from twelve days ago when the paying session has no cookie linking back to it.

No custom group un-strips a UTM that iOS 17 removed before the page loaded. These are structural, and they are exactly why connecting Google Analytics to Stripe revenue rarely works no matter how carefully you configure it.

Why the alternatives don't solve this either

Bolting an e-commerce attribution tool onto a SaaS billing model doesn't help, because those tools inherit GA4's assumptions.

Triple Whale and Northbeam are built for Shopify-style one-time carts; they expect a purchase to complete in a session and struggle with recurring MRR, off-session renewals, and the trial-to-paid lag that defines subscription revenue.

HYROS is tuned for high-ticket info-product and DTC funnels and models a single conversion event, not a subscription that expands and renews for years.

ClickMagick and PixelMe track the click well but stop at the signup boundary, leaving you exactly where GA4 left you: clicks on one side, Stripe revenue on the other, and nothing tying a renewal back to its channel.

ToolBuilt forSees recurring MRR?Ties Stripe renewal to original UTM?SaaS billing native
GA4Web sessions / e-commerceNoNoNo
Triple WhaleShopify DTCPartialNoNo
NorthbeamDTC media buyingPartialNoNo
HYROSInfo-product / high-ticketNoNoNo
ClickMagickClick trackingNoNoNo
TrackRev Revenue AttributionSaaS subscriptionsYesYesYes

How common attribution tools handle SaaS revenue that GA4 misses. 'Ties Stripe renewal to original UTM' is the capability that determines whether you can see true channel LTV rather than one-session transaction value.

How TrackRev Handles This

The reason GA4 can't show revenue by channel is that it measures browsers, not billing. Fix it by attributing from the billing system outward instead of the browser session inward.

TrackRev captures the first-party click with its full UTM context, writes that source onto the Stripe customer and every subsequent charge as durable metadata, and reads Stripe itself as the source of truth for revenue.

When a renewal charges off-session eight months later, TrackRev already knows which channel earned that customer, because the attribution lives on the Stripe object, not in a browser cookie that expired the same afternoon.

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.

Because the source of truth is your billing provider, recurring MRR, upgrades, and off-session renewals all carry their original channel, and the trial-to-paid lag becomes irrelevant: the paid charge inherits the acquisition UTM no matter how many days or sessions separate them.

If you want the underlying pattern, see how to attribute Stripe revenue to marketing channels and how UTM parameters and Stripe fit together end to end.

For teams leaving GA4 entirely, our guide to attributing revenue without GA4 covers the migration.

When NOT to use TrackRev for this

TrackRev is the wrong tool if your revenue isn't subscription or Stripe-adjacent.

If you run a one-time e-commerce store on Shopify with physical products, single-session carts, and no recurring billing, a purpose-built DTC platform like Triple Whale or Northbeam will fit your funnel better, and honestly plain GA4 e-commerce tracking may be enough.

TrackRev is also not a full product-analytics suite: if what you actually need is on-page behavior, funnel visualization, heatmaps, and event exploration across your marketing site, keep GA4 or a product-analytics tool for that job.

TrackRev answers one question with authority, which channel created and renewed each dollar of Stripe, Paddle, Polar, or Lemon Squeezy revenue. If that isn't the question keeping you up at night, it isn't the tool you need.

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.