Wszystkie wpisy

14 czerwca 2026

Wzbogacanie AddToCart danymi PII w Shopify — Event Match Quality bez logowania

Najmocniejszym sygnałem Event Match Quality w Meta CAPI są dane identyfikujące — e-mail, imię, nazwisko. Kłopot w tym, że na wczesnych etapach lejka po prostu ich nie ma: klient dodaje produkt do koszyka zanim się zaloguje, więc AddToCart leci do Mety bez żadnego PII i z marnym dopasowaniem.

Rozwiązaniem jest wzbogacanie eventów danymi PII z profilu zapisanego wcześniej. Jeśli klient kiedyś kupił i podał dane, jego profil leży w Stape Store pod trwałym identyfikatorem. Na każdym kolejnym zdarzeniu — także bez logowania — można odtworzyć ten profil i dokleić e-mail oraz nazwisko, zanim event poleci do Mety. To wariant dla Shopify: mostem tożsamości jest pierwszorzędne cookie _shopify_y.

Po co to robić: wzbogacanie eventów danymi PII dla powracających

Ważne zastrzeżenie na start, żeby dobrze ustawić oczekiwania: ta technika działa dla użytkowników powracających, którzy już kiedyś kupili i mają zapisany profil. Pierwszy AddToCart zupełnie nowego użytkownika nie ma czego wzbogacić — w magazynie nie ma jeszcze jego danych. To cecha, nie błąd. Zysk pojawia się przy kolejnych wizytach: gdy ten sam człowiek wraca anonimowo, jego wczesne zdarzenia zaczynają nieść PII, choć on sam się nie zalogował.

W pierwszym use case kluczem był stape_user_id (per urządzenie), w drugimuser_id zalogowanego klienta. Tutaj problem jest inny: chcę wzbogacać event niezalogowanego użytkownika, więc user_id odpada (jeszcze go nie ma). Wybór padł na _shopify_y:

IdentyfikatorKiedy dostępnyOgraniczenie
stape_user_idkażde żądanie onlineper żądanie / urządzenie
user_iddopiero po zalogowaniunie pokrywa fazy anonimowej
_shopify_ykażde żądanie, też bez logowaniaper przeglądarka (1st-party cookie)

_shopify_y to trwałe (~roczne) pierwszorzędne cookie, które Shopify ustawia każdemu odwiedzającemu. Jest na każdym żądaniu z tej samej przeglądarki, przeżywa wylogowanie i przerwy między wizytami. To czyni ten wariant najprostszym z trzech — nie potrzeba ani resolucji wielu identyfikatorów (jak w UC2), ani identyfikatora w webhooku. Pod dwoma warunkami: cookie dociera na serwer na obu zdarzeniach, a klucz zapisu i odczytu jest ten sam.

Architektura — dwie fazy, jeden klucz

Mechanizm działa w dwóch momentach: przy zakupie zapisuję profil, a przy AddToCart odtwarzam go i wzbogacam zdarzenie.

PRZY ZAKUPIE — zapis profilu PII
purchase
tag klienta → serwer
Writer
Save PII
📦 Store
user_data pod _shopify_y
PRZY ADDTOCART — odczyt i wzbogacenie
add_to_cart
tag klienta → serwer
Lookup
po _shopify_y
Transformacja
enriched_data
Meta — AddToCart
z e-mailem/nazwiskiem
Profil zapisany przy zakupie zasila każdy późniejszy event. Klucz dokumentu to _shopify_y — ta sama wartość przy zapisie i przy odczycie, bo to trwałe cookie tej samej przeglądarki.
#ElementStronaRola
1cookie _shopify_yklienttrwały identyfikator z Shopify
2tag purchase (X: Data Tag / Y: GA4)klientwysyła shopify + user_data na serwer
2btag add_to_cart (X: Data Tag / Y: GA4)klientwysyła shopify na serwer — klucz do Lookup
3zmienne Event Data shopify, user_dataserwerwyciąga identyfikator i profil ze zdarzenia
4Stape Store Writerserwerzapisuje user_data pod kluczem _shopify_y
5Stape Store Lookupserwerodczytuje user_data po _shopify_y
6Transformacja enriched_dataserwerdokleja profil do zdarzenia
7zmienne Event Data enriched_data.*serwerwyciąga pojedyncze pola PII
8Meta — AddToCartserwerwysyła wzbogacone zdarzenie do CAPI

Dwa warianty transportu danych na serwer

Dane z przeglądarki na serwer możesz przesłać na dwa sposoby. Strona serwerowa (Writer, Lookup, transformacja, Meta) jest wspólna — różnica jest tylko w tym, jak tagi klienckie dostarczają dane.

Wariant X — Data TagWariant Y — tag GA4
TransportOsobny request (Stape Data Tag)Istniejący hit GA4
Klient sGTMData ClientKlient GA4
Trigger Writeradc - purchasega4 - client_name + purchase
user_dataSam definiujesz schemat i polaSurowy schemat GA4 (niehashowany): email, phone_number, address.0.first_name/last_name
Parametr shopifyPole w Event Data taguParametr zdarzenia w tagu GA4
Kiedy wybraćPełna kontrola schematu, wartości surowe spoza GA4Domyślnie — jeden request mniej, natywny klient GA4, wbudowana obsługa zgody

