Playbook Tracking and analytics
Shopify GA4 purchase event firing twice: the fast fix
Duplicate purchase events in GA4 on Shopify almost always come from two sources firing the same event, or the thank-you page being reloaded. Here is how to find the source and stop the double count.
If your GA4 purchase event is firing twice on Shopify, your revenue in GA4 will read high and stop matching Shopify. The cause is almost always one of two things: two different sources are both sending the purchase event, or a single source re-fires when the customer reloads the thank-you page. Here is how to tell which, and fix it.
Why a double purchase event quietly costs you money
A doubled purchase event is not just a cosmetic reporting error. It feeds every decision downstream. Your conversion rate looks better than it is. Your return on ad spend looks higher than it is, so you keep scaling campaigns that are not actually paying back. If GA4 is wired to your Google Ads account, the inflated conversions train the bidding algorithm on numbers that were never real. By the time someone notices the GA4 total is twice the Shopify payout, weeks of spend decisions have been made on a lie. That is the real cost, and it is why this is worth fixing the same week you spot it.
Find the source first
Do not change anything until you know what is firing. Open GA4 DebugView, place a test order, and watch the purchase event land.
Count the purchase events in DebugView
Complete one test checkout and watch DebugView. If you see two purchase events for one order, you have a duplicate. Click each one and compare the parameters.
Check whether the transaction_id matches
If both events carry the same transaction_id, GA4 can deduplicate them and the fix is simple. If they carry different IDs, or none, that is why your revenue is doubling.
Read the timestamps to tell reload from two sources
Two events a fraction of a second apart point to two sources firing on the same page load. Two events minutes or hours apart, on the same order, point to a reloaded or revisited thank-you page. The gap tells you which problem you have.
Where Shopify can send a GA4 purchase from
Before you can pick one source of truth, you have to know every place a purchase event can originate on a Shopify store. On most stores that have been worked on by more than one person over the years, several of these are live at once:
- The native Google & YouTube channel. Shopify’s own Google connection can send GA4 ecommerce events, including purchase.
- A Google Tag Manager container, firing purchase from a Customer Event (a Web Pixel) or from a tag on the order status page.
- A hardcoded gtag snippet pasted into
theme.liquidor into the old Additional Scripts box on the checkout settings. - A third-party app, such as a subscription tool or a post-purchase upsell, shipping its own analytics.
Any two of these running together will double your purchases. All four, and you will see far worse than double.
The two usual causes
Two sources firing. The most common setup that breaks this way is Shopify’s native Google and YouTube channel sending GA4 purchases, while a second GTM container or a hardcoded gtag snippet in the theme sends its own. Both are correct individually. Together they double everything.
A reloaded thank-you page. If a single source fires on the order status page and the customer refreshes it, or returns to it from their email, the event can fire again. A stable transaction_id is what protects you here too.
Checkout extensibility moved where this breaks
If your store was set up before 2024, this is worth a careful look. Shopify has
moved checkout tracking away from checkout.liquid and the Additional Scripts
box toward Customer Events, also called Web Pixels, which run in a sandbox. A lot
of stores now have the new Web Pixel firing a purchase and an old script that was
never fully removed firing another. The old method looks switched off but is
still loading on the order status page. When you audit your sources, check the
new Customer Events area and the legacy scripts, because the duplicate is often
one of each.
The fix
Work through these in order
- Pick one source of truth for the purchase event, native or GTM, not both
- Remove the second source completely, do not just pause it
- Send the Shopify order number as transaction_id on every purchase
- Re-test in DebugView and confirm exactly one purchase per order
- Check GA4 revenue against Shopify for the next day to confirm they match
The principle underneath this is the same one that shows up everywhere in tracking: one event, one source, one stable ID. Get those three right and the numbers start telling the truth again. It is the same discipline that fixes low Meta event match quality, where the problem is rarely the pixel and almost always the data feeding it.
Verify it actually worked
A fix you cannot confirm is a guess. After you remove the second source, prove the change held before you move on.
Re-test in DebugView
Place another test order. You should now see exactly one purchase event, carrying the Shopify order number as its transaction_id.
Watch Realtime on a live order
For the next genuine order, open the Realtime report and confirm a single purchase lands. One real order is worth more than ten test orders.
Reconcile the next full day against Shopify
Compare GA4 purchase revenue for a complete day against the Shopify sales for the same day. They will rarely match to the cent, because of refunds, timezones, and attribution windows, but they should now be close, not double.
When it is not a duplicate at all
Sometimes the second purchase is real, or at least intentional, and the fix is to decide how you want it counted rather than to delete it. Subscription tools fire on the recurring charge. One-click post-purchase upsells can create a second transaction with its own order. Headless and custom builds sometimes fire both a client-side and a server-side purchase on purpose. None of those are bugs. They only become a reporting problem when they reach GA4 without a transaction_id that reflects what they are. Give each its own correct ID and GA4 will count them the way you actually mean.
This is the unglamorous core of the tracking and analytics work: not clever tags, but one event, one source, one stable ID, checked end to end.
If your GA4 revenue still will not match Shopify after this, the duplication is usually hiding deeper in the data layer, and that is the kind of thing a short tracking audit sorts out fast.