Skąd biorą się duplikaty faktur w KSeF?
Sieć zawodzi w sposób niesymetryczny. Żądanie może dotrzeć do serwera i zostać przetworzone, a odpowiedź zaginąć w drodze powrotnej. Z perspektywy klienta oba przypadki — „nie dotarło" i „dotarło, ale odpowiedź przepadła" — wyglądają identycznie: brak odpowiedzi w wyznaczonym czasie.
Trzy scenariusze prowadzą do tego samego skutku:
- Timeout połączenia. Klasyczny przypadek. Domyślna polityka „ponów trzy razy z wykładniczym opóźnieniem", wpisana w większość bibliotek HTTP, w tym kontekście generuje duplikaty zamiast im zapobiegać.
- Restart procesu w trakcie wysyłki. Kontener zostaje zrestartowany między wysłaniem żądania a zapisaniem odpowiedzi. Po starcie kolejka zawiera dokument, który wygląda na nieprzetworzony.
- Równoległe przetwarzanie tej samej pozycji. Dwa procesy pobierają to samo zadanie z kolejki, bo blokada nie została prawidłowo założona lub wygasła.
Częściowo nieudana paczka
W KSeF API 2.0 tryb wsadowy przetwarza każdą fakturę niezależnie, zamiast odrzucać całą paczkę z powodu jednego błędu. To zmiana na lepsze, ale zmienia też sposób obsługi błędów. Po częściowo nieudanej paczce nie wolno wysłać jej ponownie w całości — trzeba rozliczyć wynik dokument po dokumencie. Integracje przeniesione z wersji 1.0, w których ponowienie całej paczki było poprawną reakcją, powielają dokumenty właśnie tutaj.
Zasada: sprawdź, zanim ponowisz
Reguła jest prosta i rzadko wdrażana: po nieudanym wywołaniu nie wysyłaj dokumentu ponownie — najpierw ustal, co się z nim stało.
W praktyce oznacza to sekwencję:
- Nadaj dokumentowi własny identyfikator referencyjny po swojej stronie, zanim wykonasz jakiekolwiek wywołanie. Identyfikator musi być trwały i deterministyczny — wynikać z dokumentu źródłowego, a nie z losowania przy każdej próbie.
- Zapisz stan „wysyłka rozpoczęta" przed wywołaniem, nie po nim.
- Po timeoucie odpytaj status sesji lub dokumentu, zamiast wysyłać go ponownie.
- Ponów wysyłkę wyłącznie wtedy, gdy uzyskasz jednoznaczną informację, że dokument nie został przyjęty.
- Po przyjęciu zapisz numer KSeF i UPO w trwałym powiązaniu z dokumentem źródłowym.
Punkt drugi jest tym, który najczęściej się pomija. System, który zapisuje stan dopiero po otrzymaniu odpowiedzi, po restarcie nie ma śladu, że próba w ogóle nastąpiła.
Maszyna stanów zamiast flagi
Reprezentacja „wysłane / niewysłane" jest niewystarczająca, bo nie odróżnia stanu „nie wiem" od stanu „na pewno nie". Minimalny zestaw stanów wygląda tak:
| Stan | Znaczenie | Dozwolona akcja |
|---|---|---|
przygotowany | Dokument zbudowany, jeszcze niewysłany | Wysyłka |
wysyłka_w_toku | Żądanie wysłane, brak odpowiedzi | Wyłącznie odpytanie statusu |
przyjety | Nadany numer KSeF, odebrane UPO | Brak — stan końcowy |
odrzucony | Jednoznaczna odmowa z kodem błędu | Poprawa i ponowna wysyłka jako nowa próba |
offline_oczekujacy | Wystawiony offline, oczekuje na przesłanie | Przesłanie w terminie właściwym dla trybu |
Stan wysyłka_w_toku jest tym, który zapobiega duplikatom. Dopóki dokument w nim pozostaje, jedyną dozwoloną operacją jest odpytanie — nigdy ponowna wysyłka. Zobacz też artykuł o trybach offline, gdzie stan offline_oczekujacy wymaga własnego terminu.
Jak wykryć duplikat, zanim zrobi to kontrahent?
Kontrola stanu chroni przed duplikatami powstającymi w warstwie transportowej. Nie chroni przed duplikatami logicznymi — dwoma dokumentami zbudowanymi z tego samego zdarzenia biznesowego, na przykład po ponownym uruchomieniu importu.
Przeciwko tym pomaga uzgodnienie, wykonywane cyklicznie, nie tylko przy zamknięciu miesiąca:
- Uzgodnienie liczby. Liczba dokumentów w stanie
przyjetypo Twojej stronie względem liczby faktur w KSeF za ten sam okres. - Wykrywanie powtórzeń logicznych. Zapytanie o dokumenty o tym samym kontrahencie, kwocie i dacie sprzedaży, wystawione w krótkim odstępie.
- Kontrola sierot. Dokumenty w KSeF bez odpowiednika w Twoim rejestrze i odwrotnie.
Trzeci punkt jest najważniejszy operacyjnie, bo wykrywa dokument, który został przyjęty przez KSeF w momencie, gdy Twój system uznał wysyłkę za nieudaną. Bez tego uzgodnienia taka faktura funkcjonuje w obrocie prawnym, nie funkcjonując w Twoich księgach.
Co zrobić, gdy duplikat już powstał?
Faktury przyjętej przez KSeF nie można usunąć. Nadmiarowy dokument koryguje się fakturą korygującą. Warto pamiętać, że korekty wystawiane obecnie stosują strukturę FA(3) również wtedy, gdy dokument pierwotny powstał wcześniej według FA(2) lub FA(1).
Poza samą korektą zdarzenie należy udokumentować: przyczyna, moment powstania, moment wykrycia, sposób usunięcia skutków i wprowadzona zmiana zapobiegająca powtórzeniu. Od 1 stycznia 2027 r. ta dokumentacja przestaje być dobrą praktyką — staje się materiałem, na którym opiera się miarkowanie kary.
Szczególny przypadek: agenty AI
Proces deterministyczny ponawia operację według reguły, którą ktoś zapisał. Agent AI może podjąć decyzję o ponowieniu na podstawie interpretacji komunikatu błędu — a modele bywają skłonne interpretować niejednoznaczny wynik jako niepowodzenie i próbować ponownie.
Tam, gdzie w pętli działania znajduje się model, kontrola idempotencji nie może być pozostawiona jego decyzji. Musi być egzekwowana w warstwie, przez którą agent przechodzi: identyfikator operacji nadawany poza modelem, odrzucenie powtórzonego wywołania z tym samym identyfikatorem, i zapis każdej próby niezależnie od tego, jak agent ją zinterpretował.
Najczęstsze pytania
Czy timeout oznacza, że faktura nie została przyjęta?
Nie. Oznacza wyłącznie brak odpowiedzi. Dokument mógł zostać przyjęty i mieć nadany numer KSeF.
Jak sprawdzić, czy faktura została przyjęta po nieudanym wywołaniu?
Odpytać status po własnym identyfikatorze referencyjnym, zamiast wysyłać dokument ponownie. Dopiero jednoznaczna informacja o braku przyjęcia uzasadnia ponowienie.
Co zrobić, gdy duplikat już powstał?
Skorygować fakturą korygującą i udokumentować całe zdarzenie. Usunięcie dokumentu z KSeF nie jest możliwe.
Czy tryb wsadowy odrzuca całą paczkę przy jednym błędzie?
Nie w API 2.0 — każda faktura jest przetwarzana niezależnie. Ponowna wysyłka całej paczki po częściowym niepowodzeniu tworzy duplikaty.
Czy wystarczy unikalny numer faktury, żeby uniknąć duplikatów?
Nie. Numer faktury jest atrybutem dokumentu, a nie operacji. Dwie próby wysłania tego samego dokumentu to dwie operacje — i to one wymagają identyfikatora.
Dalej w tym cyklu
- KSeF, automatyzacja i AI — kompletny przewodnik dla firm
- Integracja KSeF API: jak projektować niezawodne procesy automatyczne
- Ślad audytowy w KSeF: jak udokumentować każdą automatyczną operację
- Tryby offline w KSeF
BarzelVault egzekwuje kontrolę idempotencji na poziomie operacji — także wtedy, gdy operację inicjuje agent AI — i zapisuje każdą próbę wraz z jej wynikiem, niezależnie od tego, co system wywołujący uznał za sukces.
W praktyce
Kontrola musi zadziałać, zanim faktura stanie się nieodwracalna.
Przyjętą fakturę ustrukturyzowaną można skorygować, ale nigdy usunąć, a od dnia wejścia kar każdy błąd ma swoją cenę. Barzel stawia próg akceptacji, kontrolę duplikatów i podpisany zapis przed wysyłką, tak aby proces dało się obronić w dniu, w którym zapyta o niego audytor albo urząd skarbowy.
Pozostało 95 dniKary KSeF obowiązują od 1 stycznia 2027 r.
BarzelVault
Firewall działań AI: decyduj, co agent może zrobić, zanim to zrobi.
- Progi akceptacji i reguły polityki egzekwowane przed wykonaniem; zatwierdzenia przez człowieka z terminem ważności i eskalacją.
- Kryptograficznie podpisane potwierdzenia audytowe: wyzwalacz, dane wejściowe, wersja polityki, osoba zatwierdzająca, wynik.
- Izolacja poświadczeń, limity kwot i działań oraz awaryjny wyłącznik.
Plan bezpłatny: 10 000 wywołań miesięczniePlany płatne od 199 USD miesięcznieDostępne na MCPize
Zacznij bezpłatnie Zapytaj e-mailemStrona produktuDokumentacja
BarzelOps
Nadzorowana automatyzacja procesów między systemami, na których działa firma.
- Trwałe, idempotentne wykonanie: przekroczenie czasu jest ponawiane raz, faktura nigdy nie trafia do systemu dwa razy.
- Punkty zatwierdzenia przez człowieka, które wstrzymują proces i wznawiają go.
- Izolacja per podmiot lub klient, podpisane dowody i przenośny manifest; integracje HubSpot, Xero, Gmail, Google Drive i Slack.
Plan bezpłatny: 100 wywołań dzienniePlany płatne od 19 USD miesięcznieDostępne na MCPize
Zacznij bezpłatnie Zapytaj e-mailemStrona produktuDokumentacja
Enterprise: pisemna wycena e-mailem w ciągu dwóch dni roboczych. Bez rozmowy handlowej.
Źródła
- Ministerstwo Finansów, Przegląd kluczowych zmian KSeF API 2.0 — github.com/CIRFMF/ksef-api.
- Ministerstwo Finansów, Broszura informacyjna dotycząca struktury logicznej FA(3), 4 marca 2026 r.
Artykuł ma charakter informacyjny i nie stanowi porady podatkowej ani prawnej.