Wariant Y jest rekomendowany dla tego use case: reużywa istniejący hit GA4, nie generuje osobnego requestu do serwera i korzysta z natywnego klienta GA4 z wbudowaną obsługą Consent Mode. Wariant X wybierasz, gdy potrzebujesz pełnej kontroli nad schematem danych lub wartości spoza ekosystemu GA4.

Poniższa konfiguracja krok po kroku opisuje oba warianty tam, gdzie się różnią.

Konfiguracja krok po kroku

Strona klienta (kontener web)

Krok 1 — CDP 1. cookie - shopify

Zmienna „Własny plik cookie” (First-Party Cookie), Nazwa pliku cookie: _shopify_y. To Shopify tworzy to cookie; ja je tylko czytam i przekazuję dalej jako parametr o nazwie shopify.

Krok 2 — tag purchase (tu jest różnica X / Y)

Wariant X — Data Tag na purchase: tag Data Tag (Stape), event Purchase, GTM Server Side URL. W Event Data przekaż parametry ecommerce oraz pole shopify (= {{CDP 1. cookie - shopify}}) i obiekt user_data.

Wariant Y — tagi GA4 (rekomendowany): dane jadą na istniejących hitach GA4. Dwie rzeczy do ustawienia:

  • Na tagu GA4 - purchase dodaj parametr zdarzenia shopify = {{CDP 1. cookie - shopify}}.
  • PII (user_data) ustawiasz nie na evencie purchase, lecz na głównym tagu Google (Tag Google — page_view / konfiguracja) w sekcji „Ustawienia konfiguracji”: parametr user_data = {{3. Dane przekazywane przez użytkowników}} (wbudowana zmienna User-Provided Data). To ustawienie obejmuje wszystkie zdarzenia GA4 — purchase też niesie user_data, bez dodatkowej konfiguracji.

Krok 2b — tag add_to_cart — KRYTYCZNY

To najczęściej pomijany krok, a bez niego cały enrichment nie zadziała. Strona serwera pobiera profil użytkownika po kluczu _shopify_y — ale żeby to zrobić, musi znać wartość cookie na zdarzeniu add_to_cart. Cookie nie trafia do event data samo z siebie; musi je explicite przesłać tag kliencki.

  • Wariant X: osobny Data Tag na event add_to_cart z polem shopify = {{CDP 1. cookie - shopify}}.
  • Wariant Y: tag GA4, event add_to_cart, parametr zdarzenia shopify = {{CDP 1. cookie - shopify}}. user_data tu niepotrzebne — PII i tak pochodzi z magazynu, nie z bieżącego eventu.

Brak tego taga → add_to_cart dociera na serwer bez shopify → Lookup nie ma klucza → enrichment nie zachodzi. Tag Meta odpali się na zielono, ale bez PII. Cicha awaria.

Strona serwera — zapis profilu (przy zakupie)

Krok 3 — CDP 3. shopify i CDP 3. user_data

Dwie zmienne typu „Dane zdarzenia” (Event Data):

  • CDP 3. (Use case 3) shopify → Ścieżka klucza: shopify (wartość cookie = klucz dokumentu w Store).
  • CDP 3. (Use case 3) user_data → Ścieżka klucza: user_data (cały obiekt PII z eventu).

W wariancie Y dane user_datasurowe (niehashowane) — GA4 hashuje je dopiero przy wysyłce do Google, nie w event data. Struktura: email, phone_number, address.0.first_name, address.0.last_name.

Krok 4 — CDP 4. Stape Store Writer - Save PII

Tag Stape Store Writer:

  • Document ID: {{CDP 3. (Use case 3) shopify}} — klucz = wartość cookie.
  • Custom Data: pole user_data = {{CDP 3. (Use case 3) user_data}}.
  • Trigger: wariant X: dc - purchase; wariant Y: ga4 - client_name + purchase.

Strona serwera — odczyt i wzbogacenie (przy AddToCart)

Krok 5 — CDP 5. Stape Store Lookup - user_data

Zmienna Stape Store Lookup: Lookup Type Document ID = {{CDP 3. (Use case 3) shopify}}, Key Path user_data. Ten sam klucz co w Writerze — to warunek powodzenia. Zwraca zapisany obiekt user_data dla bieżącej przeglądarki.

Krok 6 — CDP 6. Transformation - user_data

Przekształcenie „Uzupełnij zdarzenie”: parametr enriched_data = {{CDP 5. Stape Store Lookup - user_data}}, zakres „niektóre tagi” → CDP 8. Wkłada cały odczytany obiekt pod klucz enriched_data w event data bieżącego zdarzenia.

Krok 7 — CDP 7. enriched_data.email i CDP 7. enriched_data.address.0.last_name

