Skip to main content

Referință API POSfix

Prezentare generală​

Serverul API POSfix rulează local pe dispozitivul POS și expune un API REST pe portul 4567 (HTTP). Acesta permite unui sistem ERP extern să efectueze operațiuni fiscale — vânzări, depunere/retragere numerar, rapoarte Z/X, rapoarte periodice și interogări — direct pe terminalul POS prin rețeaua locală.

URL de bază: http://<ip-dispozitiv>:4567

Pornire rapidă​

  1. Asigurați-vă că dispozitivul POS și ERP-ul sunt în aceeași rețea locală.
  2. Obțineți adresa IP a dispozitivului din Setări > Hardware în aplicația POS, sau de la endpoint-ul de health.
  3. Obțineți cheia API din panoul de control POSfix cloud.
  4. Verificați conectivitatea:
    GET http://<ip-dispozitiv>:4567/api/health
  5. Începeți să efectuați operațiuni fiscale folosind header-ul X-API-Key.

Autentificare​

Toate endpoint-urile (cu excepția /api/health) necesită header-ul X-API-Key.

X-API-Key: cheia-dvs-api

Cheia API este provizionată prin platforma cloud POSfix și este unică per terminal.

Cheie lipsă → 401 MISSING_API_KEY Cheie invalidă → 401 INVALID_API_KEY


Formatul răspunsului​

Fiecare răspuns urmează acest format:

{
"success": true,
"data": { ... },
"error": null,
"timestamp": "2026-02-16T12:00:00.000Z"
}

În caz de eroare:

{
"success": false,
"error": {
"code": "COD_EROARE",
"message": "Descriere lizibilă",
"details": [ ... ]
},
"timestamp": "2026-02-16T12:00:00.000Z"
}
CâmpTipDescriere
successbooleantrue dacă operațiunea a reușit
dataobject | nullDatele răspunsului (null în caz de eroare)
errorobject | nullInformații eroare (null în caz de succes)
error.codestringCod de eroare (machine-readable)
error.messagestringMesaj de eroare lizibil
error.detailsarray | nullDetalii erori de validare (la nivel de câmp)
timestampstringMarcaj temporal ISO 8601 UTC

Endpoint-uri​

1. Stare și Sănătate​

GET /api/health​

Verifică starea serverului. Nu necesită autentificare.

Returnează versiunea aplicației, starea fiscală, ID-ul terminalului, IP-ul dispozitivului și timpul de funcționare.

Câmpuri răspuns:

CâmpTipDescriere
statusstringStarea serverului: "ready"
versionstringVersiunea aplicației (ex. "1.0.1+5")
fiscalStatusstringStare fiscală: "online", "offline", "not_fiscal"
terminalIdstringIdentificator terminal
serverPortintPort de ascultare (4567)
uptimeintTimp de funcționare server în secunde
serverStartedAtstringMarcaj temporal ISO 8601 când serverul a pornit
deviceIpstringAdresa IP a dispozitivului în rețeaua locală

Exemplu răspuns:

{
"success": true,
"data": {
"status": "ready",
"version": "1.0.1+5",
"fiscalStatus": "online",
"terminalId": "T-12345",
"serverPort": 4567,
"uptime": 3600,
"serverStartedAt": "2026-02-16T10:00:00.000Z",
"deviceIp": "192.168.1.50"
},
"error": null,
"timestamp": "2026-02-16T12:00:00.000Z"
}

2. Vânzări​

POST /api/sales​

Creează o vânzare nouă. Efectuează înregistrarea fiscală la MEV (autoritatea fiscală), printează bonul și opțional livrează bonul prin SMS/email.

Corpul cererii:

