FacturareIntră în aplicație
API pentru firma taFacturi · pagina 3 din 9

Facturi, proforme și stornări

De la ciornă la factura emisă, într-o cerere sau pas cu pas, cu regulile aplicației.

Actualizat la

Creare și emitere

POST /companies/{company_id}/documents face o ciornă. Cu "issue": true o și emite (îi dă numărul următor din serie), iar cu "submit": true o și trimite în RO e-Factura, toate în aceeași cerere:

{
  "client_id": 55,
  "lines": [
    { "product_id": 31, "quantity": 2 },
    { "name": "Transport", "quantity": 1, "unit_price": 40, "vat_percent": 21 }
  ],
  "due_date": "2026-10-30",
  "order_ref": "PO-7781",
  "issue": true,
  "submit": true
}
  • Dacă emiterea nu reușește (lipsește județul clientului, seria e dezactivată), cererea întoarce eroarea și nu lasă nicio ciornă în urmă.
  • Dacă emiterea reușește, dar ANAF nu primește factura chiar atunci, factura rămâne emisă și programată pentru trimitere; reîncercăm noi.
  • Fără issue, documentul rămâne ciornă: îl vezi în aplicație și îl emiți mai târziu, din aplicație sau cu /issue.

Data emiterii este implicit ziua de azi în România, scadența vine din setările firmei, iar totalurile, TVA-ul și cursul valutar le calculăm noi.

Clientul

Dai fie client_id, un client din agendă, fie client, scris direct pe document. Cu "save_client": true, clientul scris direct intră și în agendă (dacă există deja cu același CUI, CNP sau ref, se folosește acela).

  • Pentru RO e-Factura, o firmă din România are nevoie de CUI, localitate și județ. În București, localitatea este sectorul: "city": "Sector 3", "county": "București".
  • O persoană fizică: "kind": "pf", cu sau fără CNP. Fără CNP, sau cu "send_cnp": false, în e-Factura pleacă 13 zerouri, cum cere ANAF.
  • O firmă din alt stat: "country": "DE" și codul ei de TVA în cui.

Liniile și TVA-ul

  • quantity și unit_price (în moneda documentului); cu "price_includes_vat": true, prețul conține TVA. discount_percent reduce linia.
  • TVA-ul: vat_rate_id (o cotă a firmei, din GET /companies/{company_id}), sau vat_percent cu vat_category, sau nimic, pentru cota implicită a firmei. La o firmă neplătitoare de TVA nu se aplică TVA.
  • Unitatea este un cod UN/ECE: H87 bucată (implicit), HUR oră, KGM kilogram, MTR metru, C62 unitate.
  • Cu product_id, linia ia din catalog denumirea, prețul, unitatea și cota; ce trimiți în plus are prioritate.

Valuta

Cu "currency": "EUR" și fără exchange_rate, punem cursul BNR pentru data emiterii (ultimul comunicat înaintea ei) și îl arătăm în exchange_rate și exchange_rate_date. Dacă dai tu cursul, rămâne cel dat. Un produs cu prețul în euro pe o factură în lei se convertește la același curs (src_price, src_currency).

Încasată la emitere

Cu "collected": true și payment_method, factura iese încasată integral, cu încasarea înregistrată la emitere. Cu "payment_method": "numerar" se emite și chitanța. "payment_method": "bon_fiscal" face factura de tip 751 (emisă pe baza unui bon fiscal).

Numerotarea

La emitere, numărul este următorul din seria principală a firmei. Altă serie: series_id (seriile sunt în GET /companies/{company_id}); alt număr: number. Un număr deja folosit în serie primește 409 conflict.

Modificare și ștergere

PATCH schimbă doar câmpurile trimise; lines, dacă îl trimiți, înlocuiește toate liniile. Se poate modifica o ciornă și o factură emisă care nu a ajuns la ANAF (de exemplu una respinsă). După ce ANAF a primit-o, factura nu se mai modifică și nu se mai șterge: se stornează. Ștergerea (DELETE) merge pentru ciorne și pentru documentele emise netrimise, fără chitanțe și fără stornări; ea rămâne în jurnalul firmei.

Stornarea

POST …/storno emite factura de stornare: cantități negative, cu trimitere la factura inițială, totală sau doar pe unele linii ({"line_id", "quantity"}, cu id-urile liniilor din document). O factură trimisă în RO e-Factura se stornează după ce ANAF a validat-o. Stornarea se trimite apoi ca orice factură.

Proforme

