eFiskalizacija.cloud

API Referenca

Kompletna referenca svih API endpointa eFiskalizacija.cloud platforme. Za detalje o autentifikaciji pogledajte Autentifikacija (HMAC).

Bazni URL

https://efiskalizacija.cloud
Svi zahtevi moraju sadržati HMAC autentifikacione hedere. Pogledajte vodič za autentifikaciju za detalje.

Endpointi

Endpoint Metod Opis
/api/multitenant.php/fiskalizacija POST Fiskalizacija računa
/api/multitenant.php/status GET Status tenanta
/api/multitenant.php/invoice GET Lista računa
/api/multitenant.php/pdf GET PDF računa
/api/multitenant.php/send-email POST Slanje računa na email
/api/multitenant.php/test POST Test fiskalizacija (samo sandbox)

POST/fiskalizacija

Glavni endpoint za fiskalizaciju računa. Šalje račun na VSDC PFR i vraća verifikacioni (PFR) broj i QR kod.

Request body (JSON)

Polje Tip Obavezno Podrazumevano Opis
stavke array Da - Niz stavki računa
tip_racuna string Ne prodaja Tip fiskalnog računa
tip_transakcije string Ne sale Tip transakcije: sale / prodaja / P ili refund / povracaj / R
nacin_placanja string|array Ne kartica Način plaćanja (string za jedan tip, niz objekata za split payment — vidi sekciju ispod)
kasir string Ne - Ime kasira
broj_racuna string Ne Automatski Interni broj računa
kupac object Ne - Podaci o kupcu
referentni_dokument string Uslovno - PFR broj referentnog dokumenta. Obavezan za refundaciju i avans-refundaciju. Nije obavezan za kopiju.
reklamni_tekst string Ne - Reklamni tekst (za avansne račune)

Stavka - polja

Polje Tip Obavezno Opis
naziv string Da Naziv artikla
kolicina number Da Količina (mora biti veća od 0)
jedinicna_cena number Da Jedinična cena BEZ PDV-a (osnovica; PDV se obračunava i dodaje na vrh prema pdv_stopa). Ne može biti negativna.
pdv_stopa number Da PDV stopa: sandbox 19/10/0, produkcija 20/10/0
pdv_kategorija string Ne Za 0% PDV: oslobodjen ili nije_u_pdv. Default: oslobodjen
sifra string Ne Šifra artikla
jedinica_mere string Ne Jedinica mere (podrazumevano: "kom")
popust number Ne Fiksni iznos popusta u RSD (pre PDV-a). Ne može biti veći od kolicina × jedinicna_cena. Podrazumevano: 0
rabat_procenat number Ne Procentualni popust (0-100%). Primenjuje se na osnovicu pre PDV-a. Default: 0
Popusti: Polja popust i rabat_procenat su međusobno isključiva, pa ne mogu da se koriste oba na istoj stavci. Popust se uvek primenjuje na osnovicu pre obračuna PDV-a.
Formula za obračun iznosa: osnovica = kolicina × jedinicna_cena − rabat  |  pdv_iznos = osnovica × (pdv_stopa / 100)  |  ukupan_iznos = osnovica + pdv_iznos
Primer: artikal po ceni 1100,00 RSD (bez PDV-a), količina 1, PDV 19% → osnovica 1100,00 + PDV 209,00 = ukupno 1309,00 RSD

Kupac - polja

Polje Tip Opis
ime string Ime kupca ili naziv firme
pib string PIB pravnog lica (9 cifara). Sistem šalje VSDC-u sa prefiksom 10:
jmbg string JMBG fizičkog lica (13 cifara) ili broj pasoša/stranog dokumenta. Sistem šalje VSDC-u sa prefiksom 11:
jbkjs string Broj iz Registra korisnika javnih sredstava. Sistem šalje VSDC-u sa prefiksom 12:
identifikator string Generički identifikator sa automatskom detekcijom tipa: 9 cifara = PIB (prefiks 10:), 13 cifara = JMBG (prefiks 11:), alfanumerički = broj pasoša (prefiks 11:)
tip string Informativan/opcioni atribut: pravno_lice ili fizicko_lice. Sistem ne čita ovo polje pri detekciji tipa — stvarni tip kupca određuju polja pib, jmbg ili identifikator.
adresa string Adresa kupca
mesto string Mesto kupca
email string Email adresa kupca
telefon string Telefon kupca
Avansni računi: Za avansne račune kupac je obavezan i mora sadržati barem jedno od polja pib, jmbg ili identifikator.

Način plaćanja - vrednosti

