Online certification courses
Low match quality and a purchase that fired on every reload
An online course seller's Meta purchases had weak match quality and re-fired on page reloads. I fixed both in GTM and verified one purchase per order.
- // symptom
- Meta Purchase match quality (EMQ) was low, and purchase counts looked inflated.
- // cause
- No advanced matching on the browser pixel, and a confirmation-page trigger that re-fired Purchase with a fresh event ID on every reload.
- // fix
- Advanced matching wired in through GTM. Then event ID tied to the order ID, plus a fire-once guard.
- // result
- Purchase EMQ 6.1 → 8.3 with 100% CAPI coverage. A live reload test showed 2 page loads → 1 Purchase.
- 01 Purchase EMQ 6.1/10 ⚠
- 02 advanced matching em/fn/ln wired ✓
- 03 Purchase EMQ 8.3/10 ✓
- 04 reload → 3 Purchase, 3 event_ids ✗
- ── patch: event_id ← order ID ──
- 05 reload → PageView only 1 Purchase ✓
- GTM
- Meta Pixel
- Meta Conversions API
- Google Ads
- Microsoft UET
Two problems wearing one symptom
Meta’s Purchase numbers weren’t trustworthy, and the match quality score was low. It looked like one problem. It was two.
Match quality
Event Match Quality measures how well Meta can tie a conversion back to a real person. It depends on the identity data you send with the event. I audited every source sending events to Meta: the browser pixel plus several server-side feeds that had piled up over about five years.
The ceiling was the browser pixel itself. It sent no advanced matching on checkout and purchase events. I wired email and name matching into the pixel through GTM, from data the checkout already had.
Purchase EMQ went from 6.1 to 8.3, with 100% Conversions API coverage. Checkout events came up too.
The reload problem
Then I ran a reload test on the order confirmation page. One order produced three Purchase events with three different event IDs.
Meta dedupes on event name plus event ID. The confirmation trigger generated a new ID on every page load, so dedup could never match the copies. Every reload looked like a new sale.
The fix
Two layers, both in GTM:
- Event ID = order ID on the Meta Purchase tag. Now every copy of a purchase carries the same ID, so Meta collapses them.
- A fire-once guard that remembers which orders already fired in this browser. It fails open: if it breaks, tracking keeps working and Meta’s dedup stays as the backstop.
In the same pass I added the order ID to the Google Ads tag and stopped a checkout event from firing on the confirmation page.
How I proved it
Live test: two loads of the confirmation page produced one Purchase, with the event ID equal to the order ID. The reload fired a PageView only.
Limits
Microsoft’s tag has no order ID field, so it relies on the guard. The guard works per browser, so a second device can still re-fire. That’s where Meta’s event ID dedup catches it.
Seeing something like this?
Tell me what's not counting