"type": "proforma" face o proformă, cu seria ei. O proformă nu ajunge în RO e-Factura și nu se stornează. Când clientul plătește, POST …/convert face din ea o ciornă de factură cu aceleași linii, pe care o emiți cu /issue.

PDF și email

GET …/pdf dă PDF-ul, cu sigla firmei și contul bancar. POST …/email îl trimite clientului (sau adreselor din to), de la adresa Chappa, cu suma, scadența și IBAN-ul în mesaj; merge pentru firmele verificate, conectate la ANAF.

Găsirea documentelor

GET …/documents are filtre pentru tip, stare, starea în e-Factura, plată, perioadă și client. Cel mai sigur mod de a regăsi o factură a ta este external_ref: pune la creare id-ul comenzii și caută după el cu ?external_ref=comanda-1042. Lista cuprinde și facturile trimise din alte programe prin SPV ("source": "spv"); pe acestea doar le citești.

Referința

Lista documentelor

GET /api/v1/companies/{company_id}/documents

Permisiune: documents:read.

Facturile, proformele și stornările firmei, cele mai noi primele, fără linii și încasări. Include facturile trimise din alte programe prin SPV (source: "spv").

ParametruTipCe este
company_id în adresăintegerId-ul firmei.
typeinvoice | proforma | stornoTipul.
statusdraft | issuedCiorne sau emise.
efacturanot_sent | scheduled | queued | processing | accepted | rejectedStarea în RO e-Factura.
paymentunpaid | paid | overdueÎncasare (doar facturi emise).
issued_fromdateEmise de la data.
issued_todateEmise până la data (inclusiv).
client_idintegerAle unui client din agendă.
external_refstringCu id-ul tău.
qstringCaută în număr, client și CUI.
limitintegerCâte pe pagină, 1–100. Implicit 25.
starting_afterstringnext_cursor din pagina anterioară.

Răspuns 200: o List de Document.

{
  "object": "list",
  "data": [
    { "id": 812, "object": "document", "type": "invoice", "status": "issued", "number": "FCT 42",
      "issue_date": "2026-10-09", "currency": "RON", "client": { "kind": "pj", "name": "Beta Construct SRL", "cui": "RO18547290", "country": "RO" },
      "totals": { "net": 610, "vat": 128.1, "total": 738.1 },
      "efactura": { "applies": true, "status": "accepted", "upload_index": "5012345678", "errors": null, "scheduled_at": null, "anaf_id": null },
      "payment": { "status": "unpaid", "paid": 0, "outstanding": 738.1, "overdue": false }, "…": "…" }
  ],
  "has_more": true,
  "next_cursor": 812
}

Creează o factură sau o proformă

POST /api/v1/companies/{company_id}/documents

Permisiune: documents:write.

Creează o ciornă; cu issue: true o și emite (număr din serie), cu submit: true o și trimite în RO e-Factura, toate într-o cerere. Răspunsul este documentul întreg. Totalurile, TVA-ul, cursul BNR și scadența le calculăm noi, cu regulile aplicației.

ParametruTipCe este
company_id în adresăintegerId-ul firmei.

Corp: DocumentCreate, de exemplu.

{
  "type": "invoice",
  "client": {
    "name": "Beta Construct SRL",
    "cui": "RO18547290",
    "address": "Str. Fabricii 12",
    "city": "Sector 3",
    "county": "București",
    "email": "contabilitate@beta.ro"
  },
  "save_client": true,
  "lines": [
    { "name": "Abonament lunar", "unit": "H87", "quantity": 1, "unit_price": 250, "vat_percent": 21 },
    { "name": "Ore suport", "unit": "HUR", "quantity": 3, "unit_price": 120, "vat_percent": 21 }
  ],
  "payment_method": "ordin_plata",
  "external_ref": "comanda-1042",
  "issue": true,
  "submit": true
}

Răspuns 201: Document.

