GA4 ecommerce tracking not working: find lost purchases

GA4 shows fewer orders than your store backend? The likely causes, from consent to double counting, and how to find each one using DebugView.

ecomando editorial9 min read
Contents
  1. Measure the gap before you hunt for it
  2. The most common causes at a glance
  3. Cause 1: the purchase event does not fire
  4. Cause 2: consent blocks measurement
  5. Cause 3: double counting
  6. Cause 4: revenue is wrong but the order count is right
  7. Cause 5: items missing from the report
  8. Cause 6: the payment provider as the source of all revenue
  9. Cause 7: a drop with a date on it
  10. The full check sequence
  11. What correct data lets you do differently

Your backend shows 240 paid orders for the month. GA4 shows 187 purchases. Or the other way round: GA4 reports more purchases than you actually had. Either way, every analysis built on top of it is worthless, because conversion rate, ROAS and channel performance are all being calculated from the wrong number. This article works through the causes in the order you should check them, from most to least common.

Measure the gap before you hunt for it

Before you change anything, you need a gap you can trust. Otherwise you will chase a problem that does not exist.

  1. Pick a completed month, not the last seven days. Short windows swing too much.
  2. Read the number of paid orders and the revenue for that month in your store backend.
  3. Read purchases and revenue for the same period in GA4, under Monetization.
  4. Watch two traps. The time zone of your GA4 property has to match the time zone your store reports in, otherwise day boundaries shift. And you need to know whether your backend has already deducted cancellations and refunds.
  5. Calculate the gap as a percentage.

Example for illustration: backend 240 orders, GA4 187 purchases. That is roughly a 22 percent gap, which as an experience value is far too much to shrug off. At 240 against 232 there would be nothing to investigate.

A degree of undercounting is normal and technically unavoidable. Ad blockers, declined measurement, browsers with strict tracking protection and abandoned page loads all take their cut. Do not expect the numbers to match exactly.

The most common causes at a glance

SymptomLikely causeWhere you look
GA4 counts clearly fewer purchasesMeasurement blocked when visitors decline in the bannerConsent settings, consent rate
Purchases counted, revenue emptycurrency or value missingDebugView, parameters of the purchase event
No purchases at allpurchase does not fire on the confirmation pageDebugView during a test order
GA4 counts more purchases than the backendEvent sent twiceThe same transaction_id appearing repeatedly
Revenue correct, items missingitems array empty or wrongly namedDebugView, item report
Revenue systematically too high or too lowShipping or tax inside value differs from the backendYour definition of value
All purchases come from a payment providerThe redirect starts a new sessionUnwanted referrals list in the data stream
Purchases only for one payment methodThat method has no classic thank-you pageOne test order per payment method
A sudden drop on a specific dateTheme, app or tag changeChange log, release dates
Numbers drift apart slowlyRising share of ad blockers and strict browsersChannel and device breakdown

That is the short version. Now the detail.

Cause 1: the purchase event does not fire

The classic. Check it like this:

  1. In GA4, open the admin area and then DebugView.
  2. Enable debug mode on your device, either through preview mode in Google Tag Manager or with the Google Analytics Debugger extension for Chrome.
  3. Place a real test order. Do not simulate it. Use a high-value discount code or a test payment method if your store supports one.
  4. Watch DebugView during checkout. Does purchase appear, and when?

If purchase never shows up, it is usually one of these:

The confirmation page does not load the tag. On many platforms the thank-you page is built differently from the rest of the store. A tag that only lives in the regular theme never runs there.

The order does not end on a page of its own. Some payment methods and express checkouts complete the purchase in an overlay or redirect straight to a provider status page. Then there is no page view to attach the event to.

The data for the event is not ready yet. If the script reads the order value out of the page content but executes before the page is assembled, it sends an empty or incomplete event.

Test every payment method individually. It happens often that card and PayPal are measurable while a wallet, a buy-now-pay-later option or an express checkout is not, and if that share is large it explains the whole gap on its own.

If your consent banner only releases measurement after agreement, every order from a visitor who declines or ignores the banner is missing. That is intentional behavior, not a bug. You just have to account for it.

How to get close to the magnitude:

  • Most banner tools report a consent rate. Read it.
  • Multiply backend orders by the consent rate for a rough ceiling on what GA4 can receive.
  • If GA4 lands in that range, your tracking is technically fine. If it lands far below, keep looking.

Worked example: 240 orders in the backend, consent rate around 78 percent. That predicts roughly 187 purchases in GA4, exactly the figure from the example above. In that case the tracking was never broken.

Also check that the banner actually releases measurement after agreement. A frequent fault: the visitor consents, but the analytics tag only activates on the next page view. Then the session start is missing and the purchase ends up as a direct visit with no source. What is legally required of your banner, and how consent must be stored, is a question for your lawyer or data protection officer.

Cause 3: double counting

When GA4 shows more purchases than your backend, it is counting things that did not happen. Three typical triggers:

The tag is installed twice. Once through the platform integration and once manually in the theme. Then every event fires twice, not just purchase. A tell-tale sign: page views are suspiciously high and engagement time looks unrealistic.

The confirmation page gets reloaded. The customer hits refresh, forwards the confirmation email to themselves and opens the link, or uses the back button. Without protection, purchase fires again each time.

No transaction_id. Google states that Analytics deduplicates purchase events with the same transaction ID, so a unique order number is your safety net. If transaction_id is missing or regenerated on every load, that protection never engages. One trap from the same help page: never send an empty string, because Analytics then deduplicates every purchase that has transaction_id="" and you lose real orders instead of duplicates.

