RO_CIUS și UBL 2.1: formatul XML al e-Facturii, explicat
Ce conține un fișier RO_CIUS: cele trei straturi EN 16931 → UBL 2.1, anatomia XML-ului, CustomizationID-ul și regulile de validare BR-RO explicate.

„Obligatorie" e cuvântul pe care îl știe toată lumea despre e-Factura. Mult mai puțini știu ce se întâmplă de fapt cu fișierul XML după ce apeși „trimite" — de ce SPV respinge unele facturi în câteva secunde și acceptă altele identice ca sumă totală, dar diferite ca structură internă. Răspunsul stă în RO_CIUS: profilul românesc construit peste standardul UBL 2.1, cu propriul set de reguli de validare. Dacă construiești sau integrezi un generator XML pentru facturare, articolul de față e despre ce anume trebuie să conțină fișierul și de ce arată așa — nu despre termene, sancțiuni sau pașii de înregistrare.
De ce contează formatul, nu doar obligația
Un ERP care „știe" că trebuie să trimită facturi prin SPV nu e automat un ERP care generează XML valid. Diferența dintre cele două e exact ce acoperă articolul de față — structura fișierului, nu procesul de conformitate în sine. Dacă vrei contextul obligației, al sancțiunilor și al celor trei moduri uzuale de integrare a unui ERP cu sistemul, integrarea ERP cu e-Factura și ANAF le tratează pe larg; articolul de față pornește de acolo și merge în profunzime pe formatul propriu-zis — pe ce pui efectiv în XML, nu pe cum ajunge el la ANAF.
Merită și o clarificare din start, ca să nu confunzi cele două fluxuri: RO_CIUS nu are nicio legătură directă cu SAF-T (D406). Primul e formatul facturii individuale, trimise prin SPV la fiecare tranzacție, în timp real. Al doilea e o raportare periodică, agregată, a întregii evidențe contabile către ANAF, pe o schemă complet diferită. Poți avea facturi RO_CIUS impecabile și, în paralel, un SAF-T cu erori de mapare pe alte câmpuri — sunt fișiere diferite, cu scheme diferite, verificate de mecanisme diferite. Dacă lucrezi și pe partea de raportare periodică, ghidul dedicat SAF-T explică ce se raportează acolo și cum se generează.
Miza practică a înțelegerii formatului corect: o eroare de structură nu se manifestă ca o eroare de business pe care o prinzi la revizuirea manuală a facturii — se manifestă ca o respingere tehnică la ANAF, uneori pe un câmp pe care nimeni din echipa financiară nu s-ar fi gândit să-l verifice vizual. Cu cât generatorul XML e mai aproape de spec, cu atât mai puține din aceste respingeri ajung să blocheze fluxul de facturare live.
Costul real al unui generator „aproape corect" nu e vizibil în faza de dezvoltare — apare mai târziu, ca un ciclu repetitiv de respingere-diagnosticare-corectare-retransmitere pe fiecare tip de factură pe care echipa nu l-a testat explicit (o notă de credit, o autofactură, o factură cu discount la nivel de document). Restul acestui ghid trece prin exact structura care previne acel ciclu — ce înseamnă articolele din conformitatea fiscală pentru ERP, de la header până la ultima regulă de validare.
De la EN 16931 la UBL 2.1 la RO_CIUS: trei straturi
Cea mai frecventă confuzie la cineva care vede pentru prima dată o factură RO_CIUS: crede că e un format inventat de ANAF de la zero, cu reguli arbitrare. Nu e. Sunt trei straturi suprapuse, fiecare cu rolul lui, și odată ce le separi mental, tot restul XML-ului capătă sens.
Modelul semantic: BT-uri și BG-uri
La bază stă standardul european SR EN 16931-1, care nu descrie XML — descrie ce informație trebuie să conțină o factură, indiferent de format concret. Fiecare bucată de date are un identificator stabil: BT (Business Term) pentru un câmp individual — BT-1 e numărul facturii, BT-2 data emiterii, BT-5 codul monedei — și BG (Business Group) pentru un grup de câmpuri înrudite, cum e adresa vânzătorului sau o linie de factură. E un vocabular semantic, nu o sintaxă — aceleași BT-uri există identic și într-o factură germană, și într-una franceză.
UBL 2.1 — una din cele două sintaxe acceptate
EN 16931 permite două moduri de a „turna" acel vocabular în XML concret: UBL 2.1 (Universal Business Language, standard OASIS) și UN/CEFACT CII (Cross Industry Invoice). Fiecare BT/BG din model se leagă de un element XML precis în fiecare sintaxă — de exemplu, BT-1 devine cbc:ID în UBL. Legea românească acceptă ambele: facturile trebuie emise în format XML, folosind fie sintaxa UBL 2.1, fie CII, conform specificațiilor RO_CIUS, ambele compatibile cu EN 16931.
RO_CIUS — profilul românesc
Un CIUS (Core Invoice Usage Specification) e o restrângere/precizare a EN 16931 pentru o piață locală: ce câmpuri opționale în standardul european devin obligatorii aici, ce coduri suplimentare se acceptă, ce reguli de validare se adaugă peste cele generice. RO_CIUS e definit prin Ordinul MF nr. 1.366/2021, care leagă explicit modelul semantic de bază de SR EN 16931-1 și raportează identificatorul setului de reguli în câmpul BT-24 „Identificatorul specificației"; ordinul a fost modificat ulterior prin Ordinul 4.092/2022. Practic: RO_CIUS = EN 16931 + reguli suplimentare specifice României, exprimate aproape întotdeauna în sintaxă UBL 2.1.
Anatomia unui fișier RO_CIUS
Un fișier RO_CIUS minim, dar valid, are patru zone. Le parcurgem în ordinea în care apar în document, cu elementele lor obligatorii — mai complet decât un fragment ilustrativ, ca să ai un punct de plecare real pentru un generator.
Header-ul: identificarea facturii
Primele câmpuri din Invoice declară CE este documentul, nu conținutul lui comercial: cbc:CustomizationID (identificatorul RO_CIUS, detaliat în secțiunea dedicată mai jos), cbc:ID (numărul facturii, BT-1), cbc:IssueDate (data emiterii, BT-2, format YYYY-MM-DD), cbc:InvoiceTypeCode (BT-3 — codul care spune dacă e factură standard, notă de credit, factură de corecție etc., detaliat la secțiunea Capcane) și cbc:DocumentCurrencyCode (BT-5, codul monedei — RON pentru facturile interne).
Părțile: cine vinde, cine cumpără
cac:AccountingSupplierParty și cac:AccountingCustomerParty sunt structuri gemene, fiecare încapsulând un cac:Party cu nume, adresă poștală (cu cod de țară obligatoriu) și identificatorul fiscal, sub cac:PartyTaxScheme. Pentru vânzătorul român, aici intră și numărul de înregistrare la Registrul Comerțului, sub cac:PartyLegalEntity/cbc:CompanyID, în formatul uzual J//.
Liniile: ce s-a vândut
Fiecare produs sau serviciu e un cac:InvoiceLine, cu identificator unic, cantitate (cbc:InvoicedQuantity, cu atributul de unitate de măsură din lista UN/ECE Recommendation 20), valoarea netă a liniei (cbc:LineExtensionAmount) și un cac:Item cu denumirea și categoria de TVA aplicabilă, prin cac:ClassifiedTaxCategory.
Totalurile: reconcilierea sumelor
cac:TaxTotal agregă TVA-ul pe categorii de cotă, iar cac:LegalMonetaryTotal conține sumele de închidere ale facturii — valoare netă totală, valoare fără TVA, valoare cu TVA, sumă de plată. Aceste totaluri nu sunt introduse liber: trebuie să reconcilieze matematic, exact la bănuț, cu suma liniilor — asta verifică regulile Schematron descrise mai jos.
Fișierul real mai are câmpuri obligatorii pe care exemplul de mai sus le omite pentru claritate — adresa completă a cumpărătorului, și, pentru majoritatea facturilor emise contra plată, un cac:PaymentMeans cu contul bancar (IBAN) și codul modalității de plată. Un caz special merită menționat aici, fiindcă revine des la ERP-urile care emit și autofacturi: când cumpărătorul emite factura în numele furnizorului (cbc:InvoiceTypeCode 389), RO_CIUS cere înscrierea explicită a mențiunii „autofactura" — de obicei prin câmpul cbc:Note (BT-22, „Comentariu în factură"), care în rest rămâne opțional și liber ca text.
Scopul secțiunii de mai sus e să vezi scheletul corect, nu un XML gata de trimis fără modificări.
cbc și cac: cum citești sintaxa UBL
Toate elementele UBL au un prefix, iar prefixul îți spune imediat ce fel de element e, fără să cauți în schemă. cbc (Common Basic Components) marchează o valoare simplă — text, număr, dată — care nu se mai descompune în alte elemente: cbc:ID, cbc:IssueDate, cbc:PayableAmount. cac (Common Aggregate Components) marchează un container care grupează alte elemente, cbc sau alte cac imbricate: cac:Party, cac:InvoiceLine, cac:TaxTotal.
Regula practică, utilă când scrii sau debughezi un generator: dacă un element are copii XML în interior, e cac; dacă are doar text simplu, e cbc. Namespace-urile din header-ul documentului (vezi exemplul de mai sus) leagă fiecare prefix de definiția lui oficială OASIS — un validator XSD respinge orice element cu prefix greșit sau namespace lipsă, înainte să apuce măcar să verifice conținutul semantic al facturii.
CustomizationID: cum declari că ești RO_CIUS
Anatomia URN-ului
Câmpul cbc:CustomizationID (BT-24) e prima linie pe care o citește orice validator, pentru că îi spune ce set de reguli să aplice mai departe peste tot restul documentului. Pentru o factură RO_CIUS, valoarea trebuie să fie exact:
urn:cen.eu:en16931:2017#compliant#urn:efactura.mfinante.ro:CIUS-RO:1.0.1
Structura are trei segmente despărțite de #: primul (urn:cen.eu:en16931:2017) declară conformitatea cu standardul european de bază; al doilea (compliant) marchează statusul de conformitate deplină, nu doar parțială sau extinsă; al treilea (urn:efactura.mfinante.ro:CIUS-RO:1.0.1) identifică profilul local exact — inclusiv numărul de versiune, 1.0.1. Un CustomizationID greșit, trunchiat sau cu versiune incorectă e motiv de respingere fatală, nu doar de avertisment — validatorul nici nu mai verifică restul facturii dacă nu recunoaște profilul declarat aici.
Comparație cu alte CIUS-uri: cazul Peppol
Alte țări europene rezolvă aceeași problemă — „cum declar profilul local peste EN 16931" — cu același tipar de URN, dar valori diferite. Un CIUS francez pe rețeaua Peppol, de exemplu, declară ceva de forma urn:cen.eu:en16931:2017#compliant#urn:peppol:france:billing:cius:1.0. Structura seamănă, dar documentele nu sunt interschimbabile: sistemul RO e-Factura nu e conectat la rețeaua Peppol — nu are punct de acces (Access Point) propriu, nu are firme înregistrate în SMP-ul Peppol — ci funcționează ca platformă centralizată proprie, unde ANAF validează și aplică sigiliul electronic direct, prin SPV, mai degrabă decât printr-un model „cu patru colțuri" descentralizat. O factură cu CustomizationID Peppol nu va fi acceptată de SPV, și invers — cele două rețele nu comunică.
Cele două straturi de validare: XSD și Schematron
O factură RO_CIUS trece prin două tipuri de verificare, cu roluri complet diferite, și confuzia dintre ele explică multe erori greu de depanat la prima integrare.
XSD — verifică structura
Schema XSD (pentru sintaxa UBL, schemele Invoice-2 și CreditNote-2) verifică forma: elementele apar în ordinea corectă, tipurile de date se potrivesc (o dată nu poate fi text liber), elementele obligatorii există. E validare mecanică, fără cunoștințe de business — un XSD nu știe că TVA-ul standard e 21%, doar că cbc:Percent trebuie să fie un număr valid. ANAF publică validatoare atât pentru sintaxa UBL, cât și pentru CII, plus fișierele Schematron corespunzătoare pentru verificarea regulilor operaționale.
Schematron — verifică regulile de business
Aici intră regulile BR (Business Rules) din EN 16931 — aproximativ 170 de reguli europene de bază, prefixate BR-, BR-CO- (reguli de calcul/consistență) și BR-CL- (reguli de listă de coduri) — plus setul suplimentar BR-RO- specific României. O regulă Schematron poate verifica lucruri pe care XSD nu le poate exprima: relații între câmpuri, calcule, coduri dintr-o listă închisă. De exemplu, BR-CO-13 cere ca valoarea totală fără TVA (BT-109) să fie exact egală cu suma valorilor nete ale liniilor (BT-131), minus reducerile la nivel de document, plus taxele suplimentare la nivel de document — o factură cu rotunjire greșită pe ultima zecimală pică exact această regulă, chiar dacă diferența e de un bănuț.
Un al treilea grup de reguli, BR-CL-, verifică apartenența unui cod la o listă de coduri standard externă — nu valoarea în sine, ci faptul că există în lista respectivă. Codul de monedă (BT-5) trebuie să aparțină standardului ISO 4217, codul de țară (BT-40, BT-55) standardului ISO 3166-1, iar codul de tip factură (BT-3) listei UNTDID 1001. Practic, un generator care validează local aceste liste — în loc să lase verificarea integral pe seama respingerii de la ANAF — prinde cu o zi mai devreme exact genul de greșeală de tastare care altfel ajunge să blocheze o factură reală.
Exemple reale de erori
Câteva reguli RO_CIUS publicate de Ministerul Finanțelor ilustrează bine ce verifică stratul suplimentar, dincolo de EN 16931: o regulă restrânge codul tipului de factură (BT-3) la o listă închisă de valori acceptate pentru fluxul național; alta cere completarea referinței cumpărătorului (BT-10) când acesta e o autoritate contractantă; altele validează formatul codului de subdiviziune administrativă pentru municipiul București (RO-B) sau numărul maxim de apariții permis pentru notele facturii. Toate sunt marcate „Fatal" în tabelul oficial de reguli — spre deosebire de un „Warning", o eroare fatală blochează acceptarea facturii în SPV până la corectare și retransmitere completă a fișierului. După ce ambele straturi trec, ANAF aplică sigiliul electronic al Ministerului Finanțelor și alocă un identificator unic facturii — abia atunci devine ea disponibilă cumpărătorului în propriul SPV.
UBL vs CII: de ce piața românească alege aproape mereu UBL
Legea permite ambele sintaxe pentru RO_CIUS, dar în practică, aproape toată piața — de la ANAF însuși, care publică documentație și exemple predominant în UBL, până la furnizorii de software de facturare și librăriile open-source disponibile pentru dezvoltatori români — folosește UBL 2.1. CII (Cross Industry Invoice), moștenit din standardele UN/CEFACT pentru comerț internațional, e o sintaxă mai densă, cu o structură mai puțin intuitivă pentru cineva venit din lumea web/JSON, și cu un ecosistem de librării și exemple mult mai subțire în context românesc.
UBL, în schimb, beneficiază și de faptul că e sintaxa implicită pe rețeaua Peppol la nivel european — chiar dacă RO_CIUS nu circulă pe Peppol (vezi secțiunea anterioară), tooling-ul și expertiza acumulate global pentru UBL 2.1 se transferă direct: parsere, validatoare, generatoare de test, toate mai ușor de găsit decât echivalentele lor pentru CII.
Concluzia practică pentru un ERP nou: dacă nu ai un motiv specific care să ceară CII (o integrare cu un partener extern care îl impune, de exemplu), pornește direct cu UBL 2.1. Găsești mai multe validatoare open-source, mai multe exemple reale de facturi corecte și mai puține suprafețe de eroare necunoscute, pur și simplu pentru că mai multă lume din piață a trecut deja prin aceleași capcane.
Capcane practice de mapare
Patru greșeli revin constant în facturi generate automat de sisteme noi, toate ușor de prevenit odată ce știi exact ce caută validatorul.
Cote de TVA greșite în categoria de taxă. cac:ClassifiedTaxCategory cere o pereche coerentă: codul din lista UNCL 5305 (S pentru cotă standard, Z pentru cotă zero, E pentru scutit, printre altele) și procentul efectiv trebuie să se potrivească logic — un cod S cu procent 0 sau un cod E cu procent nenul e o inconsistență pe care Schematron o prinde imediat, chiar dacă suma finală a facturii pare corectă.
Cod tip factură greșit. Cele cinci valori uzuale pentru cbc:InvoiceTypeCode (BT-3) au sensuri precise, non-interschimbabile: 380 e factura standard, 381 nota de creditare (pentru retururi sau discounturi acordate ulterior), 384 factura de corecție a unei facturi inițiale eronate (conform art. 330 alin. 1 lit. b din Codul Fiscal), 389 autofactura (emisă de cumpărător în numele și contul furnizorului) și 751 factura informativă în scopuri contabile. Trimiterea unei corecții cu codul 380 în loc de 384, de exemplu, rupe trasabilitatea pe care validarea o așteaptă între factura corectată și cea inițială.
CustomizationID greșit sau incomplet. O variantă trunchiată, o versiune veche în loc de 1.0.1, sau un URN de la alt profil (Peppol, alt CIUS național) pică validarea imediat, înainte ca restul facturii să mai conteze pentru validator.
Rotunjiri care sparg BR-CO-13. Cel mai frecvent motiv de respingere „nevinovată": totalul fără TVA nu se potrivește la bănuț cu suma liniilor, de obicei pentru că rotunjirea se face pe fiecare linie separat, apoi din nou pe total, în loc să se calculeze totalul din valorile exacte, nerotunjite, ale liniilor. Soluția practică: păstrează precizie completă intern, pe tot parcursul calculului, și rotunjește o singură dată, doar la afișarea/totalizarea finală.
Ce diferență e între RO_CIUS și UBL 2.1?
UBL 2.1 e sintaxa XML — modul în care se scrie orice factură electronică europeană conformă EN 16931. RO_CIUS e profilul: setul de reguli suplimentare specifice României, aplicate peste acea sintaxă. O factură RO_CIUS e aproape întotdeauna și o factură UBL 2.1, dar nu orice factură UBL 2.1 generică e automat RO_CIUS-conformă.
Pot trimite facturi în format CII în loc de UBL 2.1?
Da, legal e permis — ANAF publică validatoare și pentru CII, pe lângă cele pentru UBL. Practic, ecosistemul de tooling și exemple disponibile în România e construit aproape exclusiv pe UBL 2.1, deci CII rămâne opțiunea rar aleasă, de obicei doar când un partener extern o cere explicit.
De ce mi-a respins SPV o factură care pare corectă vizual?
Pentru că validarea nu se uită la cum arată factura randată pentru ochiul uman, ci la structura XML brută. Cauzele frecvente: un CustomizationID incorect, un cod tip factură nepotrivit cu situația reală, sau un total care nu reconciliază matematic cu suma liniilor (regula BR-CO-13). Fiecare respingere vine cu un cod de regulă specific — pornește depanarea de acolo, nu de la aspectul vizual al facturii.
Ce diferență e între o eroare „Fatal" și una „Warning" în Schematron?
O eroare „Fatal" blochează acceptarea facturii — trebuie corectată și fișierul retransmis integral. Un „Warning" semnalează o problemă, de obicei o recomandare de completitudine sau o bună practică, fără să oprească acceptarea. Regulile RO_CIUS menționate în acest articol sunt, în majoritate, fatale.
Am nevoie de semnătură electronică pe lângă un XML valid RO_CIUS?
Da — validarea structurală (XSD + Schematron) și autentificarea la transmitere sunt cerințe separate. Un XML perfect structurat, dar netransmis cu autentificarea corectă (certificat digital sau, pentru integrare API, tokenul asociat firmei), nu ajunge niciodată să fie procesat de SPV.
Dacă abia acum construiești modulul de facturare într-un ERP la comandă, pasul următor logic e înregistrarea firmei și fluxul de transmitere efectiv prin SPV — ghidul pas cu pas acoperă exact asta, de la înrolare la primul index de încărcare. Și dacă evaluezi de la zero cum arată un sistem ERP construit pe măsura proceselor tale, ghidul complet pentru ERP la comandă e punctul de plecare potrivit.
Surse
- Specificații tehnice și de utilizare a elementelor de bază ale facturii electronice RO_CIUS (Ordinul MF 1.366/2021) — Monitorul Oficial / Legislație.just.ro, 2021
- eFactura — Informații tehnice — Ministerul Finanțelor, 2026
- UBL 2.1 Invoice — documentație și schemă XSD — OASIS Open, 2013
- Ghid coduri facturi RO e-Factura (tipuri de documente, BT-3) — ANAF
- Prezentare RO e-Factura — reguli de validare RO_CIUS (BR-RO) — Ministerul Finanțelor
Andrei Badulescu
Fondator & Software ArchitectConstruiește sisteme B2B la BaseTech — ERP la comandă, platforme SaaS, agenți AI și arhitecturi programmatic SEO. Scrie despre deciziile tehnice din spatele lor: stack, trade-off-uri și ce ține la scară.
Vezi profilul autorului →Articole conexe

Modulul de raportare și BI avansată într-un ERP la comandă
Vezi cum se agregă datele din toate modulele ERP într-un strat de raportare unic, ce KPI-uri contează pe departament și când merită BI dedicat.

Modulul HR și salarizare într-un ERP la comandă: funcționare
Cum funcționează HR și salarizarea într-un ERP la comandă: dosar de personal, pontaj, calcul salarial și pragul de la care modulul intern chiar merită.

Modulul CRM într-un ERP la comandă: pipeline și oportunități
Cum urmărește modulul CRM dintr-un ERP la comandă pipeline-ul de vânzări, oportunitățile și activitățile de contact legate de fiecare client.
Insights pentru companii
care construiesc
Articole noi despre ERP, AI, agenți și pSEO, direct pe email. Fără spam.