Meta Ads tracking instellen via Webhook Matching
Dit artikel gaat over het Meta CAPI-deel van AdPage Webhook Matching: hoe je de AdPage - Meta Conversion API-tag koppelt aan de merged payload die Webhook Matching aanlevert. Belangrijk om vooraf te begrijpen: dit CAPI-event is geen vervanging van je browser-side Meta Pixel — het is een toevoeging daarop. Beide sturen een Purchase, en Meta dedupliceert ze aan de hand van een gedeeld event_id, zodat je aankoop niet dubbel telt.
Heb je Webhook Matching nog niet ingericht? Doorloop eerst het basisartikel (activeren, Event Notifier-template, BasketKey, Measurement Protocol Client) — dit artikel bouwt daar direct op verder.
Kort: wat is Webhook Matching ook alweer?
Webhook Matching is een AdPage-functionaliteit die twee databronnen server-side samenvoegt tot één gevalideerd event:
Prepare (browser-side, vlak vóór checkout): vangt browser-context —
gclid, cookies (_fbp/_fbc), user-agent, items-arrayTrigger (server-side webhook, bij de order): vangt de backend-ordergegevens — klant, adres, bedrag,
transaction_id
Beide kanten worden gekoppeld via een BasketKey (user_id, cart_token of quote_id, afhankelijk van je platform). Het resultaat komt binnen op je sGTM server container via een Measurement Protocol (GA4) Client op het pad /data, en bevat direct alle velden die GA4, Meta, Google Ads, TikTok én Pinterest nodig hebben — inclusief consent-forwarding.
Hoe de deduplicatie werkt
Meta dedupliceert het browser-Pixel-event en het server-side CAPI-event van dezelfde aankoop wanneer beide hetzelfde event_id én dezelfde event_name (Purchase) dragen. Meta houdt er dan één aan (binnen een venster van ~48 uur) en negeert de tweede.
De sleutel is dus het event_id. Dat moet twee dingen tegelijk zijn:
Identiek op de browser-Pixel én de CAPI-kant voor dezelfde aankoop.
Uniek per aankoop — anders worden verschillende orders ten onrechte samengevoegd.
De enige waarde die aan beide voldoet is het transaction_id (order-ID). Gebruik dus:
Bron |
| |
|---|---|---|
Browser-side (bestaand) | Meta Pixel |
|
Server-side (deze setup) | AdPage - Meta Conversion API op de Measurement Protocol Client |
|
⚠️ Gebruik niet
user_idalsevent_id. Die is stabiel per klant, niet per order — een tweede aankoop van dezelfde klant binnen 48u zou dan onterecht als duplicaat worden weggegooid.user_idhoort thuis als BasketKey en alsexternal_id, niet als dedup-sleutel.
⚠️ Het
event_idmoet exact dezelfde string zijn aan beide kanten. Let op prefixes of formatting: stuurt de browser12345en de serverorder_12345, dan ziet Meta twee verschillende events en dedupt het niet.
💡 Zorg dat het CAPI-
event_iduit de Trigger/order-kant (transaction_id) komt, en niet uit een willekeurigevent_iddat in de Prepare/begin_checkout-stap is gegenereerd — dat laatste matcht nooit met het browser-Purchase-event.
Wat heb je nodig?
Je bestaande browser-side Meta Pixel
Purchasewerkend, ingesteld metevent_id = transaction_idWebhook Matching actief voor deze klant (stap 1 uit het basisartikel)
De Prepare- en Trigger-tags (op basis van
adpage-event-notifier.tpl) al ingericht met de juiste BasketKey — inclusief een consistenttransaction_idEen Measurement Protocol (GA4) Client op pad
/data, met een herkenbare naam — in dit artikel gebruiken weWebhook Matching - GA4als voorbeeldJe Meta Pixel ID en API Access Token — zie dit artikel
Het template-bestand
AdPage - Meta Conversion API.tpl(AdPage-fork van de Facebook Conversion API-template) — https://adpage.b-cdn.net/GTM-Templates/Facebook%20Conversion%20API.tpl
Stap 1: Template uploaden
Open je GTM server container en ga naar Templates
Klik bij Tag Templates op New
Klik rechtsboven op de drie puntjes (⋮) en kies Import
Selecteer het bestand
AdPage - Meta Conversion API.tpl(https://adpage.b-cdn.net/GTM-Templates/Facebook%20Conversion%20API.tpl)Klik op Save
Stap 2: Tag aanmaken en basisinstellingen
Ga naar Tags in het linkermenu
Klik op New
Kies als Tag Configuration de AdPage - Meta Conversion API
Geef de tag een herkenbare naam, bijvoorbeeld
AdPage - Meta Purchase (Webhook Matching)Vul Facebook Pixel ID en API Access Token in
Laat Action Source op de standaardwaarde
WebsitestaanVink Generate _fbp cookie if it not exist uit — Webhook Matching stuurt de echte
_fbp/_fbcvan de Prepare-stap al mee; een zelfgegenereerde fallback voegt daar niets aan toe
Stap 3: Trigger instellen op de Measurement Protocol Client
Dit event komt niet binnen als een custom event met een trytagging_-prefix. Het komt binnen via de Measurement Protocol Client die je in stap 4 van het basisartikel hebt aangemaakt, met een schone event_name: "purchase".
Klik in de tag op Triggering → +
Kies als trigger type Custom
Stel in: {{Client Name}} komt overeen met de naam van je Measurement Protocol Client (bijv.
Webhook Matching - GA4)Voeg optioneel een tweede voorwaarde toe: Event Name is gelijk aan
purchaseGeef de trigger een naam, bijvoorbeeld
Webhook Matching - PurchaseKlik op Save
💡 Je browser-side Meta Pixel
Purchaseblijft gewoon staan — dit is bewust. Het CAPI-event vult de gevallen op waar de browser faalt (ad-blockers, ITP, consent, afgebroken sessies), en Meta dedupt op het gedeeldeevent_id.
⚠️ Gebruik voor de CAPI-tag zelf maar één trigger. Zet niet ook nog de "Client Name equals GA4"-trigger uit het reguliere Meta CAPI-artikel op deze tag — dat zou een tweede server-side CAPI-event voor dezelfde aankoop veroorzaken, en die twee delen niet noodzakelijk hetzelfde
event_id.
Stap 4: Event Name — "Inherit from client" werkt hier prima
Omdat de Measurement Protocol Client een schone event_name: "purchase" doorgeeft (géén trytagging_-prefix), herkent de tag dit automatisch als het standaard Facebook-event Purchase via de ingebouwde naam-mapping.
Laat Event Name Setup Method op Inherit from client staan
Wil je liever expliciete controle? Zet dan Override → Standard → Purchase. Functioneel maakt het in deze setup geen verschil — zolang het event maar als Purchase bij Meta binnenkomt, want de dedup vereist dezelfde event_name als je browser-Pixel.
Stap 5: Consent — controleren, niet blind uitzetten
Webhook Matching stuurt consent standaard mee, in meerdere vormen (gcs/gcd, en een genest consent.*-object). Zet Consent Settings dus in eerste instantie niet op "Send data always", maar test eerst of het "gewoon werkt":
Laat Consent Settings op de standaardwaarde staan: "Send data in case marketing consent given"
Test de flow (zie Stap 7)
Zie je in de preview mode dat de tag Fired toont, maar niets onder Outgoing HTTP Requests from Server? Dan komt de consent niet aan in het formaat dat deze tag verwacht (
consent_state.ad_storageofx-ga-gcs) — zet dan als tijdelijke fix Consent Settings op Send data always, en meld dit door aan het Tracking & Tools-team, want dan klopt de gcs-doorvertaling van de Measurement Protocol Client niet.
💡 Dit is een bewuste afwijking van eerdere Meta CAPI/webhook-artikelen: bij de losse AdPage Webhook Client ontbreekt consent-data structureel (zie de kanttekening onderaan), maar bij Webhook Matching hoort consent er wél doorheen te komen omdat het via de Measurement Protocol Client loopt.
Stap 6: Klant- en aankoopdata — automatisch gemapt
De merged payload van Webhook Matching bevat exact de velden die deze tag automatisch herkent. Volgens het basisartikel worden deze Meta-velden standaard meegestuurd:
Meta-veld | Herkomst (via Webhook Matching) |
|---|---|
|
|
| e-mail, voornaam, achternaam, telefoon — tag hasht deze automatisch met SHA256 als ze nog niet gehasht zijn |
| postcode, stad, provincie, land |
|
|
| IP en user-agent voor matching |
|
|
| order- en productdata, inclusief de items-array uit de Prepare-stap |
Je hoeft de User Data- en Custom Data-tabellen dus in de regel niet handmatig te vullen. Kom je toch een veld tegen dat leeg blijft? Check eerst in de sGTM preview of het veld daadwerkelijk in de payload van de Measurement Protocol Client staat, vóór je het als custom property toevoegt.
Stap 7: Testen
Open je server container → Webhook Logs
Zoek een recente purchase-webhook en klik op Replay
Open je GTM server container in Preview Mode
Klik rechtsboven op de drie puntjes en kies Send requests manually
Kopieer de
x-gtm-server-previewheader en plak deze in de Webhook Replay-popupKlik op Replay
Via onderstaande link kun je de stappen zien: https://app.arcade.software/share/0HswbFejHQLFQeeC2NXw
Controleer in de preview mode, in deze volgorde:
De Prepare- en Trigger-tag van Event Notifier hebben eerder al gematcht (geen
missed-status in de Webhook Matching-logs — zie troubleshooting in het basisartikel)Je Measurement Protocol Client (
Webhook Matching - GA4) verschijnt met het request op/dataDe AdPage - Meta Conversion API-tag toont Fired
Onder Outgoing HTTP Requests from Server staat een request naar
graph.facebook.com— staat hier None, ga terug naar Stap 5 (consent)Controleer dat het uitgaande
event_idgelijk is aan hettransaction_id— en aan hetevent_iddat je browser-Pixel voor dezelfde order meestuurt
💡 Extra check in Meta zelf: vul tijdens het testen het veld Test ID in met de code uit Gebeurtenisbeheer → Test-gebeurtenissen in Meta, zodat je meteen de Event Match Quality-score ziet. In het overzicht van gebeurtenissen zie je bovendien of het browser- en server-event als gededupliceerd worden herkend op basis van gedeeld
event_id. Verwijder het Test ID voordat je live gaat.
Veelvoorkomende problemen
Aankoop wordt dubbel geteld in Meta
De dedup mislukt. Loop deze drie na:
event_id: sturen browser-Pixel én CAPI exact dezelfde waarde (transaction_id, zonder prefix/formattingverschil)?event_name: komt het server-event alsPurchasebinnen, en niet alstrytagging_purchaseof een custom naam?Dubbele CAPI-trigger: staat er per ongeluk náást de Webhook Matching-trigger ook nog een "Client Name = GA4"-trigger op deze CAPI-tag? Gebruik er maar één.
Zie ook Event Deduplicatie instellen voor Meta Ads.
Tag toont "Fired", maar geen Outgoing HTTP Request
Zie Stap 5 — de gcs/consent-doorvertaling van de Measurement Protocol Client komt niet aan zoals de tag verwacht. Zet tijdelijk Consent Settings op Send data always en meld dit intern.
"Match identifier value could not be resolved" in de Webhook Matching-logs
Dit gebeurt vóór de Meta-tag en heeft niets met deze tag te maken — de BasketKey wordt niet gevonden. Zie de troubleshooting in het basisartikel.
Event komt bij Meta binnen met een lege of onverwachte event-naam
Controleer of de trigger inderdaad op de Measurement Protocol Client staat (Stap 3) en niet op een custom event met een trytagging_-prefix — dat laatste hoort bij de losse Webhook Client, niet bij Webhook Matching (zie hieronder).
Verschil met de standaard Webhook Client
Gebruik je (nog) geen Webhook Matching, maar wel de gewone AdPage Webhook Client rechtstreeks (zoals in het GA4 webhook-artikel)? Dan gelden twee afwijkende punten ten opzichte van dit artikel:
Het event komt binnen met de ruwe naam
trytagging_purchase, niet als schonepurchase. Zet Event Name Setup Method dan op Override → Standard → Purchase — "Inherit from client" stuurt anders een custom eventtrytagging_purchasenaar Meta, dat niet dedupt met je browser-Pixel.De payload bevat geen consent-signaal. Zet Consent Settings dan direct op Send data always, anders stopt de tag stilzwijgend zonder een request te versturen.
