Przejdź do głównej zawartości

Konfiguracja

Ustawienia trzymane są w jednej opcji withdraw_settings. Ekran ustawień to WooCommerce > Withdrawal i wymaga uprawnienia manage_woocommerce, tak samo jak rejestr wniosków.

Ustawienie Klucz Domyślnie Co robi
Withdrawal period (days) period_days 14 Długość okresu odstąpienia w dniach. Przy zapisie wartość jest przycinana do zakresu od 1 do 365.
Withdrawal form page form_page_id brak Strona z shortcodem [withdraw_form]. Dopóki nie jest wskazana, przycisk odstąpienia przy zamówieniu się nie renderuje.
Eligible order statuses eligible_statuses completed, processing Statusy zamówień, dla których wniosek jest przyjmowany. Lista pól wyboru budowana jest z wc_get_order_statuses(), więc obejmuje też statusy własne. Zapis bez zaznaczonego statusu wraca do dwóch wartości domyślnych.
Link text link_text puste Etykieta każdego elementu otwierającego formularz: przycisku w widoku zamówienia, shortcode’u [withdraw_link] i linku w stopce. Puste pole daje ustawowe „withdraw from contract here”, tłumaczone razem z resztą wtyczki. Art. 11a ust. 1 dopuszcza jednoznaczny odpowiednik, więc pole nie jest zablokowane. Przed 1.6.2 przycisk w widoku zamówienia je ignorował.
Notification email notify_email puste Adres powiadomień o nowych wnioskach. Puste pole oznacza adres administratora witryny.
Form intro text intro_text puste Akapit nad pierwszym krokiem formularza. Puste pole oznacza wbudowany, tłumaczony tekst wtyczki.
Model withdrawal text model_form_text puste Wzór oświadczenia pokazywany w kroku wyboru pozycji. Puste pole oznacza wzór generowany z danych sprzedawcy poniżej.
Seller name seller_name puste Nazwa firmy używana w generowanych tekstach. Puste pole oznacza tytuł witryny.
Seller email seller_email puste Puste pole oznacza adres administratora witryny.
Seller phone seller_phone puste Opcjonalny. Załącznik I prosi o numer telefonu, jeśli sprzedawca go ma.

Nad tabelą ustawień wtyczka pokazuje liczbę wniosków w każdym z czterech statusów oraz link do rejestru. Przy każdym polu jest podpowiedź pod znakiem zapytania, dostępna także z klawiatury.

Muszą być spełnione wszystkie warunki:

  1. Zamówienie o podanym numerze istnieje, a podany e-mail zgadza się z adresem rozliczeniowym zamówienia (bez rozróżniania wielkości liter).
  2. Status zamówienia jest na liście dozwolonych statusów.
  3. Okres odstąpienia jeszcze się nie skończył.
  4. Dla tego zamówienia nie ma otwartego wniosku, czyli takiego ze statusem pending lub accepted.

Każdy niespełniony warunek daje konkretny komunikat na formularzu, na przykład „The withdrawal period for this order has ended.” Warunki sprawdzane są dwa razy: przed pokazaniem pozycji i jeszcze raz przy zapisie, więc formularz przetrzymany w przeglądarce albo zmodyfikowany po stronie klienta nie ominie żadnej reguły. Oba kroki chroni nonce, a jego brak lub wygaśnięcie cofa klienta do wyszukiwania zamówienia z komunikatem błędu.

Termin liczony jest tak:

  • początek, data oznaczenia zamówienia jako zrealizowane; jeśli zamówienie nigdy nie zostało zrealizowane, data jego złożenia,
  • długość, wartość period_days pomnożona przez dobę,
  • koniec, suma powyższych; po tej chwili formularz odmawia przyjęcia wniosku.

Wyliczona data końcowa jest pokazywana klientowi w kroku wyboru pozycji, w formacie daty ustawionym w witrynie.

Warto to skonfrontować z własnym procesem. Ustawa o prawach konsumenta liczy termin od objęcia rzeczy w posiadanie przez konsumenta, a wtyczka używa daty zrealizowania zamówienia jako przybliżenia dostawy. Jeśli sklep oznacza zamówienia jako zrealizowane w chwili nadania, realny termin klienta jest dłuższy niż ten wyliczony, więc odpowiednio zwiększ liczbę dni.