{
  "id": 812,
  "object": "document",
  "company_id": 7,
  "type": "invoice",
  "status": "issued",
  "source": "chappa",
  "number": "FCT 42",
  "series": "FCT",
  "sequence": 42,
  "issue_date": "2026-10-09",
  "due_date": "2026-10-23",
  "currency": "RON",
  "exchange_rate": null,
  "exchange_rate_date": null,
  "client_id": 55,
  "client": {
    "kind": "pj", "name": "Beta Construct SRL", "cui": "RO18547290", "cnp": null, "send_cnp": false,
    "reg_com": null, "address": "Str. Fabricii 12", "city": "Sector 3", "county": "București",
    "country": "RO", "email": "contabilitate@beta.ro", "phone": null
  },
  "lines": [
    { "id": 3301, "position": 1, "product_id": null, "code": null, "name": "Abonament lunar", "description": null,
      "unit": "H87", "quantity": 1, "unit_price": 250, "price_includes_vat": false, "discount_percent": 0,
      "vat_rate_id": 14, "vat_percent": 21, "vat_category": "S", "exemption_code": null, "exemption_text": null,
      "net": 250, "vat": 52.5, "gross": 302.5, "storno_of_line_id": null, "src_price": null, "src_currency": null },
    { "id": 3302, "position": 2, "product_id": null, "code": null, "name": "Ore suport", "description": null,
      "unit": "HUR", "quantity": 3, "unit_price": 120, "price_includes_vat": false, "discount_percent": 0,
      "vat_rate_id": 14, "vat_percent": 21, "vat_category": "S", "exemption_code": null, "exemption_text": null,
      "net": 360, "vat": 75.6, "gross": 435.6, "storno_of_line_id": null, "src_price": null, "src_currency": null }
  ],
  "totals": { "net": 610, "vat": 128.1, "total": 738.1 },
  "notes": null,
  "internal_note": null,
  "order_ref": null,
  "contract_ref": null,
  "external_ref": "comanda-1042",
  "payment_method": "ordin_plata",
  "bank_account_id": 3,
  "vat_on_collection": false,
  "storno_of": null,
  "stornos": [],
  "converted_from_id": null,
  "converted_to_id": null,
  "efactura": {
    "applies": true,
    "status": "processing",
    "upload_index": "5012345678",
    "errors": null,
    "scheduled_at": null,
    "deadline": "2026-10-16",
    "anaf_id": null,
    "history": [{ "status": "processing", "upload_index": "5012345678", "errors": null, "at": "2026-10-09 14:02" }]
  },
  "payment": { "status": "unpaid", "paid": 0, "outstanding": 738.1, "overdue": false, "collected_at_issue": false },
  "payments": [],
  "created_at": "2026-10-09T14:02:11+03:00",
  "issued_at": "2026-10-09T14:02:11+03:00"
}

Un document

GET /api/v1/companies/{company_id}/documents/{document_id}

Permisiune: documents:read.

Documentul întreg: linii, totaluri, starea în RO e-Factura cu istoricul trimiterilor, încasările.

ParametruTipCe este
company_id în adresăintegerId-ul firmei.
document_id în adresăintegerId-ul documentului.

Răspuns 200: Document.

Modifică un document

PATCH /api/v1/companies/{company_id}/documents/{document_id}

Permisiune: documents:write.

O ciornă, sau o factură emisă care nu a ajuns la ANAF (după o respingere, de exemplu). Doar câmpurile trimise se schimbă. După ce ANAF a primit-o, factura nu se mai modifică: se stornează.

ParametruTipCe este
company_id în adresăintegerId-ul firmei.
document_id în adresăintegerId-ul documentului.

Corp: DocumentInput, de exemplu.

{ "due_date": "2026-10-30", "notes": "Plata în două tranșe." }

Răspuns 200: Document.

Șterge un document

DELETE /api/v1/companies/{company_id}/documents/{document_id}

Permisiune: documents:delete.

Ciornele și documentele emise care nu au ajuns la ANAF, fără chitanțe și fără stornări. Ștergerea rămâne în jurnalul firmei.

ParametruTipCe este
company_id în adresăintegerId-ul firmei.
document_id în adresăintegerId-ul documentului.

Răspuns 200: Deleted.

Emite o ciornă

POST /api/v1/companies/{company_id}/documents/{document_id}/issue

Permisiune: documents:issue.

Îi dă număr din serie și îngheață datele firmei pe document. Dacă firma trimite automat, intră în programul de trimitere.

ParametruTipCe este
company_id în adresăintegerId-ul firmei.
document_id în adresăintegerId-ul documentului.

Corp: IssueInput, de exemplu.

{ "series_id": 2 }

Răspuns 200: Document.

Stornează o factură

POST /api/v1/companies/{company_id}/documents/{document_id}/storno

Permisiune: documents:issue.

Emite factura de stornare (cantități negative, cu trimitere la factura inițială), totală sau pe linii. O factură trimisă se stornează abia după validarea ANAF. Răspunsul este stornarea.

ParametruTipCe este
company_id în adresăintegerId-ul firmei.
document_id în adresăintegerId-ul documentului.

Corp: StornoInput, de exemplu.

{ "lines": [{ "line_id": 3302, "quantity": 1 }], "reason": "O oră facturată în plus" }

