Duplicate purchases in GA4 and revenue that doesn’t match the store
Published by the UTM Builder team at Limner.
GA4 counts the purchase events it receives. When it shows more purchases than the store has orders, the most common cause is two installations sending the same purchase, or a thank-you page that fires again. A revenue gap usually comes from the rules instead: shipping left out of value, manual orders, cancellations, and Pix (Brazil’s instant payment system) or boleto (a bank payment slip) counted before the customer pays.
What GA4 does with transaction_id
Google Analytics Help says that if two purchases arrive with the same transaction ID, GA4 removes the duplicate. The same article has three caveats:
- Deduplication only applies to data from web streams. A purchase recorded in an app doesn’t go through it.
- Don’t send an empty ID. With
transaction_id="", GA4 deduplicates every purchase that arrives that way, and they all collapse into one. - Reusing the same ID across different orders brings the count down. Use the order number, which is unique, and never the customer’s email or CPF (Brazilian taxpayer ID).
In Google’s event reference, transaction_id, value and currency are required on purchase.
gtag('event', 'purchase', {transaction_id: '10293', value: 249.90, shipping: 19.90, currency: 'BRL', items: [...]});
Two installations sending the same purchase
Nuvemshop’s partner guide says not to run the native GA4 integration and GA4 through GTM at the same time, to keep one GA4 tag and one GA4 ID active, and not to repeat scripts in the External codes section. The recommendation is to use the native integration and leave GTM only for what it doesn’t cover, such as WhatsApp clicks and forms. The same guide warns that with everything in GTM, events are only captured while the page is open, and refunds aren’t sent.
Loja Integrada installs GA4 through an app (Solutions > Apps) and tells you to turn off GA3 when you install GA4, so conversions aren’t duplicated. On Shopify and Tray the rule is the same: one purchase source per store. If the two sources send different IDs for the same order, each one becomes a purchase.
Reloaded thank-you page
VTEX documents this as a known issue: the transaction goes to Google Analytics when the order confirmation page loads, and reloading or returning to it fires the event again. VTEX says there’s no workaround for this kind of front-end integration and suggests sending the purchase from the back end, connecting the order APIs to Google Analytics. On any platform, check that the ID you send is the order number, identical on every load. With the same ID, web deduplication absorbs the repeat.
Pix and boleto counted before payment
On Nuvemshop, when purchase fires is set under Settings > External codes: at order completion or at payment confirmation. At order completion, Pix and boleto orders that were never paid count as purchases. At payment confirmation, the unpaid order shows in the store dashboard as started and stays out of GA4.
Kiwify has an option to send purchase when a Pix code or boleto is generated, and it lets you set a custom conversion for each payment method. If that option is on, GA4 counts the Pix being generated, not the payment.
Revenue gaps with no duplicates at all
- Shipping. Google’s reference defines
valueas the sum of price times quantity for the items, without shipping or tax, which go inshippingandtax. The store dashboard usually shows the total paid. - Commission. On Kiwify, the
valuesent to GA4 is the producer’s commission, not the amount the customer paid. - Orders that don’t go through the site. Nuvemshop notes that manual orders and orders created by apps don’t reach GA4.
- Cancellations and refunds. According to Nuvemshop, GA4 only recognizes the cancellation of an order that was already paid, removes the revenue on the refund date, and accepts the refund event up to 3 days after the purchase. GA4’s Purchase revenue metric already subtracts refunds.
- Time zone and delay. Compare in the same time zone. Nuvemshop points out that GA4 can take up to 24 hours to update.
How to check
- Place a test order with debug mode on and open Admin > Data display > DebugView. Count how many
purchaseevents arrived and look at thetransaction_idandvalueof each one. - Reload the thank-you page and see whether a second
purchaseshows up. - In an exploration, use the Transaction ID dimension with the Transactions and Purchase revenue metrics. Export the period and compare it with the store’s order spreadsheet, in the same time zone, separating paid, canceled and manual orders.
Official sources
- Google Analytics: Minimize duplicate key events with transaction IDs
- Google Analytics: Events reference (purchase and refund)
- Google Analytics: Analytics dimensions and metrics
- Google Analytics: Monitor events in DebugView
- Nuvemshop: Partner guide, setting up Google products on Nuvemshop stores (in Portuguese)
- Nuvemshop: Why do my store’s Statistics differ from Google Analytics 4? (in Portuguese)
- VTEX: Duplicate transactions being recorded in Google Analytics
- Kiwify: How to add the Google Analytics pixel (in Portuguese)
- Loja Integrada: How to set up Google Analytics 4 on my store (in Portuguese)