Why Half Your WooCommerce Orders Say "Direct" (and How to Fix It)
Why WooCommerce orders say Direct: the built-in Order Attribution cookie is session-only, so returning buyers lose their traffic source. Fixes and limits.
Tilen Ledic
Written by
Open your WooCommerce orders list and look at the Origin column. If you are like the store owner in the WooCommerce support forum who found "more than half" of orders marked Direct, your first instinct is probably the right one: there is no way half your customers typed your address into the browser.
They did not. Most of them clicked an ad or a Google result days earlier. WooCommerce orders say Direct because the built-in Order Attribution cookies are session-only: the browser closes, the cookie dies, and the returning buyer's real traffic source is gone. WooCommerce forgot, and it forgot by design.
What WooCommerce Order Attribution Actually Is
Since WooCommerce 8.5 (January 2024), every store has a built-in attribution feature, on by default. It records where each order came from: the Origin column in the orders list, an "Order attribution" panel on every order (source, campaign, device, session pages), and, with the free WooCommerce Analytics extension, channel and campaign reports.
To be clear: this feature existing is a good thing, and you should have it on. It is free, it runs on your own server data, and session-level last-click information beats flying blind. The problem is what it cannot see, and that problem is bigger than the docs make obvious.
Why WooCommerce Orders Say "Direct": the 0.00001 in the Code
WooCommerce tracks the visitor's source with a small library (sourcebuster.js) whose cookies, by the library's own default, live for six months. WooCommerce overrides that lifetime with a value you have to read twice:
wc_order_attribution_cookie_lifetime_months = 0.00001
That is in the WooCommerce source code: a fraction of a minute, which effectively makes the cookies session-only. Woo's own documentation says it plainly: this feature "cannot be used to track your visitors across sessions". (Why so short? The launch caused a GDPR backlash, and Woo shortened the cookies in response.)
The consequence plays out in almost every real purchase journey:
Monday's ad click sets the cookie. Monday evening the browser closes and the cookie dies. Friday the customer comes back (from memory, a bookmark, typing your name) and buys. WooCommerce truthfully reports what it saw on Friday: Direct. The ad that created the sale gets nothing, and if that buyer was new, "Direct" is stamped as their origin forever. Cross-device journeys (phone click, desktop purchase) lose attribution the same way, every time.
Why Some WooCommerce Orders Say "Unknown"
"Unknown" is the other confusing label, and it has five documented causes: orders placed before the feature was enabled; consent management plugins (CMPs) blocking the tracking script entirely (a known issue); cached checkout pages serving empty attribution fields; an open timing regression where valid UTM sessions still record Unknown; and, the big silent one, express checkouts: orders paid via Apple Pay or Google Pay buttons save empty attribution, because they bypass the normal checkout flow entirely.
The 10-Minute WooCommerce Order Attribution Setup Check
- Confirm Order Attribution is on: WooCommerce → Settings → Advanced → Features → Order Attribution (default on since 8.5).
- Read your Origin column for the last 50 orders and count Direct + Unknown. That share is your data-quality KPI; for most ad-running stores it is uncomfortably large.
- Install the free WooCommerce Analytics extension for channel-level reports instead of eyeballing the column.
- Know what is NOT in there: no click IDs (gclid or fbclid are not stored as fields; at best they survive incidentally inside the landing-page URL), no cross-session memory, no cross-device stitching.
Optional hardening for developers: both the cookie lifetime and the 30-minute session length are filterable (wc_order_attribution_cookie_lifetime_months, wc_order_attribution_session_length_minutes). Extending them improves continuity, with three honest caveats: it re-raises the consent questions that made Woo shorten the cookies in the first place, Safari's ITP still caps script-set cookies at 7 days no matter what the filter says, and it does nothing for cross-device journeys or express checkouts. For capturing gclid properly, see our click-ID capture guide.
How Enalitica Fixes WooCommerce Attribution Gaps
We built our WooCommerce attribution around exactly these gaps, and the fixes are mechanical, not modeled:
- 90-day first-party memory. Our tracking script stores click IDs (gclid, fbclid, and the rest), UTM parameters and the original marketing landing URL in first-party cookies that survive browser restarts. Monday's ad still gets Friday's order.
- We repair Woo's own fields, conservatively. At checkout, when Woo's attribution inputs are blank or "typein", we fill them from that 90-day memory, never overwriting a genuinely captured source. Your Woo admin's Origin column improves too, not just our reports.
- Express checkouts included. Our order-meta snippet hooks both checkout paths, classic and the Store API used by Apple Pay / Google Pay buttons, so the orders Woo saves with empty attribution still arrive with click IDs and their real source. As far as we know, no other tool covers this path.
- The click ID lives on the order. Once captured, it is order metadata: permanent, auditable, and the basis for attribution that reconciles to real orders, keyword-level Google Ads detail, and profit per campaign.
The philosophy difference is simple: Woo's feature describes the session that placed the order, honestly but forgetfully. Enalitica describes the customer journey that earned the order, and writes the evidence onto the order itself.
Frequently Asked Questions
Should I turn WooCommerce Order Attribution off?
No. Free, native, session-level data is strictly better than nothing, and other tools (including ours) can read what it captures. Just do not make budget decisions from its Direct share, because a large part of that "Direct" is forgotten ads.
Why did my Direct share jump even though nothing changed in my marketing?
Common culprits: a consent-mode or caching change on your site, a new express-checkout button (Apple Pay / Google Pay orders save empty attribution), or simply more returning buyers, whose repeat sessions legitimately start direct. Check the Unknown share alongside; the two together tell you whether it is a tracking problem or a customer-behavior pattern.
Does WooCommerce store the gclid?
Not as a field. Attribution stores UTM parameters and a referrer-derived origin; a gclid can incidentally survive inside the stored landing URL, but nothing parses it and it dies with the session cookie. If you run Google Ads, capture the gclid into order meta explicitly, via a snippet, a plugin, or Enalitica's tracking, which does it automatically.
Can I trust the Origin column for judging campaigns?
Use it directionally, never proportionally. It is last-click within a single browser session, with no last non-direct click memory across sessions, so it systematically over-credits brand search and direct, and under-credits the prospecting ads that start journeys. For spend decisions you need attribution with cross-session memory and, ideally, profit per campaign.
I use Enalitica. Do I still need Woo's attribution on?
Yes, leave it on. We read Woo's attribution as one of our signals and repair it where it is blank, so the two work together: your Woo admin stays informative, and Enalitica adds the 90-day memory, click IDs, express-checkout coverage, and order-reconciled reporting on top.
See your real numbers
Import 30 days of orders or leads instantly during 5-minute onboarding. Works for e-commerce and service businesses.
Start free