Przejdź do treści
codecollab.pl
§ Blog własne pola w checkoucie WooCommerce

Własne pola w checkoucie WooCommerce - jak je dodać, żeby nie zniknęły

Najczęstszy problem z własnym polem w kasie nie polega na tym, że trudno je dodać - tylko na tym, że dodane starym sposobem przestaje istnieć po przejściu na kasę blokową

Krystian Kacik 10 min czytania
Spis treści

Najczęstszy problem z własnym polem w kasie nie polega na tym, że trudno je dodać - tylko na tym, że dodane starym sposobem przestaje istnieć po przejściu na kasę blokową. Sklep działa dalej, zamówienia wpadają, a pole „numer klienta” albo „preferowana godzina dostawy” po prostu znika z formularza. Nikt tego nie zauważa przez tydzień, bo zamówienia przecież chodzą.

To dziś główna pułapka tego tematu i od niej trzeba zacząć, zanim napiszesz jedną linijkę kodu.

Ten tekst jest o stronie technicznej: gdzie się wpina pole, jak je zapisać, gdzie je zobaczyć i kiedy wybrać wtyczkę zamiast kodu. Osobne pytanie, które pola w ogóle powinny zostać w kasie - i dlaczego krótszy formularz sprzedaje lepiej - rozłożyłem w tekście o krótszym checkoucie. Tu zakładam, że tę decyzję masz już za sobą i wiesz, po co Ci to pole.

Najpierw ustal, którą kasę masz

WooCommerce ma dziś dwie równoległe implementacje strony zamówienia i wpinają się do nich zupełnie inne mechanizmy:

  • Klasyczny checkout - strona zbudowana na shortcodzie [woocommerce_checkout]. Formularz renderuje PHP, wszystko modyfikuje się filtrami i akcjami znanymi od lat.
  • Kasa blokowa (Checkout block) - strona zbudowana z bloków w edytorze. Formularz renderuje JavaScript i komunikuje się z serwerem przez Store API. Filtry PHP z klasycznego checkoutu nie działają tu w ogóle.

Sprawdzisz to w pół minuty: otwórz stronę „Zamówienie” w edytorze WordPressa. Widzisz jeden blok shortcode z [woocommerce_checkout] - masz klasyczną. Widzisz zestaw bloków z podglądem formularza - masz blokową.

To rozróżnienie decyduje o całej reszcie. Nowe instalacje WooCommerce dostają dziś kasę blokową domyślnie, ale ogromna część działających sklepów siedzi na klasycznej - bo tak zostało od wdrożenia albo bo któraś wtyczka wymusiła powrót.

Klasyczny checkout: trzy filtry, które wszystko robią

W klasycznej kasie cała struktura formularza siedzi w jednej tablicy, którą przepuszcza filtr woocommerce_checkout_fields. Tablica ma trzy sekcje: billing, shipping i order (tam mieszkają uwagi do zamówienia).

Co się robi tym filtrem:

  • Usuwa pole - wystarczy je z tablicy wykasować (unset).
  • Zmienia etykietę, placeholder, kolejność lub wymagalność - podmieniając klucze label, placeholder, priority, required.
  • Dodaje własne pole - dopisując nowy element do sekcji.

Dwa pokrewne filtry, o których warto wiedzieć:

  • woocommerce_default_address_fields - modyfikuje pola adresowe naraz w rozliczeniu i w wysyłce. Jeśli zmieniasz to samo pole w dwóch miejscach, ten filtr oszczędza połowę roboty.
  • woocommerce_form_field_args - wchodzi jeszcze niżej, na poziom pojedynczego pola przy renderowaniu. Przydaje się, gdy chcesz dołożyć atrybut HTML, na przykład poprawny autocomplete.

Samo dodanie pola to jednak dopiero pierwszy z czterech kroków. Pole, które się wyświetla, ale nie zapisuje, jest gorsze niż jego brak - klient je wypełnia i nic z tego nie wynika.

Cztery kroki, bez których pole jest bezużyteczne

