Brak transakcji w GA4 to zwykle nie jedna usterka, a jedna z trzech różnych warstw: brak sesji, brak zdarzenia purchase albo zdarzenie jest, tylko nie trafia do raportu. Zanim zaczniesz grzebać w kodzie, ustal, którą warstwę naprawiasz – inaczej tracisz dzień na poprawianie czegoś, co działa. Poniżej masz triage w 5 minut, cztery najczęstsze przyczyny po stronie PrestaShop i listę kontrolną, która porządkuje całość. Każdy krok weryfikujesz w konkretnym miejscu w GA4, nie „na wyczucie”.
Zanim dotkniesz kodu, ustal, którą z trzech warstw naprawiasz. Triage zajmuje około 5 minut i wymaga jednego zamówienia testowego oraz otwartego GA4.
Krok 1 – czy w ogóle jest sesja. Wejdź w Raporty > Realtime i otwórz sklep w drugiej karcie. Brak page_view w ciągu 30 minut oznacza, że tag nie wystartował: baner consentu (Consent Mode v2) blokuje gtag do momentu zgody, kontener GTM nie został opublikowany, w kodzie siedzi stary identyfikator UA albo polityka CSP blokuje domenę googletagmanager.com.
Krok 2 – czy jest zdarzenie purchase. Sesje są, ale w Realtime nie pojawia się purchase? Otwórz Administracja > DebugView i przejdź ścieżkę zakupu na zamówieniu testowym. Brak purchase to wina sklepu: hook, szablon, dataLayer. To najczęstszy przypadek i nim zajmują się kolejne sekcje.
Krok 3 – czy purchase jest, ale nie w raportach. DebugView pokazuje purchase, a Raporty > Monetyzacja > Zakupy e-commerce świecą pustkami? Sprawdź Administracja > Filtry danych (wykluczanie ruchu wewnętrznego po IP potrafi zjeść wszystkie Twoje testy), próg danych przy włączonych sygnałach Google, zakres dat oraz to, czy patrzysz na właściwą usługę i strumień. Standardowe opóźnienie agregacji to 24–48 godzin – świeże dane mogą jeszcze nie być w raportach.
Testuj bezpiecznie. Zamówienie testowe na produkcji zabrudzi dane. Lepiej: kopia na stagingu albo filtr ruchu wewnętrznego po IP plus debug_mode=1 w GTM. Pamiętaj, że GA4 deduplikuje purchase po transaction_id – powtórzone zdarzenie z tym samym numerem nie zdubluje transakcji. Jeśli wolisz mieć porządek w pomiarze raz na zawsze, robimy to w ramach opieki nad sklepami internetowymi.
| Objaw | Gdzie sprawdzisz | Co to zwykle znaczy |
|---|---|---|
| Zero sesji w ciągu 30 minut | Raporty > Realtime | Tag, consent, GTM lub CSP – GA4 w ogóle nie startuje |
| Sesje są, brak purchase | Administracja > DebugView | Hook, szablon potwierdzenia lub brak push w dataLayer |
| purchase w DebugView, brak w raportach | Raporty > Monetyzacja > Zakupy e-commerce | Filtr danych, próg danych, zakres dat lub opóźnienie 24–48 h |
Zanim zaczniesz szukać usterki, ustal, którą drogą purchase trafia do GA4. W praktyce spotykamy trzy i każda psuje się inaczej.
Miejsce odpalania jest wspólne dla wariantu 1 i 2: hook displayOrderConfirmation (oraz displayOrderConfirmationTop) wywoływany z szablonu templates/checkout/order-confirmation.tpl, obsługiwanego przez OrderConfirmationController. W PrestaShop 1.7 i 8 kontroler znajdziesz w controllers/front/OrderConfirmationController.php – warto sprawdzić, jakie zmienne przypisuje do szablonu, bo tam siedzą id_order, wartość koszyka i waluta.
Dlaczego begin_checkout i add_payment_info zwykle działają, a purchase nie? Bo pierwsze dwa odpalają się w standardowym przepływie koszyka, na stronach, których prawie nikt nie nadpisuje. Purchase odpala się dokładnie raz, na stronie potwierdzenia – po przekierowaniu z bramki płatniczej, często po powrocie z innej domeny, na szablonie modyfikowanym przez motyw. Jeden brakujący hook i cały łańcuch się urywa, choć reszta pomiaru wygląda zdrowo. Kolejność hooków i strukturę szablonów opisuje dokumentacja dla deweloperów PrestaShop – to najszybszy sposób, żeby sprawdzić, czy Twój motyw w ogóle wywołuje właściwe miejsce.
To najczęstsza przyczyna, jaką znajdujemy w sklepach po wdrożeniu nowego wyglądu. Motyw child albo szablon kupiony od agencji nadpisuje templates/checkout/order-confirmation.tpl i gubi wywołanie {hook h='displayOrderConfirmation'}. Strona potwierdzenia renderuje się poprawnie, klient widzi numer zamówienia, a gtag nigdy się nie odpala. Panel PrestaShop nie zgłasza braku hooka jako błędu, więc usterka potrafi siedzieć w sklepie miesiącami.
Drugi wariant to cache. Moduły pełnego cache stron i wbudowane opcje wydajności potrafią serwować zapisany HTML strony potwierdzenia bez skryptu pomiarowego. Sprawdź Zaawansowane > Wydajność: „Smart cache for JavaScript”, „Minify HTML” oraz „Move JavaScript to the end”. Minifikacja inline'owego gtag i przestawianie kolejności skryptów to klasyczne źródło błędów. Każdy test rób na wyczyszczonym cache i w trybie incognito – cache przeglądarki dokłada trzecią warstwę złudzeń.
Test palca. Otwórz stronę potwierdzenia na zamówieniu testowym i zrób dwie rzeczy. Po pierwsze: podgląd źródła (Ctrl+U) i wyszukaj „gtag”, „dataLayer” oraz „purchase”. Brak tych ciągów oznacza problem w szablonie, nie w GA4. Po drugie: DevTools > Network, filtr „collect” (lub „g/collect”), złóż zamówienie i szukaj requestu z parametrem en=purchase oraz tid=G-XXXXXXX. Brak requestu = GA4 nic nie dostało i szukanie przyczyny w raportach nie ma sensu. Response 204 oznacza, że zdarzenie przyjęto; 400 wskazuje na błędne parametry, np. brak currency albo ujemną wartość.
Pułapka na koniec: blokery reklam. Popularne listy filtrów blokują domenę google-analytics.com, więc na Twoim komputerze test może „nie działać”, a u klientów wszystko będzie w porządku. Wyłącz adblock albo sprawdź stronę w czystym profilu przeglądarki. Jeśli motyw był niedawno aktualizowany, zajrzyj też do materiału o PrestaShop AutoUpgrade – po aktualizacji nadpisania szablonów często wskazują na nieaktualne pliki.
Masz w GA4 sesje i zdarzenia, ale nie ma purchase. Pierwsze pytanie nie brzmi „czy tag jest wpięty”, tylko „czy w chwili zakupu zgoda na analitykę była aktywna”. Od marca 2024 Google wymaga w EEA czterech sygnałów Consent Mode v2: ad_storage, ad_user_data, ad_personalization i analytics_storage. Dla sprzedaży liczy się jeden — analytics_storage. Bez niego GA4 nie zapisze identyfikatora, a hit z potwierdzenia zamówienia pójdzie jako ping bez cookies.
Objaw jest mylący: widać sesje i część zdarzeń, ruch potrafi być modelowany, a transakcji nie ma. Powód jest prozaiczny — purchase odpala się na stronie potwierdzenia, czyli zwykle po powrocie z bramki płatności, długo po pierwszej wizycie. Jeśli użytkownik odrzucił baner albo CMP ustawiło analytics_storage = denied, purchase nie zostanie policzony. Kliknięcie „Akceptuję” po fakcie nic nie naprawi wstecz: zgoda działa od momentu aktualizacji, nie od początku sesji. To najczęstszy powód sytuacji „u mnie w DebugView działa, w raportach nie”.
Druga pułapka to sam CMP. Baner z jedną kategorią „Marketing i analityka” sprawia, że analytics_storage dostaje zgodę tylko wtedy, gdy użytkownik zaakceptuje wszystko. Sprawdź w panelu CMP, czy analityka jest osobnym przełącznikiem i czy nie jest zaznaczona domyślnie.
Jeśli baner, tagi i sklep wdrażasz równolegle, uporządkuj to na etapie wdrożenia sklepu internetowego — poprawianie zgód po starcie kampanii kosztuje więcej niż konfiguracja od początku.
| Sygnał Consent Mode | Czego dotyczy | Co widzisz przy denied |
|---|---|---|
| analytics_storage | pomiar ruchu i sprzedaży w GA4 | sesje bez cookies, brak transakcji w raportach |
| ad_storage | remarketing i odbiorcy | brak list odbiorców, słabsze dopasowanie kampanii |
| ad_user_data | przekazywanie danych do Google Ads | kampanie bez sygnałów konwersji |
| ad_personalization | personalizacja reklam | ograniczony remarketing dynamiczny |
Polska specyfika: większość zamówień nie kończy się na stronie sklepu, tylko w aplikacji banku albo w bramce. Przelewy24, PayU, Tpay czy BLIK jako metoda płatności działają przez przekierowanie — użytkownik wychodzi z domeny sklepu i wraca na stronę potwierdzenia. Dla GA4 to dwa różne wejścia, nie jedno.
Skutek pierwszy: powrót generuje nową sesję, a źródłem ruchu staje się domena bramki. Transakcja jest, ale wisi pod „referral / przelewy24.pl”, więc kampania w Google Ads nie dostaje konwersji, a raport kanałów kłamie. Naprawa jest tania: Admin → Data streams → Configure tag settings → List unwanted referrals i dodaj domeny bramek oraz stron płatności. Wtedy referral nie nadpisze źródła. Sprawdź też, czy nie wykluczasz przy okazji własnej domeny — to częsty błąd przy kopiowaniu listy.
Skutek drugi, gorszy: hit purchase wysyłany w chwili opuszczania strony. Jeśli moduł robi to w handlerze beforeunload, przeglądarka może ubić żądanie, zanim wyjdzie ono na zewnątrz. Na desktopie z dobrym łączem zwykle przejdzie, na mobile w roamingu — nie. Dlatego statystyki „brakuje 5% transakcji” biorą się głównie z telefonów.
Uwaga na pułapkę Measurement Protocol: bez session_id i client_id zdarzenie trafi do GA4 jako nowy użytkownik bez atrybucji. Zapisz oba identyfikatory w zamówieniu jeszcze przed przekierowaniem do bramki.
| Objaw w GA4 | Przyczyna | Co zrobić |
|---|---|---|
| purchase jest, ale źródło ruchu to przelewy24.pl lub payu.com | powrót przez przekierowanie nadpisał źródło sesji | dodaj domeny bramek do listy niechcianych poleceń |
| brak purchase mimo opłaconego zamówienia, częściej na mobile | hit wysłany przy page unload, żądanie przerwane | transport_type: 'beacon' i 300–500 ms opóźnienia przekierowania |
| purchase jest, ale bez sesji i bez atrybucji | zdarzenie dosłane serwerowo bez session_id | zapisz client_id i ga_session_id w zamówieniu przed przekierowaniem |
Bywa, że purchase dochodzi, tylko nie widać go w raportach. Zanim zaczniesz szukać błędu w module, wejdź w Admin → Ustawienia danych → Filtry danych. Dwa filtry potrafią wyciąć transakcje: Developer traffic (zdarzenia z parametrem debug_mode) oraz Internal traffic (ruch z IP oznaczonych jako wewnętrzne). Liczy się kolumna stanu: filtr ustawiony na Testing nic nie wycina, Active wycina z raportów. W DebugView zdarzenia nadal będą widoczne, bo DebugView pokazuje strumień, a nie raport — stąd wrażenie, że „dane są, tylko ich nie ma”.
Druga warstwa jest po stronie sklepu. W PrestaShop każdy status zamówienia ma flagi paid, logable i shipped, ustawiane w Shop parameters → Order settings → Statuses. Moduł GA4 wysyła purchase tylko dla statusów zaznaczonych w jego konfiguracji — domyślnie bywa to „Płatność zaakceptowana” (w czystej instalacji ID 2, ale w Twojej może być zupełnie inne). Jeśli doszedł własny status „Opłacone – Przelewy24” albo „BLIK potwierdzony”, a nie ma go na liście modułu, transakcje z tej bramki nie pojawią się nigdy. Strukturę statusów opisuje dokumentacja deweloperska PrestaShop. Osobno sprawdź, czy moduł nie dubluje się z tagiem w GTM — GA4 deduplikuje po transaction_id, ale tylko gdy identyfikator jest identyczny w obu źródłach.
Na koniec oddziel błędy od świadomych wyjątków: zamówienia testowe, płatność za pobraniem (pieniądze dopiero przy odbiorze) i zamówienia anulowane. To nie awaria pomiaru, tylko decyzja — zapisz ją, żeby za pół roku nikt nie „naprawiał” czegoś, co ma działać właśnie tak.
GA4 traktuje transaction_id jak klucz idempotencji: dwa zdarzenia purchase z tym samym identyfikatorem policzą się raz. Kłopot zaczyna się, gdy identyfikator przestaje być stały. Najczęstszy scenariusz: moduł GA4 w PrestaShop dokleja prefiks (PS-1042), a równolegle tag w GTM wysyła czysty numer (1042). Jedno zamówienie, dwa purchase w raporcie. Drugi scenariusz: klient odświeża stronę potwierdzenia albo wraca z bramki płatności, a skrypt generuje identyfikator od nowa zamiast odczytać go z zamówienia — każde wejście to kolejna transakcja. Identyfikator bierz z obiektu zamówienia (hook displayOrderConfirmation, opisany w dokumentacji dla deweloperów PrestaShop), nigdy z koszyka ani z timestampu.
Druga grupa błędów to parametry, które przechodzą przez walidację, ale psują raporty:
"129,99" z przecinkiem nie jest liczbą — GA4 pokaże zero albo pominie wartość. Wysyłaj typ number z kropką dziesiętną.item_id musi być spójne z id_product + id_product_attribute.currency to kod ISO („PLN”), nie „zł”. Przy multistore z walutami w różnych kontekstach sumy przestają się zgadzać z panelu.Uzgodnienie rób zawsze na tych samych widełkach czasowych i tylko na statusach zamówień, które uznajesz za opłacone — nie na „wszystkich zamówieniach”.
| Źródło | Co liczysz | Gdzie sprawdzasz | Typowa różnica |
|---|---|---|---|
| PrestaShop | Zamówienia ze statusem opłaconym w wybranym zakresie dat | Zamówienia → filtr statusu i daty | punkt odniesienia |
| GA4 | Zdarzenia purchase | Raporty → Monetyzacja → Przegląd e-commerce | −5% do −30%: odrzucone zgody, adblocki, tag, który się nie załadował |
| ERP / magazyn | Zamówienia zaksięgowane | np. Subiekt, Comarch, BaseLinker | zwykle kilka % więcej: zamówienia telefoniczne i B2B wprowadzane ręcznie |
Kolejność jest ważna, bo każdy krok zawęża obszar. Nie zaczynaj od kodu motywu.
purchase? Przechodzisz do uzgodnień. Nie widzisz — idziesz dalej.order-confirmation. Szukasz dataLayer.push z transakcją. Jeśli w HTML-u nic nie ma, a dane pojawiają się dopiero po JS — sprawdź, czy moduł nie ładuje się asynchronicznie po zdarzeniu DOM-ready.collect. Sprawdź en=purchase, ep.transaction_id, epn.value, cu=PLN, pr1… Status 204 = serwer przyjął. Brak requestu = tag nie wystartował. Status 4xx/5xx = WAF lub mod_security po stronie hostingu./g/collect.Docelowo warto uniezależnić pomiar od przeglądarki: kontener server-side na własnej subdomenie (np. measure.twojsklep.pl) albo Measurement Protocol wysyłany webhookiem z bramki płatności po potwierdzeniu transakcji. Pamiętaj wtedy o zapisaniu client_id z cookie _ga przy składaniu zamówienia — bez niego zdarzenie trafi do puli „unassigned”.
Audyt zewnętrzny ma sens, gdy motyw jest mocno zmodyfikowany, jest kilka wariantów płatności albo sklep działa w multistore. To zadanie łączymy zwykle z utrzymaniem i wdrożeniami sklepów internetowych. Widełki poniżej to nasze własne szacunki, nie rynkowy standard — pytaj o nie przed startem prac.
| Scenariusz | Co komplikuje pracę | Szacowany nakład |
|---|---|---|
| Standardowy motyw, jedna bramka płatności | jeden szablon potwierdzenia, brak modyfikacji | 4–8 h |
| 2–4 metody płatności, one-page checkout | kilka stron powrotu, osobne hooki | 8–16 h |
| Multistore lub własne moduły zamówień i ERP | wiele kontekstów, dodatkowe źródło prawdy | 16–32 h |
Naprawianie konfiguracji GA4, gdy problemem jest brak sesji – czyli tag nie wystrzelił albo consent zablokował pomiar.
Jak wykryć: Raport Realtime pokazuje 0 użytkowników, gdy wchodzisz na stronę sklepu z własnej przeglądarki po wyczyszczeniu cookies.
Jak naprawić: Najpierw sprawdź obecność tagu i stan zgody, dopiero potem zdarzenia. Brak sesji wyklucza dalszą analizę purchase.
Testowanie zamówień bezpośrednio na produkcji bez filtra ruchu wewnętrznego i bez trybu debugowania.
Jak wykryć: W raportach Monetyzacja > Zakupy e-commerce pojawiają się transakcje z adresami e-mail lub kwotami, których nie ma w systemie zamówień.
Jak naprawić: Użyj środowiska staging albo wykluczenia po IP i uruchom test z parametrem debug_mode. Jedno i drugie ustaw przed testem, nie po.
Założenie, że skoro GTM jest wpięty, to purchase wyśle się sam – a motyw child nadpisał order-confirmation.tpl i wyciął wywołanie hooka.
Jak wykryć: begin_checkout i add_payment_info widać w DebugView, purchase nigdy. W źródle strony potwierdzenia brak requestu z en=purchase.
Jak naprawić: Przywróć wywołanie hooka displayOrderConfirmation w szablonie potomnym albo przenieś logikę purchase do kontrolera. Potem powtórz test.
Mylenie danych z DebugView z danymi raportowymi i wyciąganie wniosków w kilka godzin po wdrożeniu.
Jak wykryć: W DebugView zdarzenie purchase jest widoczne, ale w Raporty > Monetyzacja > Zakupy e-commerce nadal pusto.
Jak naprawić: Poczekaj 24–48 h i sprawdź, czy nie działają filtry danych ani próg danych. DebugView pokazuje zdarzenia surowe, raporty już przetworzone.
Zakładanie, że po powrocie z bramki płatności GA4 „samo” przypisze transakcję do źródła ruchu.
Jak wykryć: Transakcja jest w GA4, ale ma pustą lub inną atrybucję niż sesja, w której klient zaczął zakupy.
Jak naprawić: Sprawdź, czy purchase leci przed przekierowaniem, czy po powrocie. Dla płatności z przekierowaniem rozważ Measurement Protocol po stronie serwera.
Zostawianie włączonego pełnego cache stron, który serwuje zapisany HTML strony potwierdzenia bez skryptu pomiarowego.
Jak wykryć: Po wyłączeniu cache purchase pojawia się w DebugView, po włączeniu znika – bez żadnej zmiany w kodzie.
Jak naprawić: Wyklucz stronę potwierdzenia zamówienia i kontroler OrderConfirmationController z cache. To strona dynamiczna per zamówienie.
Brak transakcji w GA4 to najczęściej nie awaria samego GA4, a problem z jedną z trzech warstw: tagiem, zdarzeniem purchase albo raportowaniem. Kolejność diagnozy jest stała – Realtime, DebugView, filtry danych – i to ona decyduje, czy naprawiasz właściwe miejsce. W PrestaShop najczęstsze winowajcy to nadpisany szablon strony potwierdzenia, cache pełnostronicowy i zgoda w Consent Mode v2. Przekierowania bramek płatności dokładają własny problem, który łatwo przeoczyć.
Najczęściej dlatego, że zdarzenie purchase nigdy nie zostaje wysłane. Sesje i pozostałe zdarzenia łapią się na zwykłych stronach sklepu, a purchase odpala się wyłącznie na stronie potwierdzenia zamówienia, poza standardowym przepływem koszyka. Jeśli motyw nadpisał order-confirmation.tpl albo cache serwuje zapisany HTML, skrypt pomiarowy się nie wykona. Objaw potwierdzisz w filtrze sieci: brak requestu z en=purchase.
Tak, ale dopiero na końcu. Jeśli purchase jest widoczne w DebugView, a nie ma go w raportach, sprawdź filtry danych, próg danych i czas przetwarzania. GA4 nie zawsze pokazuje dane od razu – typowo potrzebuje 24–48 h. Dopiero gdy po tym czasie purchase nadal nie ma w raportach, a DebugView go widzi, szukaj problemu w konfiguracji widoku i filtrów.
Dwie opcje. Pierwsza: środowisko staging z osobną usługą GA4. Druga: produkcja z wykluczeniem ruchu wewnętrznego po IP i testem uruchomionym z parametrem debug_mode. Wykluczenie ustaw przed pierwszym zamówieniem testowym, bo filtr cofa dane tylko w teorii – w praktyce stare transakcje zostają w raportach. Pamiętaj też, że filtr działa dopiero od momentu włączenia.
Może wyglądać, jakby tak było. Przy braku zgody na analytics_storage GA4 korzysta z modelowania, więc w raportach widzisz część sesji i zdarzeń, ale pojedyncze zdarzenia mogą nie dojść. Kluczowa jest kolejność: jeśli hit purchase wyjdzie przed aktualizacją zgody, zostanie odrzucony. Test powtórz po zaakceptowaniu banera analitycznego i sprawdź w DebugView zakładkę Consent.
Tak i to problem specyficzny dla polskiego rynku płatności. Po powrocie z bramki klient często trafia na nową sesję, a hit purchase bywa wysyłany w chwili opuszczania strony – przeglądarka, zwłaszcza na mobile, potrafi go nie zdążyć wysłać. Spotykane rozwiązania to odroczenie przekierowania o 300–500 ms, użycie transport_type beacon oraz wysyłka zdarzenia serwerowo przez Measurement Protocol po potwierdzeniu płatności.
Punktem startu jest kontroler OrderConfirmationController i hook displayOrderConfirmation (oraz displayOrderConfirmationTop) w motywie. Zajrzyj do order-confirmation.tpl w motywie child – jeśli brak w nim wywołania hooka, żaden moduł ani tag GTM się nie uruchomi. Dokumentacja dla deweloperów PrestaShop opisuje strukturę hooków i kontrolerów: devdocs.prestashop-project.org.
Triage zająć powinien około 5 minut: Realtime, DebugView, filtry. Jeśli na tym etapie wiesz, która warstwa zawodzi, reszta to kwestia poprawki w szablonie, module lub konfiguracji. Jeśli nie potrafisz ustalić, czy brakuje sesji, zdarzenia, czy tylko raportu, dalsze klikanie w GA4 zwykle miesza bardziej, niż pomaga.
Jeśli wolisz, żeby ktoś przeszedł tę ścieżkę za Ciebie, zajrzyj do naszego obszaru sklepów internetowych albo napisz – powiemy wprost, czy problem jest w motywie, w consent, czy w konfiguracji GA4.