Duplicate GA4 purchase events on Shopify: how to find the second one
GA4 says you took 180 orders last week. Shopify says 96. Your return on ad spend looks wonderful, and it is wrong. When GA4 reports more purchases than your store took, something is almost certainly sending the purchase twice. Here is how to prove it, find the second sender, and remove it.
The short answer: GA4 removes duplicate purchases only when they carry the same transaction_id, from the same user, on a web data stream. Two installs that each send the purchase with a different ID, or with no ID, are both counted.
On Shopify the usual cause is GA4 installed twice: once through the Google & YouTube app and again through Google Tag Manager, a custom pixel or code in the theme. Find it by listing your purchases by transaction ID in GA4, then confirm with one test order.
Why GA4 doesn't catch it for you
GA4 does have duplicate protection. Google's help page on transaction IDs says it deduplicates purchase events that share a transaction ID, but only within the same user, and only for data from web streams. Three situations get through:
- Different IDs for the same order. One install sends the order as one identifier, another sends a different one, for example an order name like
#1042and a long numeric order ID. To GA4 those are two orders. - No ID at all. A purchase without
transaction_idcannot be matched to anything, so every copy counts. - An empty ID. The opposite failure, and worth knowing about. Google warns that sending
transaction_id=""makes GA4 treat every such purchase as the same one, so it undercounts badly. If GA4 shows far fewer purchases than you took, check for this first.
Step 1: confirm the purchases really are doubled
Compare like with like before you go hunting. In Shopify admin, open Orders, filter by Sales channel › Online Store, and count orders for the last 7 full days. In GA4, read Transactions for the same days in Reports › Monetization › Ecommerce purchases, allowing for GA4's processing delay.
If GA4 is close to double, or noticeably above your online orders every day, you have duplicates. If GA4 is lower, this is not your problem: see Why Shopify and GA4 purchases don't match instead.
Step 2: list purchases by transaction ID
This is the quickest way to see how the purchases are being doubled, without touching the site.
- In GA4, open Explore and start a Free form exploration.
- Add the dimension Transaction ID and the metric Transactions (or Ecommerce purchases).
- Set the date range to a few recent days, and read down the list.
| What the list shows | What it means |
|---|---|
| Each order appears twice, in two different formats | Two installs, each sending its own ID for the order. This is the classic double install. |
A large (not set) row alongside normal IDs | One install sends purchases with no transaction ID. Every one of those counts, on top of the good ones. |
| One row with a blank ID and a huge count | An empty transaction ID. GA4 is merging those purchases into one, so you are undercounting. |
| Clean, one row per order | No duplicates by ID. If GA4 is still high, look for purchases from other sources, covered below. |
Would you rather check your store than read a checklist? AuditTag reads your public pages and shows whether GA4 and Google Tag Manager are both installed in your theme, a common starting point for a double install, in about a minute. Run a free audit →
Step 3: prove it with one test order
Open DebugView in GA4, and Tag Assistant if you use Tag Manager. Place a low-value order and refund it afterwards. Two purchase events for one order is the fingerprint. Tag Assistant shows which tags fired, which usually names the second sender.
You can also open your browser's developer tools on the confirmation page, go to the Network tab and filter for collect. Each request carrying en=purchase is one purchase sent to GA4. There should be one.
One testing trap, from Google's own validation guide: because GA4 deduplicates repeated transaction IDs, re-testing with the same ID can make a working event look missing. Use a fresh order for each test.
Where the second purchase comes from on Shopify
The Google & YouTube app plus another GA4 install
The most common version. The Google & YouTube app sends GA4 purchases through Shopify's own checkout events. Then GA4 is added again, through Tag Manager, a custom pixel or a snippet in the theme. Shopify's Tag Manager help page warns that adding Google Analytics through Tag Manager as well as its built-in integration can cause duplicate tracking.
Fix: choose one route for GA4 and remove the other. The app is the simplest to maintain. Tag Manager, run from a custom pixel, gives more control. Either works; both at once does not.
Two tags sending the purchase inside Tag Manager
A container that grew over time can end up with two GA4 event tags on the same purchase trigger, or a GA4 tag in the container while gtag.js is also hardcoded. Google's validation guide says plainly to use only one Google tag or Tag Manager instance per page.
Fix: in Tag Manager's preview, place a test order and check that exactly one tag fires on the purchase. Pause or delete the others.
A purchase rebuilt inside GA4
GA4 can generate new events from existing ones, under Admin › Events › Create event. A rule that creates a purchase from another event, set up once as a workaround, keeps adding a second purchase long after the real one was fixed.
Fix: check the Create event list for anything that outputs purchase, and remove it if a real purchase event now exists.
Server-side and browser purchases with different IDs
Some setups send purchases from the server as well as the browser, through a server-side container or a tracking app. That can be fine, but only if both send the same transaction ID, so GA4 can collapse them. If each side builds its own ID, both count.
Fix: make every sender use the same order identifier as transaction_id, or send the purchase from one side only.
Hand-built code on the confirmation page
Shopify's checkout_completed event fires once per checkout, so purchases sent through the app or a Customer events pixel do not repeat when a customer revisits their order page. Old custom code on that page can, and without a transaction ID every revisit is a new purchase.
After the fix
- Test again with a fresh order: one
purchasein DebugView, with a transaction ID matching the Shopify order. - Re-run the exploration after a few days of new data. One row per order is the goal.
- Remember Google Ads. If you import GA4 purchases into Google Ads as a conversion, the duplicates were inflating that too. Google Ads has its own transaction ID deduplication, but only when the ID is sent.
- Old data stays doubled. Reports for the period before the fix will not correct themselves. Note the date so nobody compares across it without knowing.
What AuditTag checks on your public pages
- GA4 detected in the page source
- Google Tag Manager detected
- Google Ads tag and Meta Pixel detected
- Legacy Universal Analytics still present
What this doesn't prove
Seeing GA4 and Tag Manager together in your theme is a reason to check for a double install. It does not prove the purchase is sent twice. The Google & YouTube app and Customer events pixels may not appear in the page source at all, and the audit cannot see inside checkout. The exploration and a test order are the proof. Catching a second install the day an app adds it is what Guardrails monitors.
See what's installed in your theme
The free audit reads your public pages and tells you which tracking it can detect: GA4, Google Tag Manager, Google Ads and Meta Pixel. It takes about a minute. No account, no card, nothing installed, and it never touches your store.
Run a free audit →The audit confirms presence on your public pages. Watching what GA4 actually receives, and catching the day it changes, is what Guardrails monitoring covers.