Cash Flow Inventory
Menu
Documentation

Meta: Pixel, Conversions API and catalogue

Connect your Meta ad account, send paid orders through the Conversions API, run the Meta Pixel on your shop without double counting, and test it all first.

Where in the app
IntegrationsAttributionAd platforms
Last reviewed
Reading time
11 min

What it is

Meta (Facebook and Instagram) needs to learn which ads bring real sales. This guide sets up three connected parts:

  • Spend: your Meta ad account sends its daily spend per campaign every night, so the ROAS report can compare spend with your real revenue and profit.
  • Server conversions: your app's server tells Meta which orders were really paid, through Meta's Conversions API. For cash on delivery this happens only when the courier's cash is settled, so refused parcels are never counted as sales.
  • The Meta Pixel on your shop: the CFI Order Attribution plugin on your WooCommerce store loads the pixel after the shopper agrees, and sends shop events such as viewed product and added to cart. Each browser event and its server copy carry the same event id, so Meta counts it once.

Why it matters: if Meta counts every placed order as a purchase, it learns from orders that are later refused or returned. Your ads then find more people who order and do not pay.

Example: a cash-on-delivery shop in Dhaka gets 100 orders in a week from one campaign, at about BDT 1,250 each. 82 parcels are delivered and paid, 18 are refused. A browser pixel that sends Purchase at checkout tells Meta "100 sales". This set-up tells Meta "82 sales", each with its real net value, and keeps the 18 refused orders out.

Who it is for

  • Shops that advertise on Facebook or Instagram
  • Cash-on-delivery sellers who want Meta to learn only from paid orders
  • Shops that run Advantage+ catalogue ads
  • Owners who already have another pixel plugin and want to avoid double counting

Before you start#

  • You need access to Integrations; connecting accounts and changing the conversion settings needs the Integrations Edit right.
  • A Meta Business portfolio with your ad account and a dataset (the pixel). In Meta's words a pixel is now a "dataset"; it has one id.
  • The CFI Order Attribution plugin, version 2.3.0 or later, on your WooCommerce store, and a consent banner. See the store plugin.
  • Developer rights on the dataset in Meta, to create a Conversions API access token.
  • Value basis Profit also needs the Gross profit report right.

Step by step#

  1. Open Integrations › Attribution, go to the Ad platforms tab and choose Connect on the Meta Ads card.
  2. Choose Sign in with Meta Ads, sign in on Meta's page and allow read-only reporting access. If you have several ad accounts, tick them under Choose the ad accounts to connect and choose Connect selected.
  3. In Meta Events Manager, open your dataset, go to Settings, and under Conversions API choose Generate access token (Meta: get started with the Conversions API (opens in a new tab)). Copy the token and the dataset id.
  4. Back on the Ad platforms tab, find Server conversions and choose Set up on the Meta (Facebook, Instagram) card.
  5. Enter the Dataset (pixel) id and paste the Conversions API access token.
  6. Under Events, keep the three boxes ticked: checkout started, purchase once paid, and late delivery.
  7. Choose Value sent: Net revenue (ex tax, after refunds) is the default.
  8. Open Events Manager › your dataset › Test events, copy the test code and paste it in Test event code (optional) (Meta: test events (opens in a new tab)).
  9. Tick Send conversions to Meta (Facebook, Instagram) and choose Save. The card now shows On and Test mode.
  10. In WordPress, open WooCommerce › Settings › CFI Attribution, section Meta Pixel, and enter the same id in Meta Pixel (dataset) id. Keep Who loads the Meta Pixel on Cash Flow Inventory (this plugin, recommended).
  11. Place a test order on your shop, and check the events in Meta's Test events screen.
  12. When the test is right, clear Test event code (optional) in the app (and in the plugin, if you set it there) and choose Save. You are live.

How to connect with the advanced form#

Use this when the sheet says "CFI’s Meta Ads app isn’t set up on this server yet — use the advanced form.", or when you prefer a system-user token.

  1. In Meta, open Business settings › Users › System users, create a system user and give it access to your ad account (Meta Business Help: system users (opens in a new tab)).
  2. Generate a token for that system user with the ads_read permission.
  3. In the app, choose Connect on Meta Ads, open Advanced: paste credentials.
  4. Paste Access Token (System User, ads_read) and Ad Account ID (for example act_1234567890 or just the digits), then choose Connect. The details are checked with Meta before they are saved.

