Tracking & Attribution

How Do You See Which WooCommerce Orders Came From a Specific Facebook Ad?

Ads Manager counts purchases per ad but never names the orders. Here's how to see the exact WooCommerce orders, buyers and revenue behind one Facebook ad.

Quick answer

Put the ad's name or ID into the ad URL, store it when the shopper lands, and match each paid WooCommerce order back to that stored visit. Meta Ads Manager reports purchase counts per ad but never lists order numbers, and the fbclid on the click is opaque outside Meta. Add utm_content={{ad.name}} or {{ad.id}} through Meta's URL parameters, then join orders to visits by visitor ID or email.

Tell us what's broken. We'll fix your tracking — free.

Describe the tracking/attribution problem you're stuck on and we'll map it to a fix: server-side conversions to Meta, Google, TikTok and Pinterest, plus first-party tracking that survives Safari. No code required.

To see which WooCommerce orders came from a specific Facebook ad, you have to name the ad in its landing URL, store that name when the shopper arrives, and join each paid order back to the stored visit. Meta Ads Manager reports purchases per ad as a count and a value. It never lists which orders those were, and your store can’t read an ad name out of a Facebook click ID.

So the order list you want doesn’t exist in either tool yet. You build it with a join.

Below: why Meta can’t show you order numbers, how to get the ad name onto each visit, how to join orders to it, why your count won’t match Meta’s, and where the join still breaks.

Why can’t Meta Ads Manager show you the orders behind an ad?

Because Meta reports conversions as aggregates, not as a list of buyers. Ads Manager can tell you an ad drove 8 purchases worth $640 inside your attribution setting. It won’t tell you those were orders #4821, #4830 and six others, or who placed them. Your store holds the orders but only knows what the landing URL told it.

That split is by design. Meta matches a purchase event to a person on its side, credits it to an ad, and shows you the total. The link between a specific order and a specific ad lives inside Meta and isn’t exported.

Your WooCommerce store sees the other half. When a shopper clicks a Facebook ad, Meta appends an fbclid to the URL. That value is a click identifier for Meta’s matching, not a label. Inside your store it’s a long random string. It carries no campaign, ad set or ad name you can read. Only UTM parameters you set yourself name anything outside the platform.

So you end up with two true reports that don’t meet:

  • Ads Manager: “Ad: UGC video v3, 8 purchases, $640.”
  • WooCommerce: “Order #4821, $79, Origin: Facebook” or “Unknown”.

Nothing says #4821 was one of the video’s 8.

How do you get the ad’s name onto the visit?

Add UTM parameters to every ad through Meta’s URL parameters field, using its dynamic placeholders so they fill in at click time. Put the ad in utm_content, the ad set in utm_term and the campaign in utm_campaign. Meta swaps each placeholder for the real value when someone clicks, so the landing URL names the exact ad.

A parameter string that works for most stores:

utm_source=facebook&utm_medium=paid_social&utm_campaign={{campaign.name}}&utm_term={{adset.name}}&utm_content={{ad.name}}

A shopper then lands on a URL like:

https://yourstore.com/product/linen-shirt/?utm_source=facebook&utm_medium=paid_social&utm_campaign=Prospecting+Sept&utm_term=Broad+25-44&utm_content=UGC+video+v3&fbclid=IwAR...

Three details decide whether this holds up.

Names versus IDs. {{ad.name}} is readable, but it changes when someone renames the ad, and two ads can share a name. {{ad.id}} never changes. A safe pattern is the ID in utm_content and a readable name in your own lookup sheet, or the name if your team never renames ads mid-flight.

Check every ad. The URL parameters field is set per ad, so one ad built without it breaks the chain for its orders. Spot-check a few live ads, especially ones created by a different teammate or agency.

Test the landing URL. Click a live ad and confirm the parameters reach the page the shopper actually sees. Redirects, language switchers and some cache setups drop query strings before the page loads.

Diagram of a Facebook ad click URL carrying utm_content with the ad name and an fbclid, stored on the landing visit, then joined to a paid WooCommerce order by visitor ID and email so the order row shows which ad it came from

Doesn’t WooCommerce’s own order attribution already do this?

Partly. WooCommerce’s built-in order attribution records the source of the buyer’s visit on each order, including utm_campaign, utm_content and utm_term when the landing URL had them. So once your ads carry the parameters above, an order’s attribution panel can show which ad it came from. The weak points are timing and history.

