Implementation Guide
Google Ads Enhanced Conversions Setup
A practical guide to set up Enhanced Conversions the right way, avoid common failures, and validate that it’s actually working.
Enhanced Conversions (EC) helps Google Ads match conversions when cookies fail. It does this by sending hashed first-party data (like email or phone) with your conversion tag.
If your account has missing conversions, unstable CPA/ROAS, or “Needs attention” statuses, start by stabilizing the base tag first: /fix/google-ads-conversion-tracking/ .
1) Web vs Leads: two different setups
EC is not one switch. It has two modes. Pick the right one before you build.
Enhanced Conversions for Web
- Trigger: immediate online conversion (purchase, signup).
- Data source: dataLayer / DOM / JS variable at conversion time.
- Goal: recover lost matches from ITP, ad blockers, cross-device.
- Key: hashed email/phone + transaction/order ID.
Enhanced Conversions for Leads
- Trigger: offline event later (qualified lead, closed deal).
- Data source: CRM / backend export.
- Goal: attribute revenue even if GCLID is missing or truncated.
- Pairs with: offline uploads and CRM processes.
If you’re importing offline events, use: /fix/offline-conversions-and-crm-uploads/ .
2) Signal hierarchy: what matters most
Match rate lives or dies by data quality. Email is usually the strongest identity key. Phone helps a lot. Address can help, but only if it’s clean.
Relative impact on match rate
What to prioritize
- Email (primary)
- Phone (strong secondary)
- Name + address (supporting)
- IP / user-agent (not your focus; handled by Google)
Normalization rules you can’t skip
- Email: trim + lowercase. For Gmail/Googlemail, remove periods before the domain.
- Phone: format as E.164 (include country code with “+”). Strip spaces/dashes.
- Country: use 2-letter ISO code (US, CA, GB).
Common miss: Gmail dots. john.doe@gmail.com and johndoe@gmail.com should normalize to the same identity. If you hash the dotted version as-is, matches can fail.
3) Implementation decision matrix
Don’t guess. Use the setup path that fits your platform and the level of control you need.
Shopify
Prefer the Google & YouTube app for simple stacks. For deeper control, use a Custom Pixel that subscribes to checkout events and sends user data in the right schema.
Avoid “classic GTM in checkout” assumptions.
WooCommerce
Use a stable dataLayer push on the order-received page (plugin or server hook). Then map billing email/phone into your GTM user-provided data variable.
If GA4 revenue doesn’t match orders, fix that first: /fix/ga4-purchase-and-revenue-mismatches-woocommerce/ .
Custom / other
Use GTM with a code-based user-provided data variable so you can normalize data before it’s hashed and sent.
If you want a team to own the whole pipeline, see: /services/ppc-technical-ownership/ .
4) Method analysis: reliability vs complexity
“Automatic” setups are fast, but they often break on multi-step forms, dynamic DOM changes, or checkout constraints. GTM gives you the control to keep match quality high.
| Method | Best for | Reliability | Complexity |
|---|---|---|---|
| GTM (manual user data) | Most businesses | High | Medium |
| Automatic collection | Simple sites, low control | Low–Medium | Low |
| Direct code (gtag) | Dev-owned stacks | High | High |
5) Lead-to-sale recovery (Enhanced Conversions for Leads)
Leads often close days later inside a CRM. Enhanced Conversions for Leads can join those offline wins back to the ad click using hashed identifiers.
Typical recovery funnel
1) Web leads captured
Form submit happens. Email/phone is collected.
2) Hashed identifiers stored
Normalize, then hash (SHA-256). Store in CRM or a clean export table.
3) Offline stage happens
Qualified lead, appointment, closed deal—whatever you optimize for.
4) Upload conversion (API/CSV)
Upload with hashed email/phone so Ads can match even without GCLID.
5) Smart Bidding learns from real outcomes
Your bidding optimizes for the stages that actually drive revenue.
If your offline import pipeline is messy, start here: /fix/offline-conversions-and-crm-uploads/ .
6) Consent Mode v2: the gate that can shut EC off
In many regions, your tag can’t use user-provided data unless consent allows it. Consent Mode v2 adds ad_user_data. If it’s denied, Enhanced Conversions won’t send the hashed identifiers.
If ad_user_data = denied
- Conversion ping may still fire (depending on other consent settings).
- User-provided fields are suppressed.
- Match rate drops, especially in cookie-restricted browsers.
If ad_user_data = granted
- Google tag can hash + send identifiers.
- Enhanced Conversions can contribute to matching and modeling.
- Status in Ads Diagnostics can improve over time.
For a full compliance + measurement architecture pass, see: /services/tracking-and-analytics-integrity/ .
7) Fast diagnosis: “EC not detected” or “Needs attention”
Use this quick decision tree before you start changing everything.
Step 1: Is the base conversion tag firing?
If no, fix the core tag first: /fix/google-ads-conversion-tracking/.
Step 2: Is user data present at the conversion moment?
Check GTM preview / dataLayer. If it’s undefined, you have a capture problem (wrong keys, timing, or DOM assumptions).
Step 3: Is sequencing correct?
User-provided data must be processed before the conversion beacon. Use a setup tag sequence to avoid race conditions.
Step 4: Is consent blocking it?
If ad_user_data is denied, EC identifiers won’t send.
Step 5: Is normalization correct?
Trim + lowercase. Apply Gmail dot rule. Format phone as E.164.
8) QA & troubleshooting matrix
Implementation is only half the job. This table helps you move from symptom to fix, then validate the result.
| Symptom | Probable cause | Fix | Validate |
|---|---|---|---|
| “Needs attention” in Ads | User data event never fires or isn’t linked to the conversion ID | Confirm User-Provided Data Event tag, same conversion ID, correct trigger | Ads Diagnostics improves in the conversion action (can take days) |
| User data “null/empty” | Wrong dataLayer keys or form fields removed on submit (AJAX) | Capture at submit success event; push values into dataLayer before tag fires | GTM preview shows values at conversion event |
| Low match rate (<20%) | Guest checkout emails not captured, or normalization is wrong | Fix guest flows; trim/lowercase; apply Gmail dot rule; E.164 phone | Match rate improves over 1–2 weeks (varies by audience) |
| Duplicate conversions | Two tags firing (client + server), reloads, or wrong firing options | Deduplicate by transaction_id/order ID; set GTM to once per event | Conversion count stops inflating; orders reconcile |
| EC works in US, fails in EU | Consent Mode v2 not wired correctly; ad_user_data denied by default | Fix consent init order; region defaults; verify CMP updates consent state | EU traffic starts sending user data only after consent is granted |
Want proof that Ads and GA4 agree on what “worked”? See: /proof/ga4-and-google-ads-attribution-alignment/ .
9) How to know it’s fixed
Browser checks
- Use GTM preview: user data variables must be populated at the conversion event.
- Use Tag Assistant: confirm the conversion fires on the correct event.
- Spot-check: transaction_id/order ID is present for purchases.
Google Ads checks
- Conversion action Diagnostics should stop showing “Needs attention.”
- Watch for stability: no sudden doubling of conversions from duplicates.
- Track trend shifts: CPA/ROAS changes should have a clear reason.
Need this implemented and kept clean?
Enhanced Conversions touches PII handling, consent, tag sequencing, ecommerce integrity, and deduplication. If you want a team to own it end-to-end, book here: