Google Analytics 4 not showing revenue by channel: four checks that find the cause

Google Analytics 4 shows no revenue by channel when the purchase event lacks a value, UTMs get lost, or Stripe renewals skip the browser. Four checks find it.

Muzahid Maruf — Founder of TrackRev.io

Muzahid MarufUpdated

Attribution · 10 min read
On this page
  1. 01GA4 not showing revenue by channel: match your symptom
  2. 02What you can fix in Google Analytics 4 and what you cannot
  3. 03Reading revenue by channel from Stripe instead

Explore with AI

Opens this article inside the chosen assistant with a ready-made prompt.

If Google Analytics 4 is not showing revenue by channel, one of four things is usually behind it: the purchase event lacks a value or currency, it arrives with no campaign source, the report credits a different scope, or the money never passed through a browser, as with every Stripe renewal.

Configuration fixes clear the Direct, Unassigned and (not set) rows in an afternoon. Renewals, refunds and any trial longer than 7 days need events that Stripe creates and the Google Analytics tag never sees.

Key takeaways

  • Google Analytics 4 counts a purchase toward Total revenue only when the event carries both a value and a currency.
  • Stripe renewals, trial conversions and refunds fire no browser event. A $29 plan paid 12 times leaves Google Analytics 4 holding 1 payment, 8.3% of the year's revenue, unless your server posts the rest.
  • Stripe as a referrer, Unassigned and (not set) rows are configuration problems. The fixes inside Google Analytics 4 are an unwanted-referrals entry, a custom channel group or a Session dimension.
  • Traffic acquisition, User acquisition and Model comparison credit 1 sale to 3 different channels, because their user, session and event scopes differ.
  • A 14-day trial is 336 hours, 7 times Google's 48-hour Measurement Protocol guidance and twice the 7 days Apple Safari keeps a script-written cookie.
  • TrackRev reads revenue from Stripe and joins each charge to the original click by email, from $29 a month, while Google Analytics 4 stays in place for on-site behavior.

GA4 not showing revenue by channel: match your symptom

What you see in Google Analytics 4Usual causeWhere to look
Total revenue is $0.00 on every rowPurchase event missing, or sent without a value or currencyCheck 1
Revenue appears a day lateProcessing runs up to 24 to 48 hoursCheck 1
Google Analytics total far below StripeRenewals, trial charges and refunds fire no browser eventCheck 2
Most revenue under DirectCookie lost, UTMs stripped, domains not linkedCheck 3
Revenue under stripe.com / referralcheckout.stripe.com missing from unwanted referralsCheck 3
Revenue under Unassignedutm_medium matches no default channel ruleCheck 3
Source and medium read (not set) beside revenueEvent-scoped dimension used on a non-key eventCheck 4
2 reports name different channels for 1 saleSession, user and event scopes credit differentlyCheck 4

Check 1: Does the purchase event carry a value and a currency?

Open DebugView, send 1 test purchase and expand the event. Google's help page for the Traffic acquisition report says a purchase sent without both parameters never reaches Total revenue.

FieldWhat Google expectsExample: $39 plan, $3.12 tax
valuePre-tax amount, with shipping and tax left out39, never 42.12
currencyISO 4217 code, required whenever value is setUSD
transaction_idUnique per order, because matching IDs are deduplicated1 per order, never an empty string

From the purchase event reference and the transaction ID page. Deduplication works on web streams only.

Purchase data lags in reports, and the data freshness page lists 2 to 6 hours for intraday data, 12 hours for daily data on a standard property and 24 to 48 hours for full processing.

Stripe Checkout runs on Stripe's page

A Stripe Checkout page cannot run your tag.

Stripe's conversion funnel guide tags 3 pages (product, success and canceled) and counts begin_checkout events and success views, none with an amount, so build the revenue event on the success page or on your server.

End success_url with ?session_id={CHECKOUT_SESSION_ID}, as Stripe's redirect documentation shows, and look up the Checkout Session for its amount.

Success page: a purchase event with revenue
// after your server returns the Checkout Session for session_idgtag("event", "purchase", {  transaction_id: "cs_live_a1B2c3",   // Checkout Session ID, unique per order  value: 39.0,                        // pre-tax amount in major units  currency: "USD",  items: [{ item_id: "starter-monthly", item_name: "Starter plan" }],});

