A customer finishes checkout on a Magento store, lands on the order success page, and taps the back button out of habit before hitting refresh to make sure the confirmation is really there. Nothing about that is unusual. Most people do it without thinking.
Magento thinks about it differently. The success page does not expire after the first view, and depending on how the purchase event was wired, that second look can get counted as a second order. No error appears anywhere. The order grid still shows one sale. GA4 shows two.
That is the kind of gap a typical Magento audit checklist was never built to catch, because it is auditing a completely different layer of the stack.
In this piece:
- Why GA4 revenue can drift from Adobe Commerce's own order data with nothing visibly broken
- The exact mechanism, straight from Magento's own source code, behind success-page duplicate purchases
- How Magento's store-view configuration scope quietly merges analytics data across brands
- A checklist a measurement-first Magento audit actually runs, beyond speed and security
Why the standard checklist never gets there
Search "Magento audit checklist" or "Magento 2 audit checklist" and the results cluster around the same three categories every time: performance (application mode, cache types, indexer schedule, Core Web Vitals), security (patch level, extension vulnerabilities, admin two-factor, file permissions, PCI DSS posture), and code quality (PHP_CodeSniffer against the Magento coding standard, PHPStan, PHPMD scores). That work is legitimate and worth doing on its own schedule.
None of it touches whether the order count GA4 reports for last month matches what Adobe Commerce's own sales grid says actually shipped. Those checklists are written by and for a different audience, developers and agencies optimizing uptime, patch compliance, and maintainability, and there is no reason for that discipline to also ask a measurement question. A measurement-first audit has no other job.
The checklist a measurement-first Magento audit actually runs
1. Check whether the purchase event re-fires on every reload of the success page
This is the one almost every setup skips, and it is specific to how Magento's checkout actually works. Magento's own Onepage\Success controller source clears the active cart quote on every request to the success page, but it does not clear the session's last-order reference, the getLastOrderId() and getLastRealOrder() values that the page's event dispatch reads from. The companion SuccessValidator class only checks that those session values exist before letting the page render again, it does not check whether this is the first view or the fifth.
In practice, that means the thank-you page stays "valid" and keeps serving the same order's data for as long as the session lives, unless the customer starts a new checkout, which resets those values. A refresh, a back-and-forward tap, or reopening the page from browser history all hit that same code path. If the purchase event on that template fires from the page render itself rather than from a deduplicated trigger, every one of those reloads looks to GA4 like another completed order.
2. Confirm transaction_id is unique and present on every purchase event
Google's own guidance on minimizing duplicate key events is direct: GA4 deduplicates purchase events that share the same transaction ID. If the dataLayer push on a Magento success page template sends the order's real increment ID as transaction_id every time, GA4 collapses repeat fires from the mechanism above into one event. If the value is missing, blank, or hardcoded, GA4 has nothing to deduplicate against, and every reload counts as new revenue.
3. Reconcile the order export against GA4, Meta, and Google Ads for the same window
Pull Adobe Commerce's sales order export for a 30-day window and compare total revenue against what GA4, Meta, and Google Ads each report as purchase revenue for the identical window. A small, explainable gap, timezone differences or a known excluded order status, is normal. A gap that is wide, growing, or specific to one channel is the signal that a tag, a success-page reload, or an offline-payment flow is being counted wrong somewhere upstream.
4. Check the Google Analytics configuration scope, not just Default Config
This is the Magento-specific trap that platforms without a multi-store architecture simply cannot have. Adobe Commerce's configuration model cascades through global, website, store, and store view scope, and the documentation is explicit that, outside single-store mode, the scope of every configuration field is shown in small text below its label, meaning a setting has to be deliberately applied at the right level.
The Google Analytics and Google Tag fields live under Stores > Configuration > Sales > Google API, and that configuration runs at store view scope. A merchant running multiple brands or regional storefronts on separate store views, but who only ever touched the measurement ID at Default Config, has every one of those store views quietly inheriting the same ID. Traffic that was supposed to report as three separate properties lands in one, with no error and no obvious symptom beyond numbers that never quite add up per brand.
5. Confirm a custom or fast checkout extension hasn't moved the success page
Plenty of Magento stores replace the default one-step checkout with a third-party or custom-built flow for speed or UX reasons. If that extension renders its success state at a different URL than the default checkout/onepage/success path, and the GA4 or GTM trigger watching for a purchase is still scoped to the old path, the purchase event simply stops firing. Nothing throws an error. The dashboard just quietly stops counting revenue from the exact flow that is actually converting customers.
6. Confirm checkout and account pages stay out of full-page cache
Magento's built-in full-page cache and most Varnish configurations already exclude checkout and customer-account URLs from the cacheable set, since that content is order-specific. The risk shows up when a custom Varnish VCL, a CDN rule, or an aggressive cache-warming plugin is added later and broadens what gets cached without re-checking that exclusion. A cached checkout or account page can serve one customer's data, or a stale measurement state, to someone else entirely.
7. Check what the consent extension is actually blocking
A consent management extension sits in front of every tag on this list, and a scope mistake here is invisible until someone tests it directly. Test the accept and reject paths from more than one region before trusting the configuration, the same verification a Google Consent Mode v2 rollout requires on any platform, Magento included.
8. Re-check after any extension, theme, or core update
Magento ships regular core and security patches, and tracking-adjacent extensions, checkout customizations, and currency modules update on their own separate schedules. A tracking audit run in January on a store that has since updated its checkout extension or added a store view for a new region is auditing a setup that no longer exists. Re-run the reconciliation in step 3 after any change that touches checkout, the success page, or a module with tracking permissions, not on a fixed annual calendar.
The one number that actually tells you if this is broken
Pull Adobe Commerce's sales order export for the last 30 days and compare total revenue against what GA4 reports as purchase revenue for the same window, broken out by store view if you run more than one. That single percentage gap tells you more about whether your numbers can be trusted than any cache score or security scan ever will. A small, explainable gap is normal. A gap that is wide, or that only shows up on one store view, is the signal that a success-page reload, a scope mistake, or a moved checkout path is quietly miscounting revenue.
If that gap shows up and nobody can say with confidence whether the purchase event deduplicates correctly or which store view actually owns which measurement ID, a fixed-scope Magento tracking audit reconciles every tag source against the order data directly, starting at $500 and delivered in one to two days, with the fee credited toward implementation if you move forward within 60 days. For a broader read across tracking, CRO, paid media, and reporting together, the full ecommerce audit service scopes all four in one fixed-price engagement on the same terms.
Platform-specific measurement gaps aren't unique to Magento. Shopify and WooCommerce each carry their own version of the same underlying question: does the revenue number on the dashboard match what the store platform says actually happened.

