Meta Pixel i Conversions API (CAPI) w SalesCRM
SalesCRM śledzi zdarzenia Meta (Facebook/Instagram) dwoma kanałami naraz: Pixelem w przeglądarce oraz Conversions API z naszego serwera. Oba dla tego samego zakupu wysyłają identyczny event_id, dzięki czemu Meta deduplikuje zdarzenia i nie liczy konwersji podwójnie.
1. Dwa kanały — o co chodzi
Meta zbiera te same zdarzenia (np. Purchase) z dwóch źródeł, bo każde ma inne mocne strony:
- Pixel (client-side) — kod
fbqwstrzykiwany na strony sklepu. Działa w przeglądarce kupującego, dostarcza sygnały przeglądarkowe (m.in._fbp,_fbc). Wadą jest podatność na blokery reklam, brak zgody na ciasteczka i ograniczenia przeglądarek — część zdarzeń nigdy nie dolatuje. - Conversions API / CAPI (server-side) — zdarzenie wysyłane bezpośrednio z serwera SalesCRM do Meta (Graph API). Omija blokery i ograniczenia przeglądarki, więc łapie praktycznie 100% zakupów.
Najlepszy efekt daje uruchomienie obu kanałów jednocześnie — wtedy Meta ma komplet danych, a duplikaty usuwa po wspólnym event_id (patrz sekcja 4).
2. Konfiguracja w panelu
Wejdź w Konfiguracja → Integracje → Pixel Meta. Dostępne pola:
| Pole | Kanał | Co robi |
|---|---|---|
| Pixel ID | oba | Identyfikator pixela z Menedżera Zdarzeń Meta. Samo jego ustawienie wstrzykuje na strony sklepu bazowy kod pixela (fbq('init', …) + <noscript>). |
| Śledzenie wyświetleń | client-side | Wysyła PageView przy wczytaniu strony. |
| Śledzenie dodań do koszyka | client-side | Wysyła AddToCart przy dodaniu produktu. |
| Śledzenie zakupów | client-side | Wysyła Purchase z przeglądarki. |
| Strona śledzenia zakupów | client-side | Gdzie odpalić przeglądarkowy Purchase: Potwierdzenie złożenia zamówienia, Przekierowanie po płatności albo Tylko po stronie serwera (przeglądarka nie wysyła nic — patrz sekcja 3). |
| Śledzenie zakupów po stronie serwera | CAPI | Wysyła Purchase przez Conversions API po potwierdzeniu płatności. Wymaga tokenu API. |
| Śledzenie dodań do koszyka po stronie serwera | CAPI | Wysyła AddToCart przez CAPI. Działa niezależnie od wersji client-side. |
| Śledzenie wyświetleń produktów po stronie serwera | CAPI | Wysyła ViewContent przez CAPI przy każdym wejściu na stronę produktu. |
| Token API konwersji | CAPI | Token dostępu z Menedżera Zdarzeń Meta (Ustawienia → Conversions API). Bez niego kanał serwerowy nie wyśle nic. |
| Identyfikator drugiego pixela | oba | Opcjonalny. Drugie konto reklamowe, do którego mają trafiać te same zdarzenia — patrz sekcja 8. |
| Token API konwersji drugiego pixela | CAPI | Token wystawiony dla drugiego pixela. Token pierwszego tu nie zadziała. |
Checkboxy „client-side" i „po stronie serwera" są niezależne. Aby uzyskać deduplikację, włącz dla danego zdarzenia oba (np. Śledzenie zakupów + Śledzenie zakupów po stronie serwera).
3. Jakie zdarzenia i którym kanałem
SalesCRM używa standardowych nazw zdarzeń Meta (pisownia PascalCase). Nazwy małymi literami, np. purchase czy view_cart, to konwencja Google Analytics 4, a nie Meta — do Meta ich nie wysyłamy.
| Zdarzenie | Client-side (Pixel) | Server-side (CAPI) | event_id |
|---|---|---|---|
PageView | tak (jeśli „śledzenie wyświetleń") | – | – |
AddToCart | tak | tak (osobny checkbox) | atc-<id>-… (wspólny dla obu kanałów) |
ViewContent | – | tak (osobny checkbox) | vc-<produkt>-… |
Purchase | tak | tak (osobny checkbox) | orders_<id zamówienia> (wspólny dla obu kanałów) |
InitiateCheckout nie jest nadawany przez SalesCRM — pojawia się tylko, jeśli własny front sklepu (architektura headless) odpala je samodzielnie.
3a. Kiedy dokładnie liczy się zakup
Domyślnie przeglądarkowy Purchase odpala się na stronie potwierdzenia zamówienia — czyli w chwili złożenia zamówienia, zanim klient trafi do bramki płatności. Zamówienie, za które nikt nie zapłaci, i tak zostanie zaraportowane jako zakup. Meta optymalizuje wtedy kampanie na zawyżonym sygnale.
Pole Strona śledzenia zakupów ma trzy ustawienia:
| Ustawienie | Kiedy leci Purchase | Zamówienie nieopłacone |
|---|---|---|
| Potwierdzenie złożenia zamówienia (domyślne) | zaraz po złożeniu, na stronie podziękowania | zostanie policzone jako zakup |
| Przekierowanie po płatności | gdy klient wraca z bramki bez błędu | zwykle nie, ale powrót z bramki to jeszcze nie potwierdzona wpłata |
| Tylko po stronie serwera | dopiero po potwierdzeniu płatności przez operatora | nie zostanie policzone |
Jeśli zależy Ci, żeby w Meta widnieć wyłącznie faktycznie opłacone zamówienia, wybierz Tylko po stronie serwera i upewnij się, że masz zaznaczone Śledzenie zakupów po stronie serwera oraz wpisany token API konwersji. Opłacone zamówienie da wtedy dokładnie jedno zdarzenie, a nieopłacone żadnego. Powtórne powiadomienie od operatora płatności ani odświeżenie strony niczego nie dublują.
Cena tego wyboru: Meta nie dostaje kopii przeglądarkowej, a dwa zgodne sygnały zwykle dają lepsze dopasowanie użytkownika niż jeden. To kompromis między jakością dopasowania a czystością danych o sprzedaży.
Sprzedaż za pobraniem: takie zamówienia trafią do Meta dopiero, gdy oznaczysz je w panelu jako rozliczone — przy pobraniu nie ma automatycznego potwierdzenia wpłaty.
Zamówienia za 0 zł nie tworzą płatności, więc liczą się od razu przy złożeniu — niezależnie od wybranego trybu.
4. Deduplikacja po event_id
Meta uznaje dwa zdarzenia (jedno z Pixela, drugie z CAPI) za ten sam fakt, gdy mają identyczne event_name oraz event_id. Dla zakupu SalesCRM używa po obu stronach klucza:
event_id = orders_<wewnętrzny numer zamówienia> // np. orders_18345
To ten sam identyfikator wysyłany przez Pixel (jako eventID) i przez Conversions API (jako event_id), więc Meta widzi jeden zakup zamiast dwóch. Analogicznie AddToCart deduplikuje się po wspólnym kluczu atc-….
Aby deduplikacja działała, ten sam zakup musi dolecieć oboma kanałami z tym samym event_id. Jeśli któryś kanał jest wyłączony albo wysyła inny identyfikator, Meta nie ma czego sparować.
5. Dane dopasowania (Event Match Quality)
Kanał serwerowy (CAPI) dołącza do zdarzenia dane dopasowania, które podnoszą skuteczność atrybucji. Dane osobowe są hashowane SHA-256 przed wysyłką:
- Hashowane: e-mail kupującego (oraz, jeśli dostępne, telefon, imię, nazwisko, miasto, kod pocztowy, kraj).
- Niehashowane sygnały: adres IP, user-agent,
fbc(identyfikator kliknięcia reklamy z?fbclid),fbp(cookie pixela) orazexternal_id— anonimowy, trwały identyfikator odwiedzającego (cookiescrm_eid), wysyłany identycznie przez Pixel i CAPI.
6. Architektura headless (własny front sklepu)
Jeśli sklep działa na własnym froncie (np. Next.js), a SalesCRM pełni rolę zaplecza, to przeglądarkowy Pixel odpala Twój front, a Conversions API wysyła SalesCRM. Żeby oba kanały deduplikowały się poprawnie, front musi użyć tego samego event_id co serwer (orders_<id>).
Udostępniamy do tego endpoint REST API (uwierzytelnienie nagłówkiem X-API-KEY sklepu), który zwraca kanoniczne dane zakupu na podstawie identyfikatora płatności z adresu powrotu bramki:
GET /api/v1/purchase_pixel_data?payment_id=<OrderID z powrotu płatności>
X-API-KEY: <klucz API sklepu>
→ { "event_id": "orders_18345", "value": 59.98, "currency": "PLN", "contents": [ ... ] }
Front pobiera stąd event_id (oraz autorytatywną wartość zamówienia) i oznacza nim przeglądarkowe zdarzenie Purchase — dzięki czemu jest zgodne z tym, co równolegle wysyła Conversions API.
Bramki płatności (np. Autopay) na powrocie przekazują zwykle własny identyfikator transakcji/płatności, a nie wewnętrzny numer zamówienia. To najczęstsza przyczyna „rozjazdu" event_id między frontem a serwerem — powyższy endpoint mapuje jedno na drugie.
7. Drugi pixel — raportowanie do dwóch kont
Sklep może wysyłać te same zdarzenia do dwóch pixeli naraz. Typowa sytuacja: własne konto reklamowe i konto agencji, która prowadzi kampanie. Zamiast wybierać, kto widzi dane, uzupełniasz Identyfikator drugiego pixela w tym samym ekranie konfiguracji.
Co warto wiedzieć:
- Ustawienia śledzenia są wspólne. Checkboxy z sekcji 2 dotyczą obu pixeli tak samo — nie da się wysyłać zakupów do jednego, a wyświetleń do drugiego.
- Token jest osobny. Meta wystawia go dla konkretnego pixela, więc token pierwszego nie zadziała przy drugim. Bez własnego tokenu drugi pixel zbiera zdarzenia wyłącznie z przeglądarki, a kanał serwerowy do niego milczy.
- Deduplikacja działa w każdym koncie osobno. Oba pixele dostają zdarzenie z tym samym
event_id, więc każde konto paruje swoją kopię przeglądarkową z serwerową niezależnie od drugiego. - Drugi pixel wymaga pierwszego, a identyfikatory muszą się różnić. Ten sam numer wpisany dwa razy podwoiłby zdarzenia w jednym koncie, zamiast trafiać do dwóch — panel na to nie pozwoli.
Zdarzenia w obu kontach będą identyczne. Jeżeli agencja potrzebuje innego zestawu zdarzeń niż Ty, drugi pixel tego nie załatwi.
8. Najczęstsze pytania
Odznaczyłem checkboxy, a kod pixela dalej jest na stronie. Dlaczego?
Bazowy kod pixela (fbq('init', …) z external_id oraz znacznik <noscript> PageView) renderuje się zawsze, gdy wpisany jest Pixel ID — niezależnie od checkboxów. Checkboxy sterują tylko wysyłką poszczególnych zdarzeń, nie samą inicjalizacją. Aby usunąć pixel całkowicie, wyczyść pole Pixel ID.
W Menedżerze Zdarzeń mam niskie pokrycie deduplikacji (np. 9,6%) i ostrzeżenia o event_id.
To znaczy, że dla większości zakupów Meta dostaje zdarzenie tylko z jednego kanału albo z dwoma różnymi event_id. Sprawdź kolejno:
- Czy włączone są oba kanały dla
Purchase(client-side + po stronie serwera) i czy uzupełniony jest token API. - Czy w architekturze headless front używa kanonicznego
event_id(sekcja 6).
Pamiętaj, że 100% jest nieosiągalne — część przeglądarkowych Pikseli zawsze utną blokery reklam i brak zgody na ciasteczka. To normalne i bezpieczne: Conversions API łapie wszystkie zakupy, więc atrybucja pozostaje kompletna niezależnie od wskaźnika deduplikacji.
Czy wysyłacie zdarzenia purchase / view_cart (małymi literami)?
Nie do Meta. To nazewnictwo Google Analytics 4. Do Meta lecą standardowe zdarzenia PageView, AddToCart, ViewContent, Purchase.
Czy event_id to numer zamówienia?
Pełni dokładnie tę rolę. Kanoniczny klucz deduplikacji zakupu to orders_<wewnętrzny numer zamówienia> — spójny między Pixelem a Conversions API.
event_id = orders_<id>. Przy własnym froncie użyj endpointu z sekcji 6.