Vrednost Kod VSDC Opis
gotovina G 1 Gotovina
kartica K 2 Platna kartica
virman V 4 Prenos na račun (virman)
vaucer U 5 Vaučer
instant I 6 Instant plaćanje (IPS QR)
drugo O 0 Drugo bezgotovinsko plaćanje
Napomena: Ček (VSDC kod 3) nije podržan jer je ESIR namenjen isključivo za web shopove i daljinsku prodaju.

Tip računa - vrednosti

Vrednost Kod Opis
prodaja P Promet (fiskalni račun)
avans A Avansni račun
proforma F Predračun
kopija K Kopija računa
obuka T Račun za obuku (trening)

Primer zahteva

POST /api/multitenant.php/fiskalizacija
Content-Type: application/json
X-API-Key: vaš_api_ključ
X-Timestamp: 1706000000
X-Signature: hmac_potpis

{
  "stavke": [
    {
      "naziv": "Laptop ASUS VivoBook",
      "kolicina": 1,
      "jedinicna_cena": 89990.00,
      "pdv_stopa": 20,
      "sifra": "LAP-001"
    },
    {
      "naziv": "Miš bežični",
      "kolicina": 2,
      "jedinicna_cena": 1990.00,
      "pdv_stopa": 20,
      "sifra": "MIS-005",
      "rabat_procenat": 15
    }
  ],
  "nacin_placanja": "kartica",
  "kasir": "Marko Petrović",
  "kupac": {
    "ime": "Tech Solutions d.o.o.",
    "pib": "107026577",
    "adresa": "Knez Mihailova 10",
    "mesto": "Beograd"
  }
}

// Obračun: Laptop — osnovica 89990,00 + PDV (20%) 17998,00 = 107988,00
//          Miš (2×1990, rabat 15%) — osnovica 3383,00 + PDV (20%) 676,60 = 4059,60
//          Ukupno: 112047,60 RSD

Uspešan odgovor (200)

{
  "success": true,
  "data": {
    "tenant": "Tech Solutions d.o.o.",
    "rezultat": {
      "success": true,
      "racun_id": 156,
      "broj_racuna": "1/156",
      "ukupan_iznos": 112047.60,
      "pfr_broj": "F7W3XLMA-Dt1Ov2o0-12345",
      "pfr_datum_vreme": "2026-01-23T10:30:00+01:00",
      "qr_kod": "https://suf.purs.gov.rs/v/?vl=F7W3XLMADt1Ov2o012345...",
      "esir_oznaka": "EFISK-1.0",
      "status": "success",
      "message": "Fiskalizacija uspešno izvršena",
      "duration_ms": 342,
      "cert_warning": null
    }
  },
  "timestamp": "2026-01-23T10:30:00+01:00"
}

Split payment (podeljeno plaćanje)

Kada kupac plaća kombinacijom više načina plaćanja, polje nacin_placanja se šalje kao niz objekata:

{
  "stavke": [ ... ],
  "nacin_placanja": [
    { "tip": "gotovina", "iznos": 10000.00 },
    { "tip": "kartica",  "iznos": 102047.60 }
  ]
}

Pravila validacije za split payment:

Greška - nedostaje polje (400)

{
  "success": false,
  "error": "Stavke su obavezne",
  "timestamp": "2026-01-23T10:30:00+01:00"
}

Greška - neautorizovan (401)

{
  "success": false,
  "error": "Nevažeći API ključ ili potpis",
  "timestamp": "2026-01-23T10:30:00+01:00"
}

Greška - pristup odbijen (403)

{
  "success": false,
  "error": "Tenant nije aktivan ili nema podešen sertifikat",
  "timestamp": "2026-01-23T10:30:00+01:00"
}

Greška - previše zahteva (429)

{
  "success": false,
  "error": "Rate limit dostignut. Pokušajte ponovo za minut.",
  "timestamp": "2026-01-23T10:30:00+01:00"
}

GET/status

Vraća status tenanta uključujući informacije o nalogu i statistiku računa.

Primer zahteva

GET /api/multitenant.php/status
X-API-Key: vaš_api_ključ
X-Timestamp: 1706000000
X-Signature: hmac_potpis

Uspešan odgovor (200)

{
  "success": true,
  "data": {
    "tenant": {
      "naziv": "Moj Web Shop",
      "pib": "107026577",
      "environment": "production",
      "current_month_invoices": 287,
      "max_invoices_per_month": 1000
    },
    "statistics": {
      "total_invoices": 1523,
      "this_month": 287,
      "success_rate": 99.5
    },
    "system": {
      "version": "1.3.0",
      "api_version": "v1",
      "timestamp": "2026-01-23T10:30:00+01:00"
    }
  },
  "timestamp": "2026-01-23T10:30:00+01:00"
}

