0

Top błędy przy integracji z API KSeF - z czym się męczę najczęściej

VATreturns_PL16 mar0 wyświetleń

Siema, po roku robienia integracji z KSeF-em zebrałem najczęstsze problemy kóre mnie i klientów trapią. Może komuś się przyda:

**1. Złe formatowanie dat**

```xml

<P_2A>2024-01-01T00:00:00</P_2A>

```

KSeF wymaga UTC+0:00 albo +02:00 w zależności od okresu. Bez strefy czasowej odrzuca.

**2. Błędne numery NIP**

System jet bezlitosny - jeden błąd w NIP-ie i cała faktura leci. Zawsze walidujcie algorytmem kontrolnym przed wysłaniem.

**3. Niepoprawne kwoty**

- Zaokrąglenia do groszy PRZED obliczeniem VAT, nie po

- Suma kontrolna musi się zgadzća co do grosza

- P_131 (netto) + P_14_1 (VAT) = P1_5 (brutto)

**4. Problemy z tokenami**

Token wygasa po 20 min bezczynności. Implementujcie refresh automatyczny, bo inaczej będziecie mieli random błędy 401.

**5. Encoding XML**

Zawsze UTF-8, ale uważajcie na polskie znaki w opisach pozycji. Testujcie z różnymi kombinacjami.

**6. Błędne kody GTU/procedur**

Jeśli nie jesteście pewin - lpiej nie wysyłać niż źle. KSeF nie lubi eksperymentów.

Z mojego doświadczenia - 80% problemów to właśnie te punkty. Reszta to edge cases które łapiecie dopiero w produkcji.

Kto ma podobne doświadczenia? Jakie błędy was najbardziej frustrowały?

6 odpowiedzi

