Bramka pobrała pieniądze, a zamówienie po godzinie ląduje w anulowanych. Cztery prawdziwe przypadki z naszego serwisu: Paynow po migracji, ERP nadpisujący statusy, PayU zablokowany przez Cloudflare i bramka psująca się co 60 dni.
Marcin Ledwolorz
CEO, APTURN
Najgorsze awarie sklepu to nie te, po których strona leży. Jak sklep nie działa, ktoś to zauważy w ciągu kwadransa. Gorzej, kiedy działa prawie wszystko: klient płaci, bramka pobiera pieniądze, a w panelu zamówienie po godzinie ląduje w „Anulowanych”. Nikt nie pakuje paczki. Klient czeka, potem pisze, a jeśli nie pisze, wystawia opinię.
W ostatnich miesiącach naprawialiśmy cztery takie przypadki w różnych sklepach. Za każdym razem przyczyna była inna, a objaw prawie ten sam. Opisujemy je, bo żadnej z tych przyczyn nie widać w panelu WooCommerce.
Skąd się bierze „60 minut”
Najpierw mechanizm, bo bez niego trudno zrozumieć resztę. WooCommerce ma ustawienie „Wstrzymaj stan magazynowy (minuty)” w WooCommerce → Ustawienia → Produkty → Magazyn. Domyślnie to 60 minut. Jeśli przez ten czas zamówienie nie dostanie potwierdzenia płatności, WooCommerce uznaje je za porzucone i anuluje, żeby zwolnić towar.
Potwierdzenie płatności nie przychodzi z przeglądarki klienta, tylko z serwera bramki. Paynow, PayU, Przelewy24 czy Stripe wysyłają do sklepu powiadomienie w tle (IPN, webhook, notyfikacja). Jeśli to powiadomienie nie dojdzie albo sklep je odrzuci, zamówienie po godzinie się anuluje, choć pieniądze dawno są na koncie.
Pierwsze pytanie przy każdym takim zgłoszeniu
Czy powiadomienie od bramki w ogóle dotarło do sklepu i co sklep z nim zrobił?
Przypadek 1: brak klucza podpisu po przeniesieniu sklepu (Paynow)
Objaw: po przeprowadzce sklepu na nowy serwer przez trzy dni każde zamówienie opłacone przez Paynow anulowało się po godzinie. Płatności w panelu Paynow miały status potwierdzonych.
Przyczyna: wtyczka Paynow podpisuje powiadomienia kluczem i sprawdza ten podpis po stronie sklepu. Po migracji w głównej konfiguracji wtyczki zabrakło klucza podpisu. Sklep dostawał każde powiadomienie, ale nie mógł go zweryfikować, więc je odrzucał. Z zewnątrz wyglądało to tak, jakby Paynow nic nie wysyłał.
Naprawa: uzupełnienie klucza i ręczne przywrócenie dziesięciu zamówień. Ręcznie, ale nie na ślepo: status każdego sprawdziliśmy w API Paynow, a „w trakcie realizacji” wróciły tylko te, które miały tam status CONFIRMED.
Wniosek: po każdej migracji trzeba zrobić jedną prawdziwą płatność testową i poczekać, aż zamówienie samo zmieni status. To, że strona się otwiera, a koszyk działa, niczego tu nie sprawdza.
Przypadek 2: to nie sklep anulował, tylko ERP
Objaw: w tym samym sklepie, kilka godzin po naprawie, trzy z przywróconych zamówień znowu zmieniły status na anulowane. Klient zapytał więc, dlaczego API je co chwilę anuluje.
Przyczyna: notatki zamówienia mówiły tylko tyle, że status się zmienił. Odpowiedź znaleźliśmy dopiero w logach serwera. Co do sekundy z każdą zmianą zgadzało się żądanie PUT /wp-json/wc/v3/orders/… z zewnętrznego systemu ERP, podpisane jednym z kluczy API sklepu. ERP pobrał zamówienia wtedy, kiedy faktycznie były anulowane, a po ich przywróceniu odesłał do sklepu swój nieaktualny stan i nadpisał poprawny.
Naprawa: poprawka statusów po stronie ERP i diagnoza, dlaczego wysłał stary stan. Zaproponowaliśmy też bezpiecznik w sklepie: zamówienia z potwierdzoną płatnością nie da się anulować przez API, tylko ręcznie z panelu.
Wniosek: jeśli sklep jest zintegrowany z ERP, systemem magazynowym albo marketplace’em, „sklep anuluje zamówienia” bardzo często znaczy „coś z zewnątrz zapisuje do sklepu”. Sprawdzenie, który klucz API i z jakiego adresu zmienił zamówienie, zajmuje kilka minut, jeśli ma się dostęp do logów serwera.
Przypadek 3: Cloudflare blokował PayU przez sześć dni
Objaw: po przeniesieniu domeny na nowe konto Cloudflare opłacone zamówienia z PayU anulowały się po 60 minutach. Strona działała, koszyk działał, PayU pobierał pieniądze.
Przyczyna: nowa strefa w Cloudflare startuje z domyślnymi ustawieniami, w tym z włączonym Browser Integrity Check. Ta funkcja odrzuca żądania, które nie wyglądają na pochodzące z normalnej przeglądarki. Powiadomienia PayU wychodzą z serwerów PayU i przedstawiają się jako biblioteka HTTP Javy, więc dla Cloudflare wyglądały jak bot. Odpowiedź 403 dostawał PayU, nie sklep, więc w logach WordPressa nie było żadnego śladu.
Naprawa: reguła w Cloudflare, która pomija tę kontrolę wyłącznie dla sieci PayU (po numerze ASN) i wyłącznie dla adresu powiadomień. Cała reszta strony zostaje chroniona tak jak wcześniej.
Wniosek: przeniesienie strefy Cloudflare to zmiana w płatnościach, nawet jeśli nikt nie dotykał wtyczek. Po zmianie nameserverów trzeba zajrzeć do Security → Events i przefiltrować zdarzenia po adresie powiadomień (np. wc-api) albo sieci bramki.
Przypadek 4: płatność padała co dwa miesiące i za każdym razem „naprawiało” ją wpisanie danych od nowa
Ten przypadek jest trochę inny, bo tu płatność w ogóle nie dochodziła do skutku. Pasuje jednak do reszty, bo też nic nie było widać.
Objaw: metoda płatności była widoczna przy zamówieniu, ale każda próba płatności kończyła się błędem. Wpisanie danych dostępowych bramki od nowa naprawiało sprawę. Problem wracał mniej więcej co 60 dni i wcześniej zgłaszano go już trzy razy.
Przyczyna: wtyczka bramki szyfruje swój sekret kluczami bezpieczeństwa WordPressa, czyli solami z wp-config.php. Wtyczka bezpieczeństwa WP Defender ma funkcję automatycznej zmiany tych kluczy, domyślnie co 60 dni. Każda zmiana sprawiała, że wtyczka płatności nie mogła odszyfrować swojego sekretu. Poprzednie „naprawy” leczyły objaw, a licznik odmierzał czas do następnej awarii.
Naprawa: wyłączenie automatycznej rotacji kluczy i usunięcie zaplanowanego zadania. Teraz klucze zmieniamy świadomie, a zaraz po zmianie wpisujemy na nowo sekrety wtyczek, które z nich korzystają.
Wniosek: ustawienia „dla bezpieczeństwa” mają skutki uboczne. Przed włączeniem rotacji kluczy trzeba sprawdzić, które wtyczki szyfrują nimi swoje dane. Zwykle robią to bramki płatności i wtyczki SMTP.
Jak to sprawdzić u siebie w 15 minut
Jeśli w sklepie zdarzają się zamówienia anulowane mimo płatności:
- Porównaj godziny. Kiedy bramka potwierdziła płatność, a kiedy zamówienie zmieniło status? Anulowanie dokładnie 60 minut po złożeniu zamówienia to prawie zawsze niedostarczone albo odrzucone powiadomienie.
- Sprawdź w panelu bramki, co odpowiedział sklep. Większość bramek pozwala podejrzeć historię powiadomień albo przynajmniej ponowić wysyłkę. Kod 403 zwykle oznacza firewall albo Cloudflare, kod 400 albo 401 problem z podpisem lub kluczem.
- Poszukaj w logach serwera żądań do adresu powiadomień. Jeśli bramka twierdzi, że wysłała, a w logu serwera nic nie ma, zatrzymało je coś przed serwerem.
- Jeśli status zmienił się „sam” w innym momencie, poszukaj w logach żądań PUT albo POST do /wp-json/wc/v3/orders/ z tej samej sekundy. Klucz API pokaże, który system to zrobił.
- Po każdej migracji, zmianie DNS albo nowej wtyczce bezpieczeństwa zrób jedną prawdziwą płatność za kilka złotych i poczekaj godzinę.
Dlaczego o tym piszemy
Każdy z tych sklepów miał sprawny hosting, aktualne wtyczki i kopie zapasowe. To nie wystarczyło, bo żadna z tych awarii nie wyświetla błędu na stronie. Coś jest nie tak w miejscu, gdzie spotykają się dwa systemy, a monitoring dostępności tego nie widzi. Każdą z tych diagnoz dało się potwierdzić konkretną linią w logu, a nie hipotezą.
Zamówienia anulują się mimo płatności?
Napisz, którą bramkę masz i od kiedy to się dzieje. Najpierw sprawdzimy w logach, co dokładnie się dzieje, a dopiero potem powiemy, ile zajmie naprawa.
Potrzebujesz pomocy z tym tematem?
Wdrażamy to, o czym piszemy. Porozmawiaj z nami o swoim projekcie - bezpłatna konsultacja bez zobowiązań.