GET/invoice

Vraća listu fiskalizovanih računa sa paginacijom.

Query parametri

Parametar Tip Podrazumevano Opis
limit integer 50 Broj rezultata po stranici (max 100)
offset integer 0 Pomak za paginaciju

Primer zahteva

GET /api/multitenant.php/invoice?limit=10&offset=0
X-API-Key: vaš_api_ključ
X-Timestamp: 1706000000
X-Signature: hmac_potpis

Uspešan odgovor (200)

{
  "success": true,
  "data": {
    "tenant": "Moj Web Shop",
    "invoices": [
      {
        "id": 156,
        "broj_racuna": "1/156",
        "pfr_broj": "F7W3XLMA-Dt1Ov2o0-12345",
        "datum_izdavanja": "2026-01-23T10:30:00+01:00",
        "kupac_ime": "Tech Solutions d.o.o.",
        "ukupan_iznos": "112047.60",
        "nacin_placanja": "K",
        "status": "success",
        "created_at": "2026-01-23T10:30:00+01:00"
      },
      {
        "id": 155,
        "broj_racuna": "1/155",
        "pfr_broj": "F7W3XLMA-Dt1Ov2o0-12344",
        "datum_izdavanja": "2026-01-23T09:15:00+01:00",
        "kupac_ime": null,
        "ukupan_iznos": "2500.00",
        "nacin_placanja": "I",
        "status": "success",
        "created_at": "2026-01-23T09:15:00+01:00"
      }
    ],
    "count": 2,
    "limit": 10,
    "offset": 0
  },
  "timestamp": "2026-01-23T10:35:00+01:00"
}
Polje nacin_placanja u listi računa se vraća kao jednoslovna VSDC oznaka: G (gotovina), K (kartica), V (virman), U (vaučer), I (instant), O (drugo).
Napomena o tipu: Polje ukupan_iznos u listi računa se vraća kao string (vrednost direktno iz baze), za razliku od endpointa za fiskalizaciju gde je broj (float). Koristite odgovarajuću konverziju pri obradi.

GET/pdf

Vraća PDF verziju fiskalnog računa kao direktan binarni sadržaj (NE JSON).

Query parametri

Parametar Tip Obavezno Opis
pfr string Da PFR broj računa
download integer Ne Kontroliše Content-Disposition header (vidi tabelu)

Parametar download

Vrednost Content-Disposition Ponašanje pregledača
1 (ili truthy) attachment Pregledač pokreće DOWNLOAD dialog
0 (ili izostavljen) inline Pregledač PRIKAZUJE PDF direktno

Primer zahteva

GET /api/multitenant.php/pdf?pfr=F7W3XLMA-Dt1Ov2o0-12345&download=1
X-API-Key: vaš_api_ključ
X-Timestamp: 1706000000
X-Signature: hmac_potpis

Uspešan odgovor (200)

API vraća direktan PDF binarni sadržaj:

Content-Type: application/pdf
Content-Disposition: attachment; filename="racun-F7W3XLMA-Dt1Ov2o0-12345.pdf"
Cache-Control: no-store, no-cache, must-revalidate, max-age=0

%PDF-1.4
...binarni PDF sadržaj...
Napomena: Za greške (404, 500) API vraća JSON sa success: false. Pogledajte PDF računi za primere u različitim jezicima.

POST/send-email

Slanje fiskalnog računa na email adresu kupca. Email sadrži PDF računa kao prilog.

Request body

PoljeTipObaveznoOpis
pfr string Da PFR verifikacioni broj računa
email string Da Email adresa primaoca

Primer zahteva

POST /api/multitenant.php/send-email
Content-Type: application/json
X-API-Key: vaš_api_ključ
X-Timestamp: 1706000000
X-Signature: hmac_potpis

{
  "pfr": "F7W3XLMA-Dt1Ov2o0-12345",
  "email": "kupac@example.com"
}

Uspešan odgovor (200)

{
  "success": true,
  "data": {
    "message": "Email uspešno poslat",
    "email": "kupac@example.com",
    "pfr": "F7W3XLMA-Dt1Ov2o0-12345"
  },
  "timestamp": "2026-01-25T23:30:00+01:00"
}

Greške

KodOpis
400Nedostaje pfr ili email parametar, ili email nije validan
404Račun sa datim PFR brojem nije pronađen
400Račun nije fiskalizovan (samo fiskalizovani se mogu slati)
Napomena: Pogledajte PDF računi za više detalja o slanju emaila.