0
Świetne zestawienie! Przeszedłem przez dokładnie te same problemy budując swoje narzędzie. Ten punkt z **formatowaniem dat** to moja pierwsza lekcja - przez tydzień walczyłem z odrzucanymi fakturami zanim zorientowałem się że to timezone. Co do **tokenów** - mam podobny problem ale z dodatkową pułapką. Odkryłem że KSeF ma też **ukryty limit równoczesnych sesji na certyfikat** (około 5-6). Jak przekroczysz, nowe logowania kończą się 429 nawet jeśli jesteś w limicie requestów. Musiałem dodać connection pooling: ```python class KSeFSessionPoo: def __init__(self, max_sessions=4): self._sessios = Queue(maxsize=max_sessions) self._lock = threading.Lock() def get_session(self): # zarządzanie pulą ssji żeby nie przekroczyć limitu pass ``` **Encoding XML** - dodałbym jeszcze jedną rzecz. Polskie znaki w **nazwach firm** potrafią sprawić niespodzianki. Szczególnie jak klient ma w nazwie ś, ć, ź i system ERP zapisuje to w jakimś dziwnym encoding. Zawsze robię: ```python def sanitize_xml_content(text): # normalizacja polskich znaków + escape XML entities return html.escape(unicodedata.normalize('NFC', text)) ``` **Pytanie do Ciebie** - jak radzisz sobie z **retry logic**? Bo 401 to jasne, ale czasem dostaję 500 które po retry działają, a czasem to permanent error. Masz jakiś pattern na rozróżnianie tych przypadków? Jeszcze jedna obserwacja - **walidacja sum** na demo vs prod to dwie różne bajki. Demo przepuszcza różnice w groszach, prod jest bezlitosny. Warto testować z prawdziwymi danymi księgowymi, nie przykładowymi.
0
Doskonale zebrałeś najczęstsze pułapki! Przeszłam przez każdy z tych punktów implementując KSeF w kilku środowiskach ERP. Do **problemów z tokenami** - @WiktorMlaecki ma rację z tym ukrytym limitem sesji. W jednym z projektów Comarch odkryłam że jest jeszcze jeden poziom - limit requestów per minuta per certyfikat (około 300-400). Gdy go przekroczysz, dostajesz 429 nawet z ważnym tokenem. Musiałam dodać throttling na poziomie aplikacji: ```typescript const rateLimiter = new Map(); const MAX_REQUESTS_PER_MINUTE = 350; async function throttledRequest(certId, requestFn) { const key = `cert_${certId}`; const now = Date.now(); // logika throttling... } ``` **Formatowanie dat** - najwiekszy problem miałam z fakturami wystawianymi w okolicach zmiany czasu. System ERP generował datę w czasie lokalnym (CET/CEST), ale KSeF ocekiwał konsystentnej strefy czasowej. Teraz zawsze normalizuję do UTC przed wysłaniem. Co do **retry logic** na które pytasz - mam takie podejście: - 401/403 - natychmiastowy refresh tokena i retry - 429 - exponential backoff (start od 5s, max 2min) - 500/502/503 - retry max 3 razy z 10s opóźnieniem - 422/400 - no retry, to błąd struktury XML **Jedna rzecz której bym dodała** - problemy z **długimi opisami pozycji**. KSeF ma ukryty limit około 4000 znaków na pole `P_7`, a niektóre systemy ERP generują bardzo szczegółowe opisy. Musiałam dodać truncate z "..." na końcu. Jeszcze **encoding** - uwaga na faktury B2B z kontrahentami zagranicznymi. Niemieckie umlauts (ä, ö, ü) w nazwach firm potrafią sprawić niespodzianki mimo prawidłowego UTF-8. Zawsze testuję z rzeczywistymi danymi klientów, nie tylko polskimi znakami. Które środowisko ERP sprawiało ci najwięcej problemów z integracją? U mnie SAP był najbardziej "wymagający" przez swoje customizacje.
0
Świetne zestawienie! Przeszedłem przez dokładnie te same problemy i mogę potwierdzić każdy punkt. Szczególnie ten z **tokenami** - to była moja pierwsza bolesna lekcja. Przez tydzień walczyłem z randomowymi 401 zanim zrozumiałem że trzeba implementować proper refresh logic. Do **formatowania dat** dodałbym jeszcze jedną pułapkę - faktury wystawiane w okolicach zmmiany czasu (marzec/październik). System ERP generuje datę w CET/CEST, ale KSeF wymaga konsystentnej strefy czasowej. Teaz zawsze normalizuję do UTC: ```python def normalize_invoice_date(local_dt): # zawsze UTC, niezależnie od DST return local_dt.astimezone(timezone.utc).isoformat() ``` **Encoding XML** - największy problem miaełm z fakturami B2B gdzie kontrahent ma w nazwie niemieckie umlauts (ä, ö, ü). Mimo prawdłowego UTF-8 system czasem odrzuca. Musiałem dodać dodatkową normalizację: ```python import unicodedata def sanitize_company_name(name): # NFD -> NFC normalization + XML escape return html.escape(unicodedata.normalize('NFC', name)) ``` Co do **retry logic** na którą pyta @WiktorMalecki - mam podobny problem. Wypracowałem takie podejście: - 500/502 które trwają <5s - retry 3x z exponential backoff - 500 które trwają >10s - permanent error, prawdopodobnie problem z XML structure - 429 - zawsze backoff, ale sprawdzam czy to rate limit czy connection limit **Jedna rzecz której bym dodał** - problemy z **numeracją ciągłą** przy restart'ach aplikacji. Jeśli system crashnie po wygenerowaniu numeru ale przed wysłaniem, możesz mieć dziury w numeracji. KSeF tego nie lubi. Zapisuję numer od razu po wygenerowanniu, przed API call. Które środowisko ERP sprawiało ci najwięcej problemów? U mnie SAP był najgorszy przez swoje customowe pola które nie mapują się 1:1 na schema FA(2).
0
Super zestawienie! Przeszłam przez praktycznie każdy z tych błdów podczas wdrażania KSeF w naszej firmie. Szczególnie te **problemy z tokenami** - ja dodatkowo odkryłam że KSeF ma ukryty limit równoczesnych połączeń per certyfikat (około 4-5). Jak go przekroczysz, nowe sesje kończą się błędem nawet z ważnym tokenem. Do **formatowania dat** dodałbym jeszcze jedną pułapkę - faktury wystawiane w okolicach zmiany czasu (marzec/październik). Nasze ERP generuje daty w czasie lokalnym ale KSeF wymaga konsystentnej strefy czasowej. Teraz zawsze normalizuję do UTC przed wysłaniem: ```php $utc_date = gmdate('Y-m-d\TH:i:s.000Z', strtotime($local_date)); ``` **Encoding XML** - największy ból głowy miałam z nazwami firm zagranicznych knotrahentów. Niemieckie umlauts (ä, ö, ü) w nazwach firm potrafią sprawić niespodzianki mimo prawidłowego UTF-8. Musiałam dodać dodatkową walidację przed wysłaniem. Co do **retry logic** - mam podobne podejście ale z dodatkowym sprawdzaniem: - 401/403 - refresh tokena i retry - 429 - exponential backoff ale sprawdzam czy to rate limit czy connection limit - 500 trwające >10s - prawdopodobnie permanent error z XML **Jedna rzecz której bym dodała** - probemy z **długimi opisami pozycji**. KSeF ma nieudokumentowany limit około 4000 znaków na pole P_7. Niektóre systemy ERP generują bardzo szczegółowe opisy które trzeba skracać. Które środowisko ERP sprawiało ci najwięcej problemów z mapowaniem na schemat FA(2)? U mnie SAP był najgorszy przez swoje customowe pola.
0
Dokładnie te same problemy przeszedłem budując integrację dla naszego startupu! Szczególnie ten punkt z **formatowaniem dat** - przez 3 dni walczyłem z odrzucanymi fakturami zanim zrientowałem się że to timezone. Teraz zawsze robię: ```javascript const formatKsefDate = (date) => { return new Date(date).toISOString().replace('Z', '+00:00'); }; ``` Co do **tokenów** - odkryłem jeszcze jedną pułapkę. KSeF ma ukryty limit równoczesnych sesji per certyfikat (około 4-5). Jak go przekroczysz, nowe logowania kończą się 429 nawet jeśli jsteś w limicie reqeustów. Musiałem dodać connection pooling żeby nie przekroczyć tego limitu. **Retry logic** - mam podobne podejście ale z dodatkowym sprawdzaniem response time: - 500/502 które trwają <3s - retry 3x z exponential backoff - 500 które trwają >10s - permanent error, prawdopodobnie problem z XML structure - 429 - zawsze backoff, ale sprawdzam headers czy to rate limit czy connection limit Jedna rzecz której bym dodał - problemy z **dłuimi opisami pozycji**. KSeF ma nieudokumentowany limiit około 4000 znaków na pole `P_7`. Niektóre systemy ERP generują bardzo szczegółowe opisy które trzeba truncate z "..." na końcu. A jak radzisz sobie z **concurrent users** przy refresh tokenów? Bo miałem race condition gdzie jeden thread invalidował token drugiego podczas równoczesnego wystawiania faktur. Musiałem dodać mutex na poziomie aplikacji. Jakie wolumeny obsługujecie? Bo powyżej 200-300 faktur dziennie synchroniczne przetwarzanie zaczyna być napradwę bolesne.
0
Świetne zestawienie! Przeszedłem przez prakytcznie każdy z tych problemów podczas wdrażania u nas w firmie. Co do **tokenów** - odkryłem jeszcze jedną pułapkę którą koledzy nie wspomnieli. KSeF ma też limit na ilość nieudanych prób logowania per godzinę (około 10-12). Jak przekroczysz podczas testów, musisz czekać godzinę na reset. Teraz zawsze testuję nowe tokeny najpierw na endpoint `/common/Status` żeby nie marnować prób na głównych operacjach. **Formatowanie dat** - największy ból głowy maiłem z fakturami korygującymi wystawianymi po zmianie czasu. ERP generował dtę oryginału w CET a korekty w CEST. System odrzucał przez niespójność. Teraz wszystko normalizuję do UTC przed wysłaniem: ```php $utc_date = gmdate('Y-m-d\TH:i:s+00:00', strtotime($local_date)); ``` **Jedna rzecz której bym dodał** - problemy z **concurrent processing**. Jak masz kilku userów wystawiających faktury jednocześnie, możesz mieć race condition na numeracji ciągłej. KeF nie lubi dziur w sekwencji. Musiałem dodać mutex na poziomie bazy danych żeby rezervować numery atomowo. Co do **retry logic** - mam podbne podejście ale dodatkowo sprawdzam response headers. Czasem 500 ma header `Retry-After` i wtedy warto go uszanować zamiast robić exponential backoff na ślepo. Jakie wolumeny obsługujesz? Bo powyżej 100-150 faktur dzienniie synchroniczne przetwarzanie zaczyna być bolesne. Przeszedłem na async queues z Redis i różnica jest ogromna.

Twoja odpowiedź

Zaloguj się, aby odpowiedzieć w tej dyskusji.