Samo śledzenie ruchu w przeglądarce nie wystarcza, gdy sprzedaż ma zostać rozliczona dopiero po późniejszej zmianie statusu w panelu sklepu. W tym projekcie potrzebny był most między identyfikatorem wizyty, zamówieniem PrestaShop i systemem atrybucji.
Problem biznesowy: połączyć faktyczną sprzedaż ze źródłem ruchu
Zespół marketingowy miał już warstwę pomiarową po stronie przeglądarki i zapisywał first-party identyfikator wizyty. Brakowało jednak informacji zwrotnej ze sklepu: która wizyta zakończyła się faktycznie opłaconym zamówieniem i jaka była wartość produktów po rabatach, bez kosztu dostawy.
Wymagania były precyzyjne: identyfikator wizyty miał mieć pierwszeństwo, przy jego braku należało użyć danych awaryjnych z zamówienia, zgłoszenie nie mogło blokować pracy sklepu, a każde zamówienie miało zostać policzone dokładnie raz nawet przy ponowieniu po timeoutcie.
Architektura: dedykowany moduł zamiast modyfikacji rdzenia
1. Zachowanie identyfikatora wizyty
Moduł przechwytuje first-party visitor ID podczas pracy z koszykiem i wiąże go z zamówieniem. Dzięki temu identyfikator nie znika, gdy klient opuszcza stronę przed późniejszą obsługą zamówienia.
2. Właściwy moment zgłoszenia
Integracja reaguje na oficjalny hook zmiany statusu PrestaShop. Sprzedaż nie jest liczona przy utworzeniu koszyka ani przy samym rozpoczęciu płatności.
3. Kolejka zamiast połączenia w krytycznym procesie
Zmiana statusu tylko zapisuje zadanie. Dopiero CRON przetwarza kolejkę, więc timeout zewnętrznego API nie opóźnia ani nie przerywa pracy panelu zamówień.
4. Idempotentny numer referencyjny
Każde zgłoszenie otrzymuje stabilny identyfikator oparty na numerze zamówienia. To pozwala bezpiecznie ponowić żądanie bez tworzenia drugiej sprzedaży.
5. Kwota zgodna z założeniem biznesowym
Do atrybucji trafia wartość faktycznie zapłacona brutto po rabatach, ale bez kosztu wysyłki, sformatowana z dokładnością do dwóch miejsc po przecinku.
Różne metody płatności, kilka statusów, jedna konwersja
W sklepie nie istniał jeden uniwersalny status „opłacone”. Płatność online, płatność mobilna i pobranie kończyły się różnymi ścieżkami obsługi. Dla pobrania sprzedaż powinna być raportowana dopiero po dostarczeniu przesyłki.
Status potwierdzonej płatności
Webhook trafia do kolejki po otrzymaniu właściwego statusu z bramki płatniczej.
Oddzielny status operatora
Druga ścieżka płatności korzysta z innego statusu, ale prowadzi do tej samej kolejki i reguł deduplikacji.
Dopiero po dostarczeniu
Zamówienie za pobraniem nie jest raportowane przy utworzeniu. Integracja uruchamia się dopiero po finalnym statusie dostarczenia.
Późniejsza zmiana niczego nie dubluje
Jeśli zamówienie po potwierdzeniu płatności później otrzyma status „dostarczone”, moduł rozpoznaje je jako już obsłużone.
Bezpieczeństwo i odporność integracji
Moduł przetwarza dane powiązane z zamówieniami, dlatego zabezpieczenia były częścią architektury, a nie dodatkiem po testach.
Allowlista domen
Moduł działa wyłącznie na wskazanej domenie produkcyjnej i kontrolowanej subdomenie testowej.
Chroniony CRON
Endpoint kolejki wymaga losowego tokenu. Po testach token został zmieniony przed uruchomieniem produkcyjnym.
Ograniczony endpoint
Połączenie wychodzące jest ograniczone do ustalonego hosta HTTPS, z weryfikacją certyfikatu i bez dowolnych przekierowań.
Kontrolowane logi
Pełne URL-e były potrzebne podczas testów, ale po potwierdzeniu działania logowanie danych wrażliwych można ograniczyć.
Założenia odporności
- awaria lub timeout API nie może wpływać na zmianę statusu zamówienia,
- maksymalnie jedna automatyczna ponowna próba po błędzie,
- lokalna deduplikacja plus stabilny identyfikator transakcji,
- brak ingerencji w pliki rdzenia PrestaShop,
- oddzielne środowisko testowe i tryb dry run przed prawdziwą wysyłką.
Testy przed wdrożeniem produkcyjnym
Integracja została najpierw zainstalowana na pełnej kopii sklepu w subdomenie testowej. Dopiero po przejściu kolejnych scenariuszy została uruchomiona na produkcji.
Ręczny identyfikator wizyty
Sprawdzono, czy identyfikator trafia z przeglądarki do koszyka, zamówienia i finalnego żądania.
Brak podwójnej sprzedaży
To samo zamówienie przechodziło później do kolejnego kwalifikowanego statusu. Liczba zgłoszeń pozostała równa jeden.
Płatność przy odbiorze
Zweryfikowano, że wcześniejszy status nie uruchamia integracji, a finalny status dostarczenia już tak.
Automatyczny CRON
Najpierw potwierdzono działanie endpointu ręcznie, później sprawdzono automatyczne opróżnianie kolejki bez używania przycisku w panelu.
Test end-to-end
Po wyłączeniu dry run zewnętrzny zespół potwierdził odbiór testowej sprzedaży, poprawny numer referencyjny oraz działanie deduplikacji.
Rezultat techniczny
Sprzedaż jest raportowana po faktycznym zdarzeniu
System atrybucji otrzymuje sygnał z serwera sklepu, a nie wyłącznie zdarzenie z przeglądarki klienta.
Jedna transakcja nie zawyża statystyk
Zmiany statusów i bezpieczne ponowienie po timeoutcie nie tworzą kolejnych konwersji dla tego samego zamówienia.
Integracja nie blokuje sklepu
Kolejka i CRON oddzielają komunikację z zewnętrznym API od codziennej obsługi zamówień.
Podczas finalnego testu zewnętrzny system poprawnie przyjął zgłoszenie, a zespół odpowiedzialny za atrybucję potwierdził numer referencyjny i ochronę przed duplikatem. Nie publikuję danych klienta ani wyników sprzedażowych, ponieważ celem tego case study jest pokazanie jakości integracji, a nie przypisywanie jej efektu finansowego bez odpowiedniego okresu pomiaru.
Najważniejsze wnioski z wdrożenia
- GTM może zapisać identyfikator wizyty, ale późniejsza ręczna zmiana statusu wymaga logiki po stronie serwera sklepu.
- Przy wielu metodach płatności nie warto zakładać jednego statusu „opłacone” — trzeba odwzorować rzeczywisty proces obsługi.
- Webhook nie powinien być wykonywany bezpośrednio w krytycznym hooku zamówienia, jeżeli timeout zewnętrznego API może spowolnić panel.
- Deduplikacja powinna istnieć jednocześnie lokalnie i po stronie systemu odbierającego, jeśli jego API to umożliwia.
- Dry run, staging i prawdziwy test end-to-end są ważniejsze niż samo przejście testów składni kodu.
Najczęstsze pytania
Czy taką integrację da się zrobić samym Google Tag Managerem?
Nie w pełni, jeśli sprzedaż ma być zgłoszona dopiero po późniejszej zmianie statusu w panelu sklepu. Wtedy potrzebny jest mechanizm serwerowy albo zewnętrzna usługa, która otrzyma informację z PrestaShop.
Czy potrzebny jest dedykowany moduł PrestaShop?
Nie zawsze, ale przy własnym identyfikatorze wizyty, kilku statusach, deduplikacji, kolejce i specyficznym formacie webhooka dedykowany moduł pozwala uniknąć modyfikacji rdzenia oraz ograniczeń ogólnych modułów webhooków.
Czy podobny mechanizm można podłączyć do innego systemu atrybucji lub CRM?
Tak, jeśli system docelowy udostępnia stabilny endpoint lub API. Zmienia się warstwa komunikacji, ale model: identyfikator → zamówienie → status → kolejka → webhook pozostaje podobny.
Dlaczego testy były prowadzone na kopii sklepu?
Integracja dotyka procesu zamówień i danych klientów. Kopia pozwala sprawdzić statusy, CRON, błędy i deduplikację bez ryzyka zanieczyszczenia produkcyjnych statystyk lub zakłócenia sprzedaży.