Shortcode nie przyjmuje atrybutów i obsługuje cztery stany, wybierane na podstawie przesłanego kroku:

  1. Wyszukanie zamówienia, pola numeru zamówienia i e-maila rozliczeniowego. Parametr wd_order w adresie URL wypełnia numer zamówienia (korzysta z tego przycisk przy zamówieniu), pole e-maila zawsze zostaje puste.
  2. Wybór pozycji, tabela pozycji zamówienia z polem ilości przy każdej, ograniczonym do liczby zamówionych sztuk, opcjonalne pole uzasadnienia, data końca terminu, wzór formularza odstąpienia i pole oświadczenia. Trzeba wskazać co najmniej jedną sztukę.
  3. Potwierdzenie, ekran z numerem wniosku, numerem zamówienia i listą pozycji objętych oświadczeniem.

Arkusz stylów i skrypt frontu ładują się wyłącznie na stronie, na której shortcode faktycznie coś wyrenderował. Skrypt pełni jedną funkcję: nie pozwala wysłać formularza z samymi zerami w polach ilości. Ta sama reguła obowiązuje po stronie serwera, więc formularz działa też z wyłączonym JavaScriptem.

Pod tabelą szczegółów zamówienia wtyczka dokłada przycisk „Withdraw from contract here” (po polsku „Odstąp od umowy tutaj”) prowadzący na stronę formularza z wypełnionym numerem zamówienia. Brzmienie narzuca art. 11a ust. 1 i można je zmienić tylko na równie jednoznaczne. Przycisk pojawia się tylko wtedy, gdy strona formularza jest wskazana w ustawieniach, a zamówienie ma jeden z dozwolonych statusów, więc sam nie wystarcza do wymaganej stałej dostępności: do tego służy shortcode [withdraw_link] albo odnośnik w stopce.

Dwie rzeczy warte odnotowania. Po pierwsze, przycisk korzysta z szablonowego haka szczegółów zamówienia WooCommerce, więc widać go zarówno w Moim koncie, jak i na stronie potwierdzenia zamówienia zaraz po zakupie. Po drugie, sprawdzany jest sam status zamówienia, a nie termin ani otwarty wniosek, więc klient może kliknąć przycisk i dopiero na formularzu zobaczyć komunikat o zakończonym terminie albo o wniosku w toku.

WooCommerce > Withdrawal Requests pokazuje wnioski po 25 na stronę w kolumnach: numer wniosku, zamówienie z odnośnikiem do edycji, e-mail klienta, pozycje z ilościami, data, termin zwrotu pieniędzy i status. Nad listą jest filtr statusów z licznikami oraz wyszukiwarka po adresie e-mail i numerze zamówienia, działająca razem z filtrem. Zapamiętany numer strony, której już nie ma, otwiera ostatnią stronę zamiast pustej tabeli. Do wersji 1.5.0 lista kończyła się na stu najnowszych wnioskach i starszych nie dało się otworzyć w kokpicie.

Numer wniosku otwiera ekran szczegółów: uzasadnienie podane przez klienta, treść zatwierdzonego oświadczenia, obie daty, pozycje i termin zwrotu pieniędzy. Tokenu dostępu ten ekran celowo nie pokazuje, bo jest poświadczeniem, a nie zapisem sprawy.

Statusy są cztery i tylko one są przyjmowane przy zapisie: pending (oczekujący), accepted (zaakceptowany), rejected (odrzucony), processed (obsłużony). Nowy wniosek zawsze zaczyna jako pending. Status zmienia się w wierszu listą rozwijaną i przyciskiem zapisu; operacja wymaga uprawnienia manage_woocommerce i poprawnego nonce’a, po zapisie strona wraca z komunikatem o powodzeniu.

Obok wyboru statusu jest pole notatki. Przy odrzuceniu jest wymagane, a jego treść trafia do wiadomości wysyłanej klientowi, przy każdym statusie. Odrzucenie mówiące tylko „wniosku nie można było przyjąć” nie daje klientowi niczego, na czym mógłby się oprzeć, a sklepowi nie zostawia zapisu, dlaczego odmówił, i to jest ta połowa, która liczy się, gdy decyzja zostanie zakwestionowana.

Ponowny zapis tego samego statusu bez przepisywania notatki zachowuje zapisaną, a sama edycja notatki nie wysyła klientowi drugiej wiadomości.

Rejestr nie dotyka płatności. Zwrot środków wykonujesz na ekranie zamówienia w WooCommerce, a status wniosku ustawiasz tutaj, żeby zamknąć sprawę w rejestrze. Zmiana statusu dopisuje notatkę do zamówienia i wysyła klientowi wiadomość odpowiadającą nowemu statusowi.