Răspuns 201: Document.

Transformă o proformă în factură

POST /api/v1/companies/{company_id}/documents/{document_id}/convert

Permisiune: documents:write.

Face din proforma emisă o ciornă de factură cu aceleași linii; o emiți apoi cu /issue.

ParametruTipCe este
company_id în adresăintegerId-ul firmei.
document_id în adresăintegerId-ul documentului.

Răspuns 201: Document.

Trimite documentul pe email

POST /api/v1/companies/{company_id}/documents/{document_id}/email

Permisiune: documents:write.

PDF-ul, atașat, de la adresa Chappa, cu IBAN-ul pentru plată. Doar pentru o firmă verificată, conectată la ANAF.

ParametruTipCe este
company_id în adresăintegerId-ul firmei.
document_id în adresăintegerId-ul documentului.

Corp: EmailInput, de exemplu.

{ "to": "contabilitate@beta.ro", "message": "Vă mulțumim pentru comandă." }

Răspuns 200: Email.

PDF-ul documentului

GET /api/v1/companies/{company_id}/documents/{document_id}/pdf

Permisiune: documents:read.

Documentul în PDF, cu sigla firmei. Și pentru facturile trimise din alte programe.

ParametruTipCe este
company_id în adresăintegerId-ul firmei.
document_id în adresăintegerId-ul documentului.

Răspuns 200: un fișier PDF (application/pdf).

Obiectul DocumentInput

Ce trimiți la creare și la modificare. La modificare, câmpurile lipsă rămân cum erau; lines trimis înlocuiește toate liniile.

CâmpTipCe este
typeinvoice | proformaDoar la creare. Implicit invoice.
issue_datedateData emiterii. Implicit azi (ora României).
due_datedate sau nullScadența. Implicit data emiterii plus zilele implicite ale firmei; "" o șterge.
currencystringMoneda, cod ISO 4217. Implicit moneda firmei.
exchange_ratenumber sau nullCursul. Lipsă: cursul BNR pentru data emiterii, completat de noi.
client_idinteger sau nullUn client din agendă…
clientClientInput…sau clientul scris direct pe document.
save_clientbooleanSalvează clientul scris direct în agendă (după CUI, CNP sau ref îl găsește dacă există).
lineslistă de LineInputLiniile documentului.
notesstring sau nullMențiuni tipărite pe document.
internal_notestring sau nullNotă internă, netipărită.
order_refstring sau nullNumărul comenzii (BT-13 în e-Factura).
contract_refstring sau nullNumărul contractului (BT-12).
external_refstring sau nullId-ul tău pentru document. Îl cauți apoi cu ?external_ref=.
payment_methodordin_plata | numerar | card | cec | bon_fiscal | altulModul de plată; bon_fiscal face factura de tip 751.
collectedbooleanÎncasată integral la emitere, prin payment_method (numerar: cu chitanță).
bank_account_idinteger sau nullContul tipărit pe factură. Implicit cel principal.

Obiectul DocumentCreate

DocumentInput, plus ce poate face aceeași cerere:

CâmpTipCe este
issuebooleanEmite documentul (îi dă număr). Dacă emiterea nu reușește, nu rămâne nicio ciornă. Cere documents:issue.
submitbooleanTrimite factura emisă în RO e-Factura. Cere issue: true și documents:submit. Dacă ANAF nu o ia acum, rămâne programată și reîncercăm.
series_idintegerSeria, la emitere. Implicit seria principală.
numberintegerNumărul, la emitere. Implicit următorul din serie.

Obiectul LineInput

O linie, cum o trimiți.

CâmpTipCe este
product_idinteger sau nullUn produs din catalog (completează restul câmpurilor lipsă).
codestring sau nullCodul articolului.
namestringDenumirea.
descriptionstring sau nullDescriere.
unitstringUnitatea, cod UN/ECE: H87 bucată, HUR oră, KGM kilogram, C62 unitate. Implicit H87.
quantitynumberCantitatea.
unit_pricenumberPrețul unitar, în moneda documentului.
price_includes_vatbooleanPrețul conține TVA.
discount_percentnumber sau nullReducere pe linie, în procente.
vat_rate_idinteger sau nullO cotă a firmei (vat_rates)…
vat_percentnumber sau null…sau procentul, cu vat_category. Lipsă: cota implicită a firmei.
vat_categorystring sau nullCategoria de TVA: S, Z, E, AE, K, G, O.
src_pricenumber sau nullPrețul în altă monedă, convertit de noi la cursul BNR dacă lipsește unit_price.
src_currencystring sau nullMoneda lui src_price.