Zmienne „Dane zdarzenia” czytające pojedyncze pola z obiektu wstawionego przez transformację:

  • CDP 7. (Use case 3) - enriched_data.email → Ścieżka klucza: enriched_data.email
  • CDP 7. (Use case 3) - enriched_data.address.0.last_name → Ścieżka klucza: enriched_data.address.0.last_name

Czytają z event data, nie odpytują Store — stąd oszczędność (patrz niżej).

Krok 8 — CDP 8. Meta - AddToCart

Tag Facebook Conversion API, event AddToCart (Override, Standard). W sekcji User Data podstaw zmienne z CDP 7 (e-mail, nazwisko…). Event ID do deduplikacji, Test ID do walidacji. Trigger: add_to_cart. Tag FB CAPI sam hashuje pola wymagające hashowania — dane surowe z GA4 zadziałają tu tak samo.

Jeden Lookup, wiele pól — optymalizacja kosztu

Najciekawszy fragment to relacja CDP 5 → 6 → 7, bo każde odpytanie Stape Store kosztuje. Gdybyś dla każdego pola (email, last_name, phone…) robił osobny Lookup z innym Key Path, byłoby to N zapytań na jedno zdarzenie. Zamiast tego:

  1. Jeden Lookup (CDP 5) pobiera cały obiekt user_data.
  2. Transformacja (CDP 6) wkłada go pod enriched_data w event data.
  3. Pola czytasz zmiennymi Event Data (CDP 7) z enriched_data.*lokalnie, bez kolejnych zapytań do Store.

To jest sens rozdzielenia user_data (z magazynu) od enriched_data (w evencie): jeden płatny odczyt z bazy, wiele darmowych odczytów z event data.

Reguła krytyczna: klucz zapisu = klucz odczytu — na obu zdarzeniach

Writer (Document ID) i Lookup (Document ID) muszą używać tego samego _shopify_y. Rozjazd oznacza, że Lookup nic nie znajdzie, a tag i tak odpali się na zielono — bez PII. Cicha awaria.

Haczyk specyficzny dla tego wariantu: _shopify_y musi być w event data zarówno przy zapisie (purchase), jak i przy odczycie (add_to_cart). Cookie samo nie trafia do event data — dostarcza je tag kliencki (Krok 2 i Krok 2b). Jeśli add_to_cart nie niesie shopify, Lookup dostaje pusty klucz i nic nie zwraca.

Najczęstsze błędy

  • Brak taga add_to_cart po stronie klienta (najczęstszy, krytyczny). Krok 2b jest łatwy do pominięcia, bo logicznie wydaje się zbędny — „przecież enrichment robimy po stronie serwera”. Ale serwer potrzebuje klucza do Lookup, a ten klucz musi przyjść z klienta jako parametr zdarzenia. Bez niego Lookup nie ma czego szukać.
  • Klucz zapisu ≠ klucz odczytu. Writer i Lookup muszą używać tej samej zmiennej CDP 3. (Use case 3) shopify. Nawet drobna różnica (np. inna nazwa parametru) = pusty Lookup.
  • Złe ścieżki pól w wariancie Y. Schemat GA4 to enriched_data.email (nie email_address), enriched_data.phone_number, enriched_data.address.0.first_name / address.0.last_name — surowo, niehashowane. Key Path ustaw 1:1 z podglądem w debuggerze, inaczej zmienna zwróci pusto.
  • Tag wstrzymany. Finalny tag Meta musi być aktywny. Wstrzymany („paused”) nie odpali się, mimo poprawnej reszty łańcucha.
  • user_data skonfigurowane na evencie purchase zamiast na Tag Google. W wariancie Y user_data ustawiasz na głównym tagu konfiguracji (Tag Google — page_view), nie na tagu purchase. Tylko wtedy PII jedzie na wszystkich hitach GA4, w tym purchase.

Weryfikacja

  1. Zapis: w preview na purchase sprawdź, że Writer tworzy dokument w Store pod kluczem = wartość _shopify_y i zawiera user_data.
  2. Odczyt: na add_to_cart (tą samą przeglądarką, po wcześniejszym zakupie) potwierdź, że Lookup zwraca user_data, transformacja wkłada enriched_data, a CDP 7 wyciąga pola.
  3. Meta Test Events: sprawdź, że AddToCart dociera z polami User Data.

Prywatność — zanim trafi na produkcję

Zapis user_data (e-mail, imię, nazwisko) do Store i wysyłka PII na AddToCart to utrwalanie i przetwarzanie danych osobowych:

  • Zapis (CDP 4) i wysyłkę PII (CDP 8) warunkuj zgodą marketingową (ad_storage).
  • Ustaw TTL na dokumentach profilowych.
  • Kluczowanie po _shopify_y, a nie po surowym e-mailu, jest pod tym względem czystsze — w nazwie dokumentu nie leży PII.

To trzeci wariant tego samego wzorca (sGTM + magazyn jako mini-CDP). Poprzednie: wzbogacanie page_view e-mailem i przywracanie fbc/fbp dla zakupu offline. Szerszy kontekst — w case study o server-side taggingu.

Powiązane wpisy