Anonimizacja: nazwa sklepu, domena, nazwa zewnętrznego systemu, numery zamówień, identyfikatory wizyt oraz dane klientów zostały celowo pominięte. Case study opisuje wyłącznie problem, architekturę rozwiązania, proces testów i rezultat techniczny.
Opracowanie: Łukasz PawlinaAktualizacja: 2 września 2026Typ: anonimowe wdrożenie PrestaShop

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.

Kluczowa decyzjaIdentyfikator wizyty trzeba zachować wcześniej przy koszyku i zamówieniu, a samo zgłoszenie sprzedaży wykonać serwerowo dopiero wtedy, gdy sklep potwierdzi właściwy status.

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.

Płatność online

Status potwierdzonej płatności

Webhook trafia do kolejki po otrzymaniu właściwego statusu z bramki płatniczej.

Płatność mobilna

Oddzielny status operatora

Druga ścieżka płatności korzysta z innego statusu, ale prowadzi do tej samej kolejki i reguł deduplikacji.

Pobranie

Dopiero po dostarczeniu

Zamówienie za pobraniem nie jest raportowane przy utworzeniu. Integracja uruchamia się dopiero po finalnym statusie dostarczenia.

Deduplikacja

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.

01

Allowlista domen

Moduł działa wyłącznie na wskazanej domenie produkcyjnej i kontrolowanej subdomenie testowej.

02

Chroniony CRON

Endpoint kolejki wymaga losowego tokenu. Po testach token został zmieniony przed uruchomieniem produkcyjnym.

03

Ograniczony endpoint

Połączenie wychodzące jest ograniczone do ustalonego hosta HTTPS, z weryfikacją certyfikatu i bez dowolnych przekierowań.

04

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

01

Sprzedaż jest raportowana po faktycznym zdarzeniu

System atrybucji otrzymuje sygnał z serwera sklepu, a nie wyłącznie zdarzenie z przeglądarki klienta.

02

Jedna transakcja nie zawyża statystyk

Zmiany statusów i bezpieczne ponowienie po timeoutcie nie tworzą kolejnych konwersji dla tego samego zamówienia.

03

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

  1. GTM może zapisać identyfikator wizyty, ale późniejsza ręczna zmiana statusu wymaga logiki po stronie serwera sklepu.
  2. Przy wielu metodach płatności nie warto zakładać jednego statusu „opłacone” — trzeba odwzorować rzeczywisty proces obsługi.
  3. Webhook nie powinien być wykonywany bezpośrednio w krytycznym hooku zamówienia, jeżeli timeout zewnętrznego API może spowolnić panel.
  4. Deduplikacja powinna istnieć jednocześnie lokalnie i po stronie systemu odbierającego, jeśli jego API to umożliwia.
  5. 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.

Powiązane case studies