If your Google Ads campaigns feel like they're flying blind — spending budget but not learning, optimizing toward the wrong signals — the problem almost always traces back to tracking. Not creative. Not bids. Not targeting. Tracking.
This guide is for e-commerce founders and operators who've seen broken tags, duplicate conversions, or suspicious numbers and want to understand what's actually happening under the hood. You don't need to be a developer to understand this. You do need to care about getting it right.
Let's go.
1. GA4 + Google Ads Linked: What Actually Syncs (and What Doesn't)
Linking GA4 to Google Ads feels like a simple checkbox. It's not. Most people link the accounts and assume everything is flowing — it isn't.
What syncs when you link
When GA4 and Google Ads are linked, two things happen:
- Audiences — GA4 audience lists (e.g., "users who added to cart but didn't purchase") become available to use in Google Ads for remarketing and bid adjustments.
- Conversions — GA4 key events (what used to be called "goals") can be imported into Google Ads as conversion actions.
What doesn't sync automatically
- Revenue data doesn't flow unless you're passing
valueandcurrencyin your GA4 purchase event. If those parameters are missing or zero, Google Ads sees zero-value conversions — useless for target ROAS bidding. - Attribution works differently in each platform. GA4 defaults to data-driven attribution across the full path. Google Ads uses its own attribution model per conversion action. The numbers will never match, and that's expected — but you need to understand which numbers you're acting on.
- The "Conversions" column in Google Ads only includes conversion actions you've explicitly marked "Include in Conversions." Importing from GA4 doesn't auto-include it.
The decision you need to make
You have two options for tracking purchases in Google Ads:
Option A: Import the GA4 purchase event into Google Ads. One tag does the work. Simpler maintenance. The trade-off: you're dependent on GA4 firing first, and you lose access to some Google Ads-specific features like Enhanced Conversions with first-party data.
Option B: Fire a native Google Ads conversion tag separately. More control, more redundancy, but higher risk of duplicate counting if both tags fire on the same order.
Most serious e-commerce setups use Option B with deduplication via transaction_id. More on that shortly.
2. Google Tag (gtag) vs Google Tag Manager: When to Use Which
This is one of the most confused areas in tracking setup. Let's be direct about what each actually is.
Google Tag (gtag.js)
gtag.js is a JavaScript library you paste directly into your site's HTML. It lets you send events to Google Analytics 4, Google Ads, and other Google products from a single script. It looks like this:
<!-- In your <head> -->
<script async src="https://www.googletagmanager.com/gtag/js?id=G-XXXXXXXXXX"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'G-XXXXXXXXXX');
gtag('config', 'AW-XXXXXXXXXX'); // Google Ads
</script>
Use gtag directly when: You have developer resources, your e-commerce platform exposes the purchase confirmation page server-side (Shopify, custom builds), and you want clean, auditable code without a third-party tag manager in the stack.
Google Tag Manager (GTM)
GTM is a tag management system — a container that loads on your site and lets you deploy and manage tags through a UI, without touching the underlying site code after initial setup. GTM itself uses a gtag.js-compatible data layer under the hood.
Use GTM when: You're on a platform with limited code access (WooCommerce with non-developer plugins, Squarespace), you need a non-technical team to manage tags, or you're deploying multiple third-party tags (Facebook, TikTok, Klaviyo) and want one place to manage them.
The honest trade-off
GTM adds a layer of abstraction. That's a feature and a bug. It's easier to deploy changes, but it's also easier to accidentally fire duplicate tags, create version conflicts, or lose track of what's live. If you're managing GTM yourself without documentation, you will create tracking problems at some point.
For a lean e-commerce team: start with gtag implemented directly in your Shopify theme or checkout extension. Add GTM later if you have specific reasons.
3. The Purchase Event: The One Conversion That Actually Matters
You can track add-to-carts, initiate-checkouts, page views. None of it matters as much as a correctly configured purchase event. This is the signal Google's Smart Bidding learns from. Get this wrong and your campaigns can't optimize properly.
The minimum viable purchase event
gtag('event', 'purchase', {
transaction_id: 'ORDER-12345', // unique per order — critical
value: 89.00, // order value, NOT including tax/shipping unless intended
currency: 'USD',
items: [
{
item_id: 'SKU-001',
item_name: 'Running Shoes',
price: 89.00,
quantity: 1
}
]
});
Why each parameter matters
transaction_id — This is your deduplication key. If the purchase event fires twice (page refresh, double-tab, tag error), Google Ads will deduplicate based on this ID. Without it, every duplicate fire is counted as a new sale. This single missing parameter is responsible for more inflated conversion numbers than anything else we've seen.
Use your actual order ID. Never use a random number or timestamp — you need it to be stable and unique to the order, not the session.
value — This is what Smart Bidding optimizes toward for Target ROAS. If you pass 0 or omit it, Google Ads can't learn your revenue curve. It'll optimize for conversion count only, which is a weaker signal.
Pass the actual order value the customer paid (subtotal or grand total — pick one and be consistent). Don't pass the gross margin; pass the revenue.
currency — Required if you're running multi-currency or if your Google Ads account currency differs from your store currency. Google Ads will flag a mismatch. Use ISO 4217 codes: USD, EUR, GBP.
Where to fire it
Fire the purchase event on the order confirmation page — once, on page load, only after the order is confirmed server-side. This means:
- Shopify: use the
thank_youpage or the checkout.order_completed web pixel - Custom builds: fire after the server confirms the order, not after payment form submission
- Never fire it on payment processing pages where the order isn't confirmed yet
4. Enhanced Conversions: First-Party Data Post-iOS14
Enhanced Conversions (EC) is Google's answer to the signal loss from iOS14, browser-level tracking prevention (Safari ITP), and the gradual deprecation of third-party cookies.
What they actually do
When a customer converts on your site, you hash and send first-party data — email address, phone number, name — along with the conversion event. Google uses that hashed data to match the conversion to signed-in Google accounts, even when cookies were blocked or cleared.
The result: more conversions get attributed. The math on your campaigns improves. And you're doing it with data your customer gave you, not third-party cookies.
Why this matters more every year
Before iOS14 (2021), a Google click → purchase was tracked via third-party cookies with ~95%+ reliability. By 2024, that rate is down to 60-70% depending on your browser mix. Enhanced Conversions recovers 10-20% of that lost signal — and the gap widens every year as browser tracking restrictions tighten.
How to implement (the straightforward version)
Enhanced Conversions require you to pass hashed customer data alongside your conversion event. Google accepts SHA-256 hashed email as the primary identifier.
With gtag:
gtag('set', 'user_data', {
email: 'customer@example.com', // unhashed — gtag hashes it automatically
phone_number: '+12025551234', // optional but improves match rate
address: {
first_name: 'Jane',
last_name: 'Doe',
postal_code: '10001',
country: 'US'
}
});
gtag('event', 'purchase', {
transaction_id: 'ORDER-12345',
value: 89.00,
currency: 'USD'
});
Call gtag('set', 'user_data', {...}) before the purchase event. Gtag handles SHA-256 hashing client-side automatically.
With GTM: Enable Enhanced Conversions in the Google Ads Conversion Tag settings and map your data layer variables (email, phone) to the EC fields.
Three prerequisites before enabling: (1) turn on Enhanced Conversions in Google Ads under Tools → Conversions → Settings, (2) update your privacy policy to disclose sharing hashed data with ad partners, (3) gate EC data behind ad_user_data consent if you're running Consent Mode.
5. Consent Mode v2: Required in EU/EEA, Here's What It Does
As of March 2024, Google requires Consent Mode v2 for all advertisers running Google Ads or using Google Analytics in the EU/EEA. Ignoring it doesn't just put you at GDPR risk — it degrades your campaign data.
What Consent Mode is
Consent Mode is a protocol that tells Google tags how to behave based on a user's cookie consent choices. Instead of firing or not firing, tags adjust their behavior:
- Full consent granted → standard tracking with cookies and identifiers
- Consent denied → tags fire in a limited mode, sending cookieless pings that Google uses for modeled conversions (filling in the gaps statistically)
This is important: with Consent Mode, you still get some signal from non-consenting users via modeling. Without Consent Mode, you get nothing from them. Which means your campaign data is biased toward users who consented — typically older demographics, not representative of your actual customer base.
The two consent signals that matter for ads
gtag('consent', 'update', {
'ad_storage': 'granted', // controls cookies for ad measurement
'ad_user_data': 'granted', // controls sending user data to Google (EC)
'analytics_storage': 'granted', // controls GA4 measurement cookies
'ad_personalization': 'granted' // controls remarketing
});
v2 added ad_user_data and ad_personalization as new required signals. If you were already on v1 and haven't updated, you're non-compliant.
Basic implementation flow
- Set defaults to denied for EU traffic before any tags load:
gtag('consent', 'default', {
'ad_storage': 'denied',
'ad_user_data': 'denied',
'analytics_storage': 'denied',
'ad_personalization': 'denied',
'wait_for_update': 500 // ms to wait for consent platform to respond
});
-
Load your CMP (Consent Management Platform — Cookiebot, OneTrust, Usercentrics, etc.)
-
Update consent based on user choice — handled by your CMP integration with Google tags
If you're not using a CMP: stop using GTM for EU traffic and fix this first. GDPR fines aside, the data quality hit from running without Consent Mode on EU traffic will distort your campaign metrics.
6. Common Tracking Mistakes That Corrupt Your Data
These are the patterns we see most often when auditing accounts.
Duplicate conversions
Symptom: Conversion count in Google Ads is 2-3x your actual order count.
Cause: The purchase event is firing multiple times per order. Common sources:
- GTM triggers misconfigured (firing on all page loads, not just the confirmation page)
- A GA4 import AND a native Google Ads tag both firing on the same order, with no
transaction_iddeduplication - Shopify "Additional scripts" field firing alongside a checkout extension or app
Fix: Add transaction_id to every purchase event. Google Ads deduplicates within a 7-day window. Also audit your GTM container for any orphaned or duplicate purchase triggers.
Missing or static transaction_id
Symptom: transaction_id is set to "1", "order", "undefined", or is absent entirely.
Cause: Hardcoded value in tag, missing dynamic variable mapping, or developer oversight.
Fix: Map transaction_id to the actual order ID from your e-commerce platform. In Shopify, this is {{ checkout.order_id }}. In GTM, it's a data layer variable — confirm it's populated before purchase tag fires by checking the Preview mode.
Wrong attribution window
Symptom: Your ROAS calculations in Google Ads don't match what you see in your e-commerce platform.
Cause: Google Ads defaults to a 30-day click attribution window and 1-day view-through. If your buying cycle is short (same-session purchases common in fashion/consumables), a 7-day window is more representative. If your cycle is long (furniture, B2C electronics), 30 or 60 days is appropriate.
Fix: Review your attribution window under Tools → Conversions → Edit settings. Match it to your actual buying cycle. Document what you set and why — this context gets lost when teams change.
Firing on payment page instead of confirmation page
Symptom: Conversion count exceeds order count, and you see abandoned orders counted as conversions.
Cause: The purchase event fires when payment is submitted, not when the order is confirmed.
Fix: Fire purchase events only after server-side confirmation. In Shopify, the thank_you page and the checkout.order_completed pixel both fire after order creation. Payment submission pages are not confirmation pages.
7. How to Audit Your Tracking Setup in 15 Minutes
You don't need a specialist to do a first-pass audit. Here's the diagnostic sequence.
Step 1: Google Tag Assistant (2 min)
Install the Google Tag Assistant Chrome extension. Place a test order on your site. Check:
- Is GA4 firing? Is Google Ads firing?
- Are both firing on the confirmation page (not the payment page)?
- Is the purchase event appearing with
transaction_id,value, andcurrency?
Step 2: Check for duplicates (3 min)
In the Tag Assistant recording, look at the confirmation page. Count the number of purchase events. It should be exactly 1. If you see 2 or more, you have a duplication problem to fix.
Step 3: GA4 DebugView (3 min)
Enable GA4 DebugView (add ?gtm_debug=x to your URL or use the Tag Assistant). Place a test order. In GA4 → Admin → DebugView, confirm:
purchaseevent appears- It has
transaction_id,value, andcurrencypopulated - Value is a real number, not
0orNaN
Step 4: Google Ads conversion actions (3 min)
In Google Ads → Tools → Conversions:
- Find your purchase conversion action
- Check "Status" — should be "Recording conversions"
- Check "Count" — should be "One per click" for purchases (not "Every")
- Check "Attribution model" — Data-driven is recommended for most
- Check "Tracking status" — if it shows "No recent conversions," it may be misconfigured or a new account
Step 5: Enhanced Conversions check (2 min)
In Google Ads → Tools → Conversions → Settings (account level):
- Is Enhanced Conversions enabled?
- Is match rate visible? Under 40% suggests incomplete data being passed
Step 6: Consent Mode check (2 min)
If you sell to EU/EEA customers, open Chrome DevTools (F12) → Network tab → filter for google → reload the confirmation page. Look for requests to google-analytics.com and googleads.g.doubleclick.net. They should include consent parameters (gcs, gcd) in the query string.
If you don't see these parameters, Consent Mode v2 is not implemented.
What to Do With This Information
If you worked through the checklist above and found issues — duplicate events, missing transaction_id, no Enhanced Conversions, no Consent Mode — you're not alone. These are the four most common problems we find in every account audit.
The good news: most of these are fixable in a focused 2-3 hour session with a developer who has access to your tag setup and checkout code.
The bad news: every week you run campaigns on broken tracking data, Smart Bidding is learning from the wrong signals. The longer it runs broken, the more you have to unlearn.
Want a step-by-step checklist to run this audit yourself?
We've turned the diagnostic above into a one-page tracking audit checklist — with exact steps, what to look for, and what to do when you find a problem. Covers GA4, Google Ads native tags, GTM, Enhanced Conversions, and Consent Mode v2.
Download the Free Tracking Audit Checklist →
If you find issues and want a second pair of eyes, that's what we're here for.
Ads Proof — Google Ads for e-commerce brands that want clean data and real results.