Od wersji 1.4.0 każda wiadomość jest e-mailem WooCommerce: korzysta z szablonu sklepu, logo i stopki, a każda ma własną sekcję w WooCommerce > Ustawienia > E-maile, więc można ją przeredagować, przestylować albo wyłączyć osobno. Szablony da się nadpisać z motywu w yourtheme/woocommerce/emails/.

Wiadomość Sekcja Kiedy wychodzi
Withdrawal declaration received withdraw_acknowledgement Po zapisaniu oświadczenia. Do klienta.
New withdrawal request withdraw_new_request Po zapisaniu oświadczenia. Do sklepu.
Withdrawal accepted withdraw_accepted Po ustawieniu statusu accepted.
Withdrawal rejected withdraw_rejected Po ustawieniu rejected.
Withdrawal processed withdraw_processed Po ustawieniu processed.
Withdrawal under review withdraw_under_review Po cofnięciu wniosku do pending.
Withdrawal access link withdraw_access_link Gdy gość prosi o jednorazowy link, i tylko przy włączonym dostępie dla gości.

Trzy rzeczy warte zapamiętania:

  • Powiadomienie do sklepu ma własne pole odbiorcy. Puste oznacza adres z pola Notification email na ekranie Withdrawal, a w dalszej kolejności adres administratora. Sklep, który nigdy nie otworzy ekranu e-maili, dostaje pocztę dokładnie tam, gdzie dotąd.
  • Potwierdzenie cytuje zapisane oświadczenie. Treść, którą klient zatwierdził, trafia do wiersza wniosku i stamtąd jest odczytywana, więc późniejsze tłumaczenie, zmiana nazwy produktu ani edycja szablonu nie zmienią tego, co powiedziano wcześniejszemu klientowi. Wiadomość podaje też datę i godzinę złożenia, czego wymaga art. 11a ust. 4.
  • E-mail z linkiem nie przeżyje swojej funkcji. Zgłasza się jako wyłączony zawsze, gdy Guest access jest wyłączony, więc jedynym przełącznikiem pozostaje ustawienie wtyczki. Przy włączonym dostępie dla gości i wyłączonej wiadomości gość nie odstąpi w ogóle.

Trzy proste wiadomości statusowe dzielą jedną parę szablonów, withdraw-status.php i plain/withdraw-status.php, więc nadpisanie tego pliku w motywie zmienia wszystkie trzy. Akceptacja ma własny, bo jako jedyna niesie informacje o zwrocie.

Informacje o zwrocie i własny termin na oddanie pieniędzy

Dział zatytułowany „Informacje o zwrocie i własny termin na oddanie pieniędzy”

Wiadomość o akceptacji niesie informacje z art. 14 ust. 1, ustawiane w sekcji Returns na ekranie Withdrawal:

Ustawienie Klucz Domyślnie Co robi
Return address return_address puste Dokąd wracają towary. Puste pole korzysta z adresu sklepu z WooCommerce, a gdy i on jest pusty, wiadomość nie mówi nic, zamiast drukować pustą ramkę.
Who pays to send the goods back return_cost not_stated not_stated, customer albo shop. Każda inna wartość jest odrzucana przy zapisie.
Return cost, extra wording return_cost_note puste Dopisywane po zdaniu o koszcie.

return_cost domyślnie nic nie mówi i jest to celowe. Art. 14 ust. 1 w związku z art. 6 ust. 1 lit. i pozwala obciążyć konsumenta bezpośrednim kosztem zwrotu tylko wtedy, gdy został o tym poinformowany przed zawarciem umowy. Jeśli nie był, koszt ponosi sprzedawca, więc domyślne „płaci klient” kazałoby wtyczce twierdzić w imieniu sklepu coś, do czego sklep może nie mieć prawa.

Termin odesłania podawany klientowi to 14 dni od dnia złożenia oświadczenia, a nie od dnia akceptacji. Sklep, który akceptował po tygodniu, dawał wcześniej klientowi tydzień więcej, niż wynika z przepisów.

Własny zegar sklepu działa tak samo. Art. 13 ust. 1 daje 14 dni od otrzymania oświadczenia na zwrot płatności, łącznie z kosztem zwykłej dostawy zapłaconym przez klienta, a rejestr wniosków pokazuje tę datę i zaznacza ją na czerwono po terminie. Znika po ustawieniu wniosku na processed albo rejected. Przy towarach art. 13 ust. 3 pozwala wstrzymać zwrot do chwili otrzymania rzeczy albo dowodu jej odesłania.