A success page can be reloaded or never reached, so it undercounts and double counts, and transaction_id fixes only the second.

A trial subscription counts as paid once its $0 trial invoice is processed, per the Checkout Session reference, so on day 1 the page has no revenue to report.

Check 2: Do Stripe's paid invoices match Google Analytics 4?

Export 7 days of paid invoices from the Stripe Dashboard and compare the count and pre-tax total with the Ecommerce purchases report. Stripe reports the smallest currency unit, so 3900 means $39.00.

Renewals, refunds and off-session charges

Stripe charges month 2 from a saved card with no browser open, and refunds the same way, so no tag fires for either.

Unless your server posts 1 purchase per paid invoice plus a refund event with the original transaction_id, Google Analytics adds a subscription's revenue once and never subtracts it.

Worked example: 40 subscribers at $29

A cohort of 40 customers clicks a Google Ads link and each chooses a $29 monthly plan. The success page reports 40 purchases and $1,160 in month 1. Over 12 months Stripe collects $13,920. Google Analytics holds $1,160 of it, 8.3%, and the other 11 payments per customer sit in Stripe with no channel row to land in.

Google asks that Measurement Protocol events joined to browser events arrive within 48 hours of the client-side event, and warns that later ones may not process as expected for conversion attribution.

A month 2 renewal lands about 720 hours after the click. UTMs on Measurement Protocol purchases can also override a Google Click ID source, so copy them only for a new campaign interaction.

The 6-step build for posting Stripe invoices to GA4 covers the webhook.

Trials longer than a week

Take a $29 plan with a 14-day trial and a Google Ads click on day 0. The hours between the click and each payment decide what Google Analytics can credit.

PaymentDayHours after clickInside 48 hoursAmount
Trial starts on the success page00Yes$0
Charge 114336No$29
Charge 2441,056No$29
Charge 123448,256No$29

Hours counted from the click, with 30-day months. The 48-hour limit is Google's Measurement Protocol guidance.

Session rules still allow credit: a direct return takes the last non-direct source the browser remembers, per Google's referral exclusion page, and Google says the key event lookback window, 90 days by default for most events, also applies to session attribution.

The cookie is the weak link.

Google Analytics 4 writes _ga from JavaScript, Google's cookie documentation says Apple Safari limits first-party cookies to 7 days without a return visit (Google Chrome allows 400), and WebKit's policy says Intelligent Tracking Prevention deletes script-written cookies after 7 days without interaction.

A Safari visitor who returns on day 12 arrives as a new user, and the paying session is credited to whatever brought that visit, often Direct.

In my view a trial longer than 7 days is where Google Analytics 4 stops working as a revenue tool.

A visitor who blocks the tag sends nothing to Google Analytics.

A visitor who declines cookies shows up only when consent mode modeling covers the property, and Google's behavioral modeling page sets the bar at 1,000 events a day with analytics_storage denied for 7 days plus 1,000 daily users with it granted on 7 of the previous 28 days.

Modeling covers user, session and new-user counts. A site that rarely reaches 1,000 consenting users a day cannot qualify.

Check 3: Where does the revenue sit?

Open Traffic acquisition, set the dimension to Session source / medium and read Total revenue to see which row holds the money.

Direct

Google Analytics 4 labels a session Direct when the source is exactly (direct) and the medium is (not set) or (none).

Google's page on (direct) / (none) traffic lists links without UTMs, redirects that strip them, shorteners such as bit.ly, typed URLs, offline documents and ad blockers, so some Direct revenue is genuine.

Checkout adds one more. Without cross-domain measurement each domain creates its own IDs, so 1 visitor moving from your marketing site to a billing domain becomes 2 users and 2 sessions unless a _gl linker parameter carries the IDs across.

Stripe as a referrer

A return from Stripe Checkout can arrive with checkout.stripe.com as the referrer and be filed as a referral. Add the domain to the unwanted referrals list on the web stream, which holds up to 50 entries.

Unassigned

