BigCommerce gets less tracking attention than Shopify, which is a shame, because it's friendlier in one important way: Script Manager lets you place scripts on the checkout and order confirmation pages. Most stores I audit don't use that advantage. They run the native Meta channel, a half-connected GA4 integration, and nobody can tell me whether purchases are deduplicated.
| Native integrations | GTM plus server-side |
|---|---|
| Standard ecommerce events only | Anything you push to the dataLayer |
| No event_id, so no dedup control | You set event_id — use the order ID |
| EMQ is whatever the app sends | Hashed email, phone, zip lift EMQ |
| Purchase depends on the browser | Webhook-backed, fires without the page |
| Fine under a few thousand a month | Verify dedup in Events Manager |
What do BigCommerce's native tracking integrations actually give you?
The built-in GA4, Meta, and Google channel integrations give you baseline events with almost no setup, and that's genuinely fine until you're spending real money on ads. Connect GA4 and BigCommerce sends the standard ecommerce events (view_item, add_to_cart, begin_checkout, purchase) from its own data layer. The Meta channel gives you a pixel plus catalog sync; the Google channel handles Ads conversions and your Shopping feed.
Where they fall short is control. Three problems keep showing up in audits:
- No parameter control. You can't add custom parameters or enforce that content_ids match your catalog's retailer IDs.
- No dedup control. You don't set the event_id, so you can't safely run your own Conversions API feed alongside the native pixel. Meta dedupes by matching event_name plus event_id; if you don't own either side, you're guessing.
- Mediocre Event Match Quality. Meta scores EMQ on a 0–10 scale based on the customer information attached to each event. You can't add hashed email, phone, or address from the order to push that score up.
Spending under a few thousand a month? Turn the native integrations on and move on. Past that, the gaps cost real money — the platforms optimize toward whatever signal you feed them.
| Native channel integrations | GTM + server-side | |
|---|---|---|
| Event coverage | Standard ecommerce events | Anything you can push |
| event_id / dedup control | None | Full — you set it (use the order ID) |
| EMQ potential | Whatever the app sends | High — hashed email, phone, name, address from the order |
| Purchase reliability | Browser-dependent | Webhook-backed, fires even if the thank-you page never loads |
Where does Google Tag Manager go in BigCommerce?
Storefront → Script Manager → Create a Script, paste the GTM container snippet, set placement to Head, and select all pages so it loads on the storefront, checkout, and order confirmation. That's the whole install. Two things trip people up here:
- Script category. Script Manager makes you categorize each script (Essential, Analytics, Functional, Targeting) for its built-in cookie consent feature. If you run Consent Mode v2 through GTM with your own CMP, set the container to Essential so it always loads, then gate tags inside GTM by consent state. Marking GTM as Targeting kills the whole container for anyone who declines, cookieless pings included.
- Checkout placement. The checkout location is what makes begin_checkout and purchase tracking possible without an app. (historically plan-dependent — BigCommerce's current docs are the authority on which tiers get the checkout location)
Does BigCommerce have a data layer for GTM?
Not one that GTM can use out of the box. BigCommerce built its own data layer (the Big Open Data Layer, or BODL) to power the native integrations, but it's not the window.dataLayer array your GTM tags read from. So you either write your own dataLayer pushes into the Stencil theme templates or use a third-party GTM app that does it for you.
Hand-rolling it isn't bad on Stencil. Product and category templates give you what you need for view_item and view_item_list. Add to cart is the annoying one — on most themes it's an AJAX call, so you hook the theme's cart events or listen for the cart API request. The purchase push on the order confirmation page looks like this:
window.dataLayer = window.dataLayer || [];
dataLayer.push({
event: "purchase",
event_id: "BC-" + orderId, // order ID = your dedup key everywhere
ecommerce: {
transaction_id: orderId,
value: orderTotal,
currency: "USD",
items: orderItems
}
});
That event_id line matters more than everything else in the snippet. It's the shared key that lets Meta deduplicate your browser Purchase against the CAPI Purchase from the webhook.
How do you track the checkout and purchase in the browser?
Treat the browser purchase as a signal, not the source of truth. The Optimized One-Page Checkout is a single-page React app: the URL doesn't change between steps, so pageview triggers see one page. begin_checkout fires reliably when the checkout loads. Step-level events need element visibility or history triggers, and for most stores they're not worth the fragility. Checkout step data is nice to have; purchase data pays the bills.
The confirmation page has the bigger problem: it doesn't always load. Customers close the tab after paying, mobile connections drop, off-site payment methods like PayPal sometimes return customers in ways that skip your scripts. Every one of those is a purchase your pixel never saw. True on every platform, and it's why the next section exists.
- Shopper pays — Closed tabs and PayPal returns skip scripts
- Browser Purchase — Only fires if the confirmation page renders
- store/order/created — Fires from the database, no browser needed
- Your endpoint — Pulls the full order from the Orders API
- Meta CAPI, deduped — event_id BC-orderId plus hashed email and zip
Why should an order webhook be your source of truth for purchases?
Because the store/order/created webhook fires when the order exists in the database, whether or not the customer's browser ever rendered a thank-you page. No ad blocker touches it. No ITP cookie cap ages it out. The payload is small:
{
"scope": "store/order/created",
"store_id": "1025646",
"data": { "type": "order", "id": 250 },
"created_at": 1754200000
}
Your endpoint — server GTM, a Cloudflare Worker, whatever you run — takes the order ID, pulls the full order from the Orders API, and sends:
- Meta CAPI Purchase with event_id set to the same "BC-" + order ID as the browser event, plus SHA-256 hashed email, phone, name, and zip from the billing address. That's where EMQ jumps. Pass along _fbp and _fbc too if you captured them at checkout.
- Google Ads — keep the browser conversion tag with enhanced conversions as primary, and use the webhook side to catch what the browser missed via an offline-style upload keyed on gclid.
One honest caveat on GA4: the Measurement Protocol needs the visitor's client_id, and the webhook doesn't have it unless you stashed the _ga cookie value on the order during checkout. For most stores I leave the GA4 purchase in the browser, use the webhook for Meta and Google Ads, and reconcile GA4 against the orders report monthly. Within about 5% is healthy.
Also subscribe to store/order/statusUpdated if your payment methods authorize before capture — fire on paid status, not creation, or you'll report orders that never complete.
How do you keep deduplication from falling apart?
One rule: every platform gets exactly one owner. If you set up your own Meta Pixel in GTM plus your own CAPI feed, turn the native Meta channel's tracking off. Running both means two browser Purchase events with different (or missing) event_ids, and Meta can't deduplicate what doesn't share a key. You'll double-count and scale budget into a mirage.
Verify instead of assuming. Place a test order and check in Meta Events Manager that the browser and server Purchase events both arrive and show as deduplicated. Then compare a week of Events Manager purchases against your orders report. Within a few percent, it works. A 30% overage means something's double-firing, and I'd put money on a forgotten native integration.
Where does first-party server-side tracking fit on BigCommerce?
The native integrations covered above are browser-only, and that's their ceiling: they can only report what a shopper's browser is willing to run. On a store doing real volume, ad blockers and iOS quietly shave conversions off every report those integrations feed.
BigCommerce's webhooks are the way out. An order-created webhook carries the full order — value, items, customer email — straight from the platform to a server-side GTM container running on your own subdomain. From there it goes to Meta CAPI, Google, and GA4 as a first-party event that no blocker touched, enriched with hashed customer data that lifts match quality, deduplicated against the browser event by shared event_id. Your reported revenue starts matching your control panel, and the ad platforms optimize on complete data instead of the visible subset. That's the difference between tracking most sales and tracking them all.
Frequently asked questions
How do I add Google Tag Manager to BigCommerce?
Go to Storefront → Script Manager, create a script with Head placement on all pages, and paste your GTM container snippet. Categorize it as Essential if you manage consent inside GTM with Consent Mode v2.
Does BigCommerce support Meta Conversions API natively?
The Meta channel handles its own event sending, but you don't control the parameters, event IDs, or customer data it includes. For full CAPI control you need your own setup via server GTM or an order webhook.
Why is my GA4 purchase count lower than my BigCommerce orders report?
Browser purchases only fire when the confirmation page loads with tracking allowed, so ad blockers, declined consent, closed tabs, and off-site payment returns all create gaps. Within about 5% is normal; bigger gaps mean a broken tag or consent misconfiguration.
Can I track BigCommerce checkout steps in Google Tag Manager?
Partially. The Optimized One-Page Checkout is a single-page app, so begin_checkout fires reliably on load, but individual steps need element visibility or history triggers that break when the checkout changes. Most stores are better off with solid begin_checkout and purchase events.
Should I disable the native Meta integration if I run my own pixel and CAPI?
Yes. Two Purchase sources without a shared event_id can't be deduplicated, so Meta double-counts your conversions. Every platform should have exactly one event source you control.
Which BigCommerce webhook should I use for purchase tracking?
store/order/created for the initial order, and store/order/statusUpdated if you want to fire conversions only when an order reaches paid status. The webhook gives you the order ID; pull full details from the Orders API.