WooCommerce’s own source code lists the fields it stores: source type, referrer, the UTM fields including utm_content, the session entry page, pages viewed and visit count (WooCommerce on GitHub). That’s genuinely useful. It also has three limits you should know before you trust it for ad-level reporting.

It keeps one touch. Each order stores one source, read from the visitor’s tracking cookie at checkout. If the buyer clicked the ad on Monday and came back on Thursday by another route, you see one of those visits, not both.

It lives in the browser. The source reaches the order through a script and hidden checkout fields. Ad blockers, deferred JavaScript, cached checkout pages and consent timing can leave those fields empty, and the order is saved as Unknown.

It doesn’t cross devices. A shopper who clicked the ad on their phone and bought on a laptop arrives at checkout with a fresh browser and no ad in its history.

For a quick look it’s fine. Open the orders whose origin says Facebook and read utm_content in each order’s attribution panel. For a weekly “which ads made money” report, you need the join to work across visits and devices.

How do you join orders back to the ad across visits?

Store the UTMs on the visitor when they land, and when a paid order arrives, find that visitor again by browser ID, email or phone. The ad on their landing visit becomes the ad on the order. The return visit that actually placed the order may carry nothing, so you need the earlier visit, not the last one.

A typical path:

  1. Monday: the shopper taps your UGC video ad on Instagram. The URL carries utm_content=UGC+video+v3.
  2. They view two products, add one to cart, and leave.
  3. Thursday: they search your store name on a laptop, return, and buy.

Thursday’s visit has no UTMs and a different browser. To credit the video, you need something that ties Monday’s visitor to Thursday’s buyer: the email they entered on Monday, matched to the email on the order. That kind of stitching is what visitor identity resolution does.

The do-it-yourself version is a spreadsheet. Export paid orders with emails. Export any email captures from your forms that stored UTMs. Match on email. It works for buyers who gave you an email before buying, it misses everyone else, and you redo it every week.

Why won’t your ad-level order count match Meta’s?

Because the two systems count different things. Meta credits purchases to an ad inside your attribution setting, which covers a set number of days after a click and can include views (Meta Business Help Center). Your join credits orders to the ad the buyer’s stored visit carried. Those rules overlap, but they aren’t the same rule.

That’s why “Meta says 8, I count 10” is normal. Common reasons:

  • Windows. Your join has no click window. An order three weeks after the click still carries the ad. Meta stops crediting once the purchase falls outside your attribution setting.
  • Views. Meta can credit a purchase to someone who saw the ad and didn’t click. That buyer’s landing URL never carried your UTMs, so your join can’t credit it.
  • Unpaid orders. A browser pixel can fire on the thank-you page for orders that later fail or get cancelled. Your join should only count orders that were paid.
  • Other paths. A buyer who clicked your ad and then a Google ad can appear in both platforms’ numbers.

Neither number is wrong. Meta’s tells you how its delivery system scored the ad. Yours tells you which paid orders a stored visit actually connects to that ad. The breakdown of why Meta shows more conversions than your CRM covers the reverse gap, and the same causes run both ways.

How does PartialLeads show the WooCommerce orders behind each Facebook ad?

It stores the ad on the visit and carries it to the order. The PartialLeads tag reads the UTMs, fbclid and landing page on arrival. When WooCommerce reports a paid order, PartialLeads matches it to the visitor by visitor ID, then email, then phone, then IP, and writes a first-touch and a last-touch attribution row with that visitor’s source, campaign and content.

The order comes from WooCommerce, not a thank-you page. Orders arrive through the store’s webhook once they reach processing or completed. Pending, on-hold, failed and cancelled orders aren’t recorded as purchases, so your ad-level revenue only counts money that came in. The guide to attributing ecommerce revenue to the ad click walks through that pipeline.

The ad survives the return visit. Sessions from the same person are stitched into one identity, so Thursday’s laptop buyer keeps Monday’s video ad as first touch. Last touch shows the visit that closed.

Where you see it working.

  • Attribution report, grouped by content. Group by utm_content and each ad becomes a row with its revenue and purchases. First touch and last touch sit side by side, next to the PartialLeads Resolved model; how to read an attribution report explains what each model proves. Group by campaign or term to roll up to campaigns and ad sets.
  • Leads list. Each buyer’s row shows the UTM column, the Journey ribbon (for example, Meta, then Direct, then the purchase) and the Revenue column, so you can read which ad one order came from without opening anything.
  • Purchases ledger. Every paid order PartialLeads recorded, matched or unmatched, so you can reconcile order by order against your WooCommerce order list.