W klasycznej kasie kompletne wdrożenie własnego pola to zawsze te same cztery zaczepy:

  1. Wyświetlenie - filtr woocommerce_checkout_fields, albo akcja woocommerce_before_order_notes / woocommerce_after_order_notes, jeśli chcesz umieścić pole poza sekcjami adresowymi. Do renderowania używa się funkcji woocommerce_form_field(), nie własnego HTML-a - dzięki temu pole wygląda jak reszta formularza i dziedziczy klasy motywu.
  2. Walidacja - akcja woocommerce_checkout_process. Tu sprawdzasz, czy wartość ma sens, i przy błędzie wywołujesz wc_add_notice( '...', 'error' ). Bez tego pole „wymagane” jest wymagane tylko wizualnie.
  3. Zapis do zamówienia - akcja woocommerce_checkout_create_order, w której zapisujesz wartość metodą $order->update_meta_data().
  4. Wyświetlenie tam, gdzie ktoś na to spojrzy - w panelu zamówienia (woocommerce_admin_order_data_after_billing_address) i w mailu do Ciebie oraz do klienta (filtr woocommerce_email_order_meta_fields).

Krok czwarty jest tym, który najczęściej wypada. Pole zapisuje się do bazy, ale nikt go nie widzi, więc po miesiącu ktoś stwierdza, że „to nie działa” - a ono działa, tylko dane leżą w metadanych zamówienia, do których nikt nie zagląda.

Jedna uwaga techniczna, ważna od czasu wprowadzenia nowego sposobu przechowywania zamówień (HPOS): do zapisu i odczytu używaj metod obiektu zamówienia ($order->update_meta_data(), $order->get_meta()), nie starych funkcji update_post_meta() i get_post_meta(). Stare funkcje działają dopóki sklep trzyma zamówienia w tabeli wpisów - i cicho przestają, gdy ktoś przełączy sklep na nowe tabele.

// classic checkout: save a custom field to the order
add_action( 'woocommerce_checkout_create_order', function ( $order ) {
    if ( ! empty( $_POST['delivery_window'] ) ) {
        $order->update_meta_data(
            '_delivery_window',
            sanitize_text_field( wp_unslash( $_POST['delivery_window'] ) )
        );
    }
}, 10, 1 );

Kasa blokowa: osobne API, inne reguły

W kasie blokowej pola rejestruje się jedną funkcją: woocommerce_register_additional_checkout_field(). Podajesz identyfikator z własną przestrzenią nazw (format moja-wtyczka/nazwa-pola), etykietę, typ i lokalizację.

Trzy rzeczy, które trzeba wiedzieć, zanim zaczniesz:

  • Typy pól są ograniczone. Do dyspozycji masz tekst, listę wyboru i pole wyboru tak/nie. To celowe zawężenie - kasa blokowa pilnuje spójnego wyglądu i dostępności, więc nie wstawisz tam dowolnego HTML-a.
  • Lokalizacje są trzy i to one decydują, gdzie pole się pojawi i jak się zachowa: dane kontaktowe, adres (wtedy pole pojawia się w rozliczeniu i w wysyłce, a wartość zapisuje się przy adresie klienta) oraz sekcja zamówienia.
  • Zapis dzieje się sam. Nie piszesz nic do zapisywania danych - WooCommerce zapisuje je do zamówienia i do profilu klienta, a w panelu i w mailu pokazuje je bez dodatkowego kodu. To duża różnica wobec klasycznej kasy, gdzie te dwa kroki robisz ręcznie.

Walidację podpina się osobnymi filtrami: jeden sprawdza pojedyncze pole, drugi pozwala sprawdzić całą grupę pól w danej lokalizacji naraz (na przykład zależność jednego pola od drugiego).

Wniosek praktyczny: kodu jest mniej, ale jest zupełnie inny. Snippet ze starego bloga, wklejony do sklepu na kasie blokowej, nie wyrzuci błędu - po prostu nic nie zrobi. To dokładnie ten scenariusz, w którym pole „znika po aktualizacji”.

