Faktura z odnowienia subskrypcji bez NIP – dlaczego KSeF ją odrzucił
Faktura z odnowienia subskrypcji bez NIP i błąd KSeF? Pokazujemy, jak WooCommerce Subscriptions nadpisywał NIP z kasy i jak to naprawiliśmy.

Faktura z odnowienia subskrypcji bez NIP – tak wyglądał problem, który zgłosił nam w poniedziałek rano opiekun klientki. W panelu Fakturowni wisiała faktura z czerwonym statusem KSeF. Nabywca: nazwa firmy, adres, wszystko jak trzeba. Brakowało tylko jednego pola – NIP-u. KSeF takiej faktury nie przyjmuje, więc dokument utknął, a ktoś musiał go poprawić ręcznie.
Pierwsza myśl: kupująca zapomniała wpisać NIP. Tyle że w zamówieniu NIP był. Wpisany w kasie, zapisany w bazie, widoczny w panelu WooCommerce. Fakturownia go po prostu nie zobaczyła. Poniżej opisujemy, jak doszliśmy do tego, dlaczego – i co zmieniliśmy, żeby więcej się nie powtórzyło.
Kontekst: platforma kursowa z subskrypcjami i fakturami do KSeF
Klientka prowadzi platformę kursową na WordPressie. Sprzedaż idzie przez WooCommerce, dostęp do części programów jest w modelu subskrypcji (WooCommerce Subscriptions), a faktury wystawia automatycznie wtyczka Fakturowni. Konto Fakturowni ma włączoną wysyłkę dokumentów dla firm do KSeF.
Pole „Chcę fakturę” i pole NIP w kasie dokłada nasza wtyczka. Zwykły zakup działa bez zarzutu – sprawdziliśmy 103 zamówienia z fakturą od sierpnia i wszystkie 103 miały poprawny NIP. Problem dotyczył wyłącznie odnowień subskrypcji. Mało, ale to są dokumenty księgowe: każdy błąd to ręczna korekta, telefon od kupującej firmy i nerwy przed zamknięciem miesiąca.
Diagnoza: najpierw liczby, potem kod
Zanim zaczęliśmy czytać kod, napisaliśmy mały skrypt diagnostyczny, który tylko czyta dane: bierze zamówienia od 1 sierpnia, sprawdza, czy mają nazwę firmy, czy mają NIP i jaką drogą powstały (zwykła kasa, wczesne odnowienie przez kasę, automatyczne odnowienie). Wynik:
- 435 faktur od początku sierpnia,
- 7 zamówień z nazwą firmy i bez NIP-u w polu, które czyta Fakturownia,
- 2 z nich skończyły się błędem wysyłki do KSeF,
- 4 z 97 aktywnych subskrypcji miały w danych rozliczeniowych firmę bez NIP-u – czyli kolejne odnowienia czekały w kolejce na ten sam błąd.
Ważna uwaga z tej części: dzisiejsza faktura w Fakturowni nie jest źródłem prawdy o błędzie. Część dokumentów była już ręcznie poprawiona. Prawdę mówiły dane zamówienia w WordPressie, nie stan po korekcie.
Dwa pola o prawie tej samej nazwie
Pierwsze odkrycie było banalne i bolesne. W zamówieniu były dwa wpisy z NIP-em:
billing_nip = 1234567890 (zapisany przez pole w kasie)
_billing_nip = "" (pusty tekst)
Wtyczka Fakturowni czyta wyłącznie wersję z podkreślnikiem na początku. Jeżeli w zamówieniu jest nazwa firmy, a _billing_nip jest pusty, wystawia fakturę na firmę bez NIP-u. KSeF to odrzuca. Pytanie brzmiało więc nie „gdzie jest NIP”, tylko „kto wyczyścił _billing_nip, skoro kasa go zapisała”.
Ślepa uliczka: kolejność zapisu w naszej wtyczce
Podejrzewaliśmy najpierw siebie. Nasza wtyczka zapisuje pola kasy w kilku krokach i wyglądało na to, że któryś z nich nadpisuje NIP przy odnowieniu. Przejrzeliśmy ten fragment linijka po linijce – zapis był poprawny. Przy zwykłym zakupie _billing_nip trafiał na miejsce za każdym razem. Coś działo się później, i tylko przy odnowieniach.
Moment odkrycia: priorytet 90
Rozwiązanie zagadki siedziało w WooCommerce Subscriptions. Przy wczesnym odnowieniu (kupująca sama klika „odnów teraz” i płaci w kasie) wtyczka subskrypcji podpina się pod ten sam moment tworzenia zamówienia co my – woocommerce_checkout_create_order – z priorytetem 90. I kopiuje dane z subskrypcji na nowe zamówienie.
Subskrypcja miała w _billing_nip pusty tekst. Pusty tekst to nie „brak wartości”, tylko wartość. Kopia nadpisywała więc NIP wpisany chwilę wcześniej w kasie. Pole bez podkreślnika zostawało nietknięte, bo nasza wtyczka zapisywała je później – stąd ten mylący obraz „NIP jest, a go nie ma”.
Drugi tor: automatyczne odnowienia
Przy odnowieniu automatycznym (płatność pobiera się sama, bez kasy) mechanizm był podobny, tylko źródło inne. WooCommerce Subscriptions kopiuje na zamówienie odnowienia dane rozliczeniowe z subskrypcji. Nazwa firmy jest polem adresu, więc przechodzi. NIP i zaznaczenie „Chcę fakturę” to pola dodatkowe – nie przechodzą albo przechodzą jako pusty tekst. Efekt ten sam: firma bez NIP-u na fakturze.
Do tego wczesne odnowienie przez kasę potrafiło wpisać nazwę firmy do subskrypcji, ale NIP-u już nie. Każde takie odnowienie „zarażało” subskrypcję i psuło kolejne, automatyczne.
Jeśli prowadzisz sklep z subskrypcjami i nie chcesz sam rozbierać takich zależności między wtyczkami, zajmujemy się tym w ramach opieki nad WordPressem – łącznie z pilnowaniem faktur po każdej aktualizacji.
Rozwiązanie: firma na fakturze tylko razem z NIP-em
Mogliśmy dopisać NIP ręcznie w czterech subskrypcjach i zamknąć temat. Wróciłby przy następnej kupującej. Zmieniliśmy więc regułę w naszej wtyczce, a nie dane:
- Kasa: firma i NIP zawsze razem. Nazwa firmy bez NIP-u (albo odwrotnie) daje w kasie komunikat „podaj oba albo żadne”. Odznaczona faktura = zamówienie na osobę prywatną. NIP zostaje zapamiętany na koncie i w subskrypcji, system go nigdy nie kasuje.
- Wczesne odnowienie: zapisujemy po wtyczce subskrypcji. Ten sam moment tworzenia zamówienia, ale z priorytetem 95, czyli po kopii z priorytetem 90. NIP wpisany w kasie wraca do pola, które czyta Fakturownia.
- Każde odnowienie: filtr przed wystawieniem faktury. Podpinamy się pod moment utworzenia zamówienia odnowienia i szukamy NIP-u po kolei: w subskrypcji, w zamówieniu z kasy, w zamówieniu startowym, na koncie kupującej. Znaleziony – faktura idzie na firmę z NIP-em. Nie ma go nigdzie – zdejmujemy nazwę firmy i faktura idzie na osobę. KSeF ją przyjmie, a w zamówieniu zostaje notatka, na kogo wystawiono dokument.
Szkielet drugiego punktu wygląda tak:
add_action( 'woocommerce_checkout_create_order', function ( $order ) {
if ( empty( $_POST['chce_fakture'] ) || empty( $_POST['billing_nip'] ) ) {
return;
}
$nip = sanitize_text_field( wp_unslash( $_POST['billing_nip'] ) );
$order->update_meta_data( '_billing_nip', $nip );
}, 95 ); // po WooCommerce Subscriptions (90)
Najważniejsza w tym fragmencie jest liczba na końcu. Ten sam kod z priorytetem 10 działałby przy zwykłym zakupie i przegrywał przy odnowieniu – dokładnie tak, jak wcześniej.
Najpierw kopia strony, potem produkcja
Poprawkę sprawdziliśmy na lokalnej kopii z tymi samymi wersjami WooCommerce i Subscriptions co na żywej stronie, z odciętym ruchem wychodzącym – żeby żadna próbna faktura nie poszła do prawdziwej Fakturowni i KSeF. 24 scenariusze (zwykły zakup, wczesne odnowienie, automatyczne odnowienie, z fakturą i bez) – wszystkie poprawne.
Przed wdrożeniem puściliśmy jeszcze symulację na 96 aktywnych subskrypcjach: zmieniały się dokładnie 4, te same, które wyszły w diagnozie. Trzy dostały NIP z wcześniejszych zamówień, jedna przeszła na fakturę dla osoby. Ręcznej poprawki danych nie trzeba było robić – filtr ustawi to sam przy najbliższym odnowieniu.
Efekt
- Przed: faktura na firmę bez NIP-u przy części odnowień, błąd KSeF, ręczna korekta w Fakturowni.
- Po: nie da się zapisać zamówienia z firmą bez NIP-u – ani w kasie, ani przy odnowieniu.
- Poprawka trafiła też na pozostałe strony z subskrypcjami, które obsługujemy. Skrypt diagnostyczny pokazał tam zero takich przypadków, ale reguła działa już zawczasu.
Jak to sprawdzić u siebie
- Otwórz w panelu WooCommerce zamówienie odnowienia z nazwą firmy i sprawdź pola własne: czy NIP jest w polu, które czyta Twoja wtyczka faktur (u nas
_billing_nip)? - Porównaj zamówienia „przez kasę” z odnowieniami automatycznymi – jeśli błąd dotyczy tylko jednej grupy, szukaj w kopiowaniu danych z subskrypcji.
- Sprawdź dane rozliczeniowe aktywnych subskrypcji: firma bez NIP-u to błąd, który dopiero nadejdzie.
- Pusty tekst w meta to też wartość – przy kopiowaniu nadpisze to, co było wcześniej.
- Jeśli dwie wtyczki zapisują to samo pole w tym samym momencie, decyduje priorytet. Twoja poprawka musi mieć wyższy.
- Poprawki faktur sprawdzaj na kopii z zablokowanym ruchem do Fakturowni – inaczej próbna faktura trafi do KSeF naprawdę.
Podobny problem z „tymi samymi danymi w dwóch miejscach” opisywaliśmy przy zamówieniach failed, za które klient zapłacił, a na blogu o platformach kursowych – przy tagach FluentCRM, które nie nadawały się po zakupie. Za każdym razem winne było pole o prawie tej samej nazwie.
FAQ
Dlaczego KSeF odrzuca fakturę bez NIP-u?
Jeśli faktura ma nabywcę-firmę, KSeF wymaga jego numeru identyfikacyjnego. Faktura „na firmę” bez NIP-u nie przechodzi walidacji i zostaje z błędem wysyłki. Faktura na osobę prywatną NIP-u nie potrzebuje.
Czy wystarczy ręcznie dopisać NIP w Fakturowni?
Dla jednej faktury tak, ale przy subskrypcji błąd wróci przy kolejnym odnowieniu, bo dane bierze się z subskrypcji, a nie z poprawionej faktury. Trzeba naprawić źródło – zapis w zamówieniu i w subskrypcji.
Skąd wiadomo, które pole czyta wtyczka Fakturowni?
Z kodu wtyczki albo prostą próbą: zamówienie z wypełnionym jednym polem i pustym drugim. U nas wtyczka czytała wyłącznie pole z podkreślnikiem na początku nazwy.
Czy to dotyczy tylko WooCommerce Subscriptions?
Mechanizm „druga wtyczka kopiuje dane po mojej” występuje wszędzie tam, gdzie kilka wtyczek pracuje w tym samym momencie tworzenia zamówienia: subskrypcje, raty, płatności odroczone, integracje z CRM.
Masz ten sam problem z fakturami w WooCommerce?
Faktury bez NIP-u, błędy KSeF, odnowienia, które psują dane – to są rzeczy, które warto naprawić raz, porządnie, zamiast poprawiać co miesiąc. Napisz do nas – opisz, co widzisz w Fakturowni, a powiemy, gdzie szukać przyczyny. Budujemy i utrzymujemy też sklepy internetowe na WooCommerce od początku do końca.



