Konwersja z webhooka to nie tag. Jak liczyć w Google Ads tylko opłacone zamówienia
Google potwierdził na piśmie, co uznaje za konwersję z tagu, a co nie. Tag po zapłacie plus backend przez Data Manager, odrzucone drogi i pułapki panelu diagnostyki.
Sklep chce, żeby Google Ads liczył tylko zamówienia, za które ktoś naprawdę zapłacił. To rozsądne życzenie: tag odpalany przy złożeniu zamówienia liczy też nieudane płatności, porzucone przelewy i kolejne próby tego samego klienta, a Smart Bidding uczy się na tych duchach. Odruch wdrożeniowca jest zawsze ten sam: skoro sklep wie o zapłacie z webhooka, wyślijmy konwersję z backendu, przez kontener serwerowy, oficjalnym tagiem Google Ads.
Tak zrobiłem. Konwersje się liczyły, trzeba było tylko podać tagowi click-id w formacie, którego szuka (opisałem to w tekście o serwerowym tagu, który nie widzi gclid). Potem przez trzy tygodnie próbowałem uruchomić na tym torze Enhanced Conversions. Bez skutku, bo dla Google konwersja z webhooka nie jest konwersją z tagu i żaden parametr tego nie zmieni.
We wrześniu inżynier Google odpowiedzialny za wdrożenia pomiaru odpowiedział na piśmie na dwanaście pytań o to, jak taki tor złożyć poprawnie. Poniżej te odpowiedzi, konstrukcja, która z nich wynika i działa dziś w dwóch sklepach, drogi, które odrzuciliśmy, oraz pułapki, na które trafiłem przy podłączaniu.
Stan na początek października 2026. Łączenie kilku źródeł konwersji na jednej akcji jest w Google Ads wciąż w becie, więc część opisanych zachowań może się zmienić.
Dlaczego w ogóle liczyć tylko opłacone
W sklepie klienta na trzydzieści dni przypadły 523 złożone zamówienia, z czego 54 nigdy nie zostały opłacone. To co dziesiąte. Ponad połowa z tych 54 to kolejne próby tego samego klienta: płatność nie przeszła, kupujący złożył zamówienie jeszcze raz i zapłacił. Tag przy złożeniu liczy taką osobę dwa albo trzy razy, za każdym razem z pełną wartością koszyka.
Dla raportu to kilka procent szumu. Dla strategii stawek to sygnał, że pewne kliknięcia konwertują lepiej, niż konwertują naprawdę, więc budżet przesuwa się w ich stronę. Szerzej piszę o tym, jak zaszumione dane rozjeżdżają ROAS w Smart Biddingu.
Naturalna kontra brzmi: liczmy przy złożeniu, a nieopłacone wycofujmy korektą. Liczby mówią, że to nie działa. Anulacje przychodzą w dwóch falach: połowa tego samego dnia, reszta po tygodniu i później. Google potwierdził, że Smart Bidding traktuje priorytetowo korekty, które dotrą w ciągu 7 dni od konwersji. Druga fala przychodzi więc już po oknie, a przez pierwszą dobę duch i tak siedzi w modelu stawek.
Konwersja z webhooka liczy się, ale nie jest tagiem
Tor z backendu wygląda tak: sklep dostaje webhook o zapłacie, warstwa pośrednia wysyła zdarzenie do kontenera serwerowego, a tam oficjalny tag Google Ads tworzy konwersję. Konwersja wpada do raportu, ma click-id, ma wartość. Z punktu widzenia raportu wszystko gra.
Problem wychodzi przy Enhanced Conversions i w diagnostyce akcji. Zasięg konwersji rozszerzonych z witryny stoi na zerze, a akcja zgłasza brak pingów z tagu, chociaż pingi idą przy każdym zamówieniu.
Czego brakuje hitowi z backendu
Google ocenia nie tylko treść pingu, ale też to, skąd on przychodzi. Hit z przeglądarki ma za sobą kontekst: prawdziwego klienta HTTP, adres IP kupującego, cookies. Ma też drugi etap. Kontener serwerowy, przyjmując hit od przeglądarki, odsyła jej w odpowiedzi polecenia do wykonania (dodatkowe piksele Google), a przeglądarka je wykonuje. Hit z webhooka nie ma przeglądarki, więc tych poleceń nikt nie wykona.
Przez trzy tygodnie dokładaliśmy do pingu z backendu kolejne elementy: tryb EC, prawdziwy identyfikator z cookie Google, adres IP i user agent kupującego, ten sam kanał przesyłania danych użytkownika, którego używa gtag. Zasięg EC nie drgnął ani razu. Odpowiedź Google z połowy września zamknęła temat: różnica jest strukturalna, nie parametryczna. Hit z webhooka przez kontener serwerowy nie jest pingiem tagu i żaden parametr go nim nie zrobi.
Dlaczego wzbogacanie przez API nie pomogło
Równolegle wysyłaliśmy dane klienta (zahashowany e-mail) przez Google Ads API jako wzbogacenie konwersji po numerze zamówienia. Z 292 wysłanych rekordów Google nie zaliczył ani jednego. Wzbogacenie niczego nie tworzy, tylko dokleja dane do istniejącej konwersji z tagu o tym samym numerze zamówienia. Skoro konwersja pochodziła z webhooka, w bazie Enhanced Conversions nie było czego wzbogacać.
Jest też trzecia strata, mniej widoczna. Google potwierdził, że modelowanie konwersji przy odmowie zgód (consent mode) karmi się wyłącznie pingami z przeglądarki. Akcja zasilana tylko z backendu nie dostaje modelowania w ogóle i żaden upload tego nie odtworzy.
Co Google potwierdził na piśmie
Pytania ułożyliśmy tak, żeby na każde dało się odpowiedzieć tak albo nie. Najważniejsze odpowiedzi w skrócie:
| Pytanie | Odpowiedź Google | Co z tego wynika |
|---|---|---|
| Hit z przeglądarki przez klienta GA4 w kontenerze serwerowym do oficjalnego tagu Ads to konwersja z tagu? | Tak, pełnoprawna, pod warunkiem oficjalnego szablonu tagu i standardowego schematu user_data | Kontener serwerowy nie odbiera statusu tagu. Odbiera go brak przeglądarki |
| Potrzebne osobne zdarzenie z danymi użytkownika? | Nie, ping konwersji niesie je razem | Wystarcza jedno zdarzenie zakupu |
| Czy backend może tworzyć konwersje, a tag tylko je wzbogacać? | Nie. Tag musi być głównym strumieniem, czyli dawać większość konwersji akcji, inaczej deduplikacja nie działa, a akcja przechodzi w stan zdegradowany | Najpierw tag, backend jako drugie źródło |
| Czy rekord z backendu bez click-id coś da? | Tak, Google dopasuje zahashowane dane do zalogowanych użytkowników, ale tylko gdy rekord dotrze w ciągu 24 godzin od czasu konwersji | Wysyłka zaraz po webhooku, a nie raz na dobę z pliku |
| Czy podłączenie drugiego źródła resetuje strategię stawek? | Nie. Przez 14 dni okresu próbnego dane z drugiego źródła nie biorą udziału w licytacji | Można to zrobić na akcji podstawowej, bez czekania na koniec sezonu |
| Czy Data Manager obsługuje wycofanie konwersji? | Nie, tylko zmianę wartości. Wycofania idą przez Google Ads API albo arkusz korekt | Zwroty i anulacje to osobny tor |
| Czy upload z backendu zasili modelowanie consent mode? | Nie, modelowanie bierze się tylko z pingów tagu w przeglądarce | Bez tagu w przeglądarce nie ma modelowania |
Dwa zastrzeżenia, żeby nie awansować korespondencji do rangi dokumentacji. Zdania “tag musi być głównym strumieniem” w dokumentacji Google nie ma, padło w odpowiedzi inżyniera. Z kolei 24 godziny dokumentacja opisuje jako zalecenie dla EC i Smart Biddingu, a nie twardą granicę, podczas gdy inżynier napisał wprost o odrzuceniu po tym czasie. Projektuję pod wersję ostrzejszą, bo nic na niej nie tracę.
Konstrukcja, która działa
W pytaniach zaproponowaliśmy dwie konstrukcje. Google zarekomendował tę:
- Tag na stronie powrotu po zapłacie. Kupujący wraca z bramki płatniczej do sklepu, a przeglądarka wysyła zdarzenie zakupu przez klienta GA4 w kontenerze serwerowym do oficjalnego tagu Google Ads, z numerem zamówienia (
transaction_id) i danymi klienta. - Backend jako drugie źródło na tej samej akcji. Po webhooku o zapłacie backend wysyła każde opłacone zamówienie przez Data Manager API, z numerem zamówienia w dokładnie tym samym formacie.
- Okres próbny 14 dni bez ruszania stawek. Dopiero po nim dane z backendu biorą udział w licytacji.
Google łączy oba źródła po numerze zamówienia w obrębie jednej akcji. Jeśli tag już założył konwersję, rekord z backendu jej nie dubluje: po okresie próbnym nadpisuje wartość (backend zna kwotę po rabatach) i uzupełnia dane klienta, jeśli tag ich nie miał. Jeśli tagu nie było, bo kupujący nie wrócił na stronę, rekord z backendu zakłada nową konwersję, przypisaną po click-id albo po zahashowanych danych.
Jedna rzecz, którą łatwo przeoczyć: sam powrót z bramki nie jest dowodem zapłaty, bo na stronę powrotu da się trafić także po nieudanej płatności. U mnie tag najpierw pyta backend, czy zamówienie jest już opłacone, bierze od niego kwotę i strzela dopiero po potwierdzeniu. Webhook zwykle wyprzedza kupującego. W jednym z zamówień z września wyglądało to tak: webhook o zapłacie w sekundzie zero, zdarzenie z przeglądarki po 12 sekundach, rekord do Data Managera po półtorej minuty.
Ilu kupujących wraca na stronę
Cała konstrukcja stoi na tym, że większość kupujących wraca z bramki do sklepu. W moim sklepie, licząc zamówienia z click-id, wraca 70 procent. Pozostałych 30 procent nie trzeba spisywać na straty: backend wysyła je z click-id zapisanym wcześniej w sesji albo z zahashowanymi danymi klienta, o ile kupujący wyraził zgodę.
Trudniejsza jest płatność w aplikacji, po której kupujący w ogóle nie widzi strony powrotu, a sklep nie ma nawet zapisanego stanu zgody. Tak działa InPost Pay, a to osobna historia.
Licząc udział tagu, łatwo pomylić mianownik. Konwersja z tagu może powstać tylko dla zamówienia, które da się przypiąć do kliknięcia, więc udział liczy się od zamówień z click-id, a nie od wszystkich opłaconych. U mnie zły mianownik dał wynik o połowę niższy od prawdziwego i omal nie skończył się mailem do Google z pytaniem, czy ta konstrukcja jest u nas w ogóle wykonalna.
Drogi, które odrzuciliśmy
Każda wygląda rozsądnie na tablicy i każda ma konkretny powód, żeby jej nie wybierać:
- Osobna akcja importowana z backendu. Akcja bez tagu dostaje status niskiej albo zerowej atrybucji, nowa akcja oznacza naukę strategii od zera, a bezpośredni upload przez Google Ads API od 15 czerwca 2026 nie przyjmuje nowych użytkowników, bo Google przenosi import konwersji na Data Manager API.
- Tag przy złożeniu plus wycofanie nieopłaconych. Opisane wyżej: połowa anulacji przychodzi po oknie 7 dni, a Data Manager wycofań w ogóle nie robi.
- Dwie akcje w celach, tag i import. Deduplikacja działa tylko w obrębie jednej akcji, więc dwie akcje liczone w celach to podwójne liczenie, opisane zresztą wprost w dokumentacji.
- Dalsze poprawianie pingu z webhooka. Trzy tygodnie pokazały, że to ślepy zaułek.
Jest też zalecenie Google, które świadomie odłożyłem. Po wdrożeniu stary tag zasilany z webhooka ma zniknąć z kontenera serwerowego. Zostawiłem go co najmniej na cały okres próbny, bo przez te 14 dni rekordy z Data Managera nie biorą udziału w licytacji. Gdybym wyłączył webhook od razu, kupujący, którzy nie wrócili na stronę, zniknęliby ze Smart Biddingu na dwa tygodnie. Oba pingi idą z tym samym numerem zamówienia na tę samą akcję, więc Google liczy je raz.
Pułapki przy podłączaniu
Dubel, który znika sam
Kiedy dwa tory trafiają w jedną akcję, pierwszym strachem jest podwójne liczenie. Dwa razy widziałem w raporcie zamówienie policzone podwójnie, z kwotą zgadzającą się co do grosza. Oba razy dubel zniknął sam, w ciągu kilku godzin. Deduplikacja po stronie Google potrafi nadrabiać z dużym opóźnieniem.
Wnioski praktyczne są trzy. Po pierwsze, oba tory muszą wysyłać identyczny numer zamówienia. Ja pilnuję też identycznego identyfikatora zdarzenia (event_id). Nie wiem na pewno, czy Google używa go do deduplikacji, ale kosztuje to jedną linijkę w tagu. Po drugie, dubel ocenia się z odczytu następnego dnia, według daty konwersji, a nie tego samego popołudnia. Po trzecie, nie sprawdzisz tego zamówieniem testowym z wymyślonym click-id, bo takich Google nie liczy wcale. Do tej kontroli potrzebne są prawdziwe zamówienia.
Panel diagnostyki przy dwóch źródłach
To najbardziej kosztowna pułapka. Po podłączeniu drugiego źródła wykres zasięgu konwersji rozszerzonych (tylko witryna) w diagnostyce akcji spadł do zera i tak stał. W tym samym czasie konwersje wpadały normalnie. Jednego dnia w okresie próbnym Ads naliczył 23 konwersje na 1 841 zł wobec 26 zamówień z click-id na 1 952 zł w backendzie, czyli 94 procent wartości.
Na początku października inżynierowie Google sprawdzili prawdziwe zdarzenia i potwierdzili, że dane z obu źródeł wchodzą poprawnie, a widok diagnostyki nie działa prawidłowo dla akcji z wieloma źródłami. Zgłoszenie błędu jest otwarte. Do czasu poprawki nie diagnozuję z tego wykresu i niczego pod niego nie zmieniam.
Druga cecha tego panelu, niezależna od błędu: metryka dojrzewa dwa, trzy dni i liczy się w czasie pacyficznym. Zrzut zrobiony dzień po wdrożeniu pokazuje okno, które kończy się przed dniem zmiany. Zanim wyciągniesz wniosek, sprawdź, czy ostatni punkt wykresu obejmuje dzień wdrożenia.
Gdzie szukać śladu Data Managera
Po podłączeniu API sekcja źródeł danych na akcji zostaje pusta. Pokazuje ona źródła, z których Google sam pobiera dane (arkusz, BigQuery, pliki), a API to wysyłka z twojej strony. Ślad jest w diagnostyce celów, w kolumnie ze źródłem danych. Status sukcesu w odpowiedzi API znaczy tyle, że Google przyjął rekordy, a nie że je dopasował.
Jak sprawdzić, czy to działa
Skoro panel diagnostyki chwilowo pokazuje nieprawdę, kontrola musi iść inną drogą. Ja robię ją tak:
- Raport konwersji według daty konwersji, nie kliknięcia, zestawiony z listą opłaconych zamówień z click-id z backendu. Liczba w granicach 0,95-1,05, wartość z dokładnością do 5 procent. Widok według daty kliknięcia z atrybucją opartą na danych pokazuje ułamki konwersji i do tego porównania się nie nadaje.
- Odczyt dnia następnego. Dubel z popołudnia to jeszcze nie dubel.
- Log kontenera serwerowego. Oba pingi tego samego zamówienia mają mieć identyczny numer zamówienia i identyfikator zdarzenia. Sprawdzam to parametr po parametrze przed publikacją.
- Alert o nadmiarowym liczeniu. Google ostrzega, gdy przez dwa dni mniej niż 10 procent numerów zamówień z backendu pokrywa się z numerami z tagu. Najczęściej oznacza to inny format numeru w obu torach: prefiks, spację albo liczbę zamiast tekstu.
- Udział tagu liczony od zamówień z click-id, nie od wszystkich.
W dwóch sklepach, w których ta konstrukcja działa po okresie próbnym, raport według daty konwersji zgadza się z backendem co do sztuki i co do grosza. Jeśli masz tor z webhooka i zastanawiasz się nad przejściem na tę konstrukcję, to jest dokładnie ten rodzaj przebudowy, który robię w ramach wdrożenia server-side. Różnice między wariantami samego EC opisuję w porównaniu browser-side i server-side Enhanced Conversions.
Podsumowanie
Konwersja wysłana z backendu przez kontener serwerowy liczy się w raportach, ale dla Google nie jest konwersją z tagu. Nie ma kontekstu przeglądarki ani drugiego etapu, więc nie dostaje Enhanced Conversions z witryny ani modelowania consent mode. Żaden parametr pingu tego nie zmieni.
Konstrukcja potwierdzona przez Google to tag na stronie powrotu po zapłacie, wysłany z przeglądarki przez kontener serwerowy jako główny strumień, oraz backend jako drugie źródło na tej samej akcji, przez Data Manager API, zaraz po webhooku. Tag zakłada konwersje, a backend dowozi tych, którzy nie wrócili, i poprawia kwoty.
Przy podłączaniu pilnuj identycznego numeru zamówienia w obu torach, oceniaj duble dzień później i nie wierz wykresowi zasięgu EC dla akcji z dwoma źródłami, dopóki Google nie naprawi diagnostyki.
Tag mówi Google, że zakup był. Backend mówi, ile był wart i kto go zrobił. Google chce usłyszeć oba głosy, w tej kolejności.