
Why Your Odoo Conversion Tracking Is Broken — And How to Fix GA4, Ads, Meta, TikTok & More in 2025
Updated: June 30, 2025 at 10:26 AM
Fix Broken Attribution. Track Every Click. Scale With Confidence.
Introduction: Ads Are Running. Sales Are Happening. Tracking Is Broken.
Odoo shows real orders. GA4 shows zero. Meta reports more sales than you made. TikTok and Pinterest show no data.
This means your tracking setup is broken. Odoo does not support accurate conversion tracking by default.
This guide explains how to set up full-funnel tracking across all platforms using:
- Google Tag Manager (Web and Server)
- Google Analytics 4
- Google Ads
- Meta Pixel and Conversions API
- TikTok Events API
- Pinterest Conversion API
- Microsoft Ads
- Reddit and LinkedIn tracking
- Custom dataLayer
- Consent Mode v2
We use clear, structured tracking to capture real actions, fix attribution, and connect ad data to sales.
Section 1: Why Odoo Tracking Fails by Default
- GA4 events do not exist in the default setup
- Meta Pixel fires twice or misses key values
- TikTok, Pinterest, and Microsoft tracking are not installed
- No server-side tracking means lost signals from Safari and iOS
- Click IDs like gclid, fbclid, ttclid are not stored
- Events miss required fields like transaction ID, value, currency
Section 2: What You Need to Track Accurately
Client-side tools:
- Google Tag Manager (Web)
- Google Analytics 4
- Meta Pixel
- TikTok Pixel
- Pinterest Tag
- Microsoft UET
- Reddit and LinkedIn Pixels
Server-side tools:
- Google Tag Manager (Server)
- Meta Conversions API
- TikTok Events API
- Pinterest Conversion API
- Google Ads Enhanced Conversions
- Microsoft and LinkedIn offline conversions
Privacy tools:
- Consent Mode v2
- Cookiebot or OneTrust
Section 3: Create a Clean dataLayer for Odoo
Push ecommerce event data into the dataLayer using clear key-value format.
<script>
dataLayer.push({
event: "purchase",
ecommerce: {
transaction_id: "OD123",
currency: "USD",
value: 120.50,
items: [
{
item_id: "sku123",
item_name: "Odoo Product",
quantity: 2,
price: 60.25
}
]
},
event_id: "odoo-purchase-123"
});
</script>
Section 4: Google Tag Manager (Web) Setup
Use Google Tag Manager to trigger ecommerce events at the right time using clean dataLayer signals.
Step 1: Setup Basic Ecommerce Triggers
- Create triggers in GTM for key steps: view_item, add_to_cart, begin_checkout, purchase
- Use Custom Event triggers based on event values pushed into the dataLayer
<script>
dataLayer.push({
event: "add_to_cart",
ecommerce: {
currency: "USD",
value: 29.99,
items: [
{
item_id: "sku001",
item_name: "AddToCart Product",
quantity: 1,
price: 29.99
}
]
},
event_id: "odoo-cart-001"
});
</script>
Step 2: Setup GTM Variables
- Create Data Layer Variables for:
- transaction_id
- value
- currency
- items
- event_id
These allow you to reuse the same variables across Google Ads, GA4, Meta, TikTok, and Pinterest tags.
Step 3: Block Duplicate Purchases
- Use a blocking trigger with event_id deduplication
- Create a trigger filter to fire the purchase tag only once per unique event_id
Step 4: Use Lookup Tables (Optional)
- Create Lookup Table variables to match:
- Content types (product, category)
- Currency display formats
- Dynamic product values by SKU
This ensures your data is consistently structured across all platforms.
Final Notes:
- Test tags in GTM Preview mode
- Use the browser console:
console.log(window.dataLayer);
- Confirm the timing and values of each ecommerce event
- Create triggers for view_item, add_to_cart, begin_checkout, and purchase
- Use variables to capture dynamic values
- Block duplicate purchases using triggers and event_id
- Add lookup tables to match platform naming
Section 5: Google Analytics 4 Setup
- Set up GA4 event tags in GTM for each key ecommerce step
- Enable Enhanced Measurement and Enhanced Ecommerce in GA4
- Use the following code to push a clean purchase event:
<script>
dataLayer.push({
event: "purchase",
ecommerce: {
transaction_id: "OD456",
currency: "USD",
value: 75.00,
items: [
{
item_id: "sku456",
item_name: "GA4 Sample Product",
quantity: 1,
price: 75.00
}
]
},
event_id: "ga4-purchase-456"
});
</script>
- Match these parameters inside GTM tag for event_name = purchase
- Set event parameters for transaction_id, currency, value, and items
- Validate implementation using GA4 DebugView
- Confirm reported revenue matches Odoo backend
- Use GA4 funnel reports to monitor user behavior through checkout
- Cross-check session attribution with source/medium data
- Create GA4 event tags for ecommerce steps
- Use Enhanced Ecommerce in GA4 settings
- Validate in DebugView
- Compare revenue data with Odoo admin
- Use event parameters: transaction_id, currency, value, items
Section 6: Google Ads + Enhanced Conversions
- Set up the Google Ads conversion tag using GTM Web
- Store the gclid (Google Click ID) in a first-party cookie on the user’s browser:
<script>
var gclid = getParam('gclid');
if (gclid) {
var date = new Date();
date.setTime(date.getTime() + (90*24*60*60*1000)); // 90 days expiration
document.cookie = "gclid=" + gclid + "; expires=" + date.toUTCString() + "; path=/";
}
function getParam(name) {
var match = RegExp('[?&]' + name + '=([^&]*)').exec(window.location.search);
return match && decodeURIComponent(match[1].replace(/\+/g, ' '));
}
</script>
- Capture customer email and phone at checkout
- Configure Enhanced Conversions inside GTM by mapping these fields in the conversion tag
- Send this data securely through GTM Server container to Google Ads:
fetch(“https://www.googletagmanager.com/gtag/js?id=AW-CONVERSION_ID”);
window.dataLayer.push({
event: "conversion",
send_to: "AW-CONVERSION_ID/label",
transaction_id: "OD789",
value: 150.00,
currency: "USD",
user_data: {
email: "hashed_email",
phone_number: "hashed_phone"
}
});
- Link your GA4 property to Google Ads for audience sharing
- Validate conversions using the Google Ads conversions dashboard
- Compare conversion counts to your Odoo admin order numbers
- Setup conversion tag via GTM Web
- Capture and store gclid in first-party cookie
- Setup Enhanced Conversions using email/phone
- Use GTM Server to send conversions
- Link GA4 to Google Ads for remarketing
Section 7: Meta Pixel + Conversions API
- Install Meta Pixel in GTM Web. Create tags for PageView, ViewContent, AddToCart, and Purchase.
- Use dynamic variables to map product name, SKU, value, currency.
- Example dataLayer for purchase:
<script>
dataLayer.push({
event: "purchase",
ecommerce: {
transaction_id: "OD321",
value: 85.00,
currency: "USD",
items: [
{
item_id: "sku321",
item_name: "Odoo Meta Product",
quantity: 1,
price: 85.00
}
]
},
event_id: "meta-purchase-321"
});
</script>
- Inside GTM, use this data to populate Meta Pixel tag parameters.
- For server-side, use GTM Server to send same events to Conversions API.
- Include event_name, event_time, event_id, and action_source: “website”.
- Use hashed email, phone_number, client_ip_address, and client_user_agent to improve match quality:
fetch(“https://your-gtm-server-endpoint”)
.then(() => {
dataLayer.push({
event: "meta_capi_purchase",
user_data: {
email: "hashed_email",
phone_number: "hashed_phone",
client_ip_address: "user_ip",
client_user_agent: navigator.userAgent
},
custom_data: {
currency: "USD",
value: 85.00,
content_ids: ["sku321"],
content_type: "product"
},
event_id: "meta-purchase-321",
action_source: "website"
});
});
- Make sure to pass the same event_id from Pixel and CAPI for deduplication.
- Check real-time event accuracy in Meta Events Manager.
- Track match rate, deduplication status, and parameter coverage.
- Adjust mapping if fields are missing or mismatched.
Section 8: TikTok Pixel + Events API
TikTok ad data often goes missing without proper implementation. To track conversions accurately, set up both browser and server-side tracking.
Step 1: Install TikTok Pixel via GTM Web
- Create a tag in GTM for TikTok Pixel.
- Use standard events like PageView, AddToCart, Checkout, and Purchase.
- Use dataLayer to pass values dynamically.
<script>
dataLayer.push({
event: "purchase",
ecommerce: {
transaction_id: "OD888",
currency: "USD",
value: 60.00,
items: [
{
item_id: "sku888",
item_name: "TikTok Product",
quantity: 1,
price: 60.00
}
]
},
event_id: "tiktok-purchase-888"
});
</script>
- Use GTM variables to populate TikTok Pixel tag parameters from the dataLayer.
Step 2: Capture TikTok Click ID
- Store ttclid in a first-party cookie:
<script>
var ttclid = new URLSearchParams(window.location.search).get('ttclid');
if (ttclid) {
document.cookie = "ttclid=" + ttclid + "; path=/; max-age=" + (90*24*60*60);
}
</script>
Step 3: Set Up TikTok Events API via GTM Server
- Send same purchase data to TikTok Events API.
- Include parameters like event_name, event_time, event_id, ttclid, ip, and user_agent.
fetch(“https://your-gtm-server-endpoint/tiktok”, {
method: “POST”,
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({
event_name: "Purchase",
event_time: Math.floor(Date.now() / 1000),
event_id: "tiktok-purchase-888",
ttclid: getCookie("ttclid"),
user: {
ip: "user_ip",
user_agent: navigator.userAgent
},
properties: {
value: 60.00,
currency: "USD",
contents: [
{
content_id: "sku888",
quantity: 1,
price: 60.00
}
],
content_type: "product"
}
})
});
Step 4: Validate with TikTok Events Manager
- Use TikTok’s Pixel Helper and Events Debugger.
- Check deduplication, parameter coverage, and match rate.
This setup ensures your TikTok conversions are captured accurately on both browser and server sides.
Section 9: Pinterest Tag + Conversion API
To track Pinterest conversions reliably, set up both browser-side tags and optional server-side events.
Step 1: Pinterest Tag via GTM Web
- Install Pinterest base tag using GTM’s Custom HTML tag.
- Create event tags like checkout or purchase.
- Use the dataLayer to push transaction data:
<script>
dataLayer.push({
event: "purchase",
ecommerce: {
transaction_id: "OD999",
currency: "USD",
value: 42.00,
items: [
{
item_id: "sku999",
item_name: "Pinterest Product",
quantity: 1,
price: 42.00
}
]
},
event_id: "pinterest-purchase-999"
});
</script>
- In your Pinterest tag, map value, currency, order_id, and line_items using GTM variables.
- Use triggers for the correct ecommerce step.
Step 2: Optional Pinterest Conversion API via GTM Server
- Send a server-side purchase event to Pinterest API:
fetch(“https://api.pinterest.com/v5/ad_events”, {
method: “POST”,
headers: {
"Content-Type": "application/json",
"Authorization": "Bearer YOUR_ACCESS_TOKEN"
},
body: JSON.stringify({
event_name: "checkout",
event_time: Math.floor(Date.now() / 1000),
action_source: "website",
event_id: "pinterest-purchase-999",
user_data: {
email: "hashed_email",
ip_address: "user_ip",
user_agent: navigator.userAgent
},
custom_data: {
currency: "USD",
value: 42.00,
order_id: "OD999",
line_items: [
{
item_id: "sku999",
quantity: 1,
price: 42.00
}
]
}
})
});
- Use the same event_id from the dataLayer to support deduplication.
- Send hashed user data for better attribution.
Section 10: Microsoft Ads UET + Offline Conversions
To track Microsoft Ads properly, set up both browser-side and offline conversion tracking.
Step 1: Install Microsoft UET Tag via GTM Web
- Create a new tag in GTM
- Tag Type: Custom Image Tag or Microsoft UET Template
- Add your UET tag ID from Microsoft Ads
- Trigger on all pages
Step 2: Push Purchase Event into dataLayer
<script>
dataLayer.push({
event: "purchase",
ecommerce: {
transaction_id: "ODMS123",
currency: "USD",
value: 110.00,
items: [
{
item_id: "skuMS123",
item_name: "Odoo Microsoft Product",
quantity: 1,
price: 110.00
}
]
},
event_id: "ms-purchase-123",
msclkid: new URLSearchParams(window.location.search).get('msclkid')
});
</script>
Step 3: Store msclkid in First-Party Cookie
<script>
var msclkid = new URLSearchParams(window.location.search).get('msclkid');
if (msclkid) {
document.cookie = "msclkid=" + msclkid + "; path=/; max-age=" + (90*24*60*60);
}
</script>
Step 4: Send Offline Conversions
- Export transactions with msclkid and upload to Microsoft Ads
- Include: msclkid, transaction_id, revenue, currency, timestamp
- Use manual upload or API integration for automated syncing
Step 5: Debug and Validate
- Use Microsoft UET Helper Chrome extension
- Check real-time hits
- Match transactions in Microsoft Ads dashboard
Section 11: Reddit and LinkedIn Tracking
Reddit Tracking Setup
Reddit Ads use a pixel-based tracking model. To track actions:
- Add Reddit Pixel via GTM using a Custom HTML tag.
- Use events like PageView, AddToCart, and Purchase.
- Use this sample dataLayer for a purchase event:
<script>
dataLayer.push({
event: "purchase",
ecommerce: {
transaction_id: "ODREDDIT123",
currency: "USD",
value: 95.00,
items: [
{
item_id: "skuRed123",
item_name: "Reddit Tracked Product",
quantity: 1,
price: 95.00
}
]
},
event_id: "reddit-purchase-123",
reddit_click_id: new URLSearchParams(window.location.search).get('rdclid')
});
</script>
- Reddit doesn’t offer a server-side API yet. Use browser pixel only.
- Store rdclid (if available) in a cookie for later matching.
<script>
var rdclid = new URLSearchParams(window.location.search).get('rdclid');
if (rdclid) {
document.cookie = "rdclid=" + rdclid + "; path=/; max-age=" + (90*24*60*60);
}
</script>
- Verify in the Reddit Ads dashboard and check event firing.
LinkedIn Tracking Setup
LinkedIn uses a pixel called the Insight Tag for browser tracking, and supports offline conversion uploads.
- Install the Insight Tag via GTM. Fire it on all pages.
- Capture the LinkedIn Click ID li_fat_id from the URL and store it:
<script>
var li_fat_id = new URLSearchParams(window.location.search).get('li_fat_id');
if (li_fat_id) {
document.cookie = "li_fat_id=" + li_fat_id + "; path=/; max-age=" + (90*24*60*60);
}
</script>
- For offline conversion matching, extract this ID from completed purchases.
{
"li_fat_id": "stored_value",
"transaction_id": "ODLIN123",
"value": 80.00,
"currency": "USD",
"timestamp": "2025-06-29T12:00:00Z"
}
- Upload conversion files to LinkedIn via their offline conversions tool.
- Match click IDs to backend transactions to ensure accurate reporting.
Reddit and LinkedIn do not support full server-side tracking yet, so rely on proper pixel setup and attribution ID storage for accuracy.
Reddit:
- Install Reddit Pixel via GTM Custom HTML
- Fire events like PageView, Purchase
- Store Reddit Click ID if available
LinkedIn:
- Add Insight Tag via GTM
- Store li_fat_id
- Upload offline conversions from CRM or server
Section 12: Consent Mode v2 and Privacy Compliance
- Install Consent Mode via GTM
- Sync with CMP like Cookiebot or OneTrust
- Configure GTM tags to fire based on consent
- Use ad_storage and analytics_storage flags
Section 13: Capture Click IDs for Attribution
- Store click IDs: gclid, fbclid, ttclid, msclkid, li_fat_id
- Save in first-party cookies
- Send in server-side payloads
- Link click IDs to transaction ID
Section 14: Handle External Payments (Stripe, PayPal)
- Use server-side fallback for purchases
- Match transaction ID and value from webhook
- Delay browser tag until payment confirmation
Section 15: CRM and Delayed Conversions
- Capture email/phone on checkout
- Hash and send using CAPI or Enhanced Conversions
- Match delayed CRM events to ad clicks
- Upload manually or through API
Section 16: QA and Debugging
- Use GA4 DebugView
- Use Meta, TikTok, Pinterest tag tools
- Log dataLayer values in browser console
console.log(window.dataLayer);
- Check GTM Server logs
- Confirm event_id, value, and user data in each platform
Section 17: Reporting and Attribution
- Compare GA4 vs. backend orders
- Check Meta match rates and deduplication accuracy
- Analyze drop-off using GA4 funnel reports
- Monitor attribution windows and click-match success
Section 18: Final Thoughts and Call to Action
Most Odoo stores lose conversions because tracking is outdated, inconsistent, or incomplete.
By using Google Tag Manager, clean dataLayer events, and server-side tagging, you can fix this. When your data is clean, your ad platforms finally start working for real — with true ROAS, stronger delivery, and reliable optimization signals.
If you’re tired of underreported GA4 data, Meta Pixel showing double events, or TikTok saying you’ve got nothing — I can help.
I’m a conversion tracking expert. I help eCommerce brands build systems that show exactly where their sales come from.
- Clean dataLayer
- Full platform setup: Google Ads, Meta, TikTok, Pinterest, Microsoft
- Consent Mode compliance
- Server-side tagging to recover lost signals
Let’s fix your tracking. Let’s stop wasting budget.
→ Contact me for a full Odoo tracking audit. No fluff. Just results.
Your data should match your sales. Your ads deserve accurate conversions.
With clean tracking in place, you’ll stop guessing and start scaling.
Need expert help? Let me audit your Odoo tracking, show you where it’s broken, and help rebuild it — fast and properly.
👉 Contact me for a personalized tracking audit.