Ecommerce Analytics Setup for UK SMEs: 2 Events, Clean Purchase Data

The minimum viable GA4 ecommerce setup sends purchase and add_to_cart events with a correctly formed transaction_id, currency, value and an items array, implemented through a Google Tag Manager dataLayer and checked in DebugView before you trust a single number. Get that right first. Everything else, from attribution models to custom dimensions, builds on this foundation.


TL;DR:

  • Add view_item_list, select_item, view_item, and begin_checkout after validating the essentials; hosted platform integrations, including Shopify, may send only part of the event set.
  • Keep transaction_id, currency, and numeric value at event level; each item needs item_id or item_name, numeric price, and integer quantity inside items.
  • Deduplication applies only to web streams and requires a unique, nonempty transaction_id; compare GA4 totals with order records and inspect payloads in DebugView.
  • Choose open funnels when shoppers may arrive partway through, and closed funnels when measuring drop off among shoppers who followed every step from the start.
  • Register custom dimensions in Admin only after sending their parameters, because GA4 collects those values from registration onward and cannot report them retroactively.

Fyldedigital
Build a Stronger Ecommerce Presence
Fylde Digital helps businesses improve their digital presence through web design, SEO, PPC advertising and social media management.

Explore digital marketing services

Table of Contents

Which ecommerce events GA4 needs and when to fire them

GA4 recognises a defined set of ecommerce events, and Google’s developer documentation lists the recommended names and parameters for each one. You don’t need to fire all of them to get usable reports, but each one you skip removes a stage from your funnel.

The events that matter most, roughly in the order a shopper triggers them:

  • view_item_list: fires when a shopper sees a category or search results page, giving you visibility into what gets browsed.
  • select_item or select_promotion: fires when a shopper clicks a product from a list or a promotional banner.
  • view_item: fires on a product detail page load, confirming interest in a specific item.
  • add_to_cart: fires when a shopper adds an item to their basket, usually from a button click on the product page or a quick-add control.
  • begin_checkout: fires when the checkout flow starts, often the first step after the basket page.
  • purchase: fires on the order confirmation page once payment has cleared, and is the event that populates your revenue reports.

Of these, purchase and add_to_cart are genuinely essential. Without purchase, you have no revenue data at all. Without add_to_cart, you lose the ability to measure basket abandonment, an important ecommerce metric for retailers trying to understand where shoppers drop off. The others (view_item_list, select_item, view_item, begin_checkout) are strongly recommended because they let you build a full funnel exploration, but a lean first implementation can launch with just the two essentials and add the rest once they’re validated.

One caveat worth flagging early: platform-specific automatic collection is often partial. Google’s own guidance notes that some hosted platforms, Shopify being the most common example, send a subset of ecommerce events automatically through their native integrations, but merchants frequently still need custom events to get full coverage. Never assume a native integration covers everything; check which events actually fire before building reports on top of them. If your store runs on a hosted platform and you’re also leaning on SEO to drive product traffic, our piece on ecommerce SEO covers how tracking gaps on platforms like Shopify can distort which products you think are winning.

Required parameters and the items array: exact fields GA4 requires

GA4’s ecommerce reports depend on a strict set of parameters being present, correctly typed, on the right events. Get the structure wrong and the report tiles either stay empty or show numbers that don’t reconcile with your order system.

At the event level, three parameters are non-negotiable for purchase:

  • transaction_id: a unique string identifying the order, used for deduplication and reconciliation with your order system.
  • currency: the ISO currency code (for example, GBP), required for any monetary value to be interpreted correctly.
  • value: the total transaction value as a number, not a string.

Google’s documentation on populating ecommerce reports states plainly that these events and parameters are required for the standard ecommerce reports to work, and that revenue metrics fail to populate when they’re missing or incorrectly typed. Beyond the three required fields, tax, shipping and coupon are recommended extras that enrich reporting without being strictly mandatory.

Nearly all broken ecommerce reports trace back to one of a handful of formatting mistakes, according to Google’s own troubleshooting guidance, most commonly numeric fields sent as strings rather than native numbers. A value of "49.99" (string) behaves differently in aggregation than 49.99 (number), and this single error quietly breaks revenue totals without throwing any visible error in your dataLayer.

