Enhanced E-commerce Tracking Migration
From UA's Rigid Schema to GA4's Flexible Events
Universal Analytics' Enhanced Ecommerce used a fixed, plugin-based data structure (ec:addProduct, ec:setAction) with a constrained set of actions (detail, click, add, remove, checkout, purchase, refund). GA4 replaces this with a set of recommended events (view_item, add_to_cart, begin_checkout, purchase, refund, etc.) that follow a consistent items array parameter structure, but are otherwise just ordinary events — more flexible, but also requiring deliberate remapping rather than a drop-in swap.
The Items Array Is the Core Migration Challenge
Every GA4 ecommerce event carries an items array, where each item object needs consistent fields: item_id, item_name, price, quantity, and optionally item_category, item_brand, item_variant, coupon, and up to several custom item-scoped parameters. UA's dataLayer structure for Enhanced Ecommerce doesn't map 1:1 — teams migrating directly often copy over the old ec:addProduct payload shape without restructuring it into GA4's expected item array, which silently breaks ecommerce reporting even though events technically fire.
// OLD: Universal Analytics Enhanced Ecommerce (deprecated pattern)
ga('ec:addProduct', {
id: 'SKU_001',
name: 'Premium Consulting Hour',
price: '149.50',
quantity: '1'
});
ga('ec:setAction', 'purchase', { id: 'T_98765', revenue: '149.50' });
ga('send', 'event', 'Ecommerce', 'Purchase');
// NEW: GA4 recommended event structure via dataLayer / gtag
dataLayer.push({
event: 'purchase',
ecommerce: {
transaction_id: 'T_98765',
value: 149.50,
currency: 'USD',
shipping: 10.00,
items: [
{
item_id: 'SKU_001',
item_name: 'Premium Consulting Hour',
price: 149.50,
quantity: 1
}
]
}
});Clear the Ecommerce Object Between Events
ecommerce object without first nulling out the previous one causes GA4 (and GTM's Enhanced Ecommerce variable) to merge old and new item arrays, duplicating or corrupting item data across unrelated events. Always push { ecommerce: null } immediately before pushing a new ecommerce event object.Currency and Value Consistency
GA4 expects value and currency as top-level parameters on ecommerce events, and if currency is omitted, GA4 silently defaults it based on property-level settings — which causes real reporting errors for multi-currency sites if the event itself doesn't explicitly pass the transaction's actual currency code. Always pass currency explicitly on every ecommerce event; never rely on the property default for a multi-region store.
Refunds and Partial Refunds
GA4's refund event supports both full-order refunds (just transaction_id) and partial refunds (an items array with only the refunded SKUs and quantities). A frequent migration gap: teams implement purchase tracking correctly but never implement refund at all, which inflates net revenue reporting in GA4 relative to actual settled revenue — a discrepancy that surfaces months later during a finance reconciliation.
Validate With the GA4 DebugView Before Trusting Any Migration
What's Next?
Ecommerce migration challenges compound further on specific platforms with their own quirks — Shopify, WooCommerce, Magento, and headless setups each have distinct patterns worth understanding individually, starting with server-side tracking approaches for Shopify.
I build these systems professionally.
Whether it's a RAG pipeline, analytics migration, or AI workflow — let's talk.