Obiectul Document

O factură, o proformă sau o stornare.

CâmpTipCe este
idintegerId-ul documentului.
objectdocumentMereu document.
company_idintegerFirma.
typeinvoice | proforma | stornoFactură, proformă sau factură de stornare.
statusdraft | issuedCiornă sau emis (cu număr).
sourcechappa | spvspv: trimisă din alt program prin SPV și preluată de noi (nu se modifică).
numberstring sau nullNumărul tipărit (seria și numărul). null la ciornă.
seriesstring sau nullSeria.
sequenceinteger sau nullNumărul din serie.
issue_datedateData emiterii.
due_datedate sau nullScadența.
currencystringMoneda.
exchange_ratenumber sau nullCursul folosit.
exchange_rate_datedate sau nullData cursului BNR (lipsă când cursul a fost scris de mână).
client_idinteger sau nullClientul din agendă.
clientClientSnapshotClientul de pe document.
lineslistă de LineLiniile (lipsesc din liste).
totalsobjectnet, vat, total.
notesstring sau nullMențiunile.
internal_notestring sau nullNota internă.
order_refstring sau nullComanda.
contract_refstring sau nullContractul.
external_refstring sau nullId-ul tău.
payment_methodstring sau nullModul de plată.
bank_account_idinteger sau nullContul tipărit.
vat_on_collectionbooleanEmisă cu TVA la încasare.
storno_ofobject sau nullPe o stornare: factura stornată (id, number, date).
stornoslistă de objectPe o factură: stornările ei (id, number, date, total).
converted_from_idinteger sau nullProforma din care vine factura.
converted_to_idinteger sau nullFactura în care s-a transformat proforma.
efacturaEfacturaStateStarea în RO e-Factura.
paymentPaymentStateCât s-a încasat.
paymentslistă de objectÎncasările (lipsesc din liste): id, amount, paid_on, method, reference, note, receipt_id, receipt_number.
created_atdate-timeCreat.
issued_atdate-time sau nullEmis.

Obiectul Line

O linie, cum o citești: câmpurile din LineInput, plus:

CâmpTipCe este
idintegerId-ul liniei (îl folosești la stornare).
positionintegerOrdinea.
exemption_codestring sau nullCodul motivului de scutire (VATEX).
exemption_textstring sau nullTemeiul scutirii.
netnumberValoarea fără TVA.
vatnumberTVA-ul liniei.
grossnumberValoarea cu TVA.
storno_of_line_idinteger sau nullLinia stornată, pe o stornare.

Obiectul ClientSnapshot

Clientul cum a rămas pe document.

CâmpTipCe este
kindpj | pfFirmă sau persoană fizică.
namestringDenumirea sau numele.
cuistring sau nullCUI-ul firmei.
cnpstring sau nullCNP-ul persoanei (mascat pentru rolul de vizualizare).
send_cnpbooleanCNP-ul se transmite în e-Factura (altfel 13 zerouri).
reg_comstring sau nullRegistrul Comerțului.
addressstring sau nullAdresa.
citystring sau nullLocalitatea (în București: Sector 1…6).
countystring sau nullJudețul.
countrystringȚara, ISO 3166-1.
emailstring sau nullEmailul.
phonestring sau nullTelefonul.

Obiectul IssueInput

Emiterea unei ciorne. Toate opționale.

CâmpTipCe este
series_idintegerSeria. Implicit cea principală.
numberintegerNumărul. Implicit următorul liber.
issue_datedateData emiterii. Implicit cea din ciornă.

Obiectul StornoInput

O stornare (factură cu cantități negative care face trimitere la cea inițială).

CâmpTipCe este
lineslistă de object{line_id, quantity}: cât stornezi din fiecare linie. Lipsă: tot ce se mai poate storna.
series_idintegerSeria stornării. Implicit seria facturii.
issue_datedateData. Implicit azi.
reasonstringMotivul, tipărit în mențiuni.

Obiectul EmailInput

Trimiterea PDF-ului pe email, de la adresa Chappa, în numele firmei. Doar pentru o firmă verificată, conectată la ANAF.

CâmpTipCe este
tostringAdrese separate prin virgulă. Implicit emailul clientului.
messagestringMesajul tău, deasupra facturii.

Obiectul Email

Emailul trimis.

CâmpTipCe este
objectemailMereu email.
document_idintegerDocumentul (sau receipt_id, chitanța).
sent_tolistă de stringAdresele.