Do wersji 1.5.0 wstęp do formularza i wzór oświadczenia były angielskimi zdaniami zapisanymi w pliku konfiguracyjnym i pokazywanymi klientowi dosłownie, razem z miejscem do uzupełnienia. Tekstu z pliku konfiguracyjnego nie da się przetłumaczyć, więc polski sklep pokazywał angielski, dopóki ktoś tego nie przepisał ręcznie. Oba są teraz generowane i tłumaczone razem z resztą wtyczki.

  • Załącznik I lit. B, wzór formularza odstąpienia, pokazuje się w kroku wyboru pozycji. Powstaje z nazwy sprzedawcy, adresu sklepu z WooCommerce, adresu e-mail i telefonu, z tytułem witryny i adresem administratora jako wartościami zapasowymi, więc wzór zawsze kogoś wskazuje. Wpisz własne brzmienie w Model withdrawal text, a użyte będzie Twoje.
  • Załącznik I lit. A, wzór pouczenia o odstąpieniu, renderuje shortcode [withdraw_instructions]. Art. 6 ust. 1 lit. h czyni z niego informację przedumowną, więc jego miejsce jest na stronie regulaminu albo zwrotów, a nie na samym formularzu. Podaje ustawiony period_days, a nie zaszyte 14 dni, więc nie rozjedzie się z tym, co formularz naprawdę egzekwuje.
[withdraw_instructions]
[withdraw_instructions heading="no" form="no"]

heading="no" usuwa nagłówek, gdy strona ma już własny. form="no" usuwa wzór formularza drukowany pod pouczeniem.

Zdanie o koszcie zwrotu trafia do pouczenia dopiero po ustawieniu reguły w sekcji Returns. To zdanie jest właśnie tym pouczeniem z art. 6 ust. 1 lit. i, na które sprzedawca powołuje się później, obciążając konsumenta kosztem, więc generowanie go domyślnie oznaczałoby, że wtyczka sama wytwarza podstawę, z której sklep korzysta.

Każdy akapit przechodzi przez filtr withdraw/model_instructions, i tam sklep dokłada brzmienie dla umów o świadczenie usług albo treści cyfrowych, którego wymaga jego własny asortyment:

add_filter( 'withdraw/model_instructions', function ( array $parts ): array {
$parts[] = 'Jeżeli zażądałeś rozpoczęcia świadczenia usług przed upływem terminu do odstąpienia, zapłacisz nam kwotę proporcjonalną do zakresu świadczeń spełnionych do chwili odstąpienia.';
return $parts;
} );

Przy aktualizacji wstęp albo wzór pozostawiony co do znaku w postaci, w jakiej przyszedł z wtyczką, jest czyszczony, żeby zadziałał tekst generowany. Wszystko, co zostało zmienione, w tym ręczne tłumaczenie, jest porównywane dokładnie i zachowane.

Withdraw podłącza się do narzędzi prywatności WordPressa:

  • eksport, pozycja „Withdrawal Declarations” zwraca dla podanego adresu e-mail numer zamówienia, status, uzasadnienie i datę każdego wniosku, stronami po 100 rekordów,
  • usuwanie, żądanie usunięcia danych anonimizuje wnioski danego adresu: e-mail zastępowany jest wartością [email protected], uzasadnienie jest czyszczone, a sam wiersz i powiązanie z zamówieniem zostają, bo są potrzebne do rozliczeń i dokumentacji.

Wtyczka zakłada jedną tabelę {prefix}withdraw_requests (identyfikator zamówienia, e-mail klienta, token, lista pozycji w formacie JSON, uzasadnienie, status, znaczniki czasu) oraz dwie opcje: withdraw_settings i withdraw_schema_version. Schemat powstaje przy aktywacji i dodatkowo naprawia się przy starcie wtyczki na każdej witrynie, co ma znaczenie w sieci multisite, gdzie aktywacja wykonuje się tylko na witrynie głównej.

Odinstalowanie usuwa obie opcje i całą tabelę wniosków wraz z zawartością. W sieci multisite usuwana jest tabela bieżącej witryny, więc tabele pozostałych witryn trzeba posprzątać osobno. Przed odinstalowaniem zrób kopię danych, których potrzebujesz do dokumentacji.

Pakiet zawiera wyłącznie wzorzec tłumaczeń .pot, bez plików .po i .mo. Do czasu zainstalowania tłumaczenia etykiety interfejsu, w tym napis na przycisku odstąpienia, wyświetlają się po angielsku.

Po zarejestrowaniu wszystkich funkcji wtyczka wywołuje akcję withdraw/booted z instancją klasy głównej. To jest przewidziany punkt wejścia dla dodatków.