Sklep, który zbierał dane bez zgody
ALU-GUM to rodzinna firma z Sulmierzyc, na rynku od 2007 roku. Około sześciu tysięcy felg na stanie: oryginały OE do Renault, Dacii, grupy PSA, Volkswagena, BMW i Jaguara, felgi stalowe, opony, koła kompletne. Realny magazyn, realni klienci, sprzedaż w kilku kanałach jednocześnie.
I sklep internetowy, który tego wszystkiego nie udźwignął. Zbudowany na Elementorze, obwieszony wtyczkami, z bannerem zgody na cookies, który był wyłącznie dekoracją. Google Analytics odpalał się i tak, zanim ktokolwiek kliknął „akceptuję".
Ten case study opisuje projekt, który z każdym miesiącem robił się większy. Zaczął się od audytu zgodności, przeszedł przez nowy sklep i pięć rynków, a skończył na tym, że sklep przejął rolę zewnętrznego systemu do obsługi sprzedaży: ceny, zamówienia z Allegro, wysyłkę i płatności firma prowadzi dziś z jednego panelu.
Audyt: od najpilniejszego
Zaczęliśmy od przeglądu na żywo, po publicznym kodzie, sitemapach, stronach prawnych i danych strukturalnych. Nie od projektu graficznego, tylko od pytania, co grozi firmie już jutro.
Skrypt Google Analytics ładował się jako zwykły, wykonywalny tag, bez blokady i bez Consent Mode. Dane zbierały się przed zgodą użytkownika. To realne ryzyko RODO, a od 2024 roku brak Consent Mode w wersji drugiej odcina też remarketing i pomiar konwersji w Google Ads.
Reszta listy była podobnie konkretna. Polityka cookies szablonowa, bez nazw ciasteczek i czasu ich życia. Deklaracja dostępności istniała jako pusty adres, bez daty, poziomu zgodności i kontaktu. Przy formularzu zwrotu widniało „POBIERZ", tylko że bez żadnego linku, jako goły tekst.
Do tego warstwa niewidoczna dla klienta, a kosztowna dla sklepu: po trzy nagłówki H1 na stronie, dane strukturalne strony głównej opisujące sklep jako artykuł na blogu, produkty bez marki i kodu producenta oraz opinie klientów niewpięte w dane dla wyszukiwarki.
Analityka startowała przed zgodą na cookies
Deklaracja dostępności: pusta strona
Formularz zwrotu: napis „POBIERZ" bez pliku
Trzy nagłówki H1 na jednej stronie
Strona główna opisana w danych strukturalnych jako artykuł
Produkty bez marki i kodu producenta
Jeden język, jedna waluta
Elementor i 31 arkuszy stylów
Ceny, stany i zamówienia z Allegro w zewnętrznym systemie
Własny mechanizm zgody, analityka rusza dopiero po akceptacji
Deklaracja dostępności i polityka cookies z tabelą ciasteczek
Interaktywny formularz zwrotu z klauzulą i zgodą
Jeden H1 na stronę, nawigacja klawiaturą, skip link
Sklep opisany jako sklep z częściami, produkty z marką i kodem
Marka i kod producenta uzupełnione na blisko trzech tysiącach pozycji
Pięć języków i cztery waluty
Własny motyw, dwa arkusze stylów
Sklep jako jedyne źródło cen, z własną integracją Allegro i wysyłki
Decyzja: nie łatanie, tylko nowy fundament
Klient dostał dwie wyceny. Pierwsza obejmowała samo zdjęcie ryzyka prawnego. Druga, wybrana, oznaczała wyrzucenie Elementora i zbudowanie sklepu od nowa, przy zachowaniu katalogu i zamówień. Nie migrowaliśmy danych, tylko wymieniliśmy całą warstwę prezentacji i logiki wokół nich.
Audyt i koncept
Przegląd stanu faktycznego i klikalny koncept na dziesięć ekranów, zaakceptowany przed pierwszą linią kodu produkcyjnego
Warstwa zgody i pomiaru
Własny mechanizm zgody z Consent Mode w wersji drugiej, zamiast zewnętrznej wtyczki. Kontener pomiarowy i pełna warstwa danych e-commerce
Motyw od zera
Klasyczny motyw w PHP z Tailwindem, bez page buildera, od strony głównej po kasę i konto klienta
Reguły biznesowe w kodzie
Sprzedaż w kompletach, dodatki do felg, matryca przewoźników i płatności. To, co wcześniej było ustaleniem w głowie właściciela, stało się regułą, której sklep pilnuje sam
Migracja na nowy hosting
Przeniesienie sklepu ze starego dostawcy, przepięcie domeny, poczty i certyfikatów, bez przerwy w sprzedaży
Ekspansja i automatyzacja
Pięć języków, cztery waluty, reguły sprzedaży zagranicznej, katalog produktowy w Google, asystent zakupowy i kampanie reklamowe
Wyjście z BaseLinkera
Import cennika klienta, wyrównanie cen na Allegro i odcięcie zewnętrznego systemu w trzech miejscach. Od tego dnia źródłem cen i danych produktowych jest sklep
Własny hub integracji w sklepie
Allegro przez API: synchronizacja cen i stanów, zamówienia w panelu sklepu, wystawianie ofert z karty produktu. Do tego wysyłka przez Polkuriera, wydruk dla pakujących i numery przesyłek wracające do kupującego
Zgoda na cookies zrobiona uczciwie
Zewnętrzną wtyczkę do zgody zastąpiliśmy własną, bo w Consent Mode w wersji drugiej liczy się kolejność, w jakiej rzeczy trafiają do nagłówka strony. Wtyczka, która robi to po swojemu, potrafi zepsuć pomiar mimo poprawnego bannera.
- Domyślna odmowa dla analityki i marketingu, ustawiana zanim cokolwiek się załaduje
- Zapamiętany wybór użytkownika odczytywany przed startem kontenera pomiarowego
- Bez zgody dane lecą w formie anonimowej, po zgodzie w pełnej, i to jest różnica między pomiarem legalnym a nielegalnym
Na tym fundamencie stanęła warstwa danych e-commerce: obejrzenie produktu, dodanie do koszyka, rozpoczęcie płatności i zakup razem z kwotą, walutą i numerem zamówienia. Jedno źródło dla analityki i reklam.
Nowy sklep zamiast Elementora
Motyw powstał od zera, na tokenach z zaakceptowanego konceptu. Efekt widać w liczbach, bo usunięcie page buildera zdjęło ze strony około 470 kilobajtów samego kodu HTML, zanim jeszcze doliczymy style i skrypty.
Dostępność podniosła się z osiemdziesięciu ośmiu do dziewięćdziesięciu pięciu punktów. Jeden nagłówek H1 na stronę, link pomijający nawigację, poprawny kontrast, obsługa klawiaturą. To nie jest kosmetyka, tylko wymóg Europejskiego Aktu o Dostępności, który obowiązuje sklepy od czerwca 2025 roku.
Karta produktu, która sprzedaje komplet
Felgi sprzedaje się w kompletach i sklep wreszcie o tym wie. Karta produktu ma konfigurator: klient wybiera liczbę sztuk, dokłada opony, czujniki ciśnienia i montaż, a suma przelicza się na żywo. Reguła biznesowa właściciela została zapisana w kodzie, łącznie z rozpoznawaniem, kiedy oferta dotyczy pojedynczej sztuki, a kiedy pełnego kompletu.
- Wyszukiwarka rozumiejąca zapytania w rodzaju „clio 17" albo „5x114,3" i zamieniająca je na filtry
- Dobór po parametrach: średnica, szerokość, rozstaw śrub, otwór centralny i wylot
- Filtr stanu, oddzielający felgi nowe od używanych, zbudowany na danych z całego katalogu
Dostawa i płatność bez telefonu do klienta
Reguły wysyłki felg były do tej pory wiedzą plemienną. Zamieniliśmy je w automat, który nie pozwala złożyć niemożliwego zamówienia.
- Felgi jadą wyłącznie kurierem, paczkomat znika z wyboru sam
- Drobne produkty mogą iść zarówno kurierem, jak i do paczkomatu
- Przy paczkomacie pobranie jest niedostępne, zostaje przedpłata
- Za granicę wyłącznie kurierzy międzynarodowi, z progiem minimalnego kosztu
- Poza Polską pobranie nie jest oferowane w ogóle
- Płatności online przez Przelewy24, z BLIK-iem i kartą, obok przelewu tradycyjnego i pobrania
Pięć języków i cztery waluty
Sklep miał wyjść poza Polskę, więc dostał pięć wersji językowych: polską, niemiecką, czeską, słowacką i rumuńską, każdą w osobnym katalogu adresu. Przetłumaczyliśmy nie tylko interfejs, ale i katalog: ponad trzy tysiące produktów razy cztery języki to około piętnastu tysięcy wpisów produktowych, do tego menu, kategorie, strony i komplet treści prawnych.
Po włączeniu wielojęzyczności przestały działać filtry na wersjach obcych. Przyczyny były dwie: wtyczka tłumacząca obejmowała także atrybuty techniczne felg, a przetłumaczone produkty nie trafiły do tabeli, z której WooCommerce czyta ceny i stany. Naprawa obu warstw przywróciła filtry we wszystkich językach.
Do tego cztery waluty: złoty, euro, korona czeska i lej rumuński, z kursami pobieranymi automatycznie z Narodowego Banku Polskiego. Waluta dobiera się do języka, a klient może ją zmienić ręcznie i wybór zostaje zapamiętany.
Sprzedaż zagraniczna z własnymi regułami
Ceny dla zagranicy dostają ustalony narzut procentowy, doliczany zanim waluta zostanie przeliczona, żeby kolejność działań nie zafałszowała kwoty. Wysyłka poza Polskę idzie tylko wybranymi kurierami międzynarodowymi, z minimalną kwotą przewalutowywaną na walutę klienta. Wszystkie progi ustawia się z panelu sklepu, bez dotykania kodu.
Katalog gotowy na marketplace'y i Google
ALU-GUM sprzedaje nie tylko na własnej stronie. Głównym kanałem jest Allegro, a w pierwszej fazie projektu ceny i stany całego katalogu żyły w BaseLinkerze, który zasilał sklep i marketplace'y. Naszym zadaniem było wtedy uporządkowanie danych, które te kanały konsumują.
- Uzupełnienie producenta i kodu producenta na blisko trzech tysiącach pozycji, bo bez nich marketplace'y i Google Shopping traktują ofertę gorzej
- Automatyczne przypisywanie kodu producenta jako identyfikatora produktu po stronie sklepu
- Katalog wysyłany do Google Merchant Center przez API, ponad trzy tysiące ofert, ze zdjęciami i etykietami do sterowania stawkami
- Ceny dla katalogu Google zawsze w wersji krajowej, niezależnie od tego, jaką walutę widzi odwiedzający
Po włączeniu wielojęzyczności interfejs programistyczny sklepu zaczął zwracać produkty ze wszystkich języków naraz. Automat wysyłający katalog do Google zdublował więc oferty kilkukrotnie, co skończyło się tysiącami odrzuconych pozycji. Znaleźliśmy przyczynę, wyczyściliśmy duplikaty i przebudowaliśmy automat tak, żeby filtrował język i przerywał pracę, gdy dane wyglądają podejrzanie. Każdy program czytający dane wielojęzycznego sklepu musi jawnie wskazać język.
Kiedy pośrednik zaczął psuć ceny
Pod koniec września właściciel zadzwonił z problemem, który dotykał samego rdzenia sprzedaży: ceny i stany rozjechały się w całym katalogu, w sklepie i na Allegro jednocześnie. Obsługa poprawiała ceny ręcznie, oferta po ofercie. Decyzja zapadła w tej samej rozmowie: rezygnacja z BaseLinkera, a źródłem prawdy dla cen i danych produktowych staje się sklep.
Wyjście z systemu, przez który przechodziła cała sprzedaż, nie mogło oznaczać ani jednego dnia z błędnymi cenami. Zrobiliśmy to w kolejności, w której każdy krok dało się sprawdzić i cofnąć.
Cennik do wypełnienia
Zrzut wszystkich produktów do arkusza, w którym klient wpisuje tylko zmiany. Osobne narzędzie sprawdziło odesłany plik: ceny odbiegające o ponad 25 procent, ten sam towar pod różnymi cenami, klony ofert, wiersze bez ceny
Import z trybem próbnym
Najpierw plan zmian z ceną starą i nową każdej pozycji, który jest zarazem kopią do cofnięcia. Potem test na jednym produkcie w pięciu językach, dopiero na końcu całość
Wyrównanie Allegro do sklepu
Oferty Allegro sparowane z produktami sklepu. Automat zmienił tylko pary bez wątpliwości. Przypadki w rodzaju „cena za sztukę kontra cena za komplet" trafiły do arkusza do potwierdzenia przez klienta
Odcięcie w trzech miejscach
Dostęp do sklepu, dostęp do Allegro i automatyzacje w panelu. Po każdym kroku ponowny tryb próbny po obu stronach, który ma pokazać zero zmian do wprowadzenia
Przydała się historia cen, którą sklep prowadzi od lipca na potrzeby dyrektywy Omnibus: każda zmiana jest zapisana, łącznie z całym importem cennika, a najniższa cena z 30 dni pokazuje się przy obniżce.
Allegro sterowane ze sklepu
Klient postawił jasny cel: obsługa ma nie wchodzić na Allegro. Oferty, ceny i zamówienia mają być w jednym panelu. Zamiast kolejnego pośrednika napisaliśmy własną wtyczkę integrującą WooCommerce z REST API Allegro. Na starcie było już blisko trzy tysiące aktywnych ofert, więc pierwszym zadaniem nie było wystawianie, tylko trwałe powiązanie istniejących ofert z produktami.
- Autoryzacja na koncie klienta kodem do kliknięcia, bez przekierowań i bez przekazywania hasła
- 2 627 par oferta i produkt zapisanych po obu stronach: numer oferty przy produkcie, identyfikator produktu w sygnaturze oferty
- Synchronizacja cen i stanów co pięć minut, wyłącznie w kierunku sklep do Allegro, wysyłane są tylko różnice
- Zmiana ceny o ponad 25 procent nie idzie automatem, czeka na potwierdzenie w panelu
- Zamówienia z Allegro w panelu WooCommerce co dziesięć minut, oznaczone jako Allegro, ze statusem płatności i punktem odbioru
- Statusy w obie strony: zamówienie zrealizowane w sklepie jest wysłane na Allegro, anulowanie na Allegro anuluje je w sklepie
Allegro odrzuciło zapis sygnatury na 145 ofertach. Powodem nie był nasz kod, tylko przepisy o bezpieczeństwie produktów: oferty ze stanem „nowy" miały starą deklarację, której marketplace nie przyjmuje już przy edycji. Powiązanie w sklepie istnieje dla wszystkich par, a lista ofert do uzupełnienia danych producenta odpowiedzialnego trafiła do obsługi.
Wystawianie z karty produktu
Na karcie produktu bez oferty jest przycisk „Wystaw na Allegro". Kategorię Allegro, cennik dostaw i warunki zwrotów sklep bierze z najnowszej powiązanej oferty z tej samej kategorii, parametry felgi mapuje po nazwach atrybutów, wgrywa do szesnastu zdjęć i składa opis w układzie tekst i zdjęcie na przemian. Gdy brakuje wymaganego parametru albo wartość jest spoza słownika Allegro, nic nie zostaje wysłane, a obsługa dostaje listę braków. Oferta powstaje jako szkic i staje się aktywna dopiero po kliknięciu „Aktywuj". Pierwszy szkic na żywo przeszedł walidację Allegro bez błędów i bez ostrzeżeń.
Od wydruku do numeru przesyłki
Etykiety robił wcześniej zewnętrzny system, więc po jego wyłączeniu w sklepie nie było żadnej integracji z przewoźnikiem. Obieg wysyłki zbudowaliśmy na podstawie rozmowy z osobami, które codziennie pakują felgi.
- Wydruk dla pakujących: zamówienie na kartce A4 ze zdjęciem pozycji, kodem producenta, uwagami i statusem płatności, zamiast przepisywania do zeszytu
- Nowy status „Spakowane" między realizacją a wysyłką
- Liczba paczek liczona przez sklep: felgi do 18 cali w dwóch paczkach, większe w czterech, z wyjątkami po kodzie producenta ustawianymi w panelu
- Nadanie przez brokera Polkurier: felgi kurierem DPD z zamówieniem odbioru, drobnica przez InPost
- Po nadaniu zamówienie zamyka się samo, klient dostaje numer i link do śledzenia, a przy zamówieniu z Allegro numer trafia też do Allegro
W poprzednim obiegu komplet za 2 000 zł wysłany w dwóch paczkach dostawał pobranie na każdej z nich, czyli razem 4 000 zł. Klient nie odbierał przesyłki, paczki wracały, a obsługa poprawiała to ręcznie. Teraz komplet idzie jako jedna przesyłka wielopaczkowa z jednym pobraniem na całe zamówienie.
Obieg jest wdrożony i sprawdzony na wycenach oraz terminach odbioru z konta klienta. Pierwsza produkcyjna etykieta będzie jego ostatnim testem.
Kolejne kanały
Hub w sklepie nie kończy się na Allegro. Katalog Google Merchant Center od początku czyta dane ze sklepu, a sklep jest wpięty również w porównywarkę Ceneo. Na tym samym fundamencie, z tymi samymi zasadami (jeden kierunek danych, tryb próbny, dziennik), przygotowujemy kolejne marketplace'y: Ovoko i eMAG. Każdy z nich dostaje dane z jednego miejsca, więc nowy kanał nie oznacza nowego źródła błędów.
Felek, asystent zakupowy bez abonamentu
Klient zobaczył u konkurencji czat obsługiwany przez wynajętą usługę i chciał to samo. Policzyliśmy koszty i zaproponowaliśmy coś innego: własnego asystenta, bez modelu językowego i bez opłat abonamentowych.
Felek rozpoznaje intencję pytania, radzi sobie z literówkami i odmianą, rozumie pytania w pięciu językach i przeszukuje katalog sklepu. Zapytany o „golfa" albo „passata" sprowadzi nazwę do modelu auta. Na pytania o dostawę, zwroty, płatności i sprzedaż zagraniczną odpowiada danymi wprost z ustawień sklepu, więc nie rozjedzie się z rzeczywistością.
Pytania, na które Felek nie umiał odpowiedzieć, trafiają do panelu z licznikiem powtórzeń, a właściciel jednym przyciskiem dopisuje odpowiedź. Uczy się bez uczenia maszynowego: druga wersja powstała właśnie z tej listy.
Reklama, która wie, co sprzedaje
Kampanie Google Ads ruszyły dopiero wtedy, gdy sklep potrafił zmierzyć sprzedaż co do złotówki, bo bez tego reklama jest wydatkiem, o którym nic nie wiadomo.
- Trzy kampanie: wyszukiwarkowa według marki auta, produktowa zasilana katalogiem i obrona własnej nazwy
- Pięćset cztery słowa kluczowe w dopasowaniach ograniczających przypadkowy ruch
- Siedemdziesiąt cztery wykluczenia od pierwszego dnia, między innymi naprawa, prostowanie, skup i wynajem
- Pomiar zakupu przekazujący kwotę, walutę i numer zamówienia, więc raport pokazuje przychód, nie liczbę kliknięć
Start z licytacją pod kliknięcia, bo automat optymalizujący konwersje potrzebuje historii sprzedaży, której konto nie miało. Po pierwszych 30 dniach audyt pokazał, że sprzedaje kampania produktowa i to ona traci najwięcej aukcji przez budżet. Przed sezonem budżety przesunęliśmy więc tam, gdzie są zakupy, a wszystkie zmiany wprowadziliśmy przez API, z kopią stanu sprzed zmiany.
Awaria, która czegoś nauczyła
Pod koniec sierpnia sklep przestał odpowiadać na blisko dobę. Przyczyną było obejście konfiguracyjne odziedziczone po migracji, które hosting w końcu ubił. Zamiast je reanimować, przenieśliśmy sklep na aktualną, systemową wersję PHP. Tydzień później wyszedł skutek uboczny: po serii nieudanych zapytań w czasie awarii BaseLinker sam wstrzymał pobieranie zamówień i nie wznowił go po powrocie sklepu, choć sklep działał poprawnie. Dziś zamówienia z Allegro trafiają prosto do sklepu, a każde wywołanie integracji zostawia ślad w dzienniku widocznym w panelu.
Technologie
WooCommerce
PHP 8.5
MariaDB
Tailwind CSS 4
Motyw klasyczny bez page buildera
WooCommerce REST API
Polylang Pro
Multiwaluta z kursami NBP
Allegro REST API
OAuth 2.0 device flow
Polkurier (DPD, InPost)
Przelewy24
Ceneo
Google Tag Manager
GA4 z Consent Mode v2
Google Merchant Center Content API
Google Ads API
Schema.org JSON-LD
WP-Cron
Python
Docker
Rezultaty
Czego ten projekt uczy
Sklep nie był zepsuty dlatego, że komuś zabrakło chęci. Był zepsuty, bo każdy kolejny element dokładano do poprzedniego, aż całość przestała się trzymać kupy: page builder na wtyczce, wtyczka na wtyczce, zgoda na cookies jako obrazek do zamknięcia. Naprawa oznaczała odwrócenie kolejności: najpierw fundament prawny i pomiarowy, potem szybka warstwa prezentacji, dopiero na końcu ekspansja i reklama.
Dzięki tej kolejności każdy kolejny etap dało się dołożyć bez przebudowywania poprzedniego. Wielojęzyczność weszła na gotowy motyw. Waluty weszły na wielojęzyczność. Sprzedaż zagraniczna weszła na waluty. Reklama weszła na pomiar, który stał od pierwszego tygodnia projektu.
Ta sama zasada zadziałała przy największej zmianie. Wyjście z BaseLinkera zajęło niecałe dwa tygodnie, bo sklep miał już uporządkowane dane, historię cen i narzędzia z trybem próbnym. Integracje przestały być czarną skrzynką u zewnętrznego dostawcy i stały się kodem z testami, dziennikiem i jednym kierunkiem przepływu danych. Kolejny marketplace to dziś kolejny odbiorca tych samych danych, a nie kolejne miejsce, w którym ceny mogą się rozjechać.