CâmpTipObligatoriuImplicitDescriere
itemsarrayDa—Lista articolelor de vânzare (minim 1)
items[].idstringNunullID extern produs din ERP. Dacă lipsește, payload-ul de sincronizare va conține null
items[].namestringDa—Denumire produs (1-100 caractere)
items[].unitPricenumberDa—Preț unitar (trebuie să fie > 0)
items[].quantitynumberDa—Cantitate (trebuie să fie > 0). Zecimale permise dacă allowDecimals: true
items[].vatCodestringDa—Cod TVA: A, B, C, D, E sau _
items[].discountPercentnumberNu0Procent reducere la nivel de articol (0-100)
items[].allowDecimalsbooleanNufalsePermite cantități fracționare (ex. 0.750 kg)
cartDiscountobjectNunullReducere la nivel de coș
cartDiscount.percentnumberDa—Procent reducere coș (0-100)
paymentsarrayDa—Lista plăților (minim 1)
payments[].typestringDa—Cod tip plată ACPS (vezi Tipuri de plată)
payments[].amountnumberDa—Suma plății
payments[].rrnstringNunullRRN-ul unei plăți cu cardul deja încasate în altă aplicație sau pe alt terminal, max. 12 caractere. Cu el, casa nu pornește terminalul bancar și doar emite bonul; fără el, încasează ea cardul. Anularea și rambursarea unei plăți cu RRN trimis se fac în aplicația care a încasat cardul.
amountReceivednumberDa—Suma totală primită de la client
changenumberDa—Rest returnat clientului
deliveryobjectNunullOpțiuni de livrare bon (SMS/email)
delivery.customerPhonestringNunullNumăr telefon pentru livrare SMS (format: +XXXXXXXXXXX)
delivery.customerEmailstringNunullEmail pentru livrare bon
delivery.customerNamestringNunullNumele clientului (max 60 caractere)
delivery.languagestringNu"ro"Limba bonului: "ro", "en", "ru"
printReceiptbooleanNutruePrintează bonul pe imprimanta POS

Câmpuri răspuns:

CâmpTipDescriere
saleIdstringUUID local al vânzării
purchaseIdstringID achiziție pe server
serverSaleIdstringID vânzare pe server
fiscalOperationIdstringUUID operațiune fiscală
receiptNumberintNumăr secvențial bon în cadrul raportului Z curent
reportNumberintNumărul raportului Z curent
fiscalCodestringCod fiscal de la MEV
mevIdstring | nullID tranzacție MEV (null dacă offline)
isOfflinebooleantrue dacă MEV a fost inaccesibil (bon fiscal offline)
offlineFiscalCodestring | nullCod fiscal offline (când operează offline)
totalnumberTotal final al vânzării (după reduceri)
subtotalnumberSubtotal înainte de reducerea pe coș
amountReceivednumberSuma primită de la client
changenumberRest returnat
vatBreakdownobjectDefalcarea pe coduri TVA (vezi Defalcare TVA)
paymentBreakdownarrayLista de obiecte { type, amount }
qrCodeDatastringURL cod QR pentru verificarea bonului
mevResponseXmlstringRăspuns XML SOAP de la MEV
receiptDeliveryobject | null{ smsSent, emailSent } — indică faptul că livrarea a fost solicitată, nu confirmată
createdAtstringMarcaj temporal ISO 8601

Exemplu — Vânzare simplă (1 articol, numerar):

// Cerere
POST /api/sales
{
"items": [
{
"name": "Cafea espresso",
"unitPrice": 45.00,
"quantity": 1,
"vatCode": "B"
}
],
"payments": [
{ "type": "1", "amount": 45.00 }
],
"amountReceived": 45.00,
"change": 0,
"printReceipt": true
}
// Răspuns 200
{
"success": true,
"data": {
"saleId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"purchaseId": "server-purchase-001",
"serverSaleId": "server-sale-001",
"fiscalOperationId": "fiscal-op-001",
"receiptNumber": 1,
"reportNumber": 1,
"fiscalCode": "MEV-TXN-001",
"mevId": "MEV-TXN-001",
"isOffline": false,
"offlineFiscalCode": null,
"total": 45.00,
"subtotal": 45.00,
"amountReceived": 45.00,
"change": 0.00,
"vatBreakdown": {
"B": {
"code": "B",
"percent": 20.0,
"vatAmount": 7.50,
"taxableBase": 37.50,
"totalWithVat": 45.00
}
},
"paymentBreakdown": [
{ "type": "1", "amount": 45.00 }
],
"qrCodeData": "https://sift-mev.sfs.md/verify?id=MEV-TXN-001",
"mevResponseXml": "<?xml version=\"1.0\"?><soap:Envelope>...</soap:Envelope>",
"receiptDelivery": null,
"createdAt": "2026-02-16T12:00:00.000Z"
},
"error": null,
"timestamp": "2026-02-16T12:00:00.000Z"
}