The items array carries its own required fields, one object per line item:

  • item_id or item_name: at least one of the two must be present to identify the product.
  • price: the unit price of the item, as a number.
  • quantity: the number of units purchased, as an integer.

Common mistakes that break item-level reporting include sending price as a formatted string with a currency symbol attached, omitting quantity and letting GA4 assume it’s 1 when it actually wasn’t, and duplicating the same item_id across genuinely different products because of a templating shortcut. Each of these corrupts the item-level breakdown even when the overall transaction total looks fine, which is exactly why relying on the top-line revenue number alone isn’t enough validation.

Event scope vs item scope: how to design your data model correctly

This is where most GA4 ecommerce implementations quietly go wrong. Google’s documentation on ecommerce scopes draws a clear line between parameters that describe the whole event and parameters that describe a single item within it, and mixing the two up is a leading cause of broken reports.

Event-scoped parameters describe the transaction as a whole: transaction_id, currency, the overall value, tax and shipping. They sit at the top level of the event payload, outside the items array.

Item-scoped parameters describe one line item: item_id, item_name, price, quantity, item_category. These sit inside each object in the items array, and a transaction with four different products needs four separate item objects, each carrying its own price and quantity.

Transaction event containing four separate item records

Where the same conceptual field could exist at both levels, such as a discount, item-level parameters take precedence over event-level ones for that specific item. If you set an event-level coupon but also set an item-level coupon on one line, GA4 attributes the item-level value to that item specifically rather than falling back to the event-level setting.

Pro Tip: Before you ship any ecommerce tag, open the dataLayer object in your browser console and check that every price and quantity lives inside an items array element, never floating at the top level next to transaction_id.

A short scoping checklist before you push to production:

  • Confirm transaction_id, currency and value sit outside the items array.
  • Confirm every line item has its own price and quantity inside items.
  • Confirm numeric fields are native numbers, not strings, at both levels.
  • Confirm the sum of item-level values reconciles with the event-level value.

Designing a reliable dataLayer for ecommerce

A dataLayer is only as reliable as its structure is predictable, and predictability comes from naming conventions and consistent field types, not from cleverness. Practitioner guidance from Amplitude makes a similar point about ecommerce analytics generally: building a genuinely useful dataLayer is a deliberate design exercise, not a case of installing a tracking pixel and hoping for the best.

A minimal add_to_cart push looks like this:

dataLayer.push({
  event: "add_to_cart",
  ecommerce: {
    currency: "GBP",
    value: 24.99,
    items: [
      {
        item_id: "SKU123",
        item_name: "Canvas Tote Bag",
        price: 24.99,
        quantity: 1
      }
    ]
  }
});

And a minimal purchase push, which carries the additional transaction-level fields:

dataLayer.push({
  event: "purchase",
  ecommerce: {
    transaction_id: "ORD-10492",
    currency: "GBP",
    value: 49.98,
    tax: 4.16,
    shipping: 3.50,
    items: [
      {
        item_id: "SKU123",
        item_name: "Canvas Tote Bag",
        price: 24.99,
        quantity: 2
      }
    ]
  }
});

Dynamic values such as the order number, the running total and tax should come from your checkout system’s own confirmation data, never hard-coded or guessed on the front end. If your platform renders the confirmation page server-side, pull transaction_id and value directly from the order object your backend already has, rather than recalculating them in JavaScript, where a rounding difference or a race condition can silently produce a mismatched total.

DataLayer field Scope Type Example value
transaction_id Event String “ORD-10492”
currency Event String “GBP”
value Event Number 49.98
item_id Item String “SKU123”
price Item Number 24.99
quantity Item Integer 2

On naming conventions: keep field names identical to Google’s own reference names (transaction_id, not orderId or order_number) so your GTM variable mapping stays simple and new team members can cross-reference the official docs without translating your custom naming scheme first. Version your dataLayer structure in whatever documentation your team already uses, a shared wiki page or a README in the tracking repository, and note the date any field changes shape. A dataLayer that drifts quietly between site releases is the most common reason historical GA4 data stops lining up with current data without anyone noticing for weeks.