The fix: always send the real order number as transaction_id, and trigger the event once per order, either server-side or guarded by a session flag. Google's GA4 ecommerce measurement documentation lists which parameters belong to each event and marks transaction_id as required for purchases and refunds.

Cause 4: revenue is wrong but the order count is right

If purchases match and revenue does not, the problem is your definition of value. Answer three questions and write the answers down:

  • Gross or net of tax?
  • Shipping included?
  • Discounts already deducted?

Then compare against the definition your backend reports. Very often the store sends gross including shipping while the backend reports net merchandise value. Neither is broken, they are just not comparable. Google's own recommendation for value is the sum of price × quantity across all items, excluding shipping and tax — if you follow that, write it down so the difference to your backend total stops being a surprise every month.

Also check that value is sent as a number, not as text. A value like 1.299,00 in a localised format, or a currency symbol inside the field, means GA4 books nothing or nonsense. What it expects is a plain number with a dot as the decimal separator and no symbol. And currency has to travel with it: the reference states that if you set value, currency is required for revenue metrics to be computed accurately. It takes a three-letter ISO 4217 code such as USD.

Cause 5: items missing from the report

Purchases and revenue are there, but the item report stays empty or shows strange entries. Then the items array is the problem.

In DebugView, on the purchase event, check:

  • Is items present at all?
  • Does every entry have item_id and item_name?
  • Are price and quantity correct per item?
  • Are the item_id values the same ones used in view_item and add_to_cart?

That last point gets overlooked constantly. If the product page sends the SKU and the order page sends the variant ID, GA4 cannot connect the path from view to purchase, and your funnel shows jumps that are not real.

Cause 6: the payment provider as the source of all revenue

If your traffic acquisition report suddenly shows a payment provider as your best channel, the picture is clear: the redirect out to pay and back starts a new session, and the purchase is credited to that session.

The fix: in the data stream, open the tag settings and the list of unwanted referrals, then add the domains of every payment provider your customers pass through. The setting takes effect from the moment you save it, not retroactively.

Cause 7: a drop with a date on it

When the curve falls off a cliff on one specific day, it was not a gradual problem, it was a change. Work backwards:

  1. Note the date from the GA4 report.
  2. Find out what happened that day: theme update, new app or extension, a change to the consent banner, a new payment module, a checkout rebuild.
  3. Check whether an app was removed that had been providing the tracking. This happens more often than people expect.

Which is why it pays to keep a dated list of technical changes. Without it, debugging is guesswork.

The full check sequence

Work top to bottom, not at random.

  1. Measure the gap properly. Full month, matching time zone, refunds accounted for.
  2. Factor in the consent rate. If that explains the gap, you are done.
  3. Test order with DebugView. Once per payment method.
  4. Check the parameters. transaction_id, value, currency, items.
  5. Check for double counting. Same order number twice? Tag installed twice?
  6. Align the value definition. Gross or net, shipping, discounts.
  7. Check the referral exclusion list. Payment providers excluded?
  8. Look at the time series. Is there a date for the break?
  9. After the fix, observe for two weeks and recalculate the gap.

If your store runs on Shopify, the platform-specific gaps and the differences between Shopify's own revenue figures and GA4 are worked through in Shopify revenue does not match GA4.

What correct data lets you do differently

Once GA4 and your backend agree, three analyzes become usable that were noise before.

The purchase journey. In the Monetization section, GA4 ships two standard reports for this, the purchase journey report and the checkout journey report. They show how many users drop off between each step from product view through cart and checkout to purchase. They only work when the events in that chain are all firing with consistent item IDs, and their steps cannot be edited, so for anything beyond the standard sequence build a funnel exploration. The expensive drop-offs it reveals are the subject of reduce cart abandonment.

Channel assessment. Only with correctly attributed purchases can you say which channel brings revenue and which one only brings sessions. That is also the point where your core store metrics start to mean something, including how to calculate ROAS and your conversion rate.

Advertising decisions. When bidding runs on conversions, data quality decides how your budget gets spent. The case where clicks arrive and conversions do not, and how much of that is a tracking artefact, is covered in Google Ads: clicks but no conversions.

Put a recurring appointment in your calendar to compare GA4 revenue and backend revenue once a month. Tracking does not stay correct on its own; it breaks at the next change to your store. In ecomando this comparison runs as a measurement-coverage check, so a break does not surface three months late.

Frequently asked questions

How big may the gap between GA4 and my store backend be?

A small single-digit percentage gap is normal, because ad blockers, declined measurement and time zones always cost something. Once GA4 shows persistently and clearly fewer purchases than your backend, there is a technical fault worth hunting.

Why does GA4 show more purchases than my store?

Almost always the purchase event is sent twice, either because the tag is installed twice or because the confirmation page fires again on reload. Check whether the same transaction_id appears more than once.

What is the fastest way to check the purchase event?

Open DebugView in the GA4 admin area, enable debug mode on your device and place a test order. DebugView shows the event with all its parameters within seconds.

Does a consent banner cost me order data?

Yes. If visitors decline measurement, their events are not collected or only partially. How much you lose depends on your consent rate, so learn that rate before declaring your tracking broken.

Does the currency parameter have to be in the purchase event?

Yes, whenever you send a value. Google states that currency is required for revenue metrics to be computed accurately, so without it your revenue figures can stay empty or wrong even though the purchases themselves are counted.

Keep reading