Set up order attribution, step by step
Connect your WooCommerce store, install the CFI Order Attribution plugin, tag your ads and connect ad accounts, so each order shows the campaign that brought it.
What it is
Order attribution answers one question for every online order: which ad, campaign or website sent this buyer? This guide takes you from nothing to a working set-up, in the order that works.
There are three parts. The CFI Order Attribution plugin on your WooCommerce store notes where each visitor came from, but only after the shopper agrees to marketing cookies. Your store connection brings each order, with that note, into the app. Your connected ad accounts bring the daily spend per campaign every night. The Order attribution page then puts orders, revenue, profit and spend side by side.
Why it matters: an ad platform tells you how many sales it thinks it made. It does not know which cash-on-delivery parcels were refused, what each product cost you, or what the courier charged. The app knows all of that.
Note Example: a shop spends BDT 30,000 on Meta ads in a month. Meta reports 120 purchases. The app shows 120 orders credited to Meta, but 22 were refused at the door and the rest carried BDT 41,000 of goods cost and courier charges. Revenue said "good campaign"; profit says "break-even". You can only see that with attribution in place.
Who it is for
- WooCommerce shop owners who run ads on Meta, Google, TikTok or other platforms
- Cash-on-delivery sellers who want to know which campaigns bring orders that are actually paid
- Marketing staff or agencies who manage ads for a shop
- Owners of several web stores in one business
Before you start#
- Rights: you need access to Integrations. Connecting ad accounts and changing conversion settings needs the Edit right on Integrations. Profit figures also need the Gross profit report right.
- A connected WooCommerce store. Orders reach the app through the store connection. See WooCommerce if your store is not connected yet.
- WordPress admin access to the shop, to install a plugin.
- A consent banner on the shop (for example Complianz, CookieYes, Cookiebot or OneTrust). The plugin records nothing until a shopper says yes, so without a banner nothing is recorded where consent is required.
- Your ad account logins for each platform you want to connect (Google Ads, Meta, TikTok, Microsoft Advertising, LinkedIn, Pinterest, Snapchat).
Step by step#
- In the app, open Integrations and choose the CFI Order Attribution card. The Order attribution page opens.
- Choose Download the plugin (top right). A zip file downloads. Do not unzip it.
- In WordPress, open Plugins › Add New Plugin, choose Upload Plugin, pick the zip, then Install Now and Activate.
- In WordPress, open WooCommerce › Settings › CFI Attribution. Under Privacy and consent, choose Where consent is needed. Keep Ask everyone first (recommended) unless your adviser says otherwise.
- Copy the Suggested text for your privacy policy into your shop's privacy policy page, and save.
- Check that Enable attribution capture is ticked under Capture Settings, then choose Save changes.
- Back in the app, on Order attribution, open the Ad platforms tab. Under UTM templates — tag every ad with its campaign id, choose Copy on each platform you advertise on and paste the line where the note says (for example Google Ads' Final URL suffix, or each Meta ad's URL parameters).
- On the same tab, choose Connect on a platform card, then Sign in with that platform. Sign in on the platform's own page and allow read-only reporting access.
- If several ad accounts appear, tick the ones you want under Choose the ad accounts to connect and choose Connect selected.
- Place a test order on your shop: open it from a tagged link (for example your shop address with
?utm_source=test&utm_medium=cpc&utm_campaign=setup-check), accept the cookie banner, and check out. - When the order has reached the app, open the Health tab. Last order with a source should show your test order's time and platform.
- The next morning, check the platform card on Ad platforms: it shows Last run with day rows and campaigns once the nightly spend import has run.
How to send conversions back to the ad platforms#
Sending conversions is optional. It tells Meta, Google, TikTok or Microsoft which orders were really paid, so their algorithms learn from real sales.
- Connect the ad account first (steps 8–9 above). Conversions use its sign-in.
- On Ad platforms, find Server conversions and choose Set up on the platform.
- Fill in the platform's ids and token. The platform guides list exactly where each one is: Meta, Google, TikTok and Microsoft.
- Put the platform's test code in Test event code (optional) (Google: tick Test only), choose Save, and place a test order.
- When the test events look right on the platform's side, clear the test code and choose Save again. Events now go live.
How cash-on-delivery orders are counted is explained in Cash-on-delivery conversions.
How to connect with your own developer app#
Use this only when the sheet says the platform's CFI app isn't set up on this server yet, or when your agency prefers its own app.
- On the platform card choose Connect, then open Advanced: paste credentials.
- Paste the client id, client secret, refresh token, the developer token where the platform has one, and the ad account id from your own developer app.
- Choose Connect. The app checks the details with the platform before it saves them.
Daily use#
A cash-on-delivery shop in Bangladesh
You run Meta and TikTok ads and most orders are cash on delivery. Turn on Require a valid phone number under Order quality in the plugin, so every order carries a number you can call. Each morning, open the Health tab to confirm orders still arrive with their source. Once a week, open the ROAS report with POAS (profit after every cost) to see which campaigns still make money after refusals and courier charges.
An EU store with cookie consent
Keep Ask everyone first (recommended). Expect a share of orders without a click id: those shoppers said no, and that is correct. Those orders still keep the campaign name (UTM tags) without any identifier, so campaign totals stay useful. See Consent and privacy for ads.
A business with two web stores
Install the plugin on each WooCommerce store and connect each store. The Health tab then shows Captures by store (30 days), so you can see whether one store stopped capturing.
What you see#
After set-up, these places fill up:
| Where | What appears | When |
|---|---|---|
| Health tab | Orders in the last 30 days, orders with a source, capture rate, platforms, the last order with a source | As orders arrive |
| Ad platforms card | Each connected account, Last run, day rows, campaigns, history reached | After the first night |
| ROAS report tab | Orders, net revenue, spend, ROAS and POAS per platform and campaign | Once orders and spend exist |
| Insights tab | MER, new-customer cost, cohorts, estimates | Once there is enough history |
| WooCommerce order screen | A readable campaign field, if Show UTM campaign on order screen is on | Each order |
Example of the Health tab one week after set-up (a shop's own numbers will differ):
| Tile | Example value | How to read it |
|---|---|---|
| Sales orders, last 30 days | 412 | Every sales order in the business, including any typed-in or shop-counter orders |
| With an ad / campaign source | 236 | Orders that arrived with a click id or campaign tags |
| Capture rate | 57% | 236 ÷ 412 |
Good practice#
- Tag every ad with the UTM template. Without
utm_id, spend is matched to orders by campaign name, which breaks when someone renames a campaign. - Keep Google auto-tagging on. The template adds to it; it does not replace it.
- Use one source for the Meta Pixel. If another plugin already loads it, read the plugin guide before you change anything.
- Never let another plugin send a browser Purchase event. The app sends Purchase itself, only when the order is paid.
- Give the nightly import a few nights. New accounts bring 13 months of history in steps, newest first.
Troubleshooting#
| What you see | Why | What to do |
|---|---|---|
| No order has arrived with an ad source yet. | The plugin is not installed, capture is off, or no shopper has accepted cookies yet | Check the plugin is active and Enable attribution capture is ticked; place a test order and accept the banner |
| No WooCommerce store is connected. | The store connection is missing | Connect the store first, see WooCommerce |
| Test order arrives, but with no source | You declined the banner, your browser sends Global Privacy Control, or the link had no tags | Open the shop in a private window from a tagged link and accept the banner |
| CFI’s Meta app isn’t set up on this server yet — use the advanced form. (or another platform's name) | Sign-in for that platform is not available yet | Use Advanced: paste credentials |
| Choose at least one account. | You chose Connect selected with nothing ticked | Tick an account first |
| No run yet — the first sync runs tonight. | The account was connected today | Check again tomorrow |
| Sign-in expired — connect it again | The password or app access changed, or the token expired | Choose Connect again with the same account; the same account comes back with its history |
| Report rows say matched by name | The ads carry no campaign id | Paste the UTM template into those ads |
Limits and what is not there yet#
- Built and contract-tested. The whole order path, from the plugin to the app, is verified end to end in a WooCommerce sandbox. It is not yet proven on a real ad account.
- Capture works for WooCommerce stores with the plugin. Without the plugin, WooCommerce's own order attribution is read instead, with no click ids. Shopify orders bring their landing page tags, but never a consent decision, so they are never sent to ad platforms.
- The Health tab's capture rate counts every sales order in the business, not only web orders. An update that counts only store orders is coming.
Questions#
Do I need to connect an ad account?
No. With only the plugin you already see orders by platform and campaign. Connect accounts when you also want spend, cost per order, ROAS and POAS.
Can the app change my ads or budgets?
No. The sign-in asks for read-only reporting access. Nothing is changed in your ad accounts.
Does the plugin slow down my shop?
The plugin sets small first-party cookies and, only if you choose it, loads the Meta Pixel after consent. It does not send anything before the shopper says yes.
Can my agency set this up?
Yes, if you give them a user with access to Integrations and the Edit right. Every connection is written to the audit log.