Implementing ecommerce events in Google Tag Manager and gtag.js

Google Tag Manager is the recommended route for most implementations because it decouples tag logic from your codebase and gives your marketing team a way to adjust triggers without a developer redeploy. A typical GTM recipe:

  1. Install the GA4 Configuration tag, firing on All Pages, with your measurement ID.
  2. Create a GA4 Event tag for purchase, set to fire on a custom event trigger matching purchase in the dataLayer.
  3. Add Data Layer Variables for each parameter (transaction_id, currency, value, ecommerce.items) and map them into the Event tag’s parameter fields.
  4. Repeat steps 2 and 3 for add_to_cart and any other recommended events you’ve decided to implement.
  5. Set the trigger condition precisely: a purchase tag firing on every page load rather than only on the confirmation page will flood your reports with phantom transactions.

For teams implementing directly in code rather than through GTM, the equivalent gtag.js call for a purchase event looks like this:

gtag('event', 'purchase', {
  transaction_id: 'ORD-10492',
  currency: 'GBP',
  value: 49.98,
  items: [
    { item_id: 'SKU123', item_name: 'Canvas Tote Bag', price: 24.99, quantity: 2 }
  ]
});

Pro Tip: Whichever route you choose, pick one and standardise on it across your whole site; mixing GTM-pushed events with hard-coded gtag.js calls on different pages is a frequent source of duplicate or missing hits.

Server-side measurement protocol is worth considering once your implementation matures, particularly if you’re losing events to ad blockers or need to enrich hits with order data that only exists in your backend. It adds infrastructure overhead, so it’s rarely the right starting point for a first implementation, but it becomes attractive when client-side tracking alone starts producing gaps you can’t close with browser-based fixes.

Validation, debugging and deduplication: how to check your data is accurate

No ecommerce implementation should go live without a validation pass, and GA4 gives you three practical tools for it. DebugView, accessible from the GA4 admin panel once you’ve installed the GA Debugger browser extension or used Tag Assistant, shows events arriving in near real time with their full parameter payload, which is the fastest way to confirm transaction_id and items are shaped correctly before you trust the standard reports. The Realtime report gives a coarser but still useful check that events are firing at all. Browser developer tools, specifically the Network tab filtered to requests containing collect, let you inspect the raw payload GA4 actually received, which is the ultimate source of truth when DebugView and your dataLayer seem to disagree.

Deduplication deserves particular attention because duplicate purchase events are one of the most common ways GA4 revenue ends up inflated against your order system. Google’s own guidance on transaction verification is specific on this: deduplication only works for web streams, and the transaction_id must be unique per order and never an empty string, otherwise GA4 can either undercount through incorrect deduplication or fail to deduplicate a genuine repeat hit at all. A shopper refreshing the confirmation page, or landing back on it via the browser’s back button, is the classic trigger for a duplicate send.

A client-side customTask that stores seen transaction IDs in localStorage is a practical method to block duplicate purchase hits from being sent again.

That approach, documented by Simo Ahava, remains one of the most workable fixes for browser-side duplicate sends, though a server-side reconciliation step against your order system is worth adding if your stack already supports it.

A short validation checklist before you call the implementation done:

  • Confirm purchase fires once per order, not once per page view of the confirmation page.
  • Compare GA4’s total transaction count for a given day against your order system’s total.
  • Spot-check five recent orders’ value against their actual order totals.
  • Confirm item_id values in GA4 match real SKUs, not placeholder or null values.

Which GA4 reports and explorations to check once events are firing

Once your events are live, the Monetisation section of GA4’s standard reports is where ecommerce purchases and revenue metrics surface first, specifically the Ecommerce Purchases report, which breaks revenue down by item name, item ID and item category. It’s the quickest way to confirm whether item-level data is populating correctly rather than just the transaction total.

Beyond the standard reports, a handful of custom explorations are worth building early:

  • Checkout funnel exploration: chains view_item, add_to_cart, begin_checkout and purchase to show where shoppers drop off.
  • Item table exploration: breaks down revenue, quantity and add-to-cart rate by individual product.
  • Revenue by source/medium exploration: cross-references transaction revenue against the acquisition channel, useful for judging which campaigns actually convert.