Exemplu — Vânzare complexă (articole multiple, plăți mixte, reduceri, livrare):

// Cerere
POST /api/sales
{
"items": [
{
"id": "prod-001",
"name": "Cafea espresso",
"unitPrice": 45.00,
"quantity": 2,
"vatCode": "B"
},
{
"name": "Tort Napoleon (kg)",
"unitPrice": 180.00,
"quantity": 0.750,
"vatCode": "B",
"discountPercent": 10.0,
"allowDecimals": true
},
{
"name": "Apa minerala 0.5L",
"unitPrice": 15.00,
"quantity": 3,
"vatCode": "B"
}
],
"cartDiscount": {
"percent": 5.0
},
"payments": [
{ "type": "1", "amount": 200.00 },
{ "type": "2", "amount": 50.00, "rrn": "123456789012" }
],
"amountReceived": 250.00,
"change": 0,
"delivery": {
"customerPhone": "+37369123456",
"customerEmail": "client@email.com",
"customerName": "Vasile Munteanu",
"language": "ro"
},
"printReceipt": true
}

Erorile de validare returnează HTTP 400 cu detalii la nivel de câmp:

{
"success": false,
"error": {
"code": "VALIDATION_ERROR",
"message": "Request validation failed",
"details": [
{
"field": "items[0].name",
"code": "ITEM_NAME_INVALID",
"message": "Item name must be 1-100 characters"
},
{
"field": "items[0].unitPrice",
"code": "ITEM_PRICE_INVALID",
"message": "Unit price must be greater than 0"
}
]
},
"timestamp": "2026-02-16T12:00:00.000Z"
}

GET /api/sales​

Listează vânzările cu filtrare pe interval de date și paginare.

Parametri de interogare:

ParametruTipObligatoriuImplicitDescriere
dateFromstringNu—Data de început (ISO: YYYY-MM-DD)
dateTostringNu—Data de sfârșit (ISO: YYYY-MM-DD)
limitintNu50Număr maxim de rezultate pe pagină
offsetintNu0Offset paginare

Câmpuri răspuns:

CâmpTipDescriere
salesarrayLista rezumatelor vânzărilor
sales[].idstringUUID vânzare
sales[].purchaseIdstringID achiziție server
sales[].serverSaleIdstringID vânzare server
sales[].fiscalOperationIdstringUUID operațiune fiscală
sales[].cashierIdstringID casier
sales[].cashierNamestringNume casier
sales[].subtotalnumberSuma subtotal
sales[].totalnumberSuma totală
sales[].paymentTypestringEticheta tipului de plată principal
sales[].paymentAmountnumberSuma plătită
sales[].changeAmountnumberRest returnat
sales[].statusstringStarea sincronizării
sales[].createdAtstringMarcaj temporal ISO 8601
totalintNumărul total de vânzări care corespund
limitintLimita aplicată
offsetintOffset-ul aplicat

Exemplu:

GET /api/sales?dateFrom=2026-02-01&dateTo=2026-02-16&limit=50&offset=0

GET /api/sales/{saleId}​

Obține detaliile complete ale unei vânzări specifice, inclusiv articolele, plățile și datele operațiunii fiscale.

Parametri de cale:

ParametruTipDescriere
saleIdstringUUID vânzare

