GA4 Ecommerce Tracking: The Events, the Items Array, and What Breaks

ga4 ecommerce

GA4 ecommerce tracking is a specification, not a checkbox. You send a defined set of events with a defined items array, and the Monetization reports populate. Send them slightly wrong and the reports still populate — with numbers that quietly disagree with your store’s back end, which is worse than no data at all.

Universal Analytics called the full version “enhanced ecommerce.” That naming is dead along with UA, which stopped processing data on 1 July 2023. In GA4 there is one ecommerce implementation and the parameter names are different from what you may remember.

Events, not hits

Everything in GA4 is an event. Ecommerce is a set of recommended event names that GA4 recognizes and maps into purpose-built reports. Use the exact reserved names — add_to_cart, not addToCart or cart_add. A custom name still collects, but it lands in the generic events report and never reaches Monetization.

Each ecommerce event carries an items array. That array is the payload; the event name is just the context. Getting the array right matters more than getting every optional event fired.

The event sequence worth implementing

A complete funnel, in the order a shopper triggers it:

  • view_item_list — category or search results page renders products
  • select_item — shopper clicks a product from that list
  • view_item — product detail page loads
  • add_to_cart / remove_from_cart
  • view_cart
  • begin_checkout
  • add_shipping_info / add_payment_info
  • purchase
  • refund — full or partial

Promotion events (view_promotion, select_promotion) and add_to_wishlist are optional extras. If you are starting from nothing, ship view_item, add_to_cart, begin_checkout, and purchase first. That four-event spine gives you a usable funnel; the rest is refinement.

Mark the milestone events as key events — GA4’s 2024 rename of what used to be called conversions — but be selective. Flagging every step in the funnel as a key event makes your conversion rate meaningless, because a single shopper generates six of them on the way to one order. Purchase, and possibly begin_checkout for lead-gen style analysis, is enough.

Anatomy of the items array

Each object in the array describes one product. The fields that carry real analytical weight:

  • item_id — your SKU. At least one of item_id or item_name is required; send both.
  • item_name — human-readable product name, consistent across every event.
  • price — unit price as a number, not a string, and without currency symbols.
  • quantity — integer.
  • item_brand, item_category (through item_category5), item_variant — your merchandising dimensions.
  • index — position in the list, which makes view_item_list analysis meaningful.
  • item_list_id, item_list_name — which list the product was seen in.
  • coupon, discount, affiliation — promotional and channel context.

Consistency across events is the thing to guard. If view_item sends item_id “SKU-1024” and purchase sends “sku1024”, GA4 treats them as two products and your product-level funnel is fiction. Pull the values from one source in your code, not from three different templates.

Keep arrays reasonable — batching hundreds of items into a single view_item_list event risks hitting event size limits and getting the payload dropped. Send the products actually visible, not the entire catalog.

Use item_category thoughtfully. The five category levels are meant to be a hierarchy — apparel, then footwear, then running — not five unrelated attributes crammed into adjacent fields. Mapped properly they let you analyze revenue by department without touching BigQuery, which is the single biggest payoff from getting the items array right on the first attempt.

Purchase: the non-negotiables

The purchase event has requirements the others do not:

  • transaction_id — required, and it is what GA4 uses to deduplicate. Without it, a customer refreshing the thank-you page books a second sale.
  • value — the revenue figure. Decide once whether it includes tax and shipping, document that decision, and never change it mid-year.
  • currency — required whenever value is present, as a three-letter ISO code. Omit it and the revenue may not appear in reports at all.
  • items — the array, populated. A purchase with revenue but no items gives you totals with no product detail.

Mark purchase as a key event — GA4 renamed conversions to key events in 2024 — so it flows into attribution and the Advertising reports.

Implementation routes

Three realistic paths, in rough order of how much control you get:

  1. Platform plugin or native integration. Shopify, WooCommerce extensions, and similar handle the common events. Fastest to ship, least control, and you should still verify what they actually send rather than trusting the marketing copy.
  2. dataLayer plus Google Tag Manager. Your developers push a structured ecommerce object to the dataLayer; GTM reads it into GA4 event tags. The standard professional setup, and the one that survives redesigns.
  3. Server-side, via the Measurement Protocol or server-side tagging. The only reliable way to capture purchases that complete off-site or after a redirect, and it is immune to ad blockers and script failures. More work, and you have to handle session identifiers yourself.

Plenty of stores run a hybrid: client-side for the browsing funnel, server-side for the purchase confirmation. That is a sound design, provided you deduplicate on transaction_id.

Whichever route you pick, keep the event definitions in one place. The failure pattern is a plugin firing add_to_cart, a developer firing purchase from the template, and an agency firing begin_checkout from GTM — three owners, three item schemas, and a funnel that never reconciles. One owner for the ecommerce dataLayer contract is worth more than any single tracking feature.

Validating before you trust it

Do not judge an implementation from the Monetization reports on day one. Standard reports lag, sometimes 24 to 48 hours.

  • Open DebugView and complete a real test transaction. Click into each event and inspect the parameters, including the items array. This is where typos surface.
  • Use the Realtime report to confirm the events arrive from production traffic, not just your debug session.
  • After 48 hours, reconcile GA4 revenue against your store’s back end for the same date range. A gap under about 5% is normal — ad blockers, consent refusals, and timing differences account for it. A gap of 30% means something is broken.
  • If BigQuery export is on, query the raw events. It is the fastest way to find inconsistent item_ids across events.

What usually breaks

The recurring offenders, and what each looks like:

  • Duplicate purchases. Same transaction_id firing on refresh should dedupe; different or missing transaction_ids will not. Symptom: revenue higher than the back end.
  • Missing currency. Revenue silently absent or wrong. Symptom: transactions counted, value near zero.
  • Payment gateway self-referrals. The shopper returns from a third-party checkout and starts a new session attributed to that gateway. Fix by adding the gateway domain to unwanted referrals, and configure cross-domain measurement if checkout sits on your own subdomain set.
  • Price sent as a string. “$49.00” is not a number. Symptom: item revenue empty.
  • Refunds never implemented. Net revenue overstates reality all year.
  • Data thresholding. Low-volume rows can be withheld when identity signals could identify individuals. Symptom: breakdowns that do not sum to the total.

Connecting ecommerce data to organic search

Once purchase data is clean, the useful question for SEO is which page roles and which queries produce revenue. GA4 answers half of it: session channel, landing page, and revenue. It cannot answer the other half, because GA4 does not report search queries — Search Console is the source for those, and the linked Search Console reporting inside GA4 exposes a limited slice.

SEO Rocket connects Search Console and GA4 as ground truth for your own site and shows that measured data next to third-party estimates, clearly labeled so nobody confuses a modeled traffic figure with a booked sale. It does not implement your ecommerce tracking or replace GA4 — the items array above is still yours to build correctly. What it does is put the measured revenue picture beside the ranking and query picture, so the pages you invest in next are chosen on evidence rather than on whichever dashboard was open at the time.