POST/test

Test endpoint za proveru integracije. Dostupan samo u sandbox okruženju. Šalje testni račun tipa obuka (training) na VSDC sandbox — označen je kao trening račun, ne kao realan promet.

Ovaj endpoint je dostupan samo u sandbox okruženju. Na produkciji vraća grešku 403.
Napomena: Endpoint ne prima request body — koristi predefinisane test podatke (tip T, gotovina, PDV 19%, cena 100,00 RSD). Obavezni HMAC hederi i dalje moraju biti prisutni.

Primer zahteva

POST /api/multitenant.php/test
Content-Type: application/json
X-API-Key: vaš_api_ključ
X-Timestamp: 1706000000
X-Signature: hmac_potpis

// Telo zahteva nije potrebno — endpoint koristi predefinisane test podatke:
// { tip_racuna: "T", kasir: "TEST-{tenant_code}", nacin_placanja: "G",
//   stavke: [{ naziv: "Test Artikal", kolicina: 1, jedinicna_cena: 100.00, pdv_stopa: 19 }] }

Uspešan odgovor (200)

{
  "success": true,
  "data": {
    "message": "Test uspešan za tenant: Moj Web Shop",
    "tenant_code": "mojwebshop-a1b2",
    "rezultat": {
      "success": true,
      "racun_id": 12,
      "broj_racuna": "TEST-1/12",
      "ukupan_iznos": 119.00,
      "pfr_broj": "F7W3XLMA-Dt1Ov2o0-00012",
      "pfr_datum_vreme": "2026-01-23T10:30:00+01:00",
      "qr_kod": "https://suf.purs.gov.rs/v/?vl=...",
      "esir_oznaka": "EFISK-1.0",
      "status": "success",
      "message": "Fiskalizacija uspešno izvršena",
      "duration_ms": 280,
      "cert_warning": null
    }
  },
  "timestamp": "2026-01-23T10:30:00+01:00"
}

Zaštita od duplih računa

eFiskalizacija automatski štiti od kreiranja duplih fiskalnih računa na VSDC-u. Ovo je posebno važno u situacijama kada dođe do mrežnog timeout-a ili greške u komunikaciji.

Kako funkcioniše

Svaki zahtev za fiskalizaciju dobija jedinstveni RequestId (UUID) koji se šalje VSDC-u zajedno sa podacima računa. Sistem automatski:

  1. Čuva RequestId za svaki pokušaj fiskalizacije
  2. Pri ponovnom pokušaju (retry) proverava da li je prethodni zahtev već uspeo
  3. Ako je VSDC već kreirao račun — koristi postojeći odgovor umesto ponovnog slanja
  4. Ako status prethodnog zahteva nije poznat — ponovo koristi isti RequestId

Scenariji zaštite

Situacija Šta se dešava
Timeout pri fiskalizaciji Sistem čuva RequestId. Pri retry-u proverava VSDC i ponovo koristi isti RequestId.
Korisnik klikne "Ponovi" u admin panelu Sistem detektuje prethodni pokušaj i sprečava duplikat.
VSDC već kreirao račun ali naš sistem ne zna VSDC inquiry proverava status pre ponovnog slanja.
Napomena: Zaštita od duplikata radi automatski — ne zahteva nikakve izmene na strani API klijenta. RequestId se generiše i upravlja interno na serveru.

Ograničenje broja zahteva (Rate Limiting)

API je ograničen na 60 zahteva po minutu po API ključu. Kada se limit prekorači, API vraća status 429 Too Many Requests.

{
  "success": false,
  "error": "Rate limit dostignut. Pokušajte ponovo za minut.",
  "timestamp": "2026-01-23T10:30:00+01:00"
}

Kodovi grešaka

HTTP kod Značenje Opis
400 Bad Request Neispravan format zahteva ili neuspela validacija
401 Unauthorized Nevažeći API ključ ili HMAC potpis
403 Forbidden Tenant neaktivan ili nema pristup resursu
404 Not Found Traženi resurs ne postoji
422 Unprocessable Entity Podaci su ispravnog formata ali semantički neispravni
429 Too Many Requests Prekoračen limit zahteva (60/min)
500 Internal Server Error Interna greška servera

Format greške

Sve greške vraćaju isti format odgovora:

{
  "success": false,
  "error": "Opis greške",
  "timestamp": "2026-01-23T10:30:00+01:00"
}
Za interaktivno testiranje API-ja koristite Swagger UI gde možete direktno slati zahteve i videti odgovore.