PartialLeads Attribution report grouped by utm_content, showing Facebook ads with first-touch and last-touch revenue and purchases side by side, above Leads list rows where each buyer's journey ribbon shows a Meta ad touch, a Direct return visit and a completed purchase with revenue

The same paid order also goes back to Meta as a server-side Purchase through the Conversions API, carrying the full order total. If Meta for WooCommerce or another plugin already sends Purchase to the same pixel, keep one of them. PartialLeads never double-sends its own events, but it doesn’t deduplicate against another plugin’s pixel. The server-side WooCommerce purchase tracking guide covers that choice.

The honest constraints.

  • The ad must be on the URL. PartialLeads doesn’t decode fbclid into an ad. Add the URL parameters above, or orders group by source and campaign only.
  • View-through purchases don’t appear. A buyer who never clicked has no ad on any visit.
  • Matching is maximized, not guaranteed. A buyer who switched devices and never gave you an email or phone before checkout can’t always be tied to the click. Those orders sit in the Purchases ledger as unmatched.
  • Nothing is written back into WooCommerce. The ad per order lives in the PartialLeads dashboard, not the order’s attribution panel.
  • It starts at install. Visits before the tag went live weren’t captured.
What breaks The mechanism Where you see it in the dashboard
Ads Manager shows purchase counts, never order numbers Each paid WooCommerce order matched to the visit that carried the ad’s UTMs Purchases ledger, matched vs unmatched
fbclid names no ad outside Meta utm_content read from the landing URL and stored on the visit Leads list, UTM column
Buyer returns days later on another device Sessions stitched by visitor ID, email or phone; first touch keeps the ad Attribution report, first vs last touch
Thank-you page script misses or counts unpaid orders Orders taken from the WooCommerce webhook at processing or completed Purchases ledger, Revenue column
No per-ad revenue view Revenue and purchases grouped by utm_content Attribution report grouped by content

Tell us what's broken. We'll fix your tracking — free.

Describe the tracking/attribution problem you're stuck on and we'll map it to a fix: server-side conversions to Meta, Google, TikTok and Pinterest, plus first-party tracking that survives Safari. No code required.

Sources


Frequently asked questions

QCan Meta Ads Manager export the order numbers behind an ad's purchases?
No. Ads Manager reports purchases per ad as counts and values, credited under your attribution setting. It doesn't export which orders or customers those were. To get order numbers per ad, you need the ad named in the landing URL and a join between the stored visit and your store's orders, done in your own tools.
QWhy doesn't the fbclid tell WooCommerce which ad the order came from?
The fbclid is a click identifier Meta uses for its own matching. It carries no readable campaign, ad set or ad name, and only Meta can resolve it. Your store sees a random string. To see ad names in your own reports, add UTM parameters filled from Meta's dynamic placeholders, such as utm_content set to the ad name or ad ID.
QShould I use {{ad.name}} or {{ad.id}} in utm_content?
The ad ID is the safer key because it never changes and is unique, while names change when someone renames an ad and can repeat across ad sets. Names are easier to read in reports. Many teams store the ID and keep a small lookup sheet of IDs to names, or use names only when nobody renames live ads.
QDoes WooCommerce order attribution show the Facebook ad on each order?
It can, if the ad URL carries utm_content. WooCommerce stores the UTM fields of the buyer's visit on the order. It records one touch, read in the browser at checkout, so orders can be saved as Unknown when scripts are blocked or delayed, and a buyer who clicked on one device and bought on another won't show the ad.
QWhy does Meta report fewer purchases for an ad than the orders I can trace to it?
Meta only credits purchases inside your attribution setting, so an order weeks after the click drops out of its count while your visit-based join still credits the ad. The reverse also happens: Meta can credit view-through purchases your join never sees. Compare the two numbers as a trend, not as a reconciliation that should hit zero.
QCan I see which ad drove orders placed before I added UTM parameters?
Not order by order. The ad has to be captured on the landing visit, so orders from visits that arrived with only an fbclid, or before your tracking was installed, have nothing to join to. Ads Manager still holds its own per-ad purchase counts for that period, but not the link to specific orders.

Find the qualified leads your forms are currently throwing away.

Install PartialLeads on one landing page, send traffic, and compare what your CRM captured against what PartialLeads recovered and qualified.