← Powrót na blog

Solidna integracja z KSeF: dlaczego większość wdrożeń zawodzi i jak zrobić to porządnie

KSeF to nie zwykłe wywołanie HTTP. To asynchroniczny, limitowany system państwowy, który potrafi nie działać. Jak zbudować integrację, która nie zgubi ani jednej faktury.

Od 1 lutego 2026 KSeF jest obowiązkowy dla dużych podatników VAT, od 1 kwietnia 2026 dla pozostałych. Rok 2026 to okres przejściowy — kary wchodzą w życie dopiero od 1 stycznia 2027. To właśnie ten termin ujawni różnicę między integracją, która „jakoś działa", a taką, która wytrzyma próbę czasu i kontrolę skarbową.

Większość wdrożeń KSeF, które widzimy, ma tę samą wadę: są fire-and-forget. Aplikacja wysyła fakturę w żądaniu HTTP i liczy na to, że się udało. Dopóki system państwowy odpowiada sprawnie, wszystko wygląda dobrze. Problem pojawia się pierwszego dnia, gdy KSeF zwróci błąd, timeout lub limit zapytań — i faktura po cichu znika. Nikt się o tym nie dowiaduje, dopóki nie przyjdzie kontrola.

Dlaczego KSeF jest trudniejszy, niż wygląda

KSeF nie jest zwykłym REST API. Ma cztery właściwości, które razem tworzą pułapkę:

  • Jest asynchroniczny. Wysłanie faktury i otrzymanie potwierdzenia (UPO) to dwa odrębne momenty. Pomiędzy nimi musisz gdzieś przechowywać stan.
  • Ma limity wywołań. Przy wysyłce wsadowej szybko natkniesz się na ograniczenia przepustowości. Bez kolejki i kontroli tempa blokujesz całą fakturację.
  • Bywa niedostępny. Systemy państwowe mają awarie i okna serwisowe. Twoja fakturacja nie może z tego powodu padać.
  • Ma własny model sesji. Sesje wygasają, tokeny tracą ważność, a zewnętrzne SDK dokładają do tego własne osobliwości.

Gdy system ma dwie lub więcej z tych cech, nie chodzi już o proste wywołanie API. Masz do czynienia z długotrwałym, stanowym workflowem — a to wymaga zupełnie innej architektury niż „wywołaj API w kontrolerze".

Jak to budujemy: durable, nie fire-and-forget

Kluczowa zasada: każde wywołanie KSeF to trwała, idempotentna, utrwalona jednostka pracy. Nigdy fire-and-forget, nigdy wewnątrz żądania HTTP. Oto filary, na których to stoi.

1. Idempotentne wysyłanie

Każda faktura otrzymuje deterministyczny klucz idempotencji. Gdy wysyłka zostanie ponowiona — a zostanie, przez mechanizm retry, restart procesu lub race condition — system rozpoznaje, że już to obsługiwał, i nie tworzy duplikatu w systemie państwowym. Bez idempotencji każdy retry to ryzyko duplikatu.

2. Retry z exponential backoff

Przejściowe błędy i timeouty to norma, nie wyjątek. Zamiast ręcznie pisanej pętli retry (którą zawsze ktoś implementuje błędnie) używamy mechanizmu z exponential backoff — sprawdzonego w boju rozwiązania, które ponawia próby z rosnącymi odstępami i nie zalewa API, gdy to już ma problemy.

3. Rate limiting jako stan współdzielony

Limity KSeF musisz respektować nawet wtedy, gdy działasz na wielu instancjach aplikacji. Licznik in-memory w jednym procesie nie wystarczy — potrzebujesz współdzielonego token bucket (typowo przez Redis), żeby instancje nie „kradły" sobie nawzajem kwoty.

4. Job reconciliacji

To element, który niemal każdy pomija — a jest najważniejszy. Cykliczny job zadaje pytanie: „czy rzeczywistość zgadza się z naszymi danymi?" Czy każda faktura ma potwierdzenie? Czy coś nie utkwiło w stanie pending? Czy nie ma sierot? Bez reconciliacji nie monitorujesz — tylko masz nadzieję.

5. Polling statusu i UPO

Wysłanie faktury to dopiero początek. Śledzimy status aż do UPO (Urzędowe Poświadczenie Odbioru) — oficjalnego potwierdzenia, że urząd przyjął fakturę. Dopiero UPO jest dowodem. Dopóki go nie masz, faktura nie jest gotowa.

6. Audit log i alerting

Każde przejście stanu generuje strukturyzowany event. Alerty uruchamiają się na błędach terminalnych i stanach zawieszonych — zanim staną się problemem podczas kontroli. Ciche LogWarning bez alertu to odłożony dług.

7. Anti-corruption layer

Opakowujemy SDK KSeF własną warstwą, żeby jego osobliwości — obce ciągi błędów, kody numeryczne, TTL sesji — nie przeciekały do twojej logiki biznesowej. Gdy SDK się zmienia, zmieniasz jedno miejsce, a nie cały kod.

Checklist: czy twoja integracja z KSeF jest solidna?

Przejdź przez to uczciwie:

  • Czy wysyłanie faktury przeżyje restart aplikacji w połowie procesu?
  • Co się stanie, gdy KSeF zwróci 500 lub timeout — czy znajdziesz tę fakturę?
  • Czy masz dowód (UPO) dla każdej wysłanej faktury, czy tylko zakładasz, że przeszła?
  • Czy istnieje job, który codziennie weryfikuje, że nic nie utknęło?
  • Czy dostaniesz alert, gdy coś się zawiesi, czy dowiesz się o tym od księgowej?

Jeśli na którekolwiek pytanie odpowiedź brzmi „nie", masz integrację fire-and-forget. W okresie przejściowym to ujdzie. Od stycznia 2027 — już nie.

Zweryfikowane produkcyjnie

To nie są teorie ze slajdów. Dla TrafinOil podłączyliśmy fakturację do KSeF i podczas forensic recovery odtworzyliśmy 15 141 brakujących dokumentów, które poprzedni pipeline fire-and-forget po cichu utracił. Nocny dataloader skróciliśmy z 20 godzin do 30 minut. Retry, reconciliacja i monitoring działają na produkcji i pilnują, żeby się to nie powtórzyło.

Więcej o naszej usłudze integracji z KSeF.

Termin KSeF się zbliża. Jeśli masz to zrobić, zrób to tak, żeby nie padło w styczniu 2027. Napisz do nas — powiemy ci dokładnie, w którym miejscu twoja integracja jest narażona.

Masz podobny problem? Napisz do nas.

Umów konsultację