← Zpět na blog

Robustní KSeF integrace: proč většina napojení selže a jak to udělat pořádně

KSeF není jen HTTP volání. Je to asynchronní, rate-limited státní systém, který občas spadne. Jak postavit integraci, která neztratí ani jednu fakturu.

Od 1. února 2026 je KSeF (Krajowy System e-Faktur) v Polsku povinný pro velké plátce, od 1. dubna 2026 pro ostatní plátce DPH. Rok 2026 je sice grace period bez pokut, ale od 1. ledna 2027 přichází tvrdé vynucování. A právě tady se ukáže rozdíl mezi integrací, která „nějak funguje", a integrací, která vydrží.

Většina napojení na KSeF, která vidíme, má stejnou vadu: jsou fire-and-forget. Aplikace pošle fakturu v HTTP requestu a doufá, že to vyšlo. Dokud je státní systém dostupný a rychlý, vypadá to perfektně. Problém přijde první den, kdy KSeF odpoví chybou, timeoutem nebo rate limitem — a faktura tiše zmizí. Nikdo se to nedozví, dokud nepřijde kontrola.

Proč je KSeF těžší, než vypadá

KSeF není běžné REST API. Má čtyři vlastnosti, které dohromady tvoří past:

  • Je asynchronní. Odeslání faktury a její potvrzení (UPO) jsou dva různé okamžiky. Mezi nimi musíte stav někde držet.
  • Je rate-limited. Při dávkovém odesílání narazíte na limity. Bez fronty a řízení tempa se vám zastaví celá fakturace.
  • Občas je nedostupný. Státní systém má výpadky a údržby. Vaše fakturace kvůli tomu nesmí spadnout.
  • Má vlastní stav a session. Session má omezenou platnost, tokeny expirují, a cizí SDK do toho přidává své zvláštnosti.

Když systém má dvě nebo více těchto vlastností, nejde o jednoduché volání. Jde o dlouhoběžící stavový workflow — a ten potřebuje úplně jinou architekturu než „zavolej API v controlleru".

Jak to stavíme: durable, ne fire-and-forget

Klíčový princip: každé volání KSeF je durable, idempotentní, perzistovaná jednotka práce. Nikdy ne fire-and-forget, nikdy ne v HTTP requestu. Tady jsou pilíře, na kterých to stojí.

1. Idempotentní odeslání

Každá faktura dostane deterministický idempotency key. Když se odeslání zopakuje (a ono se zopakuje — kvůli retry, restartu, race condition), systém pozná, že tohle už řešil, a nevytvoří duplicitní fakturu. Bez idempotence se z každého retry stane riziko duplicity ve státním systému.

2. Retry s exponenciálním backoffem

Přechodné chyby a timeouty jsou normální, ne výjimka. Místo ručně psané smyčky (kterou vždycky někdo napíše špatně) použijeme retry s exponenciálním backoffem — battle-tested mechanismus, který opakuje s rostoucími rozestupy a nezahltí API, když má problém.

3. Rate limiting jako sdílený stav

Limity KSeF musíte respektovat i ve chvíli, kdy běžíte na více instancích. In-memory počítadlo v jednom procesu nestačí — potřebujete sdílený token-bucket (typicky přes Redis), aby si instance navzájem nepřebíraly kvótu.

4. Reconciliation job

Tohle je díl, který skoro každý vynechá — a je nejdůležitější. Periodický job se ptá: „sedí realita?" Má každá faktura potvrzení? Neuvízla některá ve stavu „pending"? Nevznikl orphan? Bez reconciliation nevíte, jestli to opravdu funguje — jen doufáte.

5. Status polling a UPO

Odeslání je teprve začátek. Sledujeme stav až po UPO (Urzędowe Poświadczenie Odbioru) — oficiální potvrzení, že stát fakturu přijal. Teprve UPO je důkaz. Dokud ho nemáte, faktura není hotová.

6. Audit log a alerting

Každý přechod stavu generuje strukturovaný event. Na terminal-failure a uvíznuté stavy jde alert — dřív, než se z toho stane problém u kontroly. Tiché LogWarning bez alertu je jen odložený dluh.

7. Anti-corruption layer

Cizí KSeF SDK obalíme vlastní vrstvou, aby jeho zvláštnosti — cizí error stringy, číselné kódy, session TTL — neprosakovaly do vaší business logiky. Když se SDK změní, měníte jedno místo, ne celý kód.

Checklist: je vaše KSeF integrace robustní?

Projděte si to upřímně:

  • Přežije odeslání faktury restart aplikace uprostřed procesu?
  • Co se stane, když KSeF vrátí 500 nebo timeout — dohledáte tu fakturu?
  • Máte důkaz (UPO) u každé odeslané faktury, nebo jen předpokládáte, že to prošlo?
  • Existuje job, který každý den ověří, že nic neuvízlo?
  • Přijde vám alert, když se něco zasekne, nebo to zjistíte až od účetní?

Pokud na některou odpovíte „ne", máte fire-and-forget integraci. Při grace periodu to projde. Od ledna 2027 už ne.

Ověřeno v produkci

Tohle nejsou teorie ze slidu. Pro TrafinOil jsme napojili fakturaci na KSeF a při forenzní recovery obnovili 15 141 chybějících dokumentů, které předchozí fire-and-forget pipeline tiše ztratila. Noční dataloader jsme zkrátili z 20 hodin na 30 minut. Retry, reconciliation a monitoring běží v produkci a hlídají, že se to nestane znovu.

KSeF deadline se blíží. Když to máte udělat, udělejte to tak, aby vám to v lednu 2027 nespadlo. Napište nám — řekneme vám, kde je vaše integrace zranitelná.

Řešíte podobný problém? Napište nám.

Domluvit konzultaci