Răspunsul include:

SecțiuneDescriere
items[]Detalii produs: productId, productName, quantity, unitPrice, originalPrice, discountAmount, markupAmount, netAmount, vatCode, vatPercent, vatAmount
payments[]Detalii plată: paymentType, amount, notes
fiscalOperationDate fiscale: mevId, receiptNumber, reportNumber, status, isOffline, mevResponseXml, qrCodeData

Eroare: 404 SALE_NOT_FOUND dacă ID-ul vânzării nu există.


3. Operațiuni cu numerar​

POST /api/cash/in​

Depune numerar în casă. Creează un bon de serviciu fiscal trimis la MEV.

Corpul cererii:

CâmpTipObligatoriuImplicitDescriere
amountnumberDa—Suma de depus (trebuie să fie > 0)
reasonstringNunullMotivul depunerii
printReceiptbooleanNutruePrintează bon de serviciu

Câmpuri răspuns:

CâmpTipDescriere
operationIdstringUUID operațiune
fiscalOperationIdstringUUID operațiune fiscală
receiptNumberintNumăr bon de serviciu
reportNumberintNumărul raportului Z curent
mevIdstring | nullID tranzacție MEV
isOfflinebooleanDacă operațiunea a fost offline
amountnumberSuma depusă
newBalancenumberNoul sold de numerar
operationTypestring"cashIn"
mevResponseXmlstringRăspuns XML SOAP
createdAtstringMarcaj temporal ISO 8601

Exemplu:

// Cerere
POST /api/cash/in
{
"amount": 500.00,
"reason": "Depunere inceput zi",
"printReceipt": true
}
// Răspuns 200
{
"success": true,
"data": {
"operationId": "op-uuid-001",
"fiscalOperationId": "fiscal-op-003",
"receiptNumber": 1,
"reportNumber": 1,
"mevId": "MEV-SVC-001",
"isOffline": false,
"amount": 500.00,
"newBalance": 500.00,
"operationType": "cashIn",
"mevResponseXml": "...",
"createdAt": "2026-02-16T08:00:00.000Z"
}
}

POST /api/cash/out​

Retrage numerar din casă. Verifică dacă soldul este suficient înainte de procesare.

Corpul cererii:

CâmpTipObligatoriuImplicitDescriere
amountnumberDa—Suma de retras (trebuie să fie > 0)
reasonstringNunullMotivul retragerii
printReceiptbooleanNutruePrintează bon de serviciu

Câmpuri răspuns: Identice cu depunerea, cu operationType: "cashOut".

Eroare: 409 INSUFFICIENT_CASH_BALANCE dacă soldul curent este mai mic decât suma solicitată.

{
"success": false,
"error": {
"code": "INSUFFICIENT_CASH_BALANCE",
"message": "Cash balance (300.00) is insufficient for withdrawal of 500.00"
}
}

4. Rapoarte​

POST /api/reports/z​

Generează un Raport Z — închide ziua fiscală.

warning

Aceasta este o operațiune ireversibilă. Resetează contoarele de bonuri și incrementează numărul raportului.

Corpul cererii:

CâmpTipObligatoriuImplicitDescriere
printReportbooleanNutruePrintează raportul

Necesită: Terminalul trebuie să fie fiscalizat și să aibă credențiale MEV valide.

Câmpuri răspuns:

CâmpTipDescriere
reportNumberintNumăr raport Z
operationIdstringUUID operațiune fiscală
mevIdstring | nullID tranzacție MEV
isOfflinebooleanDacă operațiunea a fost offline
reportDataobjectDatele complete ale raportului (vezi Obiectul Report Data mai jos)
mevResponseXmlstringRăspuns XML SOAP de la MEV
generatedAtstringMarcaj temporal ISO 8601

Obiectul Report Data:

CâmpTipDescriere
reportNumberintNumăr raport Z
dailyTotalnumberTotal vânzări pe zi
dailyTaxnumberTotal TVA pe zi
dailyUntaxednumberSuma neimpozitată
vatBreakdownobjectDefalcare pe coduri TVA
receiptsIssuedintNumăr de bonuri emise
lastReceiptNumberintUltimul număr de bon
receiptsSentToMevintBonuri trimise cu succes la MEV
paymentTotalsobjectSuma per cod tip plată ACPS (ex. { "1": 3000.00, "2": 2000.00 })
paymentCountsobjectNumăr per cod tip plată ACPS (ex. { "1": 25, "2": 17 })
cashInnumberTotal depuneri numerar
cashOutnumberTotal retrageri numerar
cashBalancenumberSold numerar curent
yearTotalnumber | nullTotal cumulativ anual (doar Z)
yearTaxnumber | nullTVA cumulativ anual (doar Z)
totalSalesnumberTotal brut vânzări
totalReturnsnumberTotal retururi
returnsCountintNumăr operațiuni de retur
cashInCountintNumăr operațiuni depunere
cashOutCountintNumăr operațiuni retragere
generatedAtstringMarcaj temporal ISO 8601

POST /api/reports/x​

Generează un Raport X — instantaneu intermediar al zilei fiscale.

NU resetează niciun contor. Aceeași structură de cerere/răspuns ca și Raportul Z.


POST /api/reports/periodic​

Generează un Raport Periodic — date agregate din mai multe rapoarte Z.

Acesta este doar un raport local (nu se trimite la MEV). Suportă două moduri de filtrare mutual exclusive.

Corpul cererii:

CâmpTipObligatoriuImplicitDescriere
dateFromstringCondiționat—Data de început (ISO: YYYY-MM-DD). Obligatoriu pentru modul interval de date
dateTostringCondiționat—Data de sfârșit (ISO: YYYY-MM-DD). Obligatoriu pentru modul interval de date
reportFromintCondiționat—Numărul raportului Z de început. Pentru modul interval de rapoarte
reportTointCondiționat—Numărul raportului Z de sfârșit. Pentru modul interval de rapoarte
detailedbooleanNufalseInclude defalcarea individuală pe rapoarte Z
printReportbooleanNutruePrintează raportul pe imprimanta POS