Watch for a few specific warning signs once reports are live. A purchase event count that’s noticeably higher than your actual order count usually points to a deduplication failure. An items table with a large share of missing item_name values usually points to a templating bug on one product type rather than a systemic tracking failure. And a revenue figure that’s exactly double your order system’s total is almost always a duplicate-firing tag, not a currency or rounding issue, so check your trigger conditions before you go hunting for an exotic cause.

Practical implementation notes and Fylde Digital proof points

When we build ecommerce tracking for a small or medium-sized retailer, the project nearly always follows the same shape: audit the existing dataLayer (or confirm there isn’t one), map the events the store genuinely needs against its checkout flow, implement through Google Tag Manager, and validate every event against the client’s own order system before calling it live. We treat the reconciliation step as mandatory rather than optional, because a dashboard that looks plausible but doesn’t match the order data is worse than no dashboard at all.

Our web design and wider service range both fold in analytics setup as standard groundwork rather than a bolt-on, since a site redesign is the natural point to fix a broken dataLayer before it gets rebuilt on top of the same mistakes.

Ecommerce measurement in GA4 isn’t a single toggle you flip in the interface the way it was in Universal Analytics. Enhanced ecommerce reporting activates automatically once GA4 receives correctly structured ecommerce events, so the real setup work happens in your tag configuration rather than in a settings menu.

Start in your GA4 property’s Admin panel and confirm your Google tag (the measurement ID, formatted G-XXXXXXXXXX) is correctly installed on every page of your site, either directly or through GTM. If you’re using Google Tag Manager, link it to your GA4 property by adding the GA4 Configuration tag with that measurement ID, set to fire on all pages.

From there, ecommerce reports populate themselves the moment valid purchase and other recommended events start arriving, there’s no separate “enable ecommerce” switch to find. What you do need to check in Admin is that Enhanced Measurement is switched on for your web data stream, since it governs some automatic event collection (page views, scrolls, outbound clicks) that complements your custom ecommerce events without replacing them.

Linking GTM to GA4 is the practical dependency here: your ecommerce tags live in GTM, your reports live in GA4, and the Configuration tag is the thread that connects them. Get that link wrong (a mismatched measurement ID, or a Configuration tag that fires after your event tags) and every other step in this guide produces events that arrive at the wrong property or not at all.

Setting up user properties and custom dimensions for enhanced ecommerce insights

Standard GA4 ecommerce reports answer “what sold and for how much.” Custom dimensions and user properties answer the next layer of questions: who bought it, and under what circumstances.

A user property is a piece of data attached to a user across sessions, such as a loyalty tier or a registered account type, set via gtag('set', 'user_properties', {...}) or the equivalent GTM variable. A custom dimension, by contrast, is typically event-scoped data you want to report on that GA4 doesn’t capture by default, such as a product’s brand name, a checkout payment method, or a discount tier.

To make either usable in reports, you need to register it in Admin > Custom definitions after you’ve started sending the underlying parameter, since GA4 only begins collecting a custom dimension’s data from the registration date forward, never retroactively. A common mistake is sending a parameter in the dataLayer for weeks before realising it was never registered as a custom dimension, which means that historical data is unrecoverable for reporting purposes.

Useful ecommerce-specific custom dimensions to consider registering early include payment method, shipping tier selected, and whether a discount code was applied, each of which turns a flat revenue number into a segmentable one. If you’re unsure which metrics deserve this treatment first, our guide to key digital marketing metrics covers the KPIs most ecommerce owners should prioritise before expanding into more granular custom dimensions.

Configuring funnel analysis and conversion paths specific to ecommerce user behaviour

A funnel exploration in GA4 is where your event implementation pays off directly: it’s only as good as the events feeding it. Build one from Explore > Funnel exploration, selecting the ecommerce events in sequence, typically view_item, add_to_cart, begin_checkout and purchase.

