Connecting Craft CMS to Meta Conversions API
Craft is a developer-oriented CMS, usually built bespoke by an agency, which means the implementation is whatever that agency decided and nothing is standard. Meta's pixel loses a large share of conversions to Safari, ad blockers and iOS, and the Conversions API exists because of it. The join between them succeeds or fails on one thing: whether the fbc and fbp values reaches the Craft Commerce order before the conversion happens, because Meta can only match a conversion it can tie back to a click it recognizes.
Free30 minutesNo obligation
Specific to this pair
Craft Commerce to Meta CAPI from an event listener, not Twig
Send Purchase to Meta's Conversions API from a PHP listener on Craft Commerce order completion, with value, currency, hashed email, and fbc and fbp copied onto the order during checkout. Use the order number as event_id in both the Twig pixel call and the listener, and exclude the confirmation route from caching.
On Craft, the Meta pixel usually lives in a layout template, and the Purchase event in the order template. Moving the server side to the Conversions API means a PHP listener on order completion that sends Purchase with the order's value, currency, hashed email and the fbc and fbp values. Those two cookies have to be copied onto the order during checkout, because the listener may run in a context, such as a payment gateway callback, where the visitor's cookies are not present.
The deduplication key should be the Commerce order number or reference, used as event_id in both places: printed into the browser pixel call in Twig and sent by the listener. That is where caching bites on Craft. If the confirmation template is served from Blitz or a template cache, the pixel can fire a stale order number, the IDs never match, and Meta counts every purchase twice. Exclude that route from caching and confirm it on an anonymous checkout.
Craft gateway setups vary. Where payment completes off-site and the order is completed by a webhook from the gateway, the listener still fires, but there is no browser context and no pixel; the server event is the only one, which is fine as long as it carries fbc and fbp from the order field.
Craft → Meta · what breaks
Why this join usually fails — Craft → Meta
- 01
The fbc and fbp values never reaches Craft
Craft's template caching and static caching plugins both serve stored output, and because every build is custom, where the capture code lives differs per site. There is no standard place to look.
- 02
Every install is bespoke
There is no standard Craft setup, so an approach that worked on another Craft site may have nothing to attach to on this one. Read the build before quoting.
- 03
Double counting from broken deduplication
Server and browser both fire, the event_id does not match, and Meta counts two purchases. Reported ROAS goes up, the business does not, and it can run for months before anyone reconciles against the store.
- 04
Nothing reconciles afterwards
Events Manager shows received events, the deduplication state and an Event Match Quality score per event. Events arriving is not the test — deduplicated, well-matched events arriving is. Compare Meta's reported purchases against your store's order count for the same window.
Craft → Meta · the fix
What working looks like — Craft → Meta
The fbc and fbp values on every order
Conversions arriving in Meta
Events appear in Events Manager with an Event Match Quality score, deduplicated against the pixel, and become usable for optimization and attribution.
Reconciled against the source
Craft CMS's own records are the reference, not either dashboard.
Craft → Meta · architecture
How Craft and Meta actually connect
- 1
Craft CMS holds the truth
Craft installs are bespoke by nature. Establish how this particular build models a completed order before assuming anything transfers from another Craft site.
- 2
Meta Conversions API needs a click to match
Meta matches server events to people using whatever identifiers you send, hashed with SHA-256 where required. There is no single mandatory key, which is why quality varies so much between implementations — a poorly matched event is accepted, reported, and worth much less than it appears.
- 3
The identifier is the bridge
The fbc and fbp values, captured at the visit and carried into the Craft Commerce order.
- 4
The event source decides reliability
Fire from the event listener in PHP rather than a Twig template, which may be cached.
- 5
Deduplication at the destination
Meta deduplicates on the pair of event_name and event_id. The browser pixel and the server event must send the same event_id for the same conversion, within the deduplication window. Get this wrong and every purchase counts twice — which is by far the most common Conversions API failure and it inflates reported ROAS rather than reducing it.
Craft → Meta · normal or broken
Working vs. broken, side by side — Craft → Meta
Normal, not a fault
The fbc and fbp values present on the order
Visible on the record itself in Craft CMS, not merely captured somewhere on the site.
Sent from the Craft Commerce order-complete event
Deduplicated correctly
Meta deduplicates on the pair of event_name and event_id. The browser pixel and the server event must send the same event_id for the same conversion, within the deduplication window. Get this wrong and every purchase counts twice — which is by far the most common Conversions API failure and it inflates reported ROAS rather than reducing it.
Reconciles with the source
Meta's count and Craft CMS's records agree within a few percent over a closed window.
Actually broken
The fbc and fbp values missing on most records
Craft's template caching and static caching plugins both serve stored output, and because every build is custom, where the capture code lives differs per site. There is no standard place to look.
Sent from the browser
There is no standard Craft setup, so an approach that worked on another Craft site may have nothing to attach to on this one. Read the build before quoting.
Counted twice, or not at all
Server and browser both fire, the event_id does not match, and Meta counts two purchases. Reported ROAS goes up, the business does not, and it can run for months before anyone reconciles against the store.
Nobody has reconciled it
The dashboard shows a number and no one has compared it to Craft CMS.
Craft → Meta · diagnose
Diagnostic order — Craft → Meta
- 01
Count orders carrying the fbc and fbp values
- 02
Follow one real conversion end to end
- 03
Read how this specific build handles order completion
Assumptions carried from another Craft project are the main source of wasted time here.
- 04
Read Event Match Quality and the deduplication indicator
In Events Manager, open the event and check both. A low match quality means weak identifiers; a missing deduplication indicator means your event_id pairing is broken.
- 05
Read the match rate, not the success message
Events Manager shows received events, the deduplication state and an Event Match Quality score per event. Events arriving is not the test — deduplicated, well-matched events arriving is. Compare Meta's reported purchases against your store's order count for the same window.
Craft → Meta · prove
How it gets proven — Craft → Meta
Against Craft CMS's own records, not against either platform's dashboard.
Source of truth
Craft Commerce's order records in your own database, filtered to completed.
- The fbc and fbp values confirmed present on a live order.
- Deduplication confirmed in Events Manager on a real purchase, with the browser and server events visibly paired rather than counted twice.
- Order custom field confirmed populated on an order placed as an anonymous visitor through cache.
Craft → Meta · free audit
What we check in the free audit
- Count orders carrying the fbc and fbp values
- Follow one real conversion end to end
- Read how this specific build handles order completion
- Read Event Match Quality and the deduplication indicator
- Read the match rate, not the success message
Checked against
Craft Commerce's order records in your own database, filtered to completed.
Free30 minutesNo obligation
Craft → Meta · when not to buy
When you don't need this — Craft → Meta
- If Meta already reports conversions that reconcile against Craft CMS's records within a few percent, this join is working and there is nothing to buy.
- Measure identifier coverage yourself first — pull your last hundred orders and count how many carry the fbc and fbp values.
- If the original agency is still engaged, the fastest path is usually specifying the field and having them add the hook.
- If you are not running Meta ads at meaningful spend, the Conversions API is effort without payoff. It earns its cost when the optimization signal is worth improving.
Craft → Meta · what we deliver
What gets built — Craft → Meta
Identifier capture into Craft
Capture the identifier and store it as a custom field on the order through a Craft event listener, server-side.
Event source: the Craft Commerce order-complete event
Fire from the event listener in PHP rather than a Twig template, which may be cached.
Dispatch to Meta
Server-side events to the Conversions API with the event_id matched to the pixel, action_source set correctly, and customer data hashed before it leaves your infrastructure.
Reversals where they exist
Refunds and cancelled orders are recorded against the order.
Written guarantee
95%+ tracking accuracy
Measured against Craft Commerce's order records in your own database, filtered to completed.. Miss it and we keep working at no cost.
From $400 · See packages
FAQ
Craft → Meta questions, answered
Check the Craft Plugin Store for your version. Many Craft sites end up with a small custom module instead, because the build is bespoke anyway.
The Commerce order reference or number, used identically in the browser pixel and the server event.
Almost always because the fbc and fbp values never reached the Craft Commerce order. Craft's template caching and static caching plugins both serve stored output, and because every build is custom, where the capture code lives differs per site. There is no standard place to look. Measure coverage before debugging the dispatch.
Two things. The _fbc cookie, derived from the fbclid parameter on the landing URL in the format fb.1.<timestamp>.<fbclid>, is the click identifier. The _fbp cookie is the browser identifier. Beyond those, Meta matches on hashed customer information — email, phone, name, city, country — and every additional field raises the Event Match Quality score. Unlike Google, Meta does not need a click ID at all if the customer data is good, but match quality drops noticeably without it.
The Craft Commerce order-complete event. Fire from the event listener in PHP rather than a Twig template, which may be cached.
Events Manager shows received events, the deduplication state and an Event Match Quality score per event. Events arriving is not the test — deduplicated, well-matched events arriving is. Compare Meta's reported purchases against your store's order count for the same window.
More on Craft → Meta
- Craft → Google AdsConnecting Craft CMS to Google Ads
- Craft → GA4Connecting Craft CMS to GA4
- Craft → HubSpotConnecting Craft CMS to HubSpot
RELATED GUIDES
Where Craft → Meta fits in the rest of your tracking
- Meta · Local servicesMeta Ads conversion tracking for local service businesses
- Meta · B2BMeta Ads conversion tracking for B2B companies
- Meta × CRM DealsHow to reconcile Meta Ads against your CRM's closed-won deals
- Meta · Comparison page → demoHow to track comparison page visit to demo request for Meta Ads
- Statamic → MetaConnecting Statamic to Meta Conversions API
- Craft → Amazon AdsConnecting Craft CMS to Amazon Ads
- Local servicesConversion tracking for local businesses, where most conversions bypass the website
- Drupal Commerce → MetaConnecting Drupal Commerce to Meta Conversions API
Free · 30 min
Get Craft and Meta joined properly
Free30 minutesNo obligation