Pola warunkowe: firma czy osoba prywatna

Najczęstsze realne wymaganie po dodaniu pola brzmi: „ma się pokazywać tylko wtedy, gdy…”. Zwykle chodzi o NIP widoczny po zaznaczeniu „chcę fakturę na firmę”.

Tu trzeba rozdzielić dwie rzeczy:

  • Ukrycie i pokazanie pola to praca po stronie przeglądarki. W klasycznej kasie robi się to JavaScriptem, który reaguje na zmianę pola sterującego. W kasie blokowej pola warunkowe obsługuje się przez logikę widoczności w rejestracji pola.
  • Walidacja musi być po stronie serwera, zawsze. Ukrycie pola w przeglądarce niczego nie wymusza - kto chce, wyśle formularz bez niego. Regułę „jeśli zaznaczono firmę, NIP jest wymagany” wpisz w walidację po stronie PHP, niezależnie od tego, co robi JavaScript.

Sam NIP i faktury to osobny temat, mocno związany z fakturowaniem i KSeF - opisałem go w tekście o integracji WooCommerce z ERP i fakturowaniem.

Wtyczka czy kod

Uczciwa odpowiedź: zależy od tego, co potem robisz z tymi danymi.

Wtyczka do edycji pól (klasy „Checkout Field Editor”) ma sens, gdy:

  • potrzebujesz kilku prostych pól tekstowych albo list wyboru,
  • nikt w firmie nie będzie utrzymywał kodu,
  • dane mają trafić tylko do panelu i do maila, bez dalszej obróbki.

Kosztuje kilkadziesiąt do kilkuset złotych rocznie i oszczędza dzień pracy. Sprawdź przed zakupem jedną rzecz: czy wtyczka obsługuje kasę blokową. Sporo popularnych wtyczek z tej kategorii przez długi czas działało wyłącznie w klasycznej i to nadal bywa aktualne.

Kod w motywie potomnym albo we własnej małej wtyczce wygrywa, gdy:

  • pole ma warunkową logikę albo walidację inną niż „wymagane”,
  • wartość ma iść dalej - do ERP, do przewoźnika, do systemu fakturowania,
  • chcesz mieć pewność, co dzieje się po aktualizacji, i móc to przeczytać.

Jedna zasada bez wyjątku: nigdy w plikach motywu nadrzędnego ani w functions.php gotowego motywu. Pierwsza aktualizacja motywu skasuje wszystko. Motyw potomny albo osobna wtyczka - i tyle.

Czego nie robić

Cztery błędy, które kosztują najwięcej i widzę je regularnie:

  • Wstawianie surowego HTML-a zamiast woocommerce_form_field(). Pole wygląda inaczej niż reszta formularza, gubi obsługę błędów, a na kasie blokowej nie zadziała w ogóle.
  • Brak sanityzacji przy zapisie. Wartość z formularza to dane od użytkownika, nie od Ciebie. Zawsze przez sanitize_text_field() albo odpowiednik dla danego typu.
  • Dokładanie pól, bo „przyda się kiedyś”. Każde pole to sekundy i wątpliwości po stronie klienta. Pole, którego nikt nie czyta w firmie, powinno wypaść - dlaczego to boli w liczbach, pokazuję przy porzuconych koszykach z powodów technicznych.
  • Testowanie na produkcji. Zmiany w kasie trafiają dokładnie w ten moment, w którym klient wpisuje dane karty. Kopia sklepu, test tam, potem wdrożenie - i zawsze kopia zapasowa przed zmianą.

Jak to przetestować, zanim wypuścisz