GA4’s funnel tool supports both open funnels (shoppers can enter at any step) and closed funnels (shoppers must complete every step in order), and the choice changes what the drop-off percentages actually mean. A closed funnel gives you a cleaner read on where a shopper who started the journey properly abandoned it; an open funnel is more forgiving of shoppers who arrive mid-journey from a bookmarked product page.

Conversion paths, visible through the Advertising > Attribution section, show which sequence of channels a converting shopper typically passed through before completing a purchase, which is distinct from the funnel view and answers a different question: not where shoppers drop off, but which combination of touchpoints tends to precede a sale.

Segment your funnel by device category and by new versus returning visitors early on. A mobile checkout funnel that haemorrhages shoppers at begin_checkout while desktop holds steady almost always points to a specific friction point in the mobile checkout form rather than a general traffic quality problem, and that’s a far more actionable finding than an aggregate conversion rate.

Attribution modelling considerations within ecommerce analytics setup

GA4 uses data-driven attribution by default for most properties, which distributes credit for a conversion across the touchpoints in a shopper’s journey based on patterns observed in your own data, rather than applying a fixed rule like last-click. This matters for ecommerce specifically because a shopper’s path to purchase is often longer than a single session, a product discovery click from social media one week, a branded search the next, and a direct visit to complete the purchase.

The practical consequence for your setup is that attribution quality depends entirely on how completely you’re capturing the events and parameters covered earlier in this guide. A purchase event with a clean transaction_id and value gives the attribution model a reliable conversion to work backwards from; a flaky implementation with duplicate or missing purchase events feeds the model noisy data, and every attribution report built on top of it inherits that noise.

Where data-driven attribution isn’t available for your property (it requires a minimum volume of conversion and click data), GA4 falls back to a cross-channel last-click model. If your traffic volume is modest, check which model is actually active in Admin > Attribution settings rather than assuming data-driven attribution is running, since the comparison between channels in your reports changes meaningfully depending on which model is behind them.

Attribution reporting is also where PPC spend and organic performance get compared directly, so if you’re weighing paid search against organic investment, a clean ecommerce implementation is the precondition for that comparison meaning anything at all. Our analysis of SEO against Google Ads goes into that trade-off in more depth once your tracking is solid enough to trust the inputs.

Linking GA4 ecommerce data with advertising platforms like Google Ads for integrated performance tracking

Linking your GA4 property to a Google Ads account, done from Admin > Product links > Google Ads linking, lets conversion data flow both ways: GA4’s ecommerce conversions become available as a conversion action inside Google Ads, and Ads campaign data becomes visible inside GA4’s acquisition reports without a separate login.

The practical value for an ecommerce store is that once the link is active, you can build Google Ads bidding strategies around actual purchase value rather than click volume or a generic “conversion” count. A purchase event that correctly carries value means Ads can optimise towards revenue, not just order count, which matters when average order values vary meaningfully by product line.

For this to work properly, your ecommerce events need to be marked as conversions inside GA4 first, under Admin > Events, by toggling the relevant event (typically purchase) as a key event. Only key events are available for import into linked advertising platforms, so a correctly firing purchase event that hasn’t been marked as a key event simply won’t appear as an option in Google Ads, even though the underlying data is there.

This is also where consent signals start to matter for accuracy: a shopper who declines marketing consent may still generate an analytics-consented purchase event but won’t be eligible for ad personalisation or certain conversion modelling, which is worth understanding before you compare Ads-reported conversions against GA4’s own totals and wonder why they don’t match exactly.

Ecommerce tracking collects transaction data, which makes consent handling a structural part of the setup, not an afterthought bolted on at the end. A consent management platform needs to gate your GA4 and advertising tags before any ecommerce event fires, and Google Tag Manager’s built-in consent mode is the most common way to implement that gate without rebuilding your tag structure from scratch.

Consent mode works by adjusting how tags behave based on the shopper’s consent state rather than blocking them outright: with analytics consent denied, GA4 can still receive a “cookieless ping” for basic measurement while skipping anything that would identify the individual shopper, and the degree of data GA4 receives shifts accordingly.

