Connecting Concrete CMS to Meta Conversions API
Concrete CMS is a self-hosted PHP CMS used by small organisations and agencies, typically with commerce added through an add-on rather than built in. 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 Concrete CMS 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
Concrete CMS to Meta: event_id from the order, not a cached page
Exclude Concrete CMS checkout and confirmation pages from caching and derive Meta's event_id from the order number. Store _fbp and _fbc as order attributes at creation, then send Purchase server-side from the commerce add-on's order-completed event with action_source website and hashed billing details, within minutes, since Meta rejects events older than seven days.
Concrete's full page cache causes a Meta-specific failure. If the order confirmation page is cached, the pixel's Purchase either does not fire or fires with the event_id baked into whichever order first produced the cached copy. Meta then cannot deduplicate it against the server event, or deduplicates the wrong purchase. Exclude checkout and confirmation pages from caching, and derive event_id from the order number so the pixel and the server send the same value for the same order.
The server event should come from the commerce add-on's order-completed event, not the template. When the order is created, read _fbp and _fbc from the request cookies in PHP and store them as order attributes; if _fbc is missing but the landing URL carried fbclid, build it from your own first-party capture. Send Purchase with action_source website, the order total and currency, and hashed email, phone, name and ZIP from the order's billing details. Send within minutes. Meta rejects website events with an event_time more than 7 days old, which bites if your add-on allows offline or manual payments that are marked paid later.
On brochure-only Concrete sites the event is Lead, sent when an Express form entry is saved, with the entry ID as event_id. Meta has no way to retract a Purchase, so refunds recorded by the add-on only correct your own reconciliation, not Meta's numbers.
Concrete CMS → Meta · what breaks
Why this join usually fails — Concrete CMS → Meta
- 01
The fbc and fbp values never reaches Concrete CMS
Full page caching and the add-on ecosystem both interfere. Because commerce is an add-on rather than core, where the order is created differs by which add-on is installed.
- 02
Commerce as an add-on, not a core feature
Which add-on is installed determines the entire integration surface, so nothing transfers between two Concrete sites without checking first.
- 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.
Concrete CMS → Meta · the fix
What working looks like — Concrete CMS → 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
Concrete CMS → Meta · architecture
How Concrete CMS and Meta actually connect
- 1
Concrete CMS holds the truth
Self-hosted means you own and can query the data directly, which makes reconciliation straightforward once the identifier is present.
- 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 Concrete CMS order.
- 4
The event source decides reliability
Fire server-side. Page caching means the confirmation template may not execute.
- 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.
Concrete CMS → Meta · normal or broken
Working vs. broken, side by side — Concrete CMS → Meta
Normal, not a fault
The fbc and fbp values present on the order
Sent from the order-completed event from your commerce add-on
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
Actually broken
The fbc and fbp values missing on most records
Full page caching and the add-on ecosystem both interfere. Because commerce is an add-on rather than core, where the order is created differs by which add-on is installed.
Sent from the browser
Which add-on is installed determines the entire integration surface, so nothing transfers between two Concrete sites without checking first.
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
Concrete CMS → Meta · diagnose
Diagnostic order — Concrete CMS → Meta
- 01
Count orders carrying the fbc and fbp values
- 02
Follow one real conversion end to end
- 03
Identify which commerce add-on is in use
That decides where the order is created and what events exist to hook.
- 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.
Concrete CMS → Meta · prove
How it gets proven — Concrete CMS → Meta
Source of truth
Your own database's order records, at agreed states.
- 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 attribute confirmed populated on a purchase through a cached page.
Concrete CMS → 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
- Identify which commerce add-on is in use
- Read Event Match Quality and the deduplication indicator
- Read the match rate, not the success message
Checked against
Your own database's order records, at agreed states.
Free30 minutesNo obligation
Concrete CMS → Meta · when not to buy
When you don't need this — Concrete CMS → Meta
- Measure identifier coverage yourself first — pull your last hundred orders and count how many carry the fbc and fbp values.
- If your Concrete site is brochure-only with enquiries by form, treat it as a lead-gen site rather than a commerce one.
- 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.
Concrete CMS → Meta · what we deliver
What gets built — Concrete CMS → Meta
Identifier capture into Concrete CMS
Capture the identifier and persist it as order attribute data through an event listener, server-side.
Event source: the order-completed event from your commerce add-on
Fire server-side. Page caching means the confirmation template may not execute.
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
Order state changes recorded by the add-on.
Written guarantee
95%+ tracking accuracy
Measured against Your own database's order records, at agreed states.. Miss it and we keep working at no cost.
From $400 · See packages
FAQ
Concrete CMS → Meta questions, answered
Usually the confirmation page is cached, so the pixel's event_id does not match the server event's. Exclude it from full page caching and derive event_id from the order number on both sides.
In an event listener on your commerce add-on's order-completed event, server-side, using the fbp and fbc values read from cookies and stored on the order when it was created.
Almost always because the fbc and fbp values never reached the Concrete CMS order. Full page caching and the add-on ecosystem both interfere. Because commerce is an add-on rather than core, where the order is created differs by which add-on is installed. 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 order-completed event from your commerce add-on. Fire server-side. Page caching means the confirmation template may not execute.
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 Concrete CMS → Meta
- Craft → MetaConnecting Craft CMS to Meta Conversions API
- Concrete CMS → Google AdsConnecting Concrete CMS to Google Ads
- Concrete CMS → GA4Connecting Concrete CMS to GA4
RELATED GUIDES
Where Concrete CMS → Meta fits in the rest of your tracking
- Meta · Local servicesMeta Ads conversion tracking for local service businesses
- Meta · SaaSMeta Ads conversion tracking for SaaS 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
- Webflow → MetaConnecting Webflow to Meta Conversions API
- Concrete CMS → Google AdsConnecting Concrete CMS to Google 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 Concrete CMS and Meta joined properly
Free30 minutesNo obligation