How to choose who loads the Meta Pixel#

When another Meta pixel plugin is active (Meta for WooCommerce, PixelYourSite, Meta pixel for WordPress or Pixel Caffeine), the store plugin does not load a second pixel. A notice in WordPress offers three choices:

  1. Use CFI Order Attribution's pixel -- I have switched the other plugin's pixel off: first switch off the other plugin's pixel, its Purchase event and its catalogue sync.
  2. Keep the other plugin's pixel: the other plugin keeps loading the pixel. Switch its Purchase event off, because your app sends Purchase from its server.
  3. No browser pixel from CFI: no pixel from the plugin; order attribution and the server conversions keep working.

You can change this later under WooCommerce › Settings › CFI Attribution › Meta Pixel with Who loads the Meta Pixel. After switching the other pixel off, tick The other plugin's pixel is off.

What each field means#

FieldMeaning
Dataset (pixel) idThe digits of your dataset in Events Manager. Use the same id in the store plugin.
Conversions API access tokenThe token from the dataset's Conversions API settings. Stored encrypted; it is never shown again. Paste a new one to replace it, or tick Remove the stored token.
EventsCheckout started (the same event id as the browser), Purchase once paid, Late delivery (paid after 7 days, sent as LateDelivery).
Value sentNet revenue (default), Cash collected, or Profit. Profit needs the Gross profit report right and the box "I understand the platform will see my profit per order (my margins)."
Test event code (optional)While set, events go to Meta's test view only. Clear it to go live.
Limited Data Use (US state privacy laws)Automatic (US buyers in covered states), Always on, or Off.

In the store plugin's Meta Pixel section:

  • When the pixel loads: Only after consent (recommended), or load at once with consent revoked (only if your consent tool needs it).
  • Server copies from this site: also sends product viewed, added to cart and payment step from the shop's own server. It needs Conversions API token for this site. Server copy of page views is off by default.
  • Test event code and Limited Data Use (US states): the same meaning as in the app, for the plugin's own events.
  • Cash Flow Inventory sends Meta conversions: keep Ask Cash Flow Inventory (it tells this site).

Daily use#

A cash-on-delivery shop in Bangladesh

Keep your ad sets optimising on Purchase. Purchase arrives when the courier's cash is settled, often two to five days after the order. Meta accepts events up to 7 days old. An order paid later than that is sent as the custom event LateDelivery instead: you can see it and use it in audiences, but not optimise on it. If you need faster learning, build a custom conversion on OrderPlaced, the event fired on the thank-you page. Refused parcels are never sent as Purchase; they are kept for an exclusion audience. See cash-on-delivery conversions.

The pixel loads only after the shopper agrees in your consent banner, and only orders with marketing consent are sent to Meta. A browser that sends Global Privacy Control counts as "no". Expect fewer events than orders: that is the consent working. See consent and privacy for ads.

A shop that runs catalogue ads

Connect the Meta catalogue in Integrations › Meta / Facebook with the Catalog ID and the System User Access Token (a system-user token with catalog_management). Then use Markets and Product sets in the Meta catalogue block. The Pixel, the server conversions and the catalogue use the same product id, so Meta can match "viewed" and "bought" to the product. All details are in Meta catalogue, Pixel and Google Merchant.

What you see#

The Meta (Facebook, Instagram) card under Server conversions shows On or Off, the dataset id (or Not set up), Test mode while a test code is set, and "Last 7 days: 12 sent, 0 failed, 3 skipped".

Recent conversions lists each event. Example:

WhenPlatformEventOrderValueStatus
2026-11-10 14:02metaInitiateCheckoutSO-1042BDT 1,250Sent
2026-11-12 09:40metaPurchaseSO-1042BDT 1,180Sent
2026-11-12 09:40metaPurchaseSO-1047—Skipped: no marketing consent
2026-11-12 10:10metaPurchaseSO-1050—Skipped · Kept for the exclusion audience (this platform has no negative event)
2026-11-12 10:20metaLateDeliverySO-0991BDT 900Sent

