Marketing attribution
How to track UTM campaigns in WooCommerce
WooCommerce tracks UTM campaigns automatically through order attribution. When a shopper lands on a link with UTM parameters and then buys, WooCommerce saves the UTM source, medium and campaign on the order. You see them in the Order attribution box on each order and as "Source: name" in the Origin column. To total orders by campaign, you need an export, SQL or a reporting tool.
The hard part isn't WooCommerce. It's tagging links consistently so the totals mean something. This guide covers what WooCommerce saves, how to build links, how to get campaign totals, and the mistakes that split your data.
How WooCommerce reads UTM parameters
UTM parameters are tags you add to the end of a link, like this:
https://yourstore.com/spring-sale/?utm_source=newsletter&utm_medium=email&utm_campaign=spring-sale
When someone arrives on that URL, WooCommerce's order attribution script reads the tags and stores them in session cookies in the visitor's browser. If they buy in that session, WooCommerce saves the values as order meta. Here's what each one becomes:
| Parameter | Saved as | What to put in it |
|---|---|---|
utm_source |
_wc_order_attribution_utm_source |
Who sent the visit: newsletter, instagram, partner-blog |
utm_medium |
_wc_order_attribution_utm_medium |
The type of channel: email, social, cpc, affiliate |
utm_campaign |
_wc_order_attribution_utm_campaign |
The campaign: spring-sale, black-friday-2026 |
utm_content |
_wc_order_attribution_utm_content |
Which link or creative: header-button, video-1 |
utm_term |
_wc_order_attribution_utm_term |
The keyword, for paid search |
utm_id |
_wc_order_attribution_utm_id |
A campaign ID, if your ad tool uses one |
WooCommerce also saves utm_source_platform, utm_creative_format and utm_marketing_tactic if they're present. Any tagged visit gets the source type utm.
UTM-tagged visits also win over other sources. Under WooCommerce's attribution rules, a UTM visit always replaces the stored source, while a direct visit never does. So a shopper who clicks your email, wanders off, and comes back by typing your address in the same browser session is still credited to the email.
How to tag your links
- Write down a naming list before you start. Three short columns: the sources you use, the mediums, and how you name campaigns. For example: sources
newsletter,instagram,facebook,tiktok; mediumsemail,social,paid-social,affiliate; campaignsseason-product-year. - Use lowercase and hyphens only.
Instagram,instagramandIGbecome three separate rows in every report. - Build each link with a URL builder (Google's Campaign URL Builder is free) or by hand:
?utm_source=…&utm_medium=…&utm_campaign=…. - Tag every link you control: email buttons, social bio links, posts and stories, influencer and partner links, QR codes on packaging and flyers, and ads that don't add their own tracking.
- Test it. Open the tagged link in a private window, place a test order, and check the Order attribution box on the order shows your source, medium and campaign.
Don't tag internal links between pages of your own store. Each tagged click starts a new source, so a tagged banner on your home page would overwrite the real source (say, Google) with your own banner.
Where to see UTM data on your orders
- WooCommerce › Orders: the Origin column shows "Source: newsletter" for UTM-tagged orders.
- The order screen: the Order attribution box shows origin, source type, UTM campaign and medium, device type and session page views.
There's no campaign report in core Analytics. To see how many orders spring-sale brought in, you need totals.
How to total orders by UTM campaign
The full set of options is in how to see which channels bring the most orders. In short: export orders with their attribution meta and pivot them, use WooCommerce's free WooCommerce Analytics extension (separate from core Analytics, with an Orders by Campaign report), ask a tool that reads attribution, or query the database.
For developers: orders by campaign in SQL
This joins the Analytics order table to the campaign meta, on an HPOS store (wp_wc_orders_meta):
SELECT COALESCE(NULLIF(c.meta_value, ''), '(no campaign)') AS campaign,
COUNT(*) AS orders,
ROUND(SUM(s.net_total), 2) AS net_sales
FROM wp_wc_order_stats s
LEFT JOIN wp_wc_orders_meta c
ON c.order_id = s.order_id
AND c.meta_key = '_wc_order_attribution_utm_campaign'
WHERE s.parent_id = 0
AND s.date_created >= '2026-10-01' AND s.date_created < '2026-11-01'
AND s.status NOT IN ('wc-pending', 'wc-failed', 'wc-cancelled', 'wc-refunded', 'wc-checkout-draft')
GROUP BY campaign
ORDER BY net_sales DESC;
On posts storage, use LEFT JOIN wp_postmeta c ON c.post_id = s.order_id AND c.meta_key = '_wc_order_attribution_utm_campaign'. Change wp_ if your prefix differs, and match the status list to your Analytics › Settings › Excluded statuses. Most orders won't have a campaign (organic, referral and direct visits don't), so expect a large (no campaign) row.
UTM mistakes that split or lose your data
- Inconsistent spelling.
emailandEmailare different mediums. So arebf-2026andblack-friday-2026. - Untagged social links. A link in your Instagram bio without UTMs shows up as a referral from an Instagram domain, or as Direct if the app didn't pass a referrer. Tag it, as explained in comparing Instagram and email revenue.
- Redirects that drop the query string. Link shorteners and some redirect plugins strip
?utm_…. Test the final URL, not the short one. - Expecting multi-day memory. WooCommerce's attribution cookies last for the browser session. A customer who clicks your email on Monday and buys on Thursday in a new session may show as Direct or Organic.
- Consent banners. If your consent tool works with the WP Consent API, visitors who decline marketing cookies aren't tracked, and their orders show as Unknown. See why attribution says Unknown.
The quick way: ask Askshelf
Askshelf adds Analytics › Askshelf to WordPress admin. Its "orders by channel" lookup reads the attribution meta WooCommerce saved, and groups orders and net sales by UTM source, UTM medium or UTM campaign (or by source type or device) for any date range, with an optional comparison period.
Which UTM campaigns brought the most revenue in October?
It groups by the values as stored, so inconsistent spelling shows up as separate rows (which is a quick way to find it). It doesn't group by utm_content or utm_term, and it doesn't calculate ad spend return or profit. More examples are on the order attribution use case page.
What to do with campaign totals
- Compare against a baseline, not against zero. A campaign that brought 40 orders during a week you'd normally get 35 did less than it looks. How to measure a sale or campaign covers this.
- Look at net sales, not just orders. A campaign full of small discounted orders can lose money. If it used a coupon, see how to tell if a coupon paid off.
- Keep your naming list next to your email tool so the next campaign uses the same words.
- Read the hub on WooCommerce order attribution for how UTM data fits with organic, referral and direct orders.
Common questions
Do I need a plugin to track UTM parameters in WooCommerce?
No. Since WooCommerce 8.5, order attribution reads UTM parameters from the landing URL and saves them on the order. You only need something extra to add up the totals, because core Analytics has no attribution report.
Which UTM parameters does WooCommerce save?
utm_source, utm_medium, utm_campaign, utm_content, utm_term and utm_id, plus the newer utm_source_platform, utm_creative_format and utm_marketing_tactic. The order screen shows source, medium and campaign.
Are UTM values case sensitive in WooCommerce?
WooCommerce stores what the link contains, so Newsletter and newsletter end up as two different sources in any grouping. Pick lowercase and stick to it.
See how Askshelf handles this: Order attribution reports for WooCommerce