You check Google Ads and see 45 conversions yesterday. Meta reports 38. But your actual Shopify order count? 30. The numbers don’t add up because your store is sending duplicate purchase events — the same order counted two, sometimes three times.
Duplicate purchase events inflate your conversion counts, corrupt your ROAS calculations, and poison your ad algorithms. Google and Meta optimize based on the data you send them. If you’re reporting 50% more conversions than actually occurred, their bidding models are working with fictional numbers.
Here’s how to find where the duplicates are coming from and fix them.
How Duplicates Happen on Shopify
Source 1: Thank-You Page Reloads
The most common cause. When a customer completes an order, they land on the thank-you page. Your conversion tags fire. Then:
- The customer refreshes the page (checking order status)
- The customer bookmarks the page and returns later
- A slow connection loads the page twice
- The customer’s browser restores tabs after a restart
Each reload fires your conversion tags again. Without deduplication, that’s two (or more) conversion events for one order.
How common: Very. Shopify’s thank-you page is a persistent URL that customers can revisit. Some customers check it multiple times for shipping updates.
Source 2: Native Shopify Integration + Custom Pixel
Shopify has native integrations for Google, Meta, TikTok, and Pinterest. If you ALSO have custom tracking via:
- GTM on the thank-you page
- Shopify Web Pixel API
- Third-party apps (Elevar, Analyzify, etc.)
- Custom
<script>tags in the checkout Additional Scripts
You get two separate tracking implementations firing for the same event. The native integration sends a purchase event, and your custom implementation sends another.
Example scenario:
Order #1234 completes
→ Shopify native "Google & YouTube" channel fires GA4 purchase event
→ Your GTM tag on thank-you page ALSO fires GA4 purchase event
→ GA4 receives TWO purchase events for order #1234
Source 3: Multiple Third-Party Apps
You installed Elevar for server-side tracking. Your agency also set up their own GTM-based tracking. And Shopify’s native pixel is still active. Now three systems are all sending purchase events.
Source 4: Pixel + Conversions API Without Dedup
If you’re running the Meta Pixel alongside Conversions API, Meta receives two events for every purchase — one from the browser, one from your server. Meta deduplicates these using event_id, but only if both events include the same event_id. If they don’t, Meta counts both.
Source 5: Checkout Redirect Chains
Some Shopify apps or payment providers redirect customers through intermediate pages before landing on the thank-you page. If your tags fire on each step:
Checkout → Payment Processor → Intermediate Page (tag fires) → Thank You (tag fires again)
How to Find Duplicates
Check 1: Compare Actual Orders to Reported Conversions
The simplest diagnostic:
| Metric | Source | Count |
|---|---|---|
| Actual orders | Shopify Admin → Orders | 30 |
| GA4 purchases | GA4 → Reports → Monetization | 42 |
| Google Ads conversions | Google Ads → Conversions | 45 |
| Meta purchases | Meta Events Manager | 38 |
If any platform shows more conversions than actual orders, you have duplicates.
Expected variance: Platforms may show slightly MORE conversions than orders due to attribution windows counting returns, test orders, etc. A 5-10% variance is normal. More than 20% means duplicates.
Check 2: GA4 Transaction IDs
In GA4:
- Explorations → Free form
- Dimension:
Transaction ID - Metric:
Event count(filtered topurchaseevent) - Sort by Event count descending
If any transaction ID appears more than once, that purchase was double-counted.
Check 3: Meta Events Manager
- Meta Events Manager → [your pixel]
- Check the Deduplicated Events column
- If dedup count is significantly lower than total count, you have duplication
- Check the Overview tab for “Duplicate Events” warnings
Check 4: Google Ads Conversion Diagnostics
- Google Ads → Goals → Conversions
- Click on your purchase conversion action
- Check the “Conversion action details” for duplicate transaction warnings
Check 5: GTM Preview Mode
- Open GTM Preview Mode
- Complete a test purchase
- On the thank-you page, check which tags fired
- Refresh the thank-you page — check which tags fire again
- If purchase tags fire on reload, you have a reload-based duplicate
Check 6: Browser Network Tab
- Open DevTools → Network
- Complete a test purchase
- Filter by “google” or “facebook” or your tracking endpoints
- Count how many purchase/conversion requests fire
- Refresh and count again
Fix 1: Implement Transaction ID Deduplication
Every purchase event should include a unique transaction ID. Platforms use this to deduplicate.
GA4
gtag('event', 'purchase', {
transaction_id: 'ORDER_12345', // Shopify order ID
value: 99.99,
currency: 'USD',
items: [...]
});
GA4 automatically deduplicates events with the same transaction_id within a session. If you send two purchase events with transaction_id: 'ORDER_12345', GA4 counts it once.
Meta Pixel + CAPI
Both must use the same event_id:
Pixel (browser):
fbq('track', 'Purchase', {
value: 99.99,
currency: 'USD',
content_ids: ['SKU123']
}, { eventID: 'order_12345' });
CAPI (server):
{
"event_name": "Purchase",
"event_id": "order_12345",
"custom_data": {
"value": 99.99,
"currency": "USD"
}
}
The event_id in both events must be identical. Use the Shopify order ID or order name.
Google Ads
Include transaction_id in the conversion tag:
Transaction ID: {{Shopify Order ID}}
Google Ads deduplicates based on this ID within the attribution window.
Fix 2: Prevent Thank-You Page Reload Fires
Option A: One-Time Cookie Flag
Set a cookie after the first fire. Check it before firing again.
GTM Custom HTML (fires on thank-you page, priority 100):
<script>
(function() {
var orderId = {{Shopify Order ID}};
var cookieName = 'purchase_tracked_' + orderId;
// Check if already tracked
if (document.cookie.indexOf(cookieName) !== -1) {
// Already tracked -- block conversion tags
window.dataLayer.push({ event: 'purchase_already_tracked' });
return;
}
// Mark as tracked (expires in 24 hours)
var d = new Date();
d.setTime(d.getTime() + 86400000);
document.cookie = cookieName + '=1;expires=' + d.toUTCString() + ';path=/';
// Fire conversion event
window.dataLayer.push({
event: 'purchase_confirmed',
ecommerce: {
transaction_id: orderId,
value: {{Shopify Order Total}},
currency: {{Shopify Currency}}
}
});
})();
</script>
Then trigger your conversion tags on purchase_confirmed instead of the page URL.
Option B: Shopify First-Time Access Check
Shopify’s Shopify.checkout object includes first_time_accessed:
if (window.Shopify && Shopify.checkout && Shopify.checkout.first_time_accessed) {
// First load -- fire conversion tags
window.dataLayer.push({ event: 'purchase_first_load' });
}
Note: This property isn’t always available in all Shopify checkout configurations. Test before relying on it.
Option C: Server-Side Only
Skip browser-based purchase tracking entirely. Fire purchase events server-side via Shopify webhooks:
- Shopify triggers
orders/paidwebhook - Your server receives the webhook
- Server sends events to GA4 (Measurement Protocol), Meta (CAPI), etc.
- No thank-you page dependency at all
This is the most reliable method — but requires server infrastructure.
Fix 3: Remove Duplicate Tracking Implementations
Audit Your Current Setup
List every tracking implementation on your store:
| Implementation | Platform | Method | Active? |
|---|---|---|---|
| Shopify Google channel | GA4 + Google Ads | Native | Yes/No |
| GTM on thank-you page | GA4 + Google Ads | Custom | Yes/No |
| Shopify Facebook channel | Meta Pixel + CAPI | Native | Yes/No |
| GTM Meta Pixel tag | Meta Pixel | Custom | Yes/No |
| Elevar | GA4 + Meta + TikTok | Server-side | Yes/No |
| Web Pixel API custom pixel | GA4 + Meta | Custom | Yes/No |
The Rule: One Implementation Per Platform
For each ad platform, choose ONE tracking method:
| Platform | Recommended | Disable |
|---|---|---|
| GA4 | Your custom GTM setup OR Elevar | Shopify’s native Google channel |
| Meta | CAPI (server-side) + Pixel with dedup | Shopify’s native Facebook channel (if running custom) |
| TikTok | Web Pixel API or Elevar | Shopify’s native TikTok channel (if running custom) |
How to disable Shopify’s native tracking:
- Shopify Admin → Sales Channels
- Click on “Google & YouTube” (or “Facebook & Instagram”)
- Either disconnect the channel or remove the measurement/pixel ID
- Do NOT just “pause” — ensure it’s fully disconnected
For a complete guide to setting up the right tracking stack, see our Shopify conversion tracking guide.
Fix 4: Deduplicate Meta Pixel + CAPI
If you need both Pixel and CAPI (recommended for Meta tracking at scale):
- Generate a unique
event_idfor each purchase - Send that SAME
event_idin both the Pixelfbq()call and the CAPI request - Check Meta Events Manager → Deduplicated Event Ratio
Target: dedup ratio of 0.8-1.0 (meaning 80-100% of duplicate events are correctly deduplicated).
If the dedup ratio is 0 or very low:
- The
event_idvalues don’t match between Pixel and CAPI - The Pixel and CAPI are sending different event names
- Timing is too far apart (Meta deduplicates within a 48-hour window)
Fix 5: Handle Express Checkout / Shop Pay
Shop Pay and other express checkout methods redirect customers off your domain. When they return to the thank-you page, your browser pixels may not have the context they need (cookies were set on a different domain).
Symptoms:
- Purchase events fire but with missing product data
- Revenue shows as $0
- Transaction ID is undefined
Fix: Use server-side tracking (webhooks or CAPI) for purchase events. Server-side tracking works regardless of the checkout flow — it fires when Shopify processes the order, not when the customer loads a page.
Verification After Fixing
After implementing fixes, verify over 3-5 days:
- Daily check: Shopify order count vs GA4 purchases vs Google Ads conversions vs Meta purchases
- Transaction ID check: In GA4 Explorations, verify no transaction ID appears more than once
- Meta dedup check: Events Manager shows healthy deduplication ratio
- Revenue check: GA4 revenue matches Shopify revenue (within 5%)
| Metric | Expected Variance |
|---|---|
| GA4 purchases vs Shopify orders | Within 5% |
| Google Ads conversions vs Shopify orders | Within 10% (attribution window differences) |
| Meta purchases vs Shopify orders | Within 10% |
| GA4 revenue vs Shopify revenue | Within 5% |
Checklist
- Compared actual Shopify orders to platform-reported conversions
- Checked GA4 for duplicate transaction IDs
- Checked Meta Events Manager for duplicate event warnings
- Implemented transaction ID / event_id on all purchase events
- Thank-you page reload protection in place (cookie flag or first_time_accessed)
- Only ONE tracking implementation active per platform
- Meta Pixel + CAPI deduplication verified (matching event_id)
- Revenue accuracy verified over 3-5 days
Duplicate purchase events are invisible to most merchants. The conversion numbers look “good” — higher than expected, even. But inflated data leads to inflated confidence. You think your ROAS is 4x when it’s really 2.5x. You scale ad spend based on phantom conversions. The math catches up when revenue doesn’t grow but ad costs do.
Not sure if your Shopify store has duplicate events? Run a free scan — we detect duplicate tracking implementations, missing deduplication, and inflated conversion counts automatically.