Waiting with "2 tries so far" means the app will try again. Failed shows Meta's own message below it.

The Pixel on your shop block shows who loads the pixel (Loaded by Cash Flow Inventory, Loaded by another plugin, Not loaded: another pixel is on, Not loaded: no pixel id), browser events and server copies of the last 7 days, and problems such as "Two Meta pixels are on the shop’s pages." Choose Check now to read it again.

In Meta Events Manager, the browser and server copies of one event show as one event (Meta deduplicates by event name and event id within 48 hours).

Good practice#

  • Use one dataset id everywhere: the app, the store plugin and the catalogue link in Events Manager.
  • Keep one pixel source and one Purchase source. Purchase must come only from the app's server.
  • Always test with a test code first, then clear it. While a test code is set, events go to Meta's test view only.
  • Keep the UTM template on every ad (see TikTok, Microsoft and other ad platforms) so spend joins orders by campaign id.
  • Paste a new token when you rotate it in Meta; the old one stays stored until you replace or remove it.

Troubleshooting#

What you seeWhyWhat to do
Server conversions need a database update first. Nothing is sent until it is applied.The app's database is not ready for this feature.Ask your account owner or support. Nothing is lost; set-up can wait.
Enter the dataset (pixel) id — digits only.Letters or spaces in the id.Copy the id from Events Manager › your dataset.
Paste the access token before switching on.No token stored.Generate one in Events Manager › dataset › Settings › Conversions API.
That doesn’t look like an access token.The pasted text is too short or has spaces.Copy the whole token again.
Choose at least one event.All event boxes are empty.Tick at least Purchase.
Confirm that the platform will see your margins.You chose Profit as the value.Tick the margin box, or keep Net revenue.
Failed, with Meta's messageMeta refused the event or the token.Fix the cause in Meta, then save a new token if needed.
Skipped: older than the platform acceptsThe event is older than Meta's 7-day limit.Normal for late payments; tick Late delivery to send LateDelivery.
Skipped · The order has no browser detailsMeta website events need the browser details.Usually an order created without the plugin; nothing to fix per order.
A Purchase is sent from the shop’s browser — Meta counts every order twice.Another plugin or the theme sends Purchase.Switch Purchase off in that plugin.
Not loaded: another pixel is onA second pixel plugin is active.Pick one of the three choices in the WordPress notice.
Meta Ads validation failed: …The advanced form's token or account id was refused.Check the system user has access to the ad account and the token has ads_read.
Sign-in expired — connect it againMeta refused the saved sign-in. Spend stops.Choose Add account and sign in again with the same account.

Limits and what is not there yet#

  • Built and contract-tested; the order path verified end to end in a WooCommerce sandbox; not yet proven on a real ad account.
  • Meta has no "undo" event: a refused order is never sent, but a Purchase already sent stays in Meta.
  • Today, if Meta refuses the token, each event is tried again for about two hours and then marked Failed. After the 2026-11 update, a refused token or permission pauses Meta and keeps the events waiting instead of failing them.
  • Today, erasing a customer's personal data does not yet stop conversion events already waiting. After the 2026-11 update, a privacy erasure also stops them.
  • Planned: Purchase events for orders that start in WhatsApp or Messenger (click-to-chat attribution), and a health centre per destination.

Questions#

Why is Purchase not sent from the browser?

Because a placed order is not a sale. The app sends Purchase from its server only when the order is paid, so Meta learns from real sales and nothing is counted twice.

Do I need a token in the store plugin too?

No. The app's own token covers checkout, order placed and purchase. The plugin token is only for the optional server copies of product viewed, added to cart and payment step.

Can I keep Meta for WooCommerce?

Yes, with Keep the other plugin's pixel, but switch its Purchase event and its catalogue sync off. Otherwise Meta counts every order twice.

Does connecting let the app change my ads?

No. The sign-in asks for reading only. Any change on the account is a separate sign-in and a proposal a person approves.

What is Limited Data Use?

A Meta setting for US state privacy laws. On Automatic, the app marks events from buyers in the covered US states; elsewhere it is off.

All guides

Type at least 2 letters.↑ ↓ to moveEnter to openEsc to close