Modelowane listy odbiorców nie zawierają konkretnych osób, tylko prawdopodobieństwa. Wyjaśniam, jak powstają, gdzie ich szukać w panelu i jak czytać ich raporty.
Telefon od klienta z e-commerce brzmi zawsze podobnie: „produkty zniknęły z reklam, w Merchant Center jest coś o cenie”. Potem loguję się do panelu i w diagnostyce widzę kilkuset odrzuconych ofert, a przy każdej komunikat, który dla większości osób jest jednym błędem, a w rzeczywistości jest workiem na co najmniej dwie zupełnie różne przyczyny.
To istotne, bo naprawa jednej z nich to poprawka w mapowaniu pliku danych — robota na kwadrans. Naprawa drugiej wymaga zrozumienia, dlaczego robot Google widzi na Twojej stronie produktowej inną cenę niż Ty w przeglądarce. To bywa najciekawszy element całej układanki i najczęściej nie leży po stronie Merchant Center.
Poniżej rozkładam ten problem na części: który komunikat oznacza co, jakie są wymagania wobec atrybutu ceny, gdzie kryją się pułapki przy promocjach i wariantach, dlaczego indeksowanie strony daje inny wynik niż Twoja wizyta na niej, i jak wygląda naprawa razem z realnym czasem oczekiwania na odwieszenie ofert.
Zacznij od tego, żeby dokładnie przeczytać, co jest napisane w zakładce Diagnostyka. W Merchant Center „problem z ceną” występuje w dwóch wariantach i mają one zupełnie inne przyczyny oraz inny tryb naprawy.
Różnica ma bardzo praktyczny wymiar. Pierwszy wariant naprawiam w pliku danych albo w regułach pliku i wynik widzę po najbliższym pobraniu. Drugi wariant naprawiam na stronie sklepu albo w danych o cenie, a potem czekam, aż Google ponownie odwiedzi adresy — i tego czekania nie da się przeskoczyć przyciskiem.
Jeśli odrzucona jest tylko część asortymentu przy tym samym szablonie strony, problem prawie zawsze dotyczy konkretnej grupy: promocji, wariantów albo towarów sprzedawanych na wagę. Pobieram wtedy z diagnostyki listę dotkniętych ofert i szukam tego, co je łączy.
Wymagania są proste, ale każda z tych reguł potrafi wywalić cały plik danych, jeśli platforma sklepowa generuje go po swojemu.
Wartość składa się z liczby i kodu waluty w standardzie ISO 4217, rozdzielonych spacją — czyli 89.99 PLN, a nie „89,99 zł”. Separatorem dziesiętnym jest kropka. Nie wolno wstawiać spacji jako separatora tysięcy, symboli waluty, dopisków typu „brutto”, „od” ani zakresów. Kod waluty warto podawać zawsze, nawet jeśli sklep celuje wyłącznie w jeden kraj — pominięcie go bywa źródłem trudnych do wyśledzenia rozbieżności, gdy plik obsługuje więcej niż jeden rynek.
Cena musi być większa od zera — produkty z ceną 0, oznaczające w sklepie „zapytaj o cenę”, nie przejdą walidacji. Dla polskiego rynku obowiązuje też podawanie kwoty z podatkiem VAT. Jeżeli sklep prowadzi sprzedaż B2B i wyświetla domyślnie ceny netto, a plik danych czerpie z tego samego pola, dostaniesz niezgodność ze stroną albo oferty tańsze od rzeczywistych — a to problem poważniejszy niż samo odrzucenie produktu.
Do ceny nie doliczasz kosztów dostawy; wysyłka jest osobnym atrybutem i osobnym ustawieniem na koncie. Ostatni warunek dotyczy dostępności ceny dla użytkownika: kwota z pliku danych musi być widoczna dla każdego, kto wejdzie na stronę produktu — bez logowania, bez rejestracji, bez kodu rabatowego i bez dodawania towaru do koszyka.
Najwięcej odrzuceń w tej kategorii widzę na produktach objętych przecenami, i prawie zawsze z tego samego powodu: sklep wysyła cenę promocyjną w atrybucie price, zamiast rozdzielić ją na dwa pola.
Właściwy układ jest taki, że price zawiera cenę podstawową, a sale_price cenę obniżoną, przy czym cena promocyjna musi być niższa od podstawowej. Dodatkowo warto uzupełnić sale_price_effective_date, czyli okres obowiązywania promocji — bez tego przecena obowiązuje do czasu, aż zmienisz plik danych, a strona sklepu już dawno wróci do ceny wyjściowej. Ten rozjazd jest jednym z najczęstszych źródeł niezgodności po zakończeniu akcji rabatowej.
Drugi klasyk to warianty. Jeżeli strona produktu wyświetla najniższą cenę z całej rodziny rozmiarów albo kolorów, a plik danych zawiera osobne oferty dla każdego wariantu z jego własną ceną, robot porówna ofertę droższego wariantu z kwotą widoczną na stronie i uzna, że się nie zgadza. Każdy wariant potrzebuje adresu, na którym po wejściu widać jego cenę — albo przez osobny URL, albo przez parametr, który od razu ustawia właściwy wybór.
Trzeci przypadek to towary sprzedawane w przeliczeniu na wagę czy objętość. Sklep pokazuje wtedy dwie liczby: cenę opakowania i cenę za kilogram albo litr. Do atrybutu ceny trafia cena opakowania, a przeliczenie na jednostkę opisuje się atrybutami unit_pricing_measure i unit_pricing_base_measure. Wysłanie ceny jednostkowej jako ceny oferty daje niezgodność natychmiast. Analogicznie działa sprzedaż abonamentowa i ratalna — miesięczna rata nie jest ceną produktu i ma własne atrybuty.
To pytanie zadaję sobie za każdym razem, gdy klient przysyła zrzut ekranu z ceną zgodną z plikiem i pyta, o co Google’owi chodzi. Odpowiedź prawie zawsze sprowadza się do tego, że robot i Ty nie odwiedziliście tej samej wersji strony.
Najczęstsza przyczyna to cena zależna od lokalizacji. Sklep rozpoznaje adres IP i przełącza walutę, wersję językową albo od razu przekierowuje na inną domenę. Ruch indeksujący Google przychodzi w większości z adresów zagranicznych, więc widzi wersję euro lub dolarową i porównuje ją z polską ceną z pliku. Efekt jest identyczny jak przy zwykłej pomyłce w cenie, tylko przyczyna leży w konfiguracji serwera.
Druga przyczyna to cena dostawiana skryptem po wczytaniu strony — z osobnego zapytania, z systemu rekomendacji albo z mechanizmu personalizacji. Jeśli kwota pojawia się dopiero po wykonaniu skryptu, po interakcji użytkownika albo po zamknięciu wyskakującego okna z akceptacją, robot może jej nie zobaczyć. Ten sam skutek daje blokowanie w robots.txt zasobów, od których zależy wyświetlenie ceny.
Trzecia to nieaktualna kopia strony. Sklepy z agresywnym cache’owaniem albo CDN-em, który nie unieważnia zawartości po zmianie ceny, potrafią wydawać robotowi wersję z poprzedniego tygodnia. Czwarta to częstotliwość aktualizacji: harmonogram pobierania pliku raz na dobę oznacza, że każda zmiana cennika w ciągu dnia zostawia po sobie godziny rozbieżności. Przy sklepach pracujących na cenach zmiennych jedynym sensownym rozwiązaniem jest przesyłanie aktualizacji przez Content API for Shopping.
Do diagnozy używam prostej metody: podglądam, jaka treść wraca dla surowego żądania bez sesji i bez plików cookie. Jeśli w tej wersji cena jest inna albo jej nie ma, temat przestaje być problemem Merchant Center i staje się zadaniem dla działu technicznego sklepu.
Google porównuje cenę z pliku danych z tym, co znajdzie na stronie, i najpewniejszym sposobem, żeby powiedział to samo co Ty, są dane strukturalne. Znaczniki schema.org typu Product z zagnieżdżoną ofertą, w której cena i kod waluty są podane wprost, usuwają element zgadywania — robot nie musi wyłuskiwać kwoty z układu strony.
Cena w znacznikach musi być liczbą bez symbolu waluty, waluta jest podawana osobno kodem, a wartość musi być zgodna z tym, co widzi użytkownik. Znaczniki niezgodne z widoczną treścią to nie sposób na obejście weryfikacji, a naruszenie wytycznych.
Merchant Center ma też mechanizm automatycznych aktualizacji produktów, który po włączeniu w ustawieniach konta korzysta z tych danych, by samodzielnie poprawiać cenę i dostępność w ofertach. Włączam go w sklepach, w których cena zmienia się często. Nie traktuję tego jednak jako naprawy — mechanizm łata skutek, a nie przyczynę, i bez poprawnych danych strukturalnych nie ma z czego czerpać.
Kolejność, w której to robię, wygląda tak samo w każdym sklepie.
Na koniec najmniej przyjemna część, czyli czas. Poprawka w pliku danych działa po pobraniu, więc praktycznie od razu. Niezgodność wykryta przy indeksowaniu strony schodzi dopiero po tym, jak Google ponownie odwiedzi adresy produktów, a na to nie ma w panelu przycisku „sprawdź teraz” na poziomie pojedynczej oferty. Liczę się z kilkoma dniami i uprzedzam o tym klienta, bo cisza po naprawie nie znaczy, że naprawa nie działa.
Utrzymujące się rozbieżności ceny i dostępności między plikiem danych a sklepem Google traktuje jako wprowadzanie użytkowników w błąd, a przy powtarzalnym problemie sprawa nie kończy się na odrzuceniu ofert — zagrożone jest całe konto. Dlatego komunikat o cenie w diagnostyce zaliczam do tych, którymi zajmuję się tego samego dnia.
Używamy plików cookies, aby ułatwić Ci nawigację oraz wykonywanie określonych funkcji. Szczegółowe informacje o wszystkich plikach cookies znajdziesz w każdej kategorii zgody poniżej.
Pliki cookies oznaczone jako "Niezbędne" są przechowywane w Twojej przeglądarce, ponieważ są one kluczowe dla zapewnienia podstawowych funkcji strony.
Używamy również plików cookies firm trzecich, które pomagają nam analizować, w jaki sposób korzystasz z tej strony, zapamiętują Twoje preferencje oraz dostarczają treści i reklamy odpowiednie dla Ciebie. Te pliki cookies będą przechowywane w Twojej przeglądarce tylko za Twoją uprzednią zgodą.
Możesz zdecydować, czy chcesz włączyć lub wyłączyć niektóre bądź wszystkie te pliki cookies, jednak wyłączenie niektórych z nich może wpłynąć na Twoje doświadczenia podczas przeglądania strony.
| Cookie | Czas przechowywania | Opis |
|---|---|---|
| __cf_bm | 13 minutes | Cloudflare bot management — distinguishes humans from bots. |
| rc::* | Persistent | Google reCAPTCHA — localStorage holding anti-bot challenge state. |
| Cookie | Czas przechowywania | Opis |
|---|---|---|
| wpEmojiSettingsSupports | Session | WordPress — sessionStorage flag caching whether the browser can render emoji (feature detection). |
| ytidb* | Persistent | YouTube — IndexedDB storing playback/search state for embedded videos. |
| Cookie | Czas przechowywania | Opis |
|---|---|---|
| _ga_* | 400 days | Google Analytics 4 — persists session state per property. |
| _ga | 400 days | Google Analytics — distinguishes unique users via a client id. |
| Cookie | Czas przechowywania | Opis |
|---|---|---|
| NID | 183 days | Google — stores preferences for personalized ads. |
| fr | 90 days | Meta — encrypted Facebook id and browser id for ads. |
| _gcl_au | 90 days | Google AdSense/Ads — experiments with advertising efficiency (conversion linker). |
| Cookie | Czas przechowywania | Opis |
|---|---|---|
| __Secure-YNID | 180 days | |
| YSC | Session | |
| __Secure-ROLLOUT_TOKEN | 180 days | |
| VISITOR_INFO1_LIVE | 180 days | |
| VISITOR_PRIVACY_METADATA | 180 days | |
| datr | 400 days | |
| sb | 400 days | |
| wd | 7 days |