unattributed revenue SaaS
How to Reduce Unattributed Revenue in Your SaaS Funnel
Unattributed revenue is real money you cannot explain. A diagnostic guide to finding the instrumentation gaps that turn paying customers into 'direct' traffic.
Open most SaaS attribution dashboards and the largest single 'source' is usually direct or unknown. For a first-week founder that might be intuitive. For a SaaS with steady traffic, real paid signups, and a working checkout, it is almost always wrong.
Unattributed revenue is rarely true direct. It is the trace of a real marketing journey that your instrumentation failed to capture. This guide walks through the four standard reasons that happens and the order to fix them in.
What unattributed revenue actually is
Unattributed revenue is a payment recorded in your payment provider where no defensible link to a marketing source survived to the moment of payment. The buyer was real. The marketing context was lost somewhere upstream.
Loss happens in four standard places. Either there was no first-party session tracking at all, or the session ID never made it into the checkout, or the webhook listener could not match the payment back, or the buyer signed in from a different device and the identity was never stitched.
Each of these is fixable. Each fix shrinks the unattributed bucket, exposes channels that were always working, and sharpens every later decision about content and pricing.
Why this matters more than it sounds
When most of your revenue is labelled direct, every channel report is a guess. You cannot evaluate a content investment if you cannot see whether it drove revenue. You cannot defend a paid spend if 'direct' is silently absorbing its conversions. You cannot decide which AI-search page to write next if AI traffic looks invisible.
Founders sometimes respond to a confusing report by spending more on the loudest channel. That is the wrong move. The right move is to shrink the unattributed bucket so the rest of the report is interpretable.
Leak #1 — No first-party session tracking
If you rely on a third-party analytics tool only, ad blockers, Safari ITP, and privacy-focused browsers will drop a meaningful percentage of sessions. The dropped sessions never see your tracker, so the buyer arrives at checkout as a stranger.
The fix is a first-party tracking script on your own subdomain. The script sets a random visitor ID in localStorage and sends events to your own ingestion endpoint. Because the request goes to your domain, it survives the common blocking lists.
Metrivo's tracker is built for this. The Sebastian script is small, asynchronous, and stores anonymous visitor/session IDs in localStorage. No third-party cookies, no cross-site tracking, no session replay, no heatmaps. Privacy-friendly by default.
Leak #2 — No metadata at checkout
The single most common cause of unattributed revenue is that the visitor ID never makes it into the payment provider. The buyer lands on the marketing site with a clean session, then clicks 'Subscribe', the server creates a Stripe Checkout Session (or Dodo/Razorpay/Paddle/Lemon Squeezy equivalent), and nobody attaches the visitor ID to the payment object.
When the webhook fires, the payment has no marketing context. The matcher has nothing to match on. The payment lands as direct.
The fix is small: set the visitor ID (and optionally session ID and landing URL) in the checkout session metadata at creation. For subscription products, also set it on the customer object so renewals inherit attribution.
Leak #3 — No webhook listener with confidence labels
Some teams collect first-party sessions and pass metadata into checkout but never run a server-side webhook listener. Payment events arrive at the payment provider and never reach the attribution layer. Revenue is real; reporting is incomplete.
The fix is a signed webhook handler per provider that verifies the signature, writes payment rows to your database, reads the metadata, and triggers a matcher. Use confidence labels so unknown stays unknown and high-confidence matches are flagged as such.
Metrivo's webhook integrations for Stripe, Dodo, Razorpay, Paddle, and Lemon Squeezy do all of this end to end. The Manual Payment API offers the same shape for custom checkouts.
Leak #4 — No identity stitching at signup
The hardest leak is the cross-device journey. A buyer reads about your product on a phone, signs up later on a laptop, and pays from yet a third device. Each event arrives with a different anonymous visitor ID. None of them connect unless your application server explicitly stitches them.
The fix is to associate the current visitor ID with the user record at signup, then with any future authenticated session. From that point on, any event by that user — including events from devices and sessions that come later — can be linked back to the original visitor.
There is no perfect stitching. A user who never signs in stays anonymous. The honest report shows that.
Confidence labels are part of the fix
Even after all four leaks are fixed, some payments will still arrive with weak or missing evidence. The right response is not to inflate the report. It is to expose the confidence breakdown so the team can see exactly where evidence is strong and where it is not.
Metrivo uses four labels. High: exact session or customer match. Medium: hashed-email match across sessions. Low: UTM or referrer hint only. Unknown: no usable join. Reporting that surfaces this structure is safer to defend and easier to act on.
The 30-day plan to shrink unattributed revenue
Week 1: Install or verify the first-party tracking script. Confirm sessions are being recorded with referrer, UTM, landing page, and an anonymous visitor ID.
Week 2: Add metadata to checkout. Pass visitor ID and session ID into Stripe/Dodo/Razorpay/Paddle/Lemon Squeezy checkout sessions or into the Manual Payment API. Set the same metadata on the customer object.
Week 3: Deploy webhook listeners. Verify signatures, write payment rows, use idempotency keys, and trigger the matcher. Surface confidence labels in your reporting.
Week 4: Add identity stitching at signup. Link the current visitor ID to the user record. Confirm that future authenticated sessions inherit the prior session.
By the end of 30 days, the unattributed share usually drops sharply. The remaining unknown bucket is genuinely unknown — and that is OK.
What not to do
Do not relabel direct traffic as your favourite channel. That is the single fastest way to turn a useful report into a misleading one.
Do not buy a new marketing channel before the existing report is interpretable. You will be making decisions in fog.
Do not chase a zero unattributed number. Some revenue legitimately has no usable source signal. The goal is to shrink the bucket honestly, not to drive it to zero with fiction.
Do not skip the audit step. A 30-minute review of where evidence drops in your funnel is worth more than a month of analytics work after the fact.
How Metrivo helps end to end
Metrivo's product is built around exactly this loop. The tracking script handles the first-party session layer. Payment integrations handle the webhook layer with signature verification, idempotency, and tenant-scoped writes. The matcher handles confidence labels. The Revenue Leak Agent flags pages and funnel steps where evidence is suspiciously sparse so you can fix instrumentation before redesigning anything.
Just as important, the product is conservative about what it claims. Unknown revenue stays unknown. AI-search labels require confirmable signals. Fix drafts require human review. None of this is romantic; it is what makes the report defensible.
When the $99 audit is the right next step
If your unattributed revenue share is over 60% and you cannot explain it, the audit is the fastest way through. The deliverable is either a specific leak with confidence and a recommended fix, or a missing-data report that tells you which instrumentation step to add first. Either outcome is more useful than another week of guessing.
Frequently asked questions
What counts as unattributed revenue in a SaaS funnel?
Unattributed revenue is any payment recorded in your payment provider that cannot be linked to a defensible marketing source. For most SaaS sites, it is the bucket called 'direct' or 'unknown' in channel reports — but the real cause is almost always missing instrumentation, not a true direct customer.
Why is my SaaS direct traffic so high?
In most cases the real source was lost between session and payment. The four standard causes are no first-party tracking, no checkout metadata, no server-side webhook listener, and no identity stitching at signup. Each of these can be fixed in a week or less.
Should I relabel direct traffic as my best channel?
No. Relabelling is the fastest way to destroy report credibility. Use confidence labels (high, medium, low, unknown), shrink the unknown bucket by fixing instrumentation, and accept that a small residual will remain genuinely unknown.
How does Metrivo handle unknown revenue?
Metrivo leaves unknown revenue in its own bucket. Payment totals are accurate; channel assignment requires evidence. The report exposes the confidence breakdown so founders can see exactly where evidence is strong and where it is missing.
What is the first fix if 70% of my revenue is direct?
Add metadata to your checkout creation calls. Pass a first-party visitor ID into the Stripe, Dodo, Razorpay, Paddle, or Lemon Squeezy checkout session and into the customer object. This single change usually moves a large share of revenue out of the direct bucket within two to four weeks.
