API dokumentacija
Greške
Svaki neuspeh ima HTTP status, kod i jasno pravilo šta sme da se ponovi. Ovde je katalog kodova koje integrator sreće, šifre odbijanja V-PFR-a i preporuke za robusnu obradu.
Ažurirano: 29. 8. 2026. · Verzija ugovora 1.0.0
Oblici odgovora
{ "code": "..." }sa opcionimmessagei dodatnim poljima (invalidLabels,module,operationId): pravilo BokaPOS-a, licenca ili okruženje.- RFC 9457 problem sa
errorspo polju (application/problem+json): validacija oblika zahteva, uvek 422. - Fiskalni dokument sa
fiscalized: false(503): V-PFR nedostupan ili nepoznat ishod;status,failureCodeiretryablekažu šta dalje. - Tok (refundacija, predračun, avans) sa svojim
status/statei ugrađenim dokumentima: greška se čita iz stanja toka.
{
"type": "https://tools.ietf.org/html/rfc9110#section-15.5.21",
"title": "One or more validation errors occurred.",
"status": 422,
"errors": {
"totals": [
"The item and payment totals must match after the mandated two-decimal currency rounding."
]
}
}{
"code": "MODULE_NOT_LICENSED",
"module": "advance",
"message": "This module is not included in the organization's licence. Contact BokaPOS Administration to enable it."
}{
"code": "TAX_LABEL_NOT_CURRENT",
"invalidLabels": ["Ђ"],
"message": "Every tax label must be present in the freshly fetched current PFR configuration."
}{
"id": "9f8e7d6c-5b4a-4321-8765-0fedcba98761",
"taxpayerId": "3f9c2a8e-6b1d-4e5a-9c47-1d2b8e6f0a11",
"businessPremiseId": "b7d4e2c1-9a3f-4c8e-8f21-6e5a0c9d3b22",
"idempotencyKey": "order-4127-sale-1",
"clientReference": "ORDER-4127",
"invoiceType": "NORMAL",
"transactionType": "SALE",
"cashierId": "web-shop",
"buyerId": null,
"buyerDetails": null,
"status": "NOT_FISCALIZED",
"fiscalized": false,
"failureCode": "PFR_SUBMISSION_FAULT",
"retryable": true,
"pfr": null,
"receipt": null,
"createdAt": "2026-09-01T08:15:31.902Z",
"updatedAt": "2026-09-01T08:15:32.611Z"
}Katalog kodova
Kolona Ponavljanje: *isti ključ* znači da isti zahtev sa istim Idempotency-Key ima smisla; *ispravi zahtev* znači nov sadržaj i nov ključ; *kasnije* znači da se stanje menja van vašeg sistema (licenca, podešavanja); *nikad* znači da ponavljanje ne može da pomogne.
| HTTP | Kod | Značenje | Šta uraditi | Ponavljanje |
|---|---|---|---|---|
| 401 | 401 | Token nedostaje, istekao je (važi 300 sekundi) ili nije izdat za ovaj API. | Zatražite nov token client credentials tokom i ponovite poziv. | isti ključ |
| 403 | CREDENTIAL_ENVIRONMENT_MISMATCH | Sandbox kredencijal pokušava da koristi produkcioni bezbednosni element ili obrnuto. Retko: obveznici, prodajna mesta i dokumenti drugog okruženja su za vaš ključ nevidljivi (404), pa se ovo vidi samo ako element i prodajno mesto ne pripadaju istom okruženju. | Proverite koji kredencijal je u konfiguraciji; okruženje određuje kredencijal, ne adresa. | ispravi zahtev |
| 403 | CREDENTIAL_ENVIRONMENT_REQUIRED | Kredencijal ne nosi okruženje (boka_env), pa ne može da registruje obveznika. Kredencijali koje izdaje BokaPOS uvek ga nose. | Koristite kredencijal koji je izdala BokaPOS administracija; ako ga imate i dalje vidite ovo, javite se podršci. | nikad |
| 403 | LICENSE_REQUIRED | Organizacija nema licencu, a poziv cilja produkcioni element. | Sandbox nastavlja da radi. Za produkciju kontaktirajte BokaPOS administraciju. | kasnije |
| 403 | LICENSE_NOT_STARTED | Licenca postoji, ali počinje kasnije. | Pročitajte GET /v1/license za datum početka. | kasnije |
| 403 | LICENSE_EXPIRED | Licenca je istekla. | Kontaktirajte BokaPOS administraciju. Refundacije i storna avansa i dalje rade. | kasnije |
| 403 | LICENSE_SUSPENDED | BokaPOS je suspendovao licencu. | Kontaktirajte BokaPOS administraciju. | kasnije |
| 403 | MODULE_NOT_LICENSED | Osnovna licenca važi, ali modul iz polja module (advance ili email) nije uključen. | Uključite modul preko BokaPOS administracije ili ne koristite tu funkciju u produkciji. | kasnije |
| 404 | TAXPAYER_NOT_FOUND | Obveznik ne postoji u vašoj organizaciji i okruženju ili nije aktivan. | Pročitajte GET /v1/taxpayers istim ključem i koristite tačan id; obveznik drugog okruženja je nevidljiv. | ispravi zahtev |
| 404 | BUSINESS_PREMISE_NOT_FOUND | Prodajno mesto ne postoji u vašem okruženju ili ne pripada navedenom obvezniku. | Pročitajte GET /v1/taxpayers/{taxpayerId}/business-premises. | ispravi zahtev |
| 404 | FISCAL_DOCUMENT_NOT_FOUND | Dokument ne postoji u vašoj organizaciji i okruženju. | Proverite identifikator; dokumenti druge organizacije i drugog okruženja su nevidljivi. | ispravi zahtev |
| 409 | IDEMPOTENCY_KEY_REUSED_WITH_DIFFERENT_REQUEST | Isti Idempotency-Key je već upotrebljen sa drugačijim sadržajem zahteva. Odgovor nosi operationId originala. | Pročitajte original preko GET /v1/operations/{operationId}. Nova prodaja mora dobiti nov ključ. | nikad |
| 409 | IDEMPOTENCY_KEY_REUSED_IN_OTHER_ENVIRONMENT | Isti Idempotency-Key je vaša organizacija već upotrebila kredencijalom drugog okruženja (na primer u sandbox testiranju). Ključevi su jedinstveni po organizaciji u oba okruženja. | Pošaljite zahtev ponovo sa novim ključem. Ništa nije izdato. | nikad |
| 422 | LPFR_REQUIRED_FOR_IN_PERSON_SALES | Prodajno mesto nije za prodaju na daljinu. BokaPOS fiskalizuje samo prodaju na daljinu preko V-PFR-a. | Za prodaju licem u lice potreban je L-PFR (na primer BokaLPFR). | nikad |
| 422 | BUSINESS_PREMISE_INACTIVE | Prodajno mesto je suspendovano ili zatvoreno. | Aktivirajte ga u portalu ili koristite drugo. | kasnije |
| 422 | PAYMENT_TYPE_NOT_ALLOWED_ON_PREMISE | Prodajno mesto radi u ograničenom režimu plaćanja (OTHER, CASH, WIRE_TRANSFER, VOUCHER), a zahtev nosi drugi način. | Promenite način plaćanja ili režim prodajnog mesta u portalu. | ispravi zahtev |
| 422 | ACTIVE_SECURITY_ELEMENT_REQUIRED | Prodajno mesto nema aktivan bezbednosni element. | U sandboxu BokaPOS dodeljuje element; u produkciji vlasnik ga otprema u portalu, BokaPOS ga aktivira. | kasnije |
| 422 | TAX_LABEL_NOT_CURRENT | Bar jedna poreska oznaka nije u svežoj konfiguraciji V-PFR-a (polje invalidLabels). | Pročitajte GET /v1/tax-rates i koristite samo oznake koje vrati; sandbox i produkcija imaju različit skup. | ispravi zahtev |
| 422 | TAX_LABEL_NOT_ALLOWED_OUTSIDE_VAT | Obveznik je označen kao van sistema PDV-a, a stavka nosi PDV oznaku. | Koristite oznaku bez PDV-a ili ispravite PDV status obveznika u portalu. | ispravi zahtev |
| 422 | REFERENCE_DOCUMENT_NOT_FOUND | Referentni dokument (reference.fiscalDocumentId) ne postoji. | Proverite identifikator iz odgovora originalnog računa. | ispravi zahtev |
| 422 | REFERENCE_DOCUMENT_NOT_FISCALIZED | Referentni dokument nije fiskalizovan, pa ne može biti referenca. | Referenca sme da pokazuje samo na dokument sa statusom FISCALIZED. | ispravi zahtev |
| 422 | REFERENCE_DOCUMENT_SCOPE_MISMATCH | Referentni dokument pripada drugom obvezniku ili prodajnom mestu. | Referenca mora biti na istom obvezniku i prodajnom mestu. | ispravi zahtev |
| 422 | REFERENCE_DOCUMENT_TYPE_NOT_ALLOWED | Kombinacija vrste računa i transakcije ne sme da se poziva na tu vrstu izvornog dokumenta (zvanična matrica referenci). | Pogledajte tabelu referenci na stranici Konvencije. | ispravi zahtev |
| 422 | REFUND_QUANTITY_EXCEEDS_ORIGINAL | Vraćena količina je veća od količine na izvornoj liniji. | Smanjite količinu; delimična refundacija je dozvoljena. | ispravi zahtev |
| 422 | REFUND_CUMULATIVE_QUANTITY_EXCEEDED | Zbir svih dosadašnjih refundacija te linije premašio bi izvornu količinu. | Proverite ranije refundacije u dnevniku. | nikad |
| 422 | REFUND_ITEM_MUST_MATCH_ORIGINAL_LINE | Naziv, cena, oznake ili GTIN se ne poklapaju sa izvornom linijom originalLineIndex. | Prepišite stavku iz izvornog računa (GET /v1/fiscal-documents/{id}/representations/canonical-json). | ispravi zahtev |
| 422 | REFUND_ORIGINAL_LINE_NOT_FOUND | originalLineIndex ne postoji na izvornom računu. | Indeksi su od nule, po redosledu stavki originala. | ispravi zahtev |
| 422 | COPY_SOURCE_NOT_COPYABLE | Kopija, predračun i obuka se ne mogu kopirati. | Kopirajte samo račun za promet ili avans. | nikad |
| 422 | COPY_SOURCE_NOT_FISCALIZED | Izvor kopije nije fiskalizovan. | Kopija postoji samo za dokument sa statusom FISCALIZED. | nikad |
| 409 | ADVANCE_CASE_NOT_OPEN | Slučaj je zatvoren, neuspešan ili čeka razrešenje ishoda. | Pročitajte GET /v1/advance-cases/{id} i polje state. | nikad |
| 422 | ADVANCE_CANCELLATION_TARGET_NOT_LATEST | Može se stornirati samo poslednja fiskalizovana avansna prodaja. | Pošaljite id poslednje stavke iz advanceSales koja nije u cancelledAdvanceSaleIds. | ispravi zahtev |
| 422 | ADVANCE_CLOSE_TOTAL_MISMATCH | remainingPayments nije jednako konačnom iznosu umanjenom za ukupan avans. | Izračunajte razliku iz advanceSales i pošaljite je; kad je nula, jedan element sa iznosom 0. | ispravi zahtev |
| 422 | ADVANCE_CASE_HAS_NO_FISCALIZED_SALE | Ne može se zatvoriti slučaj bez ijedne fiskalizovane avansne prodaje (osim kad postoji externalAdvance). | Prvo fiskalizujte uplatu. | nikad |
| 409 | ADVANCE_PAYMENT_SUPERSEDED | Ponovljeni zahtev cilja uplatu koja više nije poslednja u lancu. | Pročitajte slučaj i nastavite od aktuelnog stanja. | nikad |
| 409 | ADVANCE_CASE_CLOSE_ALREADY_RESERVED | Zatvaranje je već rezervisano drugim ključem. | Ponovite zatvaranje istim Idempotency-Key ključem kojim je započeto. | isti ključ |
| 503 | ADVANCE_REFUND_NOT_FISCALIZED | Poreska uprava je odbila avansnu refundaciju pri zatvaranju: slučaj je FAILED sa šifrom odbijanja, a rezervisani konačni račun nikad nije poslat i ima ovaj failureCode, NOT_FISCALIZED, retryable: false. | Pročitajte failureCode slučaja i advanceRefund.pfrRejection, ispravite podatke i otvorite nov slučaj. Ponavljanje istog zatvaranja ne šalje ništa. | nikad |
| 409 | PROFORMA_TRAINING_WORKFLOW_RESERVATION_CONFLICT | Izvorni dokument već ima nerazrešenu ili završenu refundaciju. | Pročitajte tok iz workflowId u odgovoru. | nikad |
| 409 | PROFORMA_TRAINING_SOURCE_ALREADY_REFUNDED | Predračun ili obuka je već refundirana u celosti. | Nema dalje akcije. | nikad |
| 409 | CATALOGUE_SKU_ALREADY_EXISTS | Šifra (sku) već postoji kod tog obveznika. | Izmenite postojeći proizvod (PUT) ili upotrebite drugu šifru. | ispravi zahtev |
| 422 | CATALOGUE_IMPORT_TOO_MANY_ROWS | CSV ima više od 1.000 redova. | Podelite uvoz na više datoteka. | ispravi zahtev |
| 422 | CATALOGUE_IMPORT_HEADERS_INVALID | Zaglavlje CSV-a nema očekivane kolone. | Preuzmite GET /v1/products/export kao šablon. | ispravi zahtev |
| 422 | JOURNAL_EXPORT_RESULT_LIMIT_EXCEEDED | Više od 10.000 redova odgovara filterima izvoza. | Suzite period (createdFrom, createdTo) i izvezite u delovima. | ispravi zahtev |
| 422 | RECEIPT_DELIVERY_DISABLED | Obveznik nije uključio dostavu e-poštom u podešavanjima portala. | Uključite dostavu u portalu (Dokumenti, E-mail računi) ili šaljite račun iz svog sistema. | kasnije |
| 422 | RECEIPT_DELIVERY_DOCUMENT_NOT_FISCALIZED | Dokument nije fiskalizovan, pa nema šta da se dostavi. | Šaljite samo dokumente sa fiscalized: true. | nikad |
| 422 | RECEIPT_DELIVERY_DOCUMENT_NOT_ISSUED_TO_BUYER | Račun Avans-Refundacija se ne izdaje kupcu, pa ga BokaPOS ne šalje na adresu kupca. Isto važi i za njegovu kopiju. | Pošaljite završni račun avansnog slučaja (Promet-Prodaja). Avans-Refundacija ostaje dostupna za štampu i u elektronskom dnevniku. | nikad |
| 503 | RECEIPT_DELIVERY_UNAVAILABLE | Platformski e-mail transport nije konfigurisan ili nije dostupan. Ništa nije stavljeno u red. | Ponovite kasnije istim ključem ili pošaljite račun iz svog sistema; fiskalizacija je već završena. | isti ključ |
| 503 | PFR_SANDBOX_NOT_CONFIGURED | Fiskalni adapter nije konfigurisan na ovoj instalaciji. Odgovor je dokument sa fiscalized: false. | Ne dešava se na api.bokapos.rs; javlja se samo na lokalnim instalacijama bez adaptera. | isti ključ |
| 503 | PFR_ENVIRONMENT_DISABLED | Fiskalni promet je isključen za okruženje ovog elementa (produkcija do njenog uključenja). | Sandbox radi; produkcija se uključuje po odluci BokaPOS-a. | kasnije |
| 503 | CURRENT_TAX_CONFIGURATION_UNAVAILABLE | V-PFR nije vratio svežu poresku konfiguraciju, pa zahtev nije ni rezervisan. | Ponovite kasnije istim ključem. | isti ključ |
| 503 | PFR_SUBMISSION_FAULT | V-PFR nije bio dostupan pre slanja; dokument je NOT_FISCALIZED, retryable: true. | Ponovite isti zahtev istim Idempotency-Key ključem posle kratke pauze. | isti ključ |
| 503 | OUTCOME_UNKNOWN | Zahtev je možda stigao do V-PFR-a, ali odgovor nije stigao nazad. Status OUTCOME_UNKNOWN, retryable: false. Nije račun, ali može da postane. | Ne šaljite nov zahtev za istu prodaju. Proveravajte GET /v1/operations/{id}; BokaPOS sam razrešava ishod čitanjem, nikad ponovnim slanjem. | nikad |
| 422 | REJECTED | V-PFR je odbio zahtev. Dokument ima status REJECTED, a GET /v1/fiscal-documents/{id} vraća pfrRejection sa putanjom polja i šifrom (2310 nepostojeća oznaka; 2800 do 2808 obavezno polje, dužina, opseg, vrednost, format, veličina liste). | Ispravite zahtev i pošaljite ga sa novim ključem. | ispravi zahtev |
Šifre odbijanja V-PFR-a
Kada V-PFR odbije zahtev, dokument dobija status REJECTED, failureCode: PFR_VALIDATION_REJECTED, a pojedinačno čitanje (GET /v1/fiscal-documents/{id}) nosi pfrRejection.items sa putanjom polja iz vašeg zahteva i šifrom:
| Šifra | Značenje | Tipičan uzrok |
|---|---|---|
2310 | nepostojeća poreska oznaka | oznaka nije u aktuelnoj grupi (BokaPOS to obično uhvati ranije kao TAX_LABEL_NOT_CURRENT) |
2800 | obavezno polje nedostaje | prazan naziv, kasir, plaćanje |
2801 | dužina | predugačak naziv, kasir ili referenca |
2802 | opseg | količina ili iznos van dozvoljenog opsega |
2803 | vrednost | nedozvoljena vrednost enumeracije |
2804 | format | više od dve decimale u ceni ili iznosu, pogrešan format vremena |
2805 do 2808 | veličina liste i srodne provere | prazna lista stavki ili plaćanja |
Robusna integracija
- Izvedite
Idempotency-Keyiz porudžbine i sačuvajte ga pre slanja, da posle prekida možete da ponovite isti zahtev. - Na
503saretryable: trueponovite istim ključem uz eksponencijalno čekanje (na primer 2, 5, 15 sekundi), najviše nekoliko puta; zatim označite porudžbinu za operatera. - Na
OUTCOME_UNKNOWNnikad ne šaljite nov zahtev: zapamtiteidi proveravajteGET /v1/operations/{id}sve dok status ne postaneFISCALIZEDili operater ne odluči. - Na
422iREJECTEDbeležiteerrorsodnosnopfrRejectionuz porudžbinu, ispravite izvor podataka i pošaljite sa novim ključem. - Na
401uzmite nov token i ponovite isti zahtev. Na403pročitajteGET /v1/license. - Osvežite poreske oznake kad dobijete
TAX_LABEL_NOT_CURRENT, ne pre svakog računa. - Postavite HTTP timeout na fiskalnim pozivima velikodušno (na primer 60 sekundi): V-PFR odgovara obično za oko dve sekunde, ali prekid veze sa vaše strane pretvara siguran ishod u nepoznat.
- Logujte
id,status,failureCodeipfr.invoiceNumber; nikad ne logujte token ni tajnu.