Croatia — Fiskalizacija (CIS)
Research doc for the Croatia fiscalization adapter. Consumed by the implementation bead (sibling of fi-g40 for Hungary). No code in this bead.
Status: Research — no adapter code written yet.
Strategic context: Phase-1 Central/Adriatic cluster, paired with Hungary
and Slovenia (fi-7en). The cluster's only country requiring a paid annual
certificate (FINA), and the only one that performs real cryptographic signing
on every fiscalization request. ~250K obligated taxpayers. Mandatory since
2013-01-01. See apps/docs-internal/docs/ops/country-prioritization.md and
the Phase-1 thesis (fi-awx).
Cloud-OK caveat. Unlike Hungary (REST + tokens, no cert) Croatia requires a FINA application certificate per fiscal device for XML-DSig signing of every SOAP request plus computation of a per-receipt ZKI (issuer protection code). The cert is a pure software credential (PKCS#12) — no HSM, no hardware seal — so Cloud deployment remains viable, but key custody and rotation are real ops surface. See §3 and §9 ("What could force us off Cloud-OK?").
1. Regulatory scope
What must be reported
Croatia's Fiskalizacija system, operated by Porezna uprava (PU — the Tax Administration) through APIS-IT's CIS (Centralni Informacijski Sustav — Central Information System), requires real-time reporting of every cash receipt issued by a fiscal-obligated taxpayer. The legal basis is the Zakon o fiskalizaciji u prometu gotovinom (Fiscalization in Cash Transactions Act, NN 133/12; consolidated text in NN 115/16, 106/18, 121/19, 138/20, 114/22, 152/22). Cited from https://www.porezna-uprava.hr/HR_Fiskalizacija/.
| Effective date | Scope change |
|---|---|
| 2013-01-01 | Stage 1 launch — mandatory for hospitality + freelance professionals issuing cash receipts (gotovinski računi). |
| 2013-04-01 | Stage 2 — wholesale & retail trade. |
| 2013-07-01 | Stage 3 — all other taxpayers obligated to report cash receipts. |
| 2017 | Added OznSlijed (sequencing-marker selector) to the schema; Hrvatska Pošta integration milestone. |
| 2019-01-01 | Schema v1.5 — added support for buyer OIB on receipts (KupacOib). |
| 2023-01-01 | Croatia adopts EUR; receipts denominated in EUR (HRK no longer issued). |
| 2025-09-01 | Fiskalizacija 2.0 — staged rollout begins. Adds tip reporting (NapojnicaZahtjev), supplemental fields for PrateciDokument, and groundwork for mandatory B2B/B2G eRačun by 2026-01-01. This adapter targets the v1.x cash-receipt envelope first; 2.0 fields are listed in §10 open questions. |
| 2026-01-01 | Mandatory eRačun (electronic invoice) for all B2B and B2G — separate flow (see §1.4 below). |
Cash-receipt threshold: none. Every cash, card, or other-non-bank-transfer receipt issued by an obligated taxpayer must be fiscalized in real-time (or within the 48-hour offline grace window — §6).
What is not in scope of RacunZahtjev
- Bank-transfer-only invoices (transakcijski račun → transakcijski račun): not fiscalized through CIS as a cash receipt; from 2026-01-01 they fall under mandatory eRačun via the FINA Servis eRačun platform (see §1.4).
- Receipts of non-fiscal-obligated entities (state organs in non-economic activity, certain agriculture exemptions, lottery, gambling — listed in Article 5 of the Act).
- Pre-2013 historical receipts — no backfill obligation.
- Internal documents (računi za vlastite potrebe) — not transmitted.
eRačun (separate track — out of scope for this adapter)
Croatia's mandatory B2B/B2G electronic invoicing system as of 2026-01-01 is eRačun, operated through FINA's Servis eRačun za državu and the e-poslovanje network. It uses UBL 2.1 / EN 16931 (CIUS HR-CEN), routing through the Peppol network (FINA is the Peppol Authority for Croatia). The endpoints and message format are entirely different from CIS Fiskalizacija:
| Fiskalizacija (this adapter) | eRačun (separate track) | |
|---|---|---|
| Purpose | Real-time cash-receipt reporting to PU | Structured electronic B2B/B2G invoice exchange |
| Format | Custom XML (f73:RacunZahtjev) | UBL 2.1 + CIUS HR-CEN |
| Transport | SOAP 1.1 with WS-Security signing | Peppol AS4 / HTTP POST to FINA gateway |
| Authority | Porezna uprava / CIS | FINA + Ministry of Finance |
| Fiscal IDs | JIR + ZKI | UUID + Peppol message ID |
| Mandatory since | 2013-01-01 | 2026-01-01 (B2B/B2G) |
This adapter implements Fiskalizacija only. A separate eRačun adapter is tracked under fi-fjm cluster validation. Many merchants will need both — the cash receipt fiscalized through CIS, and (for B2B sales) a structured eRačun submitted via FINA. The two systems do not share state.
Obligated parties
| Form | Who | OIB type |
|---|---|---|
| Pravna osoba | Limited companies (d.o.o., j.d.o.o., d.d.) — corporate | OIB of the legal entity |
| Obrt | Sole proprietors / craftspeople | OIB of the natural person |
| Slobodno zanimanje | Freelance professionals (lawyers, doctors, etc.) | OIB of the natural person |
| Paušalni obrt | Lump-sum-tax sole proprietors | OIB of the natural person |
| Branch of foreign entity | Croatian branch of foreign business | OIB issued to the branch |
The taxpayer's OIB (Osobni identifikacijski broj — 11-digit personal/tax identification number) is the primary key throughout the schema.
2. API surface
Base URLs and ports
| Environment | Endpoint (host:port/path) | Notes |
|---|---|---|
| CIS DEMO (sandbox) | https://cistest.apis-it.hr:8449/FiskalizacijaServiceTest | APIS-IT-hosted test environment. Requires FINA demo application certificate (free, see §7). |
| CIS Production | https://cis.porezna-uprava.hr:8449/FiskalizacijaService | Production. Requires FINA production application certificate (paid, see §3). |
Cited from porezna-uprava.gov.hr → "Tehnička specifikacija za korisnike" v1.5+ (Technical specification for fiscalization users) and APIS-IT's public CIS service WSDL.
Port 8449. Both environments listen on TCP 8449, not 443. Outbound firewall rules in customer infrastructure must allow that port. (Common first-day onboarding miss — flag in the integration runbook.)
Protocol
SOAP 1.1 over HTTPS with mutual TLS (mTLS) using the FINA application
certificate as the client cert, plus XML-DSig (W3C XML Digital Signature,
enveloped form) signing the SOAP <Body>. Content-Type: text/xml; charset=UTF-8. SOAPAction header is empty ("") — CIS dispatches by body
element name, not by SOAPAction.
The v1.x schema namespace is http://www.apis-it.hr/fin/2012/types/f73.
A WSDL is published at the test endpoint
https://cistest.apis-it.hr:8449/FiskalizacijaServiceTest?wsdl.
Operations
All operations are POST; the request and response top-level elements live in
the f73 namespace.
| Operation | Request element | Response element | Purpose |
|---|---|---|---|
| Echo (health) | EchoRequest | EchoResponse | Bidirectional liveness probe; returns the request payload string. No signature required. Use as smoke test. |
| Fiscalize cash receipt | RacunZahtjev | RacunOdgovor | The hot path. Submit a single fiscal receipt. Returns Jir (or error). |
| Subsequent delivery (offline catch-up) | RacunZahtjev with NakDost=true | RacunOdgovor | Same envelope, flag bit set; used for receipts issued during an offline window. |
| Supporting document | PrateciDokumentZahtjev (PD) | PrateciDokumentOdgovor | "Prateci dokument" — the goods-with-document flow used when the receipt issued at delivery is not yet a fiscal receipt (e.g. delivery-then-pay scenarios). Returns a JIR for the PD. |
| Verify by JIR/ZKI | ProvjeraZahtjev | ProvjeraOdgovor | (Test environment only.) Lookup an issued receipt by its Jir / ZKI. Production has the public web verifier instead. |
| Tip (Fiskalizacija 2.0) | NapojnicaZahtjev | NapojnicaOdgovor | Report tip ("napojnica") attached to a previously fiscalized receipt. v2.0 schema (f95 namespace, see §10). |
Adapter hot path (v1.x): RacunZahtjev → RacunOdgovor.
XML structure (the RacunZahtjev SOAP envelope)
<soapenv:Envelope xmlns:f73="http://www.apis-it.hr/fin/2012/types/f73">
<soapenv:Header/>
<soapenv:Body>
<f73:RacunZahtjev Id="signXmlId">
<f73:Zaglavlje> <!-- header -->
<f73:IdPoruke>UUID</f73:IdPoruke>
<f73:DatumVrijeme>YYYY-MM-DDTHH:MM:SS</f73:DatumVrijeme>
</f73:Zaglavlje>
<f73:Racun> <!-- the fiscal receipt -->
<f73:Oib>11111111119</f73:Oib>
<f73:USustPdv>true</f73:USustPdv>
<f73:DatVrijeme>DD.MM.YYYYTHH:MM:SS</f73:DatVrijeme>
<f73:OznSlijed>P|N</f73:OznSlijed>
<f73:BrRac>
<f73:BrOznRac>1</f73:BrOznRac>
<f73:OznPosPr>POSL1</f73:OznPosPr>
<f73:OznNapUr>1</f73:OznNapUr>
</f73:BrRac>
<f73:Pdv>
<f73:Porez>
<f73:Stopa>25.00</f73:Stopa>
<f73:Osnovica>40.00</f73:Osnovica>
<f73:Iznos>10.00</f73:Iznos>
</f73:Porez>
</f73:Pdv>
<!-- optional: Pnp (sales tax), OstaliPor (other taxes), Naknade -->
<f73:IznosUkupno>50.00</f73:IznosUkupno>
<f73:NacinPlac>G</f73:NacinPlac> <!-- G/K/T/O/C -->
<f73:OibOper>11111111119</f73:OibOper> <!-- operator OIB -->
<f73:ZastKod>32-hex-MD5</f73:ZastKod> <!-- ZKI, computed locally -->
<f73:NakDost>false</f73:NakDost> <!-- subsequent-delivery flag -->
<!-- optional: ParagonBrRac, SpecNamj, KupacOib, NakDostId... -->
</f73:Racun>
<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
<!-- enveloped XML-DSig over the RacunZahtjev element -->
</Signature>
</f73:RacunZahtjev>
</soapenv:Body>
</soapenv:Envelope>
The <Signature> is inside <f73:RacunZahtjev> — enveloped form per
W3C XML-DSig — and references the parent by Id="signXmlId". The server
expects exactly this layout; a detached or enveloping signature fails with
SOAP fault s002.
Response shape
Happy path:
<f73:RacunOdgovor>
<f73:Zaglavlje>
<f73:IdPoruke>UUID-echoed</f73:IdPoruke>
<f73:DatumVrijeme>DD.MM.YYYYTHH:MM:SS</f73:DatumVrijeme>
</f73:Zaglavlje>
<f73:Jir>e2956e8a-1f63-43a5-86c6-9be0c6f0fdf8</f73:Jir>
<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">…</Signature>
</f73:RacunOdgovor>
The Jir (Jedinstveni identifikator računa — Unique Receipt Identifier)
is a UUID-shaped 36-char string. CIS signs the response with the Porezna
uprava certificate; the adapter must verify that signature against the
embedded certificate's chain to a known PU root, otherwise we cannot trust
the JIR.
Error path: SOAP <faultcode> + <faultstring> with structured
<f73:PorukaGreske> containing <f73:SifraGreske> + text. See §8.
3. Authentication
The FINA application certificate
CIS authenticates and authorizes via a FINA-issued application certificate ("FINA RDC" — Razvoj digitalnih certifikata) for fiscalization. There are two cert types in operation:
| Type | Purpose | Cost | Validity |
|---|---|---|---|
| PRODUKCIJSKA aplikacijska certifikat (production) | Sign + mTLS to cis.porezna-uprava.hr | ~€60 first issuance, ~€53 renewal (2026 prices, single-cert FISKAL package; varies by FINA package) | 5 years |
| DEMO aplikacijska certifikat (test) | Sign + mTLS to cistest.apis-it.hr | Free | 5 years |
Pricing — current. FINA price-list (2026-04, Naknade RDC): production
"FISKAL 1" application certificate is €59.79 inclusive of VAT at first
issuance, €53.16 at renewal. Earlier FiscalAPI internal estimates of
"€50/yr" remain materially correct amortised over the 5-year validity
(€59.79 ÷ 5 = €11.96/yr first cycle); the bead's "€50/yr" figure was the
one-shot procurement cost, not the annualised cost. Document this
distinction in customer onboarding — many merchants assume €50/yr ongoing
when the actual TCO is closer to €11/yr after the initial purchase.
Per fiscal device or per legal entity? Per legal entity is the FINA default (one cert per OIB), and the cert may be installed on multiple fiscal devices belonging to that OIB. Per-device certs are an option but rarely worth the extra cost. Our adapter therefore models the cert as a per-tenant credential (one certificate object per merchant OIB), not per location.
Cited: FINA "Cjenik usluga" v2026-04-01, https://www.fina.hr/cjenik-usluga-rdc.
Cert lifecycle
- Procurement — merchant goes to a FINA office (or uses FINA online
identification) with company registration documents. Receives a CD/USB
stick or download link with a
.pfx(PKCS#12) file plus a one-time-use activation password. - Activation — within 30 days of issuance, the merchant logs into FINA's Mojcert portal and downloads the activated PKCS#12. After this point the password is set by the merchant.
- Upload to Zyntem —
POST /v1/certificateswith the PKCS#12 bytes and the merchant-set password. Stored AES-encrypted at rest, key in KMS. We track:oibderived from the cert'sserialNumber(extension OID2.5.4.5) — must equal the merchant's tax OIB.not_before/not_afterfromtbsCertificate.validity.- SHA-256 thumbprint for audit.
- Issuer DN (we recognise:
OU=RDC 2020, O=Financijska agencija, C=HRfor v3 production CA;OU=Demo CA, O=Financijska agencija, C=HRfor demo).
- Use — for every receipt:
- Compute ZKI (§3 below), embedding the cert's RSA private key as the signing key.
- Sign the SOAP envelope with XML-DSig (RSA-SHA1 in v1.x — yes, SHA-1, this is the spec. v2.0 will permit RSA-SHA256; details in §10).
- mTLS handshake with the same cert.
- Renewal alerts — webhook fires 60 days, 30 days, 7 days before
not_after. Customer must renew before then or fiscalization stops. - Revocation — FINA publishes CRL; we check before each session-start (cached 4h). On revocation, mark cert disabled, alert merchant.
ZKI (Zaštitni kod izdavatelja — Issuer Protection Code)
ZKI is a locally computed 32-character lowercase hex digest that ties the receipt content to the issuer's certificate without the tax authority needing to verify the signature itself. It is printed on the customer-facing receipt alongside the JIR.
Pre-image (concatenation, no separators):
ZKI_input = OIB # 11 digits
|| DatVrijeme as DD.MM.YYYYTHH:MM:SS
|| BrOznRac # invoice number (string)
|| OznPosPr # business premise mark
|| OznNapUr # cash register mark
|| IznosUkupno # total, formatted with comma decimal, e.g. "50,00"
Algorithm (v1.x):
sig = RSA-SHA1-sign(privkey_from_cert, ZKI_input) # 256 bytes (for 2048-bit key)
ZKI = lowercase(hex(MD5(sig))) # 32 hex chars
The IznosUkupno formatting matters — Croatian locale uses a comma decimal
separator, two decimals always, no thousands separator. 1234.50 is
"1234,50". Mismatched formatting silently produces a different ZKI; CIS
won't reject it, but the receipt won't verify against the public lookup tool.
Algorithm (v2.0, optional):
In Fiskalizacija 2.0 (rolling out from 2025-09-01) RacunZahtjev accepts
a ZastKodv2 field with RSA-SHA256 + SHA-256 digest. v1.x ZKI is still
accepted. We default to v1.x and feature-flag v2.0 in HungaryConfig's
sister CroatiaConfig.
Reference XML-DSig parameters (signing the SOAP body)
| Parameter | Value |
|---|---|
| Canonicalization | http://www.w3.org/TR/2001/REC-xml-c14n-20010315 (Exclusive XML-C14N) |
| Signature algorithm | http://www.w3.org/2000/09/xmldsig#rsa-sha1 (v1.x) |
| Digest algorithm | http://www.w3.org/2000/09/xmldsig#sha1 (v1.x) |
| Reference URI | #signXmlId (id-attr on the RacunZahtjev element) |
| Transform | enveloped-signature + exclusive c14n |
| KeyInfo | <X509Data><X509Certificate> (base64 DER of leaf cert) |
The CIS server is strict: missing xmlns:soapenv on the canonicalized body,
extra whitespace, or a wrong canonicalization mode all cause s002 ("Neispravan
digitalni potpis" — Invalid digital signature).
4. Payload shape
Racun element fields (cited from FiskalizacijaSchema XSD v1.5)
| Element | Cardinality | Type / values | Notes |
|---|---|---|---|
Oib | 1 | string, exactly 11 digits | Issuer's OIB. Must equal the OIB embedded in the signing cert. |
USustPdv | 1 | bool (true / false) | True if the issuer is in the VAT system. False suppresses Pdv block. |
DatVrijeme | 1 | string dd.MM.yyyy'T'HH:mm:ss | Issuance datetime in Croatian-locale format with literal T separator. Not ISO-8601. Local time (Europe/Zagreb), no timezone offset. |
OznSlijed | 1 | enum P / N | Sequence selector. P = sequence per business premise (PoslovniProstor); N = sequence per cash register (NaplatniUredjaj). Set once for the location, immutable for the calendar year. |
BrRac | 1 | composite | Receipt number triple (see below). |
Pdv | 0..1 | array of Porez | VAT rate breakdown — required when USustPdv=true. |
Pnp | 0..1 | array of Porez | Porez na potrošnju — local consumption tax (cities/municipalities, max 3%; mostly hospitality). |
OstaliPor | 0..1 | array of OstPorez | Other taxes (tobacco, fuel, alcohol excise reported as line items where applicable). |
IznosOslobPdv | 0..1 | string decimal | Net amount exempt from VAT (Article 39 / 41 / 44 / 45 of VAT Act). |
IznosMarza | 0..1 | string decimal | Margin-scheme net (used goods, travel agencies). |
IznosNePodlOpor | 0..1 | string decimal | Amount not subject to taxation. |
Naknade | 0..1 | array of Naknada | Supplemental fees (e.g. packaging fee). |
IznosUkupno | 1 | string decimal 0.00 | Total including all VAT/tax/fees. Comma-decimal format used in ZKI input but XML stays dot-decimal (the XSD type is decimal). |
NacinPlac | 1 | enum | Payment method (see below). |
OibOper | 1 | string, 11 digits | OIB of the operator (cashier) — always a natural person's OIB. |
ZastKod | 1 | string, 32 lowercase hex chars | ZKI computed per §3. |
NakDost | 1 | bool | true = subsequent delivery (offline catch-up). False on hot path. |
ParagonBrRac | 0..1 | string | Paragon-block number when issuing from the manual paragon block during a CIS outage. |
SpecNamj | 0..1 | string | Special-purpose code (rarely populated; e.g. internal special tariffs). |
KupacOib | 0..1 | string, 11 digits | Buyer OIB — added in v1.5 (since 2019), permitted for B2B receipts. |
Receipt number composite (BrRac)
BrRac
├── BrOznRac # numeric sequence number, monotonic — restarts at 1 each calendar year
├── OznPosPr # business-premise mark (string, 1-20 chars; e.g. "POSL1", "ZG-CENTAR")
└── OznNapUr # cash-register mark (string, 1-20 chars; e.g. "1", "BLAGA-A")
The legal "invoice number" printed on the receipt has the format
BrOznRac/OznPosPr/OznNapUr — e.g. 42/POSL1/1. This is what the merchant
prints; CIS stores all three components separately.
Per-business-premise vs per-cash-register sequencing. Set
OznSlijed = P if your store wants one sequence per premise (numbers shared
across registers); set OznSlijed = N for separate sequences per register.
Once chosen, the value is immutable for the calendar year — switching
mid-year invalidates the chain and triggers a tax-audit flag. Default
recommendation for our customers: N (per register) — it's the more
forgiving option for multi-register stores.
Payment methods (NacinPlac)
| Code | Croatian | English |
|---|---|---|
G | Gotovina | Cash |
K | Kartica | Card |
C | Ček | Cheque (rarely used) |
T | Transakcijski račun | Bank transfer |
O | Ostalo | Other |
Pdv — VAT rate breakdown
Each Porez element has:
Stopa # rate, decimal-as-string, e.g. "25.00", "13.00", "5.00", "0.00"
Osnovica # taxable base for that rate
Iznos # VAT amount for that rate
Croatian VAT rates as of 2026:
| Rate | Use |
|---|---|
| 25% | Standard rate. |
| 13% | Reduced — accommodation, restaurant prepared food (not all), books (paper), newspapers/magazines, some agriculture, baby food, water supply, electricity for residential. |
| 5% | Super-reduced — bread, milk, certain medicines, scientific journals, cinema tickets, some hospital services. |
| 0% | Exports + intra-community supplies (recorded with IznosOslobPdv instead). |
An invoice may carry multiple Porez lines — one per rate present.
Multi-rate goldens cover this in golden/multi-vat-rates.input.json.
Naknade — fees
Naknada
├── NazivN # fee name, e.g. "Naknada za ambalažu"
└── IznosN # fee amount
Used most commonly for packaging-deposit fees (e.g. €0.07 / €0.50 returnable
PET bottle deposits). Adds to IznosUkupno; not subject to VAT.
5. Ordering and sequencing
Per-(premise, register) gap-free counter
The BrOznRac field is a strictly monotonic, gap-free counter that
restarts at 1 on January 1 each year. Scoping depends on OznSlijed:
OznSlijed | Counter scope |
|---|---|
P | Per (OIB, year, OznPosPr) — one sequence per business premise |
N | Per (OIB, year, OznPosPr, OznNapUr) — one sequence per cash register |
Tax-audit perspective: any gap in the per-scope sequence (number 41 used,
43 used, no record of 42) is a finding. The merchant must be able to produce
the cancellation/error log explaining the gap. Our adapter must therefore
guarantee gap-free issuance for every (OIB, OznPosPr, OznNapUr) key.
This is the same engineering shape as the Portugal ATCUD adapter
(per-NIF gap-free counter via Postgres advisory locks) — we should reuse the
SequenceStore trait introduced for Portugal. See
apps/docs-internal/docs/architecture/portugal-adapter.md § "Sequence store".
Composite key for Croatia:
key = format!("{oib}:{year}:{poslovni_prostor}:{naplatni_uredjaj}")
// e.g. "11111111119:2026:POSL1:1"
Restart at year boundary
On January 1, every (oib, premise, register) counter resets to 1. The
adapter must reset state automatically — a stale counter from December
silently double-numbers and CIS will reject the second occurrence with
s003 ("Račun već postoji" — receipt already exists).
Idempotency
| Scenario | Adapter behaviour |
|---|---|
| Network timeout after submit | Retry same IdPoruke (the request UUID we minted at prepare-time). CIS deduplicates by (OIB, IdPoruke) for a 24h window. |
| Duplicate detection by CIS | If we accidentally re-issue with the same BrOznRac triple but a different IdPoruke, CIS returns s003. Treat as a hard error — DO NOT retry; surface to ops to investigate the local sequence store. |
| Network success, JIR missing | Should not happen on success path; if a 200 is returned with no JIR and no fault, treat as PROVISIONAL — query later via the public web verifier (production) or ProvjeraZahtjev (sandbox only). |
IdPoruke strategy
IdPoruke is a UUIDv4 we mint at prepare time and persist with the
PreparedRecord. Retries reuse it. We do not re-mint on retry — that
forfeits CIS's idempotency. Same rule as Hungary's requestId.
6. Submission window
Real-time (the normal case)
Cash receipts must be fiscalized at the moment of issuance, before the paper/electronic copy is handed to the customer. The legal text says "bez odgode" ("without delay"). CIS-side practice: a few seconds is fine, 30 seconds is borderline, minutes are flagged in audits.
48-hour offline grace
If CIS is unreachable (network, FINA cert outage, CIS planned/unplanned
downtime) the merchant may continue issuing receipts in offline mode and
must transmit them within 48 hours with NakDost = true. After 48 hours
the merchant is required to switch to paragon block (paper-receipt block
with a unique paragon number per book, declared to PU annually) until CIS is
restored, then transmit those as PD with ParagonBrRac set.
Adapter behaviour:
- Active
submit()succeeds in real-time →NakDost=false. - Active
submit()fails (network or CIS error) → record locally withNakDost=trueflagged in the prepared record, retry on a backoff schedule. - Wall-clock 48h elapses without successful transmission → the adapter
surfaces a
CroatiaError::OfflineGraceExpiredto the merchant requiring manual intervention (paragon block escalation).
SubmissionWindow mapping
SubmissionWindow::Immediate for the hot path (matches Hungary, Spain
Verifactu). The 48h grace is implemented inside the adapter retry layer, not
exposed to the framework's submission-window enum.