Practically, this means your purchase and add_to_cart events should fire through tags that respect the same consent signals as the rest of your GA4 configuration, never through a separate implementation path that bypasses the consent banner’s logic. A common and costly mistake is building ecommerce tracking before the consent layer exists, then retrofitting consent checks onto tags that were never designed with them, which tends to leave gaps where certain events fire regardless of consent state.

Data retention settings inside GA4’s Admin panel (Data Settings > Data Retention) also deserve a decision at setup time rather than being left on the default, since they determine how long user-level and event-level data remains queryable for exploration reports, separate from the aggregated data that populates your standard ecommerce reports indefinitely.

Author perspective: common pitfalls seen in SME ecommerce implementations

The same handful of mistakes show up again and again in small and medium-sized ecommerce implementations: a value field sent as a string, a transaction_id that isn’t actually unique, an add_to_cart event that fires on every page load because of a misplaced trigger. None of these are exotic. They’re all preventable with the validation checklist covered earlier in this guide, and yet they persist because teams build the full event set before testing any single one of them properly.

My advice is to resist that instinct. Instrument purchase first, validate it against real orders, then add add_to_cart, validate again, and only then expand into the richer funnel events and custom dimensions. A narrow, verified implementation beats a broad, unverified one every time, and it’s far easier to debug one event than six.

— tibor

How we can help with ecommerce analytics setup

If any of this feels like more groundwork than your week has room for, that’s exactly the gap our analytics work closes. We build GA4 ecommerce tracking as part of a wider web design and digital marketing service, which means the dataLayer, the GTM container and the reporting setup get built once, correctly, rather than patched together after a launch.

Fyldedigital

What that typically includes for an ecommerce client:

  • Event and parameter mapping against the actual checkout flow.
  • GTM container setup with validated triggers and deduplication logic.
  • Report and exploration configuration so revenue, funnel and item-level data are usable from day one.
  • Ongoing CRO support once the data is reliable enough to act on.

If your store’s product photography is pulling its weight in that funnel too, our partners at Dock Street Studio cover the kind of imagery that tends to move conversion rate once the tracking behind it is sound.

Request a free website and SEO review through our services page and we’ll tell you honestly where your current tracking stands.

FAQ

What is the 80/20 rule in ecommerce?

The Pareto principle suggests that a small share of your products or customers typically generates most of your revenue. In ecommerce analytics, this shows up clearly in the item table and revenue-by-source explorations once GA4’s ecommerce events are firing correctly, letting you identify which SKUs or channels deserve the bulk of your attention.

What is ecommerce analytics?

Ecommerce analytics is the practice of collecting and interpreting data on how shoppers browse, add items to a basket and complete purchases on an online store. It typically spans descriptive, predictive and prescriptive analysis, and practitioner guidance frames key metrics like conversion rate, average order value, customer lifetime value and cart abandonment as the core numbers worth tracking.

Is ecommerce still profitable in 2026?

Profitability in ecommerce depends on the individual store’s margins, acquisition costs and operational setup rather than any single industry-wide trend, so there’s no universal answer. What’s consistent is that stores with accurate analytics, correctly tracking revenue, cart abandonment and channel performance, are better placed to spot where margin is being lost than stores running without reliable tracking.

What are the 7 types of ecommerce?

Common ecommerce models include business-to-consumer (B2C), business-to-business (B2B), consumer-to-consumer (C2C), consumer-to-business (C2B), business-to-administration (B2A), consumer-to-administration (C2A) and mobile commerce (m-commerce). Each model can use the same GA4 ecommerce event structure covered in this guide, though the parameters you prioritise, such as order value for B2C versus contract value for B2B, often differ in practice.

Do I need Google Tag Manager for GA4 ecommerce tracking?

Google Tag Manager isn’t strictly required, since you can implement ecommerce events directly through gtag.js, but it’s the recommended route for most teams because it separates tag logic from your website’s codebase. GTM also makes it considerably easier to adjust triggers, add new events or fix a scoping mistake without needing a full code deployment.

Sources

The parameter lists, event definitions and deduplication guidance in this piece come directly from Google’s own documentation, which is worth bookmarking if you’re implementing this yourself rather than relying on a summary.

Some More Cool Projects