Last updated November 5, 2026 · Ghazanfar · 11 min read
Ecommerce conversion tracking records each order, with its ID, value, currency and items, and sends it to GA4 and your ad platforms so they can attribute revenue to channels and campaigns. It works when every platform receives one purchase per order, with the same values, and the totals reconcile against your store backend.
I judge an ecommerce setup by one test: can I take last week’s orders from the store, line them up against what GA4 and the ad platforms recorded, and explain every difference? If I can, the tracking is healthy even when the totals disagree. If I can’t, the platforms are bidding on numbers nobody understands. This guide is about passing that test. It assumes you know the basics of how conversion tracking works, which my conversion tracking guide covers.
It should carry everything any platform needs, in one consistent data layer push: the order ID, value as a number, currency, tax, shipping, the items, hashed customer data and an event ID for deduplication.
GA4 defines the purchase parameters in Google’s GA4 ecommerce developer guide, and I use that structure as the base even for stores that don’t care about GA4, because Google Ads and Meta tags can read from it in GTM. The order ID matters more than people expect. It is what Google Ads uses to drop duplicates, what Meta deduplication can key on, what refunds and adjustments reference, and what makes reconciliation possible at all.
From the moment the platform confirms the order, either in the browser on the confirmation event or from the server on the order webhook. A page view of the thank-you URL is the weakest option, and it is still the one I find most often.
| Trigger | Reliability | Risks |
|---|---|---|
| Thank-you page view | Low | Fires again on reload, back button and bookmarks; misses buyers who close the tab before it loads |
| Platform confirmation event in the browser | Good | Still lost to blockers and declined consent; needs a reload guard on some platforms |
| Server event from the order webhook | Highest | Needs browser identifiers passed through to attribute the order; more setup |
On Shopify, the confirmation event is checkout_completed in Customer Events, which I cover in my Shopify Google Analytics conversion tracking guide. On WooCommerce, it is the order-received page, which needs a guard so reloads don’t resend the order. I walk through that in my WooCommerce Google Ads conversion tracking guide.
Send each order from one source, once, with the order ID attached. Each platform then has its own safety net, but none of them should be relied on to clean up a setup that fires twice.
The most common duplicate source I find is a native platform integration left running after someone added GTM tags for the same platform. Every app that says it “adds tracking” is a candidate.
Export a closed week of orders from the store, export purchases by transaction ID from each platform, and join them on the order ID. Each mismatch falls into a bucket, and each bucket points at a different fix.
A small gap where GA4 is lower than the store is normal, because some buyers never load the confirmation page with tracking allowed. What matters is that the gap is explained and stable. The Shopify version of this exercise is in why your GA4 revenue doesn’t match Shopify.
Handle them per platform, because each one supports something different, and keep the store as the record for net revenue.
GA4 accepts a refund event with the transaction ID, which reduces revenue in ecommerce reports. Google Ads lets you retract a conversion or restate its value using the order ID, as Google explains in its guide to conversion adjustments. For stores with high return rates, I send restatements so value-based bidding learns from net revenue. Meta has no retraction that I can use, so I account for returns when reading Meta ROAS. In every case, refunds are sent from the backend when they are processed, never from the browser.
It helps when you are losing purchases to blockers and browser restrictions, or when you want the ad platforms to receive better customer data than the browser can safely send. It does not fix a broken purchase event.
The pattern I build is a server GTM container on your own subdomain, hosted on Stape, that receives the purchase from the browser and forwards it to GA4, the Google Ads tag and the Meta Conversions API with the same order ID and event ID. For stores where the browser purchase is unreliable, the order webhook can feed the server container directly. Details are on my server-side tracking service page.
Build one data layer and let every platform tag read from it. When each tag scrapes the page or uses its own app, values drift apart and duplicates creep in.
For the Google side specifically, my Google Ads conversion tracking guide and GA4 conversion tracking guide go deeper.
If your tracked revenue doesn’t reconcile with your store, I can audit and rebuild the purchase tracking across GA4, Google Ads and Meta, and prove the fix against your orders.
The store backend is the source of truth for orders and revenue. GA4 tells you which channels drove them, and each ad platform tells you what it thinks its own ads drove. I use the store to judge whether tracking is healthy and the other tools for attribution.
Pick one definition and use it on every platform. I usually send product revenue after discounts and before tax and shipping as value, and send tax and shipping as separate parameters where the platform accepts them. Mixing definitions across tools makes reconciliation impossible.
Fire the purchase once, from the order confirmation event or the server, and send the order ID with it. Google Ads uses the order ID to drop duplicates, and Meta uses the shared event ID. For GA4, the fix is making sure only one source sends the purchase.
Not always. It helps most when a large share of buyers use Safari or ad blockers, or when you want Meta and Google to receive richer customer data. A clean browser setup comes first, because the server only forwards what it receives.
Send a GA4 refund event with the transaction ID, retract or restate the Google Ads conversion using the order ID, and treat the store as the record for net revenue. Meta has no retraction I can use, so I account for returns in reporting.
Weekly for a new or recently changed setup, then monthly once it is stable. Any theme change, checkout change or new app is a reason to run the comparison again.
About the author
I’m Ghazanfar, founder of Analytigrow and a conversion tracking specialist. For 7+ years I’ve audited and rebuilt ecommerce tracking on Shopify and WooCommerce across GA4, Google Ads, Meta Pixel and Conversions API and server-side GTM on Stape, for stores in the US, UK, EU and UAE. I’m Top Rated on Upwork with 100% Job Success. Reach me at [email protected] or on WhatsApp.
A tracking audit tells you exactly which events are wrong, why, and what it takes to fix them. No pitch deck, just the findings.