Cztery testy, po kolei, i dopiero po czwartym uznaję temat za zamknięty:

  1. Złóż zamówienie z wypełnionym polem i sprawdź, czy wartość jest w panelu zamówienia oraz w mailu do Ciebie i do klienta.
  2. Złóż zamówienie z pustym polem, żeby sprawdzić, czy walidacja rzeczywiście blokuje wysłanie i czy komunikat błędu jest po polsku i przy właściwym polu.
  3. Sprawdź na telefonie. Większość zamówień idzie z komórki, a własne pola potrafią rozjechać układ formularza albo wywołać złą klawiaturę (numeryczna dla numeru, e-mailowa dla adresu).
  4. Sprawdź po zmianie metody dostawy. Kasa przeładowuje część formularza AJAX-em przy każdej zmianie wysyłki - to najczęstszy moment, w którym własne pole gubi wpisaną wartość albo znika.

Do tego jedna rzecz, o której łatwo zapomnieć: jeśli pole ma trafiać do przewoźnika albo do faktury, przetestuj cały łańcuch, a nie samo pole. Wartość zapisana w zamówieniu, której integracja nie odczytuje, to nadal połowa roboty. Jak wyglądają te przepływy w praktyce, rozłożyłem przy integracjach wysyłkowych.

Najczęstsze pytania

Dlaczego moje pole zniknęło z kasy po aktualizacji? Prawie zawsze dlatego, że sklep przeszedł na kasę blokową. Pola dodane filtrem woocommerce_checkout_fields działają wyłącznie w klasycznym checkoucie i w kasie blokowej po prostu się nie renderują, bez żadnego błędu. Sprawdź stronę zamówienia w edytorze - jeśli widzisz bloki zamiast shortcode’u, to jest ta przyczyna. Masz wtedy dwie drogi: przepisać pole na nowe API albo tymczasowo wrócić do klasycznej kasy shortcodem.

Czy da się dodać pole tylko dla wybranych produktów albo kategorii? Da się, ale to zawsze kod, nie wtyczka. Warunek sprawdzasz na zawartości koszyka i na tej podstawie rejestrujesz albo pomijasz pole. Uwaga na przypadek mieszany: klient ma w koszyku produkt wymagający pola i produkt, który go nie wymaga - trzeba z góry zdecydować, co wtedy.

Gdzie zapisują się dane z własnych pól? W metadanych zamówienia. Przy klasycznej kasie pod kluczem, który sam ustawisz; przy kasie blokowej pod kluczem generowanym z lokalizacji i przestrzeni nazw pola. Praktyczna konsekwencja: te dane nie znajdą się automatycznie w eksporcie do CSV, w integracji z ERP ani na fakturze. Wszędzie tam trzeba je świadomie zmapować.

Czy własne pola spowalniają kasę? Same pola nie. Spowalnia to, co się do nich dokłada: zewnętrzne biblioteki JavaScript do walidacji, zapytania do API przy każdym wpisanym znaku, wtyczki ładujące własny CSS na całym sklepie. Trzy pola dodane porządnie nie robią różnicy w pomiarze; jedna ciężka wtyczka do budowania formularzy robi.

Czy mogę usunąć pole wymagane przez WooCommerce, na przykład kraj? Technicznie tak, ale zwykle nie powinieneś. Kraj i kod pocztowy sterują wyliczaniem podatku i kosztów wysyłki - po ich usunięciu WooCommerce liczy stawki dla domyślnej lokalizacji sklepu, co przy sprzedaży za granicę daje błędne kwoty. Jeśli sprzedajesz tylko w Polsce, sensowniejsze jest ustawienie jednego dozwolonego kraju w ustawieniach niż wycinanie pola z formularza.


Masz sklep, w którym coś nie działa tak, jak powinno? Buduję i przebudowuję sklepy internetowe na WooCommerce - od pojedynczej naprawy po przebudowę całej sprzedaży. Opisz, z czym się mierzysz, a odeślę wycenę z zakresem i terminem.

§ Porozmawiajmy o projekcie

Twój sklep zwalnia albo wygląda staro, a nie wiesz, od czego zacząć?

Opisz zakres w dwóch zdaniach albo podeślij link do sklepu. Wskażę, co poprawić najszybciej, a wycenę dostajesz na piśmie - bez „od X zł".

Porozmawiajmy o projekcie