ePodatelna24 — Outbox Ingestion API — príručka pre integráciu ERP
Kompletný návod, ako z ľubovoľného ERP systému (nezáleží na technológii — .NET, Java, PHP, Python, Node…) odovzdať Peppol faktúru do ePodatelna24 na odoslanie do siete Peppol.
Tento repozitár je zároveň referenčná implementácia (Next.js/TypeScript), ale
API je obyčajné HTTP + XML — nasledujúci návod stačí na to, aby ste klienta
postavili vo svojom jazyku. Všetko, čo tu vidíte, komunikuje výlučne cez verejný
HTTP kontrakt: /api-docs
(OpenAPI: /api-docs/openapi.yaml).
Tok v skratke
ERP len odovzdá platné XML a dostane potvrdenie o prevzatí. Samotné odoslanie do siete Peppol aj uloženie potvrdenia o doručení už zabezpečí ePodatelna24.
Vykresľujem diagram…
Obsah
- Ako to funguje (model)
- Predpoklady
- Prostredia a základné URL
- Autentifikácia
- Kľúčové koncepty
- Endpointy
- Dátové štruktúry
- Stavové kódy a spracovanie chýb
- Postup integrácie krok za krokom
- Príklady (curl)
- Rozhodovacia logika (pseudokód)
- Kontrolný zoznam pred spustením
- Časté chyby
1. Ako to funguje (model)
ERP odovzdá jednu faktúru (UBL XML). ePodatelna24 ju synchrónne overí, skontroluje odosielateľa aj príjemcu, zarezervuje poplatok za odoslanie a prevezme za ňu zodpovednosť (custody). Jediná odpoveď na požiadavku hovorí, či bola faktúra prijatá.
Model verzie 1 je „odovzdaj a zabudni":
202= prevzali sme zodpovednosť a faktúru odošleme. ERP už nemusí nič sledovať.4xx= faktúra bola odmietnutá (dôvod je v tele odpovede).
Keďže je odpoveď jediná spätná väzba, pred vrátením 202 sa skontroluje
všetko, čo sa skontrolovať dá:
- bezpečnosť XML (žiadne DOCTYPE/entity/XXE),
- odosielateľ (DIČ vo faktúre) je v Peppol aktívna spoločnosť pod danou peňaženkou,
- faktúra prejde Peppol BIS 3.0 / EN 16931 schematronom (validácia),
- príjemca je dosiahnuteľný v sieti Peppol (SMP vyhľadanie),
- peňaženka pokryje poplatok za odoslanie.
202 teda znamená: „overené, odosielateľ aktívny, príjemca dosiahnuteľný,
poplatok zarezervovaný — počítame s doručením."
Doručenie nesledujete. Vo verzii 1 neexistuje webhook ani dopytovanie stavu
doručenia. Po 202 preberá doručenie ePodatelna24; používateľ ho vidí v nástenke
eP24.
2. Predpoklady
- API token vygenerovaný v eP24 (viď Autentifikácia).
- Odosielajúca spoločnosť (podľa DIČ vo faktúre) je v eP24 registrovaná a Peppol-aktivovaná, a patrí pod peňaženku, ku ktorej token patrí.
- Peňaženka má dostatok kreditu na poplatok za odoslanie.
- Faktúra je platné UBL 2.1 (
InvoicealeboCreditNote) podľa profilu Peppol BIS Billing 3.0.
3. Prostredia a základné URL
| Prostredie | Základná URL | Prefix tokenu |
|---|---|---|
| Sandbox (testovanie) | https://epodatelna24-sandbox.vercel.app | ep24api_test_ |
| Produkcia | https://www.epodatelna24.sk | ep24api_prod_ |
Integráciu vždy najprv postavte a otestujte v sandboxe. Token z jedného prostredia v druhom nefunguje.
4. Autentifikácia
Schéma
Každá požiadavka nesie API token v hlavičke Authorization so schémou
Token (rovnaká schéma, akú eP24 používa voči svojmu prístupovému bodu — nie
Bearer):
Authorization: Token ep24api_prod_XXXXXXXXXXXXXXXXXXXXXXXX
Ako získať token
V eP24: prihláste sa ako vlastník peňaženky (hlavný správca) → Peňaženka → API prístup → Nový token. Token sa zobrazí iba raz — ihneď ho bezpečne uložte (na strane eP24 je uložený len jeho hash).
Rozsah tokenu
Token je na úrovni peňaženky a platí pre celú peňaženku: jedným tokenom odošlete faktúry za ktorúkoľvek spoločnosť pod danou peňaženkou. Konkrétny odosielateľ sa určí z DIČ vo faktúre — do požiadavky netreba dávať žiadny identifikátor spoločnosti.
Pre účtovnícke firmy: jedna peňaženka spravuje všetkých klientov (spoločnosti) účtovníckej firmy, takže jeden token pokryje všetkých.
Bezpečnostné pravidlá (dôležité)
- API je server-to-server. Volajte ho z backendu svojho ERP, nikdy z prehliadača. API nemá CORS a token sa nesmie dostať do prehliadača.
- Token považujte za tajomstvo (ako heslo). Neukladajte ho do klientskej aplikácie, logov ani do verzovacieho systému.
- Kompromitovaný token zneplatnite v eP24 (Peňaženka → API prístup) a vygenerujte nový.
5. Kľúčové koncepty
5.1 Idempotencia (povinná)
Každé odoslanie musí niesť hlavičku Idempotency-Key — UUID, ktoré
vygeneruje a uloží váš ERP ku konkrétnej faktúre.
- Nový kľúč = nová faktúra.
- Rovnaký kľúč = bezpečné opakovanie. Ak odoslanie zopakujete s rovnakým kľúčom (napr. po timeoute), dostanete pôvodné potvrdenie namiesto druhého odoslania.
- Kľúč sa „zaviaže" až pri úspešnom
202. Zamietnutie (4xx) kľúč nespotrebuje — po oprave a opätovnom odoslaní tej istej faktúry použite rovnaký kľúč. (Aj402kľúč uvoľní: po dobití peňaženky zopakujte s rovnakým kľúčom a dostanete čerstvé202, nie opakovanie.) - Režim je prísny. Rovnaký kľúč s bajtovo iným telom vráti
409 idempotency_conflict— nič sa neuloží, nič sa neúčtuje a pôvodný dokument zostáva nedotknutý. Zhoda sa určuje zsha256surových bajtov požiadavky, takže stačí jediná zmenená medzera. Kľúče nikdy nerecyklujte medzi dokumentmi. - Opakovanie sa validuje znova. Zopakovaná požiadavka prejde celou vstupnou
kontrolou (XML, odosielateľ, jeho aktivácia, schematron, dosiahnuteľnosť
príjemcu), takže môže vrátiť
4xxaj vtedy, keď pôvodné odoslanie uspelo. Nevyhodnocuje sa len zostatok peňaženky —402preto pri opakovaní nikdy nenastane.
Prakticky: vo svojej DB majte tabuľku (id_faktúry → idempotency_key, document_id, stav). Kľúč vytvorte raz pri prvom pokuse a používajte ho pri
všetkých opakovaniach tej istej faktúry.
5.2 Odosielateľ
Odosielateľ sa určí z DIČ (10 číslic) v bloku AccountingSupplierParty.
Poradie je záväzné:
- prvý
cbc:CompanyIDv poradí dokumentu — v bežnej faktúre je toPartyTaxScheme/CompanyID, teda IČ DPH (napr.SK2020123456); - ak jeho hodnota nekončí na 10 číslic, použije sa
cbc:EndpointID.
Z víťaznej hodnoty sa berie posledných 10 číslic. Slovenské IČ DPH je
SK + DIČ, takže krok 1 vráti DIČ. CompanyID má prednosť pred
EndpointID — ak sa líšia, EndpointID sa ignoruje.
Pozor na dlhé identifikátory.
PartyLegalEntity/CompanyIDnesie IČO (8 číslic) — to je neškodné, lebo neprejde testom na 10 číslic a prepadne sa naEndpointID. Nebezpečný je identifikátor s viac než 10 číslicami, napr. 13-miestny GLN (schemeID="0088"): pravidlo „posledných 10 číslic" z neho vyrobí neplatné DIČ, ktoré navyše zatieni správneEndpointID. Výsledkom je403 sender_not_founds DIČ, ktoré ste nikdy nevideli. Uistite sa, že prvýCompanyIDv bloku odosielateľa je daňový identifikátor.
Toto DIČ musí zodpovedať aktívnej spoločnosti pod peňaženkou tokenu, inak
dostanete 403. Pri samofaktúrach (SelfBilledInvoice alebo
CustomizationID so „selfbilling") je odosielateľom odberateľ
(AccountingCustomerParty).
5.3 Príjemca
Príjemca sa určí z AccountingCustomerParty — z cbc:EndpointID s atribútom
schemeID, ktorý tvorí Peppol identifikátor schéma:hodnota, napr.
0208:0987654321. Príjemca musí byť registrovaný a dosiahnuteľný v sieti
Peppol (overuje sa SMP vyhľadaním), inak dostanete 422 receiver_unreachable.
5.4 Validácia
Faktúra sa validuje voči vendorovanému Peppol BIS 3.0 / EN 16931 schematronu
(rovnaké pravidlá ako oficiálny Peppol validátor). Chyby sa vracajú po
jednotlivých pravidlách (id pravidla, závažnosť, XPath umiestnenie, popis).
Dokument je platný len ak má nula chýb závažnosti error/fatal (varovania
neblokujú).
5.5 Limity a formát
- Content-Type:
application/xml, kódovanie UTF-8, telo = surové UBL XML. - Maximálna veľkosť: 10 MB.
- Rate limit: cca 120 požiadaviek/min na token (
429+Retry-After). - Timeout klienta: validácia + SMP + odoslanie môžu trvať niekoľko sekúnd — nastavte timeout HTTP klienta veľkoryso (napr. 60 s).
6. Endpointy
Základná cesta: /api/v1/outbox.
6.1 POST /api/v1/outbox/documents — odoslať faktúru (prevzatie zodpovednosti)
Overí, prevezme zodpovednosť a zaradí faktúru na odoslanie.
Hlavičky
| Hlavička | Povinná | Hodnota |
|---|---|---|
Authorization | áno | Token <token> |
Content-Type | áno | application/xml |
Idempotency-Key | áno | UUID (viď 5.1) |
Telo: surové UBL XML (Invoice alebo CreditNote).
Odpovede
| Kód | Význam | Telo |
|---|---|---|
202 | Zodpovednosť prevzatá | CustodyReceipt |
200 | Idempotentné opakovanie (rovnaký kľúč) — pôvodné potvrdenie | CustodyReceipt |
400 | Poškodené/nebezpečné XML, prázdne telo, alebo chýbajúci/neplatný Idempotency-Key | Problem |
401 | Chýbajúci/neplatný token | Problem |
402 | Peňaženka nepokryje poplatok | Problem |
403 | Odosielateľ nie je aktívna spoločnosť pod peňaženkou | Problem |
409 | Idempotency-Key použitý s iným telom (porovnáva sa sha256 surových bajtov) | Problem |
413 | Dokument prekračuje 10 MB | Problem |
422 | Validácia zlyhala alebo príjemca nedosiahnuteľný | Problem + errors[] |
429 | Prekročený rate limit | Problem + Retry-After |
503 | Prístupový bod dočasne nedostupný | Problem |
6.2 POST /api/v1/outbox/documents/validate — nezáväzná validácia (dry-run)
Rovnaké kontroly ako odoslanie, ale bez prevzatia zodpovednosti, bez rezervácie a bez odoslania. Ideálne na testovanie počas integrácie.
Hlavičky: Authorization (povinná), Content-Type: application/xml.
Idempotency-Key sa neuplatňuje.
Telo: surové UBL XML.
Odpovede
| Kód | Význam | Telo |
|---|---|---|
200 | Výsledok validácie (platný aj neplatný dokument) | ValidationReport |
400 | Poškodené/nebezpečné XML alebo prázdne telo | Problem |
401 | Chýbajúci/neplatný token | Problem |
413 | Dokument prekračuje 10 MB | Problem |
429 | Prekročený rate limit | Problem + Retry-After |
7. Dátové štruktúry
7.1 CustodyReceipt
Potvrdenie o prevzatí zodpovednosti (odpoveď 202/200). Uložte si
documentId na spárovanie s vašou faktúrou.
{
"documentId": "0b8c7d1e-2f34-4a56-8b9c-1d2e3f4a5b6c", // ID dokumentu v eP24 (uuid)
"status": "accepted",
"idempotencyKey": "5980895f-56b6-4a09-a069-e118a146e622",
"senderDic": "1234567890",
"receiver": { "scheme": "0208", "value": "0987654321" },
"documentType": "Invoice", // "Invoice" | "CreditNote"
"acceptedAt": "2026-07-08T09:15:06Z" // ISO 8601 UTC
}
7.2 ValidationReport
Výsledok nezáväznej validácie (odpoveď 200 z /validate).
{
"valid": false, // true len ak errors je prázdne
"senderDic": "1234567890", // alebo null
"senderActive": true, // je odosielateľ aktívna spoločnosť pod peňaženkou?
"receiver": { "scheme": "0208", "value": "0987654321" }, // alebo null
"receiverReachable": true, // nájdený v Peppol (SMP)?
"documentType": "Invoice", // alebo null
"errors": [ /* ValidationIssue */ ],
"warnings": [ /* ValidationIssue */ ]
}
7.3 ValidationIssue
Jedno porušené pravidlo Peppol/EN 16931.
{
"rule": "PEPPOL-EN16931-R010", // id pravidla (napr. BR-CO-15, BR-16)
"severity": "error", // "fatal" | "error" | "warning"
"location": "/Invoice/cac:AccountingSupplierParty/cac:Party/cbc:EndpointID", // XPath alebo null
"message": "Buyer electronic address MUST be provided."
}
7.4 Problem (RFC 7807)
Chybová odpoveď (application/problem+json). Vetvite podľa poľa code
(stabilné, strojovo čitateľné).
{
"type": "https://www.epodatelna24.sk/errors/insufficient_funds",
"title": "Insufficient funds",
"status": 402,
"code": "insufficient_funds", // stabilný kód — viď tabuľka nižšie
"detail": "Wallet balance 0.12 EUR is below the send fee 0.22 EUR."
}
Možné hodnoty code: invalid_xml, unauthorized, insufficient_funds,
sender_not_found, sender_not_active, idempotency_conflict,
missing_idempotency_key, too_large, validation_failed,
receiver_unreachable, rate_limited, upstream_unavailable.
7.5 Problem pri 422
Pri 422 nesie Problem navyše zoznam porušených pravidiel:
{
"type": "https://www.epodatelna24.sk/errors/validation_failed",
"title": "Peppol validation failed",
"status": 422,
"code": "validation_failed",
"detail": "The document violates 2 Peppol BIS 3.0 rules.",
"valid": false,
"errors": [ /* ValidationIssue */ ],
"warnings": [ /* ValidationIssue */ ]
}
8. Stavové kódy a spracovanie chýb
| Kód | code | Čo znamená | Čo má ERP urobiť |
|---|---|---|---|
202 | — | Zodpovednosť prevzatá | Ulož documentId. Hotovo. |
200 | — | Idempotentné opakovanie | Túto faktúru si už prijal; použi vrátené documentId. |
400 | invalid_xml | Poškodené/nebezpečné XML | Oprav generovanie XML. Neopakuj naslepo. |
400 | missing_idempotency_key | Chýba/neplatný Idempotency-Key | Pridaj platné UUID. |
401 | unauthorized | Zlý/zneplatnený token | Skontroluj token; prípadne vygeneruj nový. |
402 | insufficient_funds | Nedostatok kreditu | Upozorni používateľa, nech dobije peňaženku; opakuj neskôr (rovnaký kľúč). |
403 | sender_not_found | DIČ odosielateľa nie je pod peňaženkou | Zaregistruj spoločnosť v eP24. |
403 | sender_not_active | Spoločnosť ešte nie je Peppol-aktívna | Počkaj na aktiváciu, potom opakuj. |
413 | too_large | > 10 MB | Zmenši dokument. |
422 | validation_failed | Faktúra porušuje pravidlá | Zobraz errors[], oprav XML, opakuj (rovnaký kľúč). |
422 | receiver_unreachable | Príjemca nie je v Peppol | Over Peppol identifikátor príjemcu. |
429 | rate_limited | Priveľa požiadaviek | Počkaj Retry-After sekúnd, opakuj (rovnaký kľúč). |
503 | upstream_unavailable | Dočasný výpadok | Exponenciálny backoff, opakuj (rovnaký kľúč). |
Pravidlo: 429 a 503 (a 402 po dobití) sú opakovateľné s rovnakým
kľúčom. 400/401/403/422 vyžadujú opravu — neopakuj bezo zmeny.
9. Postup integrácie krok za krokom
- Vygeneruj token v eP24 (sandbox) a ulož ho bezpečne na serveri.
- Priprav UBL XML faktúry (Peppol BIS 3.0). Uisti sa, že DIČ odosielateľa a Peppol identifikátor príjemcu sú správne (viď 5.2, 5.3).
- (Voliteľné, odporúčané počas vývoja) zavolaj
POST …/documents/validatea skontrolujvalid,senderActive,receiverReachable. Oprav chyby zerrors[]. - Vygeneruj
Idempotency-Key(UUID) a ulož ho vo svojej DB spolu s ID faktúry (stav =pending). - Zavolaj
POST …/documentss hlavičkamiAuthorization,Content-Type: application/xml,Idempotency-Keya telom = XML. Timeout klienta ~60 s. - Vetvi podľa stavu (tabuľka v kap. 8):
202/200→ uloždocumentId, stav =accepted. Hotovo.429/503/402→ naplánuj opakovanie s rovnakým kľúčom (backoff).422→ zobraz chyby, oprav faktúru, opakuj s rovnakým kľúčom.400/401/403→ chyba konfigurácie/dát; vyrieš a až potom opakuj.
- Doručenie nesleduj. Po
202je faktúra v rukách eP24; stav doručenia používateľ vidí v nástenke eP24.
Tip na spoľahlivosť: ak vám klient spadne po odoslaní a neviete, či požiadavka prešla, jednoducho ju zopakujte s rovnakým kľúčom — dostanete buď pôvodné
200, alebo (ak sa prvý pokus vôbec nespracoval) čerstvé202.
10. Príklady (curl)
Nezáväzná validácia
curl -X POST "https://epodatelna24-sandbox.vercel.app/api/v1/outbox/documents/validate" \
-H "Authorization: Token ep24api_test_XXXXXXXX" \
-H "Content-Type: application/xml" \
--data-binary @invoice.xml
Odoslanie (prevzatie zodpovednosti)
curl -X POST "https://epodatelna24-sandbox.vercel.app/api/v1/outbox/documents" \
-H "Authorization: Token ep24api_test_XXXXXXXX" \
-H "Content-Type: application/xml" \
-H "Idempotency-Key: 5980895f-56b6-4a09-a069-e118a146e622" \
--data-binary @invoice.xml
Úspech (202):
{ "documentId": "0b8c7d1e-…", "status": "accepted", "senderDic": "1234567890",
"receiver": { "scheme": "0208", "value": "0987654321" },
"documentType": "Invoice", "acceptedAt": "2026-07-08T09:15:06Z" }
Neplatná faktúra (422):
{ "code": "validation_failed", "status": 422,
"detail": "The document violates 1 Peppol BIS 3.0 rule(s).",
"valid": false,
"errors": [ { "rule": "BR-16", "severity": "error",
"location": "/Invoice/cac:InvoiceLine",
"message": "An Invoice must have at least one Invoice line." } ] }
Bezpečné opakovanie (rovnaký kľúč → 200)
# rovnaká faktúra, rovnaký Idempotency-Key → pôvodné potvrdenie, nie druhé odoslanie
curl -X POST "https://epodatelna24-sandbox.vercel.app/api/v1/outbox/documents" \
-H "Authorization: Token ep24api_test_XXXXXXXX" \
-H "Content-Type: application/xml" \
-H "Idempotency-Key: 5980895f-56b6-4a09-a069-e118a146e622" \
--data-binary @invoice.xml
11. Rozhodovacia logika (pseudokód)
function odosli(faktura):
kluc = faktura.idempotency_key or nove_uuid() # vytvor raz, ulož
uloz(faktura.id, kluc, stav="pending")
odpoved = HTTP_POST(base + "/api/v1/outbox/documents",
headers = { Authorization: "Token " + TOKEN,
"Content-Type": "application/xml",
"Idempotency-Key": kluc },
body = faktura.xml,
timeout = 60s)
switch odpoved.status:
case 202, 200:
uloz_document_id(faktura.id, odpoved.body.documentId, stav="accepted")
return HOTOVO
case 422:
zobraz_chyby(odpoved.body.errors) # oprav XML, potom odosli() znova (rovnaký kľúč)
return OPRAV
case 429, 503:
pockaj(odpoved.headers["Retry-After"] or backoff())
return odosli(faktura) # rovnaký kľúč
case 402:
upozorni_dobit_penazenku() # opakuj neskôr, rovnaký kľúč
return CAKA
case 400, 401, 403:
zaloguj_chybu(odpoved.body.code, odpoved.body.detail) # vyrieš konfiguráciu/dáta
return CHYBA
Hotová referenčná implementácia tejto logiky je v
lib/ep24-client.ts (funkcie submitDocument,
validateDocument, classifySubmit). Serverový proxy (vzor „backend ERP volá
API") je v app/actions.ts.
Generovanie klienta: OpenAPI špecifikácia je na
…/api-docs/openapi.yaml. Vo väčšine jazykov z nej viete vygenerovať typového klienta (napr.openapi-generator,NSwagpre .NET,openapi-python-client).
12. Kontrolný zoznam pred spustením
- Token uložený bezpečne na serveri, volania idú z backendu (nie z prehliadača).
-
Idempotency-Keysa generuje raz na faktúru a je uložený vo vašej DB. - Ošetrené všetky stavové kódy z kap. 8.
- Opakovania pri
429/503/402používajú rovnaký kľúč a backoff. - Timeout HTTP klienta ≥ 60 s.
-
documentIdz202/200je uložené a spárované s vašou faktúrou. - Otestované v sandboxe end-to-end pred prepnutím na produkciu.
- Produkčný token má prefix
ep24api_prod_, sandboxep24api_test_.
12a. Prostredia v simulátore
Simulátor má prepínač Sandbox / Produkcia / Vlastná URL. Pri každom
prostredí zobrazí odkaz na vytvorenie tokenu (Peňaženka → API prístup → Nový
token) a očakávaný prefix; ak token prefixu nezodpovedá, upozorní ešte pred
odoslaním (token z iného prostredia vráti 401).
| Prostredie | Základná URL | Token | Vytvorenie tokenu |
|---|---|---|---|
| Sandbox | https://epodatelna24-sandbox.vercel.app | ep24api_test_ | /dashboard/wallet |
| Produkcia | https://www.epodatelna24.sk | ep24api_prod_ | /dashboard/wallet |
Poistky v produkcii
V produkcii sa platná faktúra reálne doručí cez sieť Peppol, prevezme sa zodpovednosť a peňaženka sa zaťaží poplatkom — nedá sa to vziať späť. Preto:
- Simulátor vždy štartuje v Sandboxe a voľbu prostredia neukladá — návrat na stránku, ktorá si potichu pamätá „Produkcia", je presne to, ako sa omylom odošle skutočná faktúra.
- Zobrazí sa výrazný červený banner a v hlavičke červený štítok
PRODUKCIA. - Testovacie scenáre sú vypnuté — ich vzorové faktúry by sa reálne odoslali.
- „Odoslať" je zamknuté, kým používateľ nezaškrtne potvrdenie. Jedno potvrdenie = jedno odoslanie: po odoslaní (aj po načítaní iného dokumentu) sa zaškrtnutie zruší.
- „Odoslať" je červené a premenované na „Odoslať naozaj (produkcia)"; „Validovať" sa stáva primárnou akciou — je nezáväzné, nepreberá zodpovednosť a nič neúčtuje.
12c. Demo firmy vo vyhradenom sandbox tenante
Sandbox vyhradzuje pre simulátor pevný tenant. Voči nemu je nasledujúcich šesť
DIČ konštantných — po každom POST /api/sandbox/reset sa obnovia bajt po
bajte a sú stabilné aj naprieč nasadeniami.
| DIČ | Obchodné meno | Doručovacia adresa |
|---|---|---|
9999999991 | Kaviareň Luna s.r.o. | demo+999999999-1@sandbox.epodatelna24.sk |
9999999992 | Stavebniny Tatra a.s. | demo+999999999-2@sandbox.epodatelna24.sk |
9999999993 | Pekáreň Zlatý klas s.r.o. | demo+999999999-3@sandbox.epodatelna24.sk |
9999999994 | IT Solutions Východ s.r.o. | demo+999999999-4@sandbox.epodatelna24.sk |
9999999995 | Autoservis Rapid s.r.o. | demo+999999999-5@sandbox.epodatelna24.sk |
9999999996 | Účtovníctvo Profit s.r.o. | demo+999999999-6@sandbox.epodatelna24.sk |
Vlastná fakturačná identita eP24 (rovnaká pre každý tenant): IČO 54000111,
DIČ 2120000111.
Pravidlá
- Hardcodujte len týchto šesť hodnôt. DIČ nikdy negenerujte —
companies.dicjenot null unique check (dic ~ '^\d{10}$'), takže neznáme DIČ nerozpozná žiadnu spoločnosť a kolidujúce zlyhá. - Len pod vyhradeným uid. Iná relácia (aj anonymná) dostane namespace
odvodený z
hashtext(uid)a tieto DIČ mať nebude. - Maximálne deväť klientov — DIČ je 9 číslic namespace + jednociferný index.
- Reset je idempotentný, medzi scenármi ho môžete volať voľne.
- Spoločnosti nevytvárajte priamo — seedujte cez sandbox, nech ostanú konzistentné väzby na členstvo, peňaženku a doručovanie.
Zatiaľ nie sú aktívne. Seed zmena ešte nie je zlúčená a servisné uid ešte nebolo vydané. Vzory preto stále používajú vlastného odosielateľa integrátora. Otvorené otázky (ako sa autentifikovať ako vyhradený tenant a ako demo firmu adresovať ako príjemcu v UBL) sú v MEMO_REPLY_TENANT.md.
Pozor na
9999999997–9999999999. Sú to platné indexy klientov 7–9 vo vyhradenom namespace, dnes neobsadené. Vzor presender_not_foundpreto nepoužíva9999999999, ale8888888888— inak by po doseedovaní troch klientov namiesto403vrátil skutočné202.
12b. Testovacie scenáre v simulátore
Simulátor obsahuje rozbaľovací výber „Testovací scenár“, ktorý načíta
vzorové XML (public/invoice.xml a public/samples/) a — pri výsledkoch
riadených hlavičkou alebo veľkosťou — pri odoslaní upraví požiadavku tak, aby
priviedla presne k danému kódu. Vzory používajú existujúceho odosielateľa
Kaviareň Luna s.r.o., DIČ 4706056521 (okrem scenára sender_not_found,
ktorý má zámerne neregistrované DIČ). Pri každom scenári sa zobrazí očakávaný
stav, code a miera reprodukovateľnosti:
| Scenár | Výsledok | Reprodukovateľnosť | Ako vzniká |
|---|---|---|---|
| Prijaté | 202 | závisí od peňaženky | platné XML + váš aktívny DIČ + dosiahnuteľný príjemca |
| Idempotentné opakovanie | 200 | závisí od peňaženky | 202, potom to isté odoslať s rovnakým kľúčom |
invalid_xml | 400 | deterministické | telo nie je well-formed XML |
missing_idempotency_key | 400 | deterministické | odoslanie bez Idempotency-Key |
unauthorized | 401 | deterministické | nesprávny token |
insufficient_funds | 402 | vynútené v Sandboxe | X-Ep24-Simulate: insufficient_funds |
sender_not_found | 403 | deterministické | DIČ dodávateľa nie je pod peňaženkou |
sender_not_active | 403 | vynútené v Sandboxe | X-Ep24-Simulate: sender_not_active |
idempotency_conflict | 409 | závisí od peňaženky | rovnaký kľúč, bajtovo iné telo (najprv treba 202) |
too_large | 413 | deterministické | telo sa pri odoslaní nafúkne nad limit |
validation_failed | 422 | deterministické | chýba el. adresa odberateľa (PEPPOL-EN16931-R010) |
receiver_unreachable | 422 | v sandboxe nereprodukovateľné | sandbox nemá SMP — vyžaduje simulate trigger |
rate_limited | 429 | vynútené v Sandboxe | X-Ep24-Simulate: rate_limited (reálny limit je per-inštancia) |
upstream_unavailable | 503 | vynútené v Sandboxe | X-Ep24-Simulate: upstream_unavailable |
Scenáre označené „deterministické" dajú vždy rovnaký výsledok.
Sandbox vie výsledky vynútiť. Sandbox prijíma hlavičku
X-Ep24-Simulate: insufficient_funds | sender_not_active | upstream_unavailable | rate_limited, ktorá vynúti daný výsledok. Simulátor ju pri týchto štyroch scenároch posiela automaticky — takže v Sandboxe dostanete skutočnú odpoveď zo servera, nie lokálnu ukážku. Požiadavka najprv prejde bežnou kontrolou (auth, kľúč, telo) a odpoveď nesie hlavičkuX-Ep24-Simulated. V produkcii sa hlavička vôbec nečíta, preto tam ostávajú tieto scenáre nevynútiteľné a odoslanie je pri nich vypnuté.Pozor:
openapi.yamlna sandboxe a v produkcii sa líšia — sandbox dokumentujeX-Ep24-Simulate, produkcia nie. Detaily v MEMO_REPLY.md.
Sandbox nemá register účastníkov (SMP). Mock vracia
exists:truepre ľubovoľný identifikátor, takže dosiahnuteľnosť príjemcu sa nevyhodnocuje a422 receiver_unreachablesa v sandboxe nedá vyvolať vôbec: bezschemeIDporuší XML pravidloBR-63a validácia (ktorá beží skôr) vrátivalidation_failed; s platným identifikátorom prejde ako202. Dôsledok: sandboxové202nie je dôkaz, že faktúra prejde v produkcii. Vzory si overujte priamo voči schematronu —npm run validate:fixtures.
Dve rôzne
413: nad ~4,5 MB odmietne telo platforma pred autentifikáciou (text/plain); 4–4,5 MB s platným tokenom vráti API vlastné413s telomProblemaž po autentifikácii. Pri413preto vždy kontrolujteContent-Type, než telo parsujete ako JSON.
Štyri výsledky sa nedajú vynútiť požiadavkou — insufficient_funds (402),
sender_not_active (403), rate_limited (429) a upstream_unavailable (503).
Ich vzor je platná faktúra s aktívnym odosielateľom, takže skutočné odoslanie
by skončilo ako 202 (prijaté) a prevzalo zodpovednosť — čo vyzerá ako falošný
úspech. Preto je pri nich tlačidlo „Odoslať“ vypnuté a namiesto neho
ponúkame „Zobraziť ukážkovú odpoveď“: telo Problem (RFC 7807) sa vykreslí
lokálne, zreteľne označené ako SIMULOVANÉ, aby si ERP vývojár pozrel presný
tvar odpovede, na ktorý má vetviť. Tlačidlo „Validovať“ zostáva aktívne — je
nezáväzné a pri sender_not_active v poli senderActive priamo uvidíte stav
odosielateľa.
13. Časté chyby
403 sender_not_found— DIČ odosielateľa nie je registrovaný pod vašou peňaženkou. Vzorové faktúry používajú existujúceho odosielateľa Kaviareň Luna s.r.o., DIČ4706056521; ak patrí pod inú peňaženku než váš token, nahraďte ho vlastným DIČ. (Scenár „403 · sender_not_found“ používa zámerne neregistrované DIČ9999999999.)- Volanie z prehliadača zlyhá (CORS) — API je server-to-server. Volajte z backendu.
- Druhé odoslanie vytvorí duplicitu — nezabudnite posielať rovnaký
Idempotency-Keypri opakovaní tej istej faktúry. - Timeout na strane klienta — validácia + SMP + odoslanie trvajú pár sekúnd; zvýšte timeout na ~60 s.
422 receiver_unreachable— príjemca nie je registrovaný v Peppol; overte jeho identifikátor (schéma:hodnota, napr.0208:…).
Referencie: interaktívna dokumentácia a OpenAPI —
/api-docs ·
/api-docs/openapi.yaml
Otázky → tím ePodatelna24.