Edukativni UBL 2.1 XML fragmenti s objašnjenjima. Saznajte zašto UBL XSD nije dovoljan bez EN 16931, hrvatskih pravila i validacije kanala.
⚡
UBL 2.1 je XML sintaksa za strukturirane poslovne dokumente. Fragmenti u nastavku služe za učenje i nisu cjelovita produkcijska datoteka. Za slanje trebate aktualni profil, šifrarnike i validacije svojeg B2B ili B2G kanala.
Što je UBL 2.1?
UBL (Universal Business Language) je otvoreni XML standard za razmjenu poslovnih dokumenata koji je razvila organizacija OASIS. Verzija 2.1, objavljena 2013. godine, podržava više od 60 tipova poslovnih dokumenata, od kojih je najvažniji Invoice (račun).
UBL 2.1 jedna je od sintaksi povezanih s europskom normom EN 16931. Druga je UN/CEFACT CII. Koju sintaksu smijete poslati ne određuje UBL sam po sebi, nego konkretni profil i kanal. Primjerice, Peppol BIS Billing 3 obvezno podržava UBL, dok je CII opcionalan za primatelja.
Odnos UBL-a i EN 16931
Važno je razumjeti razliku između ova dva pojma:
- EN 16931 je semantički standard. Definira koji podaci moraju biti na e-računu (prodavatelj, kupac, stavke, PDV, ukupni iznos) i koja su poslovna pravila (npr. ukupni iznos mora biti zbroj stavki).
- UBL 2.1 je sintaksna specifikacija. Definira kako se ti podaci zapisuju u XML formatu (nazivi elemenata, struktura, namespace).
Drugim riječima, EN 16931 kaže "račun mora sadržavati datum izdavanja", a UBL 2.1 kaže da se taj datum zapisuje u XML element <cbc:IssueDate>.
Struktura UBL 2.1 računa
UBL 2.1 Invoice dokument ima sljedeću visoku strukturu:
<Invoice xmlns="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2">
<!-- 1. Zaglavlje: broj računa, datum, valuta -->
<!-- 2. Prodavatelj (AccountingSupplierParty) -->
<!-- 3. Kupac (AccountingCustomerParty) -->
<!-- 4. Uvjeti plaćanja (PaymentMeans, PaymentTerms) -->
<!-- 5. PDV rekapitulacija (TaxTotal) -->
<!-- 6. Ukupni iznosi (LegalMonetaryTotal) -->
<!-- 7. Stavke računa (InvoiceLine) -->
</Invoice>
Svaki od ovih blokova sadrži ugniježđene elemente koji opisuju pojedine podatke. U nastavku slijede odvojeni fragmenti s objašnjenjima.
Edukativni fragmenti UBL 2.1 dokumenta
Fragmenti koriste izmišljene podatke kako bi pokazali gdje se pojedini elementi nalaze. Ne čine jednu validnu datoteku.
Zaglavlje i namespace deklaracije
<?xml version="1.0" encoding="UTF-8"?>
<Invoice
xmlns="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2"
xmlns:cac="urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2"
xmlns:cbc="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2">
<cbc:CustomizationID>
urn:cen.eu:en16931:2017#compliant#urn:fdc:peppol.eu:2017:poacc:billing:3.0
</cbc:CustomizationID>
<cbc:ProfileID>urn:fdc:peppol.eu:2017:poacc:billing:01:1.0</cbc:ProfileID>
<cbc:ID>R-2026-0042</cbc:ID>
<cbc:IssueDate>2026-03-11</cbc:IssueDate>
<cbc:DueDate>2026-04-10</cbc:DueDate>
<cbc:InvoiceTypeCode>380</cbc:InvoiceTypeCode>
<cbc:DocumentCurrencyCode>EUR</cbc:DocumentCurrencyCode>
</Invoice>
Objašnjenje zaglavlja:
xmlnsatributi definiraju XML namespace za UBL 2.1 elemente. Prefikscbckoristi se za jednostavne podatke (tekst, brojevi, datumi), acacza složene strukture (adrese, stranke).CustomizationIDoznačava profil pravila. Vrijednost mora odgovarati aktualnoj specifikaciji kanala, pa se ne smije proizvoljno zamijeniti bez validacije.ProfileIDoznačava poslovni proces (u ovom slučaju PEPPOL Billing).IDje jedinstveni broj računa.IssueDateje datum izdavanja u ISO 8601 formatu (YYYY-MM-DD).DueDateje datum dospijeća plaćanja.InvoiceTypeCode380 označava standardni komercijalni račun. Druge vrijednosti: 381 (odobrenje), 384 (ispravljeni račun), 389 (samoobračun).DocumentCurrencyCodeje valuta računa prema ISO 4217 (EUR za Hrvatsku).
Podaci o prodavatelju
<cac:AccountingSupplierParty>
<cac:Party>
<cbc:EndpointID schemeID="[shema iz registra]">[identifikator iz registra]</cbc:EndpointID>
<cac:PartyIdentification>
<cbc:ID>12345678901</cbc:ID>
</cac:PartyIdentification>
<cac:PartyName>
<cbc:Name>TehnoSoft d.o.o.</cbc:Name>
</cac:PartyName>
<cac:PostalAddress>
<cbc:StreetName>Ilica 100</cbc:StreetName>
<cbc:CityName>Zagreb</cbc:CityName>
<cbc:PostalZone>10000</cbc:PostalZone>
<cac:Country>
<cbc:IdentificationCode>HR</cbc:IdentificationCode>
</cac:Country>
</cac:PostalAddress>
<cac:PartyTaxScheme>
<cbc:CompanyID>HR12345678901</cbc:CompanyID>
<cac:TaxScheme>
<cbc:ID>VAT</cbc:ID>
</cac:TaxScheme>
</cac:PartyTaxScheme>
<cac:PartyLegalEntity>
<cbc:RegistrationName>TehnoSoft d.o.o.</cbc:RegistrationName>
<cbc:CompanyID>12345678901</cbc:CompanyID>
</cac:PartyLegalEntity>
<cac:Contact>
<cbc:ElectronicMail>racuni@tehnosoft.hr</cbc:ElectronicMail>
</cac:Contact>
</cac:Party>
</cac:AccountingSupplierParty>
Objašnjenje podataka o prodavatelju:
EndpointIDi njegovschemeIDmoraju točno odgovarati registru i ugovorenom kanalu. Peppolov kod 9934 označava hrvatski PDV broj, pa ga ne treba automatski koristiti kao shemu za svaki hrvatski OIB ili svaki domaći kanal.PartyIdentificationsadrži identifikator stranke (OIB prodavatelja: 12345678901).PartyNameje trgovački naziv tvrtke.PostalAddresssadrži adresu s obveznim poljima: ulica, grad, poštanski broj i država (ISO 3166-1 kod HR).PartyTaxSchemesadrži PDV identifikacijski broj (HR + OIB) i oznaku porezne sheme (VAT).PartyLegalEntitysadrži službeni registracijski naziv i OIB.Contactje opcionalan, ali preporučen za komunikaciju o računu.
Podaci o kupcu
<cac:AccountingCustomerParty>
<cac:Party>
<cbc:EndpointID schemeID="[shema iz registra]">[identifikator iz registra]</cbc:EndpointID>
<cac:PartyIdentification>
<cbc:ID>98765432109</cbc:ID>
</cac:PartyIdentification>
<cac:PartyName>
<cbc:Name>Gradska uprava Grada Zagreba</cbc:Name>
</cac:PartyName>
<cac:PostalAddress>
<cbc:StreetName>Trg Stjepana Radića 1</cbc:StreetName>
<cbc:CityName>Zagreb</cbc:CityName>
<cbc:PostalZone>10000</cbc:PostalZone>
<cac:Country>
<cbc:IdentificationCode>HR</cbc:IdentificationCode>
</cac:Country>
</cac:PostalAddress>
<cac:PartyTaxScheme>
<cbc:CompanyID>HR98765432109</cbc:CompanyID>
<cac:TaxScheme>
<cbc:ID>VAT</cbc:ID>
</cac:TaxScheme>
</cac:PartyTaxScheme>
<cac:PartyLegalEntity>
<cbc:RegistrationName>Gradska uprava Grada Zagreba</cbc:RegistrationName>
<cbc:CompanyID>98765432109</cbc:CompanyID>
</cac:PartyLegalEntity>
</cac:Party>
</cac:AccountingCustomerParty>
Objašnjenje podataka o kupcu:
Struktura kupca koristi iste skupine elemenata kao struktura prodavatelja, ali identifikatori i njihove sheme ovise o profilu i registru primatelja. Naziv javnog tijela sam po sebi nije dovoljan za zaključak o kanalu. Provjerite je li račun obuhvaćen ugovorom iz javne nabave i koji identifikator traži centralna platforma.
Uvjeti plaćanja
<cac:PaymentMeans>
<cbc:PaymentMeansCode>30</cbc:PaymentMeansCode>
<cac:PayeeFinancialAccount>
<cbc:ID>HR1234567890123456789</cbc:ID>
<cbc:Name>TehnoSoft d.o.o.</cbc:Name>
<cac:FinancialInstitutionBranch>
<cbc:ID>PBZGHR2X</cbc:ID>
</cac:FinancialInstitutionBranch>
</cac:PayeeFinancialAccount>
</cac:PaymentMeans>
<cac:PaymentTerms>
<cbc:Note>Rok plaćanja: 30 dana od datuma izdavanja računa.</cbc:Note>
</cac:PaymentTerms>
Objašnjenje uvjeta plaćanja:
PaymentMeansCode30 označava bankovni prijenos (virman). Druge česte vrijednosti: 48 (kartica), 49 (direktno terećenje), 58 (SEPA prijenos).PayeeFinancialAccount/IDje IBAN prodavatelja na koji kupac uplaćuje iznos.FinancialInstitutionBranch/IDje BIC/SWIFT kod banke (u ovom primjeru PBZ).PaymentTerms/Noteje tekstualni opis uvjeta plaćanja. Element je opcionalan, ali koristan jer se prikazuje na vizualnom prikazu računa.
PDV rekapitulacija
<cac:TaxTotal>
<cbc:TaxAmount currencyID="EUR">330.00</cbc:TaxAmount>
<cac:TaxSubtotal>
<cbc:TaxableAmount currencyID="EUR">1320.00</cbc:TaxableAmount>
<cbc:TaxAmount currencyID="EUR">330.00</cbc:TaxAmount>
<cac:TaxCategory>
<cbc:ID>S</cbc:ID>
<cbc:Percent>25.00</cbc:Percent>
<cac:TaxScheme>
<cbc:ID>VAT</cbc:ID>
</cac:TaxScheme>
</cac:TaxCategory>
</cac:TaxSubtotal>
</cac:TaxTotal>
Objašnjenje PDV rekapitulacije:
TaxTotal/TaxAmountje ukupni iznos PDV-a na računu (330,00 EUR).TaxSubtotalgrupira stavke po PDV stopi. Ako račun ima stavke s različitim stopama (npr. 25% i 13%), svaka stopa ima vlastitiTaxSubtotalblok.TaxableAmountje osnovica za tu stopu (1.320,00 EUR).TaxCategory/IDoznačava vrstu PDV-a. Kod "S" znači standardna stopa (Standard rate). Drugi kodovi: "Z" (nulta stopa), "E" (oslobođeno), "AE" (reverse charge), "K" (intra-EU isporuka).Percentje postotna stopa PDV-a (25% za Hrvatsku).
Ukupni iznosi
<cac:LegalMonetaryTotal>
<cbc:LineExtensionAmount currencyID="EUR">1320.00</cbc:LineExtensionAmount>
<cbc:TaxExclusiveAmount currencyID="EUR">1320.00</cbc:TaxExclusiveAmount>
<cbc:TaxInclusiveAmount currencyID="EUR">1650.00</cbc:TaxInclusiveAmount>
<cbc:PayableAmount currencyID="EUR">1650.00</cbc:PayableAmount>
</cac:LegalMonetaryTotal>
Objašnjenje ukupnih iznosa:
LineExtensionAmountje zbroj neto iznosa svih stavki (bez PDV-a): 1.320,00 EUR.TaxExclusiveAmountje ukupni iznos bez PDV-a (može se razlikovati od LineExtensionAmount ako postoje popusti ili naknade na razini dokumenta).TaxInclusiveAmountje ukupni iznos s PDV-om: 1.320,00 + 330,00 = 1.650,00 EUR.PayableAmountje iznos koji kupac mora platiti. Ako je već uplaćen predujam, ovaj iznos bit će manji od TaxInclusiveAmount.
Stavke računa
<cac:InvoiceLine>
<cbc:ID>1</cbc:ID>
<cbc:InvoicedQuantity unitCode="HUR">40</cbc:InvoicedQuantity>
<cbc:LineExtensionAmount currencyID="EUR">1000.00</cbc:LineExtensionAmount>
<cac:Item>
<cbc:Description>Razvoj web aplikacije za upravljanje dokumentima</cbc:Description>
<cbc:Name>Web development</cbc:Name>
<cac:ClassifiedTaxCategory>
<cbc:ID>S</cbc:ID>
<cbc:Percent>25.00</cbc:Percent>
<cac:TaxScheme>
<cbc:ID>VAT</cbc:ID>
</cac:TaxScheme>
</cac:ClassifiedTaxCategory>
</cac:Item>
<cac:Price>
<cbc:PriceAmount currencyID="EUR">25.00</cbc:PriceAmount>
</cac:Price>
</cac:InvoiceLine>
<cac:InvoiceLine>
<cbc:ID>2</cbc:ID>
<cbc:InvoicedQuantity unitCode="MON">2</cbc:InvoicedQuantity>
<cbc:LineExtensionAmount currencyID="EUR">320.00</cbc:LineExtensionAmount>
<cac:Item>
<cbc:Description>Mjesečno održavanje servera i sigurnosne zakrpe</cbc:Description>
<cbc:Name>Održavanje servera</cbc:Name>
<cac:ClassifiedTaxCategory>
<cbc:ID>S</cbc:ID>
<cbc:Percent>25.00</cbc:Percent>
<cac:TaxScheme>
<cbc:ID>VAT</cbc:ID>
</cac:TaxScheme>
</cac:ClassifiedTaxCategory>
</cac:Item>
<cac:Price>
<cbc:PriceAmount currencyID="EUR">160.00</cbc:PriceAmount>
</cac:Price>
</cac:InvoiceLine>
Objašnjenje stavki računa:
Svaka InvoiceLine predstavlja jednu stavku na računu:
IDje redni broj stavke (1, 2, 3...).InvoicedQuantityje količina s obveznimunitCodeatributom prema UN/ECE Recommendation 20. Česti kodovi: "HUR" (sati), "MON" (mjeseci), "EA" (komad), "KGM" (kilogram), "MTR" (metar).LineExtensionAmountje neto iznos stavke (količina x cijena): 40 sati x 25,00 EUR = 1.000,00 EUR.Item/Descriptionje detaljan opis stavke, aItem/Nameje kratki naziv.ClassifiedTaxCategoryoznačava PDV kategoriju i stopu za tu stavku.Price/PriceAmountje jedinična cijena bez PDV-a.
U ovom primjeru račun ima dvije stavke: 40 sati razvoja po 25 EUR/sat (1.000,00 EUR) i 2 mjeseca održavanja servera po 160 EUR/mjesec (320,00 EUR). Ukupna osnovica je 1.320,00 EUR.
Orijentacijska karta elemenata
Ova tablica pomaže pronaći česte poslovne podatke u UBL-u. Stupac nije zamjena za službene kardinalnosti EN 16931, Peppol ili hrvatskog profila jer obveznost pojedinog podatka može ovisiti o poslovnom slučaju.
| Element | UBL 2.1 put | Uloga | Napomena |
|---|---|---|---|
| Broj računa | cbc:ID | Da | Jedinstven u okviru prodavatelja |
| Datum izdavanja | cbc:IssueDate | Da | ISO 8601 format |
| Datum dospijeća | cbc:DueDate | Ne | Preporučeno za sve račune |
| Tip dokumenta | cbc:InvoiceTypeCode | Da | 380 za račun, 381 za odobrenje |
| Valuta | cbc:DocumentCurrencyCode | Da | ISO 4217 (EUR) |
| Naziv prodavatelja | cac:AccountingSupplierParty/.../cbc:RegistrationName | Da | Službeni naziv |
| Identifikator prodavatelja | cac:AccountingSupplierParty/.../cbc:CompanyID | Ovisi o profilu | OIB, PDV ID ili drugi identifikator prema pravilima |
| Adresa prodavatelja | cac:AccountingSupplierParty/.../cac:PostalAddress | Da | Ulica, grad, poštanski broj, država |
| Naziv kupca | cac:AccountingCustomerParty/.../cbc:RegistrationName | Da | Službeni naziv |
| Identifikator kupca | cac:AccountingCustomerParty/.../cbc:CompanyID | Ovisi o profilu | OIB, PDV ID ili drugi identifikator prema pravilima |
| Adresa kupca | cac:AccountingCustomerParty/.../cac:PostalAddress | Da | Ulica, grad, poštanski broj, država |
| Način plaćanja | cac:PaymentMeans/cbc:PaymentMeansCode | Da | UNCL 4461 kod |
| IBAN | cac:PayeeFinancialAccount/cbc:ID | Ne | Obvezan za virmansko plaćanje |
| BIC/SWIFT | cac:FinancialInstitutionBranch/cbc:ID | Ne | Preporučeno za međunarodno plaćanje |
| Uvjeti plaćanja | cac:PaymentTerms/cbc:Note | Ne | Slobodan tekst |
| PDV ukupno | cac:TaxTotal/cbc:TaxAmount | Da | Ukupni PDV na računu |
| PDV stopa | cac:TaxSubtotal/.../cbc:Percent | Da | Po svakoj PDV kategoriji |
| Ukupno bez PDV-a | cac:LegalMonetaryTotal/cbc:TaxExclusiveAmount | Da | Osnovica |
| Ukupno za plaćanje | cac:LegalMonetaryTotal/cbc:PayableAmount | Da | Konačni iznos |
| Redni broj stavke | cac:InvoiceLine/cbc:ID | Da | Jedinstven unutar računa |
| Količina | cac:InvoiceLine/cbc:InvoicedQuantity | Da | S unitCode atributom |
| Neto iznos stavke | cac:InvoiceLine/cbc:LineExtensionAmount | Da | Količina x cijena |
| Naziv stavke | cac:InvoiceLine/.../cbc:Name | Da | Kratki naziv |
| Jedinična cijena | cac:InvoiceLine/.../cbc:PriceAmount | Da | Cijena bez PDV-a |
| Referenca narudžbe | cbc:OrderReference/cbc:ID | Ne | Broj narudžbenice kupca |
| Referenca ugovora | cac:ContractDocumentReference/cbc:ID | Ne | Broj ugovora |
| Napomena | cbc:Note | Ne | Slobodni tekst na računu |
Validacija UBL 2.1 računa
Pouzdana provjera ima najmanje tri sloja. Konkretni kanal može ih provoditi jednim alatom ili dodati svoja pravila.
1. XSD validacija (strukturna provjera)
XSD (XML Schema Definition) provjerava je li XML dokument strukturno ispravan: jesu li svi elementi pravilno ugniježđeni, jesu li tipovi podataka ispravni (datum, broj, tekst) i jesu li namespace deklaracije točne.
Alati za XSD validaciju:
- xmllint (besplatan, CLI):
xmllint --schema UBL-Invoice-2.1.xsd racun.xml - Oxygen XML Editor: profesionalni XML editor s ugrađenom validacijom
- Online validatori: PEPPOL validator (https://peppol.helger.com/public/locale-en_US/menuitem-validation-upload)
2. Schematron validacija (poslovna pravila)
Schematron pravila provjeravaju logičku ispravnost računa prema EN 16931 i PEPPOL pravilima. Na primjer:
- Ukupni iznos mora biti jednak zbroju stavki
- PDV mora biti ispravno izračunan prema stopi
- Ako je
InvoiceTypeCode380,PayableAmountmora biti pozitivan - Država prodavatelja mora odgovarati prefiksu poreznog broja
3. Profil i pravila kanala
Za hrvatski domaći tok provjerite aktualna nacionalna pravila i specifikaciju pristupne točke, primjerice:
CustomizationIDmora odgovarati aktualnoj službenoj specifikaciji hrvatskog profila- format obveznog identifikatora stranke
- KPD (Klasifikacija proizvoda po djelatnostima) na stavkama za tuzemni B2B
- PDV stope moraju odgovarati važećim hrvatskim stopama (25%, 13%, 5%)
Česte greške pri validaciji
| Greška | Uzrok | Rješenje |
|---|---|---|
| Neispravan namespace | Krivi URI u xmlns atributu | Kopirajte točne namespace URI iz UBL 2.1 specifikacije |
| Nedostaje currencyID | Iznos bez atributa valute | Dodajte currencyID="EUR" na svaki iznos |
| Kriva PDV rekapitulacija | Zbroj TaxSubtotal ne odgovara TaxTotal | Provjerite da je TaxAmount = suma svih TaxSubtotal iznosa |
| Neispravan unitCode | Nepostojeći kod mjerne jedinice | Koristite kodove iz UN/ECE Rec. 20 (HUR, EA, MON, KGM) |
| Nedostaje TaxCategory na stavci | Stavka bez PDV kategorije | Svaka InvoiceLine mora imati ClassifiedTaxCategory |
| Neispravan format datuma | Datum u HR formatu umjesto ISO | Koristite YYYY-MM-DD format (2026-03-11, ne 11.03.2026.) |
Primjer s različitim PDV stopama
U praksi račun može sadržavati stavke s različitim PDV stopama. U tom slučaju, TaxTotal blok ima više TaxSubtotal elemenata:
<cac:TaxTotal>
<cbc:TaxAmount currencyID="EUR">292.90</cbc:TaxAmount>
<cac:TaxSubtotal>
<cbc:TaxableAmount currencyID="EUR">1000.00</cbc:TaxableAmount>
<cbc:TaxAmount currencyID="EUR">250.00</cbc:TaxAmount>
<cac:TaxCategory>
<cbc:ID>S</cbc:ID>
<cbc:Percent>25.00</cbc:Percent>
<cac:TaxScheme><cbc:ID>VAT</cbc:ID></cac:TaxScheme>
</cac:TaxCategory>
</cac:TaxSubtotal>
<cac:TaxSubtotal>
<cbc:TaxableAmount currencyID="EUR">330.00</cbc:TaxableAmount>
<cbc:TaxAmount currencyID="EUR">42.90</cbc:TaxAmount>
<cac:TaxCategory>
<cbc:ID>S</cbc:ID>
<cbc:Percent>13.00</cbc:Percent>
<cac:TaxScheme><cbc:ID>VAT</cbc:ID></cac:TaxScheme>
</cac:TaxCategory>
</cac:TaxSubtotal>
</cac:TaxTotal>
Ovdje račun ima stavke s ilustrativnim stopama od 25% i 13%. Izračun ukupnog PDV-a iznosi 292,90 EUR. Primjenjivu stopu za stvarnu isporuku odredite prema važećem Zakonu o PDV-u, a ne prema ovom XML primjeru.
Česta pitanja
Povezani vodiči
- e-Račun (FINA) vs Fiskalizacija 2.0 - B2G, B2B i B2C razdvojeno
- PEPPOL Hrvatska - PEPPOL vs nacionalni B2B model
- e-Arhiva - zakonski rokovi po vrsti dokumenta i FiskAI pohrana
Pripremite podatke za strukturirani eRačun
FiskAI priprema podatke i dokumente, dok je slanje i zaprimanje preko FINA servisa još označeno kao funkcija u izgradnji do šire potvrde stabilnosti.
Bez ugovorne obveze • Otkažite kad želite
Izvori
Informativni sadržaj. Za specifične situacije konzultirajte stručnjaka.