PrestaSignal
← All posts
Fundamentals · May 28, 2026

Event deduplication: how to stop double-counting purchases

Running the pixel and the Conversions API together can count a single sale twice. The fix is a shared event_id built from the order itself — here is how it works.

7 min read

The moment your store sends the same sale down two roads — one from the browser, one from the server — you create a new risk: counting that sale twice. Dual-path delivery is deliberate and good, but if you do not handle deduplication just as deliberately, your revenue numbers inflate and your bidding algorithms learn the wrong lesson.

The good news is that deduplication is a solved problem with a clean, repeatable answer. This article explains why double-counts happen in the first place, why naive fixes fail, and how a shared event_id built from the order itself makes one sale count exactly once — across GA4, Meta, and Google Ads alike.

Why double-counts happen

There are two common sources of duplicate conversions, and most stores eventually hit both.

The first is dual-path delivery. To recover conversions that ad-blockers and ITP hide, the recommended approach sends each purchase from both the browser (the pixel or client-side tag) and the server (the Conversions API or server-side tag). That redundancy is intentional and good — but without deduplication, the analytics platform receives two events and credits two sales.

The second is page reloads and retries. A confirmation page that the shopper refreshes, navigates back to, or that retries a failed beacon can fire the purchase event again. If each fire uses a fresh random identifier, every reload looks like a brand-new order. Stack the two causes together and a single sale can be counted three or four times.

Why random IDs make it worse

The instinct is to give each event a unique ID so you can tell them apart. For deduplication, that is exactly backwards. A random event_id guarantees that the browser event and the server event for the same sale carry different IDs — so the platform sees two distinct conversions and counts both.

The same flaw breaks reload handling. If the confirmation page generates a new random ID every time it loads, a refresh produces a second "unique" purchase that nothing recognises as a duplicate.

Deduplication needs the opposite property: the same logical sale must always produce the same ID, no matter how many times or from how many places the event fires. Uniqueness per fire is the enemy; consistency per sale is the goal.

An event_id built from the order itself

The robust solution is an event_id built from something that is already stable and unique per sale: the order itself. Because the order's identity does not change, every path and every reload can compute the identical event_id independently, without coordinating with each other. A refresh produces the same ID as the first load — so a reload can never double-count.

When the pixel and the Conversions API both send a purchase with the same event_id, Meta recognises them as one sale and counts it once. GA4 deduplicates the same way using a transaction_id built from the order, and Google Ads conversions collapse cleanly too.

This is the core design decision behind clean dual-path tracking: identity comes from the order, not from a random number generated at fire time. Reloads, back-button clicks, and dual-path delivery all resolve to one canonical conversion.

How dual-path setups deduplicate end to end

In a properly built dual-path pipeline, deduplication is not a single switch but a consistent principle applied everywhere. The browser-side event and the server-side event for a given sale share one event_id, built from the order itself. The platforms — Meta for CAPI, GA4 for analytics, Google Ads for conversions — each use that shared identity to merge the duplicate into one.

PrestaSignal implements exactly this as one integrated design. Everyday browser events are recorded through a small connector on your own website address, while the sale itself is reported by your back office on a browser-free second road — recorded exactly once, with refunds carrying the matching transaction_id so revenue reverses correctly. The purchase your browser pixel fires and the purchase our server sends share one id built from the order, so Meta CAPI keeps exactly one, GA4 merges on the matching transaction_id, and Google Ads counts a single conversion.

The payoff is that you get the reliability of server-side delivery and the behavioural richness of browser tracking, with none of the inflation that would otherwise come from sending everything twice. The redundancy protects you against loss; the deduplication protects you against double-counting.

How to tell if you have a problem

Suspect double-counting when GA4 or Meta report more conversions or revenue than your PrestaShop back office, especially after adding a server-side or pixel-plus-CAPI setup. A revenue figure that runs consistently above your actual takings is the clearest tell.

Another symptom is erratic bidding behaviour: if Smart Bidding or Meta optimisation suddenly overspends, it may have learned that certain clicks are worth twice what they really are, because duplicates taught it inflated values. Duplicate conversions distort optimisation just as badly as missing ones.

If any of this sounds familiar, the diagnosis is usually a missing or random event_id. PrestaSignal's merchant portal shows a live feed of your events as they arrive, so you can see what your shop is actually reporting instead of waiting for monthly totals. To have your setup checked against your real orders, book a teardown and we will identify exactly where the duplicates are coming from.

Good to know

Quick questions

Why do dual-path tracking setups double-count purchases?+

Because they intentionally send each sale from both the browser and the server. Without a shared event_id to link the two, the platform sees two events and counts two conversions.

What is an event_id and how does it deduplicate?+

An event_id is a shared identifier for one conversion. When the browser and server events carry the same event_id, Meta and GA4 recognise them as a single sale and count it once.

Why build the event_id from the order itself?+

Because the order's identity is stable and unique per sale. Every path and every page reload can compute the same event_id independently — never a random one — so duplicates always collapse into one.

Can a page reload cause duplicate conversions?+

Yes, if the purchase event uses a random ID each time it fires. An event_id built from the order itself makes reloads and back-button clicks resolve to the same single conversion.

How do I know if I am double-counting?+

The usual sign is GA4 or Meta reporting more revenue or conversions than your PrestaShop back office. Erratic Smart Bidding overspend can also point to inflated, duplicated values.

Find out what your tracking is missing — for free.

We'll audit your store's tracking and show you the gap. No pitch unless you ask.

Part of the PrestaChamps family →