Google Analytics 4 files a session under Unassigned when no channel rule matches, and the default channel group rules are literal about spelling.

Email needs the word email, or a variant such as e-mail, in the source or medium, Affiliates needs the medium affiliate, and Paid Search, Paid Social and Paid Video need a listed source plus a medium matching cp, ppc, retargeting or a paid prefix.

utm_source / utm_mediumChannel assignedRule that decides it
weekly-digest / emailEmailMedium is email
weekly-digest / newsletterUnassignedNo rule matches the word newsletter
acme-partners / affiliateAffiliatesMedium is affiliate
acme-partners / partnerUnassignedNo rule matches the word partner
acmeads / cpcPaid OtherA cpc medium with a source outside Google's lists

Applied from Google's default channel group rules, October 2026. Source names are examples.

The default group cannot be edited. Tag new links with the mediums in the free UTM builder and cover live ones with a custom channel group.

A standard property holds 2 of them, with up to 50 channels each, and they apply retroactively.

Check 4: Which report and scope are you reading?

Three reports can credit 1 sale to 3 channels, and each is correct by its own rule.

ReportDimensionScopeWhat it credits
Traffic acquisitionSession default channel groupSessionThe current session, reset after 30 minutes of inactivity or on a return visit
User acquisitionFirst user default channel groupUserThe channel that first brought the user, fixed for good
Model comparisonDefault channel groupEventKey events only, by data-driven or last click credit, with a 90-day default lookback

Scopes as defined on Google's traffic-source scopes page, October 2026.

User and session scopes use the paid and organic channels last click model and ignore the attribution setting.

Event-scoped reports follow it, but since November 2023 the choices are data-driven and last click, so the First user dimensions answer what introduced a customer.

A subscriber who first arrived through Organic Search in March, then clicked a Paid Search ad in April and paid in that session, shows as Organic Search in User acquisition and Paid Search in Traffic acquisition.

Unprefixed Source and Medium are event-scoped and read (not set) for non-key events, so use Session source and Session medium, or mark purchase as a key event.

What you can fix in Google Analytics 4 and what you cannot

CauseFix inside Google Analytics 4Google's limitWhat it recovers
Purchase sent without value or currencyAdd both parameters to the eventNonePurchases from the day it ships
checkout.stripe.com as a referrerAdd it to unwanted referrals50 per streamReferral handling from the change
Unassigned channelCustom channel group2 per standard property, 50 channels eachPast and future data
(not set) beside revenueSwitch to Session source / mediumNonePast data
Domains not linkedCross-domain measurement with _gl100 conditionsNew sessions
Renewals and refundsPost purchase and refund events from a webhook48 hours after the browser eventSales inside that 48-hour window
Blocked tags, declined consentConsent mode modeling, for declined consent only1,000 events a dayEstimates for users and sessions

Reading revenue by channel from Stripe instead

The alternative reverses the order: record the click first on a tracked link, read the payment from Stripe afterward, and join the two, so no browser ID has to survive a 14-day trial.

TrackRev, the affiliate software with revenue attribution built in, works this way, with a read-only restricted Stripe key and a 1-line pixel that binds each visitor to an email at signup or checkout.

It joins each paid charge to a click through that email, syncs new charges every hour, and credits every renewal to the channel of the original click, so month 12 of the $29 example lands with month 1.

Paddle Billing, Polar, Lemon Squeezy, Creem and Dodo Payments connect as well.

Revenue figures need a paid plan from $29 a month on Indie, while the free plan covers link tracking only, with 50 links and 1,000 tracked events a month. Credit rules are first click, last click or linear.

Because the join runs on email, test the buyer who pays under another address first. TrackRev does not measure page engagement or on-site funnels, so keep Google Analytics 4 for those.

For one-time purchases on your own domain, where the first payment is the whole sale, Google Analytics 4 alone is enough, and a team that wants only standalone attribution without a partner program may find another tool fits better.

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 founded TrackRev.io, SaaS affiliate software with no limit on tracked revenue, and Contant.io. He writes about affiliate programs.

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

Stop guessing where your revenue comes from.

Set up TrackRev in about five minutes. The free plan covers 1,000 events a month, no card needed.

Start free