Moduri de filtrare (mutual exclusive — furnizați un singur set):

  1. Interval de date: dateFrom + dateTo
  2. Interval de numere rapoarte: reportFrom și/sau reportTo (ambele opționale — omiteți reportFrom pentru a începe de la Z#1, omiteți reportTo pentru ultimul)

Câmpuri răspuns:

CâmpTipDescriere
filterModestring"dateRange" sau "reportRange"
dateFromstringData de început (YYYY-MM-DD)
dateTostringData de sfârșit (YYYY-MM-DD)
reportFromint(doar interval rapoarte) Numărul raportului Z de început
reportToint(doar interval rapoarte) Numărul raportului Z de sfârșit
totalSalesnumberTotal vânzări agregate
totalTaxnumberTotal TVA agregat
totalUntaxednumberTotal neimpozitat agregat
vatBreakdownobjectDefalcare agregată pe coduri TVA
receiptsCountintTotal bonuri din toate rapoartele Z
paymentTotalsobjectTotaluri agregate plăți pe tip
cashInnumberTotal depuneri numerar
cashOutnumberTotal retrageri numerar
cashInCountintNumăr operațiuni depunere
cashOutCountintNumăr operațiuni retragere
zReportsCountintNumăr rapoarte Z în interval
xReportsCountintNumăr rapoarte X în interval
firstZReportNumberintPrimul număr raport Z din interval
lastZReportNumberintUltimul număr raport Z din interval
firstZReportTimestampstringMarcaj temporal închidere primul raport Z
lastZReportTimestampstringMarcaj temporal închidere ultimul raport Z
totalReturnsnumberRetururi agregate
returnsCountintNumăr operațiuni de retur
individualZReportsarray | nullDefalcare pe fiecare Z (când detailed: true)
generatedAtstringMarcaj temporal ISO 8601

Câmpuri raport Z individual (când detailed: true):

CâmpTipDescriere
reportNumberintNumăr raport Z
closedAtstringMarcaj temporal ISO 8601 când Z-ul a fost închis
firstReceiptNumberintPrimul număr de bon din acest Z
lastReceiptNumberintUltimul număr de bon din acest Z
receiptsCountintNumăr de bonuri
totalSalesnumberTotal vânzări pentru acest Z
totalTaxnumberTotal TVA pentru acest Z
vatBreakdownobjectDefalcare TVA pentru acest Z
paymentTotalsobjectTotaluri plăți pe tip
cashInnumberDepuneri numerar în acest Z
cashOutnumberRetrageri numerar din acest Z

Exemplu — Sumar pe interval de date:

// Cerere
POST /api/reports/periodic
{
"dateFrom": "2026-02-01",
"dateTo": "2026-02-16",
"detailed": false,
"printReport": true
}

Exemplu — Sumar pe interval de numere rapoarte Z:

// Cerere
POST /api/reports/periodic
{
"reportFrom": 5,
"reportTo": 10,
"detailed": false,
"printReport": true
}

Exemplu — Detaliat pe interval de date:

// Cerere
POST /api/reports/periodic
{
"dateFrom": "2026-02-01",
"dateTo": "2026-02-16",
"detailed": true,
"printReport": false
}

Erori de validare:

CodCondiție
FILTER_REQUIREDNici interval de date, nici interval de rapoarte nu a fost furnizat
DATE_RANGE_INVALIDdateFrom este după dateTo
DATE_TO_FUTUREdateTo este în viitor
REPORT_NUMBER_INVALIDreportFrom sau reportTo < 1
REPORT_RANGE_INVALIDreportFrom > reportTo

5. Interogări fiscale​

GET /api/fiscal/operations​

Interogarea operațiunilor fiscale din baza de date de audit cu filtrare.

Parametri de interogare:

ParametruTipObligatoriuDescriere
dateFromstringNuData de început (ISO: YYYY-MM-DD)
dateTostringNuData de sfârșit (ISO: YYYY-MM-DD)
typestringNuFiltru tip operațiune (vezi Tabele de referință)
statusstringNuFiltru stare operațiune (vezi Tabele de referință)
limitintNuNumăr maxim rezultate (implicit 50)
offsetintNuOffset paginare (implicit 0)

Câmpuri răspuns:

CâmpTipDescriere
operationsarrayLista operațiunilor fiscale
operations[].idstringUUID operațiune
operations[].operationTypestringTipul operațiunii fiscale
operations[].receiptNumberintNumăr bon
operations[].reportNumberintNumăr raport Z
operations[].mevIdstring | nullID tranzacție MEV
operations[].statusstringStarea operațiunii
operations[].isOfflinebooleanDacă a operat offline
operations[].totalAmountnumberSuma operațiunii
operations[].vatBreakdownobjectDefalcare TVA simplificată
operations[].vatDetailsobjectTVA detaliat cu procent, rată, cost, brut
operations[].paymentsBreakdownobjectPlăți pe tip
operations[].mevResponseXmlstringRăspuns XML SOAP
operations[].errorMessagestring | nullMesaj de eroare dacă operațiunea a eșuat
operations[].createdAtstringMarcaj temporal ISO 8601 creare
operations[].completedAtstringMarcaj temporal ISO 8601 finalizare
totalintTotal operațiuni care corespund
limitintLimita aplicată
offsetintOffset-ul aplicat

GET /api/fiscal/daily-summary​

Obține rezumatul zilei fiscale curente. Returnează aceleași date ca un Raport X, dar fără a trimite nimic la MEV. Doar citire, nu necesită blocare fiscală.

Necesită: Terminalul trebuie să fie fiscalizat.

Răspuns: Identic cu obiectul Report Data (vezi secțiunea Raport Z).


6. Printare​

POST /api/print​

Printează text non-fiscal pe imprimanta termică POS. Suportă layout-uri multi-coloană.

Corpul cererii:

CâmpTipObligatoriuImplicitDescriere
linesarrayDa—Lista de array-uri de linii
feedLinesintNu3Număr de linii goale după conținut
cutbooleanNutrueTaie hârtia după printare

Formatul liniei — fiecare linie este un array de 1-3 șiruri:

ColoaneLayout
["text"]Lățime completă, aliniat la stânga
["stânga", "dreapta"]Aliniat stânga + dreapta
["stânga", "centru", "dreapta"]Layout pe trei coloane
[""]Linie goală (spațiu)
info

Aceasta este o operațiune non-fiscală — fără interacțiune MEV, fără bon fiscal.

Câmpuri răspuns:

CâmpTipDescriere
linesCountintNumăr de linii printate
printedAtstringMarcaj temporal ISO 8601

Exemplu — Raport de inventar (3 coloane):

POST /api/print
{
"lines": [
["RAPORT INVENTAR"],
["Data:", "16.02.2026"],
[""],
["Cod", "Denumire", "Cantitate"],
["────────────────────────────────"],
["001", "Cafea espresso", "150 buc"],
["002", "Tort Napoleon", "12.5 kg"],
["003", "Apa minerala 0.5L", "340 buc"],
[""],
["Total pozitii:", "4"],
["────────────────────────────────"],
["Responsabil:", "", "Ion Popescu"]
],
"feedLines": 3,
"cut": true
}

Eroare: 503 PRINTER_UNAVAILABLE dacă imprimanta este deconectată sau indisponibilă.


Tabele de referință​

Coduri de eroare​

CodStatus HTTPDescriere
MISSING_API_KEY401Header-ul X-API-Key nu a fost furnizat
INVALID_API_KEY401Cheia API furnizată nu este validă
VALIDATION_ERROR400Validarea corpului cererii a eșuat (vezi details[])
INVALID_JSON400Corpul cererii nu este JSON valid
TERMINAL_NOT_FISCAL409Terminalul nu este fiscalizat (fără certificat MEV)
MEV_CREDENTIALS_MISSING409Terminalul este fiscalizat dar credențialele MEV lipsesc
FISCAL_DAY_EXPIRED409Au trecut 24h de la primul bon al zilei fiscale — Raport Z necesar înainte de a continua
INSUFFICIENT_CASH_BALANCE409Sold numerar insuficient pentru retragerea solicitată
MEV_ERROR502Comunicarea cu MEV (SFS) a eșuat (timeout, eroare SOAP, certificat expirat)
BUSY429O altă operațiune fiscală este în curs (timeout 30s depășit)
SALE_NOT_FOUND404Vânzarea cu ID-ul specificat nu a fost găsită
PRINTER_UNAVAILABLE503Imprimanta nu este disponibilă sau este deconectată

Coduri TVA​

CodDescriere
ACota TVA A (conform configurării terminalului)
BCota TVA B (de obicei 20%)
CCota TVA C
DCota TVA D
ECota TVA E
_Scutit (fără TVA)

Tipuri de plată (ACPS WSDL)​

TipDescriere
"1"NUMERAR
"2"CARD
"3.1"VAUCHER
"3.2"CEC / Certificat valoric
"3.3"TICHET — plata cu document de valoare prestabilită (MDL)
"5"TME — tichet de masă pe suport electronic
"6"ABONAMENT
"7"ALT IP (alt instrument de plată)
"8.1"Credit
"8.2"Leasing
"8.3"Avans
"8.4"Arvună
"8.5"Gaj
"8.8"Compensare
"8.9"Alt mod

Tipuri de operațiuni fiscale​

TipDescriere
receiptBon fiscal (vânzare)
cash_inDepunere numerar
cash_outRetragere numerar
refundRambursare/retur
x_reportRaport X
z_reportRaport Z

Stări ale operațiunilor fiscale​

StareDescriere
pendingCreată, încă nu a fost trimisă la MEV
sentTrimisă la MEV, în așteptarea răspunsului
successProcesată cu succes de MEV
failedMEV a returnat o eroare
offlineStocată local (MEV inaccesibil)

Obiectul Defalcare TVA​

{
"B": {
"code": "B",
"percent": 20.0,
"vatAmount": 7.50,
"taxableBase": 37.50,
"gross": 45.00
}
}
CâmpTipDescriere
codestringCodul cotei TVA
percentnumberProcentul TVA
vatAmountnumberSuma TVA
taxableBasenumberSuma netă (fără TVA)
grossnumberSuma brută (cu TVA)

Note​

  • Toate sumele monetare sunt în MDL (Lei moldovenești) ca number cu precizie de 2 zecimale.
  • Toate marcajele temporale sunt în format ISO 8601 UTC.
  • Serverul utilizează un mecanism de blocare a operațiunilor fiscale — doar o singură operațiune fiscală (vânzare, depunere/retragere, raport Z/X) poate rula simultan. Cererile concurente vor aștepta până la 30 de secunde înainte de a returna 429 BUSY.
  • Modul offline: Când MEV (serverul autorității fiscale) este inaccesibil, operațiunile fiscale sunt stocate local și sincronizate ulterior. Răspunsul va avea isOffline: true și mevId: null.
  • Printarea bonurilor este de tip fire-and-forget — răspunsul API nu așteaptă finalizarea printării.

Colecții Postman​

Două colecții, pentru cele două API-uri distincte. Se importă cu Import → File.

ColecțieCe conțineDescarcă
API terminalReferința API-ului casei, în 28 de cereri: vânzări, numerar, rapoarte X/Z și periodice, tipărire, catalog, anulări și rambursări pe card, loturi de livrare. Fiecare cerere are câmpurile cererii și ale răspunsului, erorile cu statusul HTTP și exemple. Același API pe Android și pe PC-ECC (Windows); unde diferă, descrierea cererii o spune.posfix-terminal-api.postman_collection.json
API public de integrareCele 24 de cereri prin care sistemul tău extern (magazin online, ERP) citește și scrie datele comerciantului: catalog, stoc, prețuri, clienți, comenzi, rapoarte Z, webhook-uri.posfix-integration-api.postman_collection.json

API terminal​

Completează variabilele colecției:

  • baseUrl → http://<ip-terminal>:4567 în rețeaua locală, sau https://api.posfix.md/api/relay/<publicId> prin relay — adresa o vezi pe casă, în fereastra modului Provider
  • apiKey → cheia de pe terminal (Setări → Developer → Arată cheia API)

Apasă pe numele colecției în Postman ca să vezi descrierea ei: harta completă a erorilor, regulile de reluare cu Idempotency-Key și tabelele de referință.

Raportul Z închide ziua

POST /api/reports/z nu se poate anula și resetează contoarele zilei. Nu-l rula ca test pe un terminal în producție.

Tura se deschide singură

Nu e nevoie să deschizi tura: terminalul o deschide la prima vânzare sau operațiune cu numerar. Ziua se închide cu raportul Z.

API public de integrare​

Cheia se creează în Control Panel → Chei API de integrare și se afișează în clar o singură dată, la creare. Pune-o în variabila apiKey; se trimite pe fiecare cerere ca X-Posfix-Api-Key.

Fiecare cheie primește doar permisiunile (scopes) alese la creare — descrierea fiecărei cereri spune de care are nevoie. Fără scope-ul cerut, răspunsul e 403.

Modulul de abonament

API-ul cere modulul «API Integrare» activ pe comerciant. Fără el răspunde 403 chiar și cu o cheie validă și cu scope-ul corect.

Comerciantul nu se trimite ca parametru: organizația vine din cheie, deci nu se pot citi datele altcuiva. Începe cu GET /api/public/v1/ping — confirmă cheia, comerciantul și scope-urile.