API dokumentacija
Račun za promet
Glavni poziv integracije: kupac je platio, vi šaljete stavke i plaćanja, BokaPOS izdaje Промет Продаја. Ovde su sva polja zahteva, popust, kupac, više načina plaćanja i kopija računa.
Kada se izdaje
Račun za promet se izdaje u trenutku kada je promet ostvaren: kod prodaje na daljinu to je kada je roba isporučena ili usluga izvršena, odnosno kada je plaćanje primljeno, u skladu sa vašim poslovnim modelom i propisima. Ako kupac plaća pre isporuke, a isporuka je kasnije, to je avans. Ako samo šaljete ponudu, to je predračun.
Zahtev
curl -X POST "https://api.bokapos.rs/v1/fiscal-documents" \
-H "Authorization: Bearer $BOKAPOS_TOKEN" \
-H "Idempotency-Key: order-4127-sale-1" \
-H "Content-Type: application/json" \
-d '{
"taxpayerId": "3f9c2a8e-6b1d-4e5a-9c47-1d2b8e6f0a11",
"businessPremiseId": "b7d4e2c1-9a3f-4c8e-8f21-6e5a0c9d3b22",
"clientReference": "ORDER-4127",
"invoiceType": "NORMAL",
"transactionType": "SALE",
"cashier": {
"id": "web-shop",
"displayName": "Web shop"
},
"items": [
{
"name": "Bluetooth slušalice",
"unitOfMeasure": "kom",
"quantity": 1,
"unitPrice": 8990,
"gtin": "8606012345678",
"taxLabels": [
"F"
]
}
],
"payments": [
{
"type": "CARD",
"amount": 8990
}
],
"metadata": {
"orderId": "4127",
"channel": "web"
}
}'Polja
| Polje | Obavezno | Pravilo |
|---|---|---|
taxpayerId, businessPremiseId | da | obveznik i aktivno prodajno mesto za prodaju na daljinu |
clientReference | da | vaš broj porudžbine; ne mora biti jedinstven, ali je pretraživ |
invoiceType, transactionType | da | ovde uvek NORMAL i SALE |
cashier.id | da | kasir ili sistem; displayName je opcion |
items[] | da, bar jedna | vidite ispod |
payments[] | da, bar jedno | zbir jednak zbiru stavki; više načina plaćanja je dozvoljeno |
buyer | ne | obavezan kada propis traži identifikaciju kupca (B2B sa PIB-om i drugi slučajevi) |
commercialFooter | ne | vaš tekst ispod fiskalnog dela (do 2000 znakova): zahvalnica, reklamacije, kontakt |
metadata | ne | vaši parovi ključ-vrednost; čuvaju se uz operaciju, nikad ne idu V-PFR-u i nisu na računu |
reference | ne | samo za kopiju spoljnog dokumenta (source: EXTERNAL); promet prodaja nema referencu |
Stavka
| Polje | Obavezno | Pravilo |
|---|---|---|
name | da | naziv artikla ili usluge, do 2048 znakova; na računu se štampa kao naziv/jedinica |
unitOfMeasure | da | jedinica mere (kom, kg, h, m...), do 50 znakova; izuzetak su samo propisane avansne stavke |
quantity | da | do tri decimale, najmanje 0.001 |
unitPrice | da | konačna bruto jedinična cena posle popusta, dve decimale |
taxLabels | da | jedna ili više oznaka iz GET /v1/tax-rates; obično jedna |
gtin | ne | GTIN/EAN 8 do 14 cifara; štampa se na računu |
catalogProductId | ne | id proizvoda iz kataloga, ako ga vodite u BokaPOS-u; stavke mogu biti i potpuno slobodne |
unitPriceBeforeDiscount | ne | cena pre popusta, mora biti veća od unitPrice; prikazuje se izvan fiskalnog dela |
Odgovor
{
"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": "FISCALIZED",
"fiscalized": true,
"failureCode": null,
"retryable": false,
"pfr": {
"invoiceNumber": "JWX4K9PL-JWX4K9PL-1042",
"sdcTime": "2026-09-01T10:15:32.483+02:00",
"requestedBy": "JWX4K9PL",
"signedBy": "JWX4K9PL",
"transactionTypeCounter": 897,
"totalCounter": 1042,
"invoiceCounterExtension": "ПП",
"totalAmount": 8990,
"totalTax": 890.9009,
"verificationUrl": "https://sandbox.suf.purs.gov.rs/v/?vl=A0pXWDRLOVBMSldYNEs5UEwSBAAAEAQAAKCLPAAAAAAAAAABnAqJa1EAAAA...",
"journal": "============ ФИСКАЛНИ РАЧУН ============\n115711881\nBOKA GROUP DOO\nBokaPOS sandbox\nРоза Луксембург 16\nБеоград-Раковица\nКасир: web-shop\nЕСИР број: 1656/1.0.0\n-------------ПРОМЕТ ПРОДАЈА-------------\nАртикли\n========================================\nНазив Цена Кол. Укупно\nBluetooth slušalice/kom (F)\n 8.990,00 1 8.990,00\n----------------------------------------\nУкупан износ: 8.990,00\nПлатна картица: 8.990,00\n========================================\nОзнака Име Стопа Порез\nF ECAL 11,00% 890,90\n----------------------------------------\nУкупан износ пореза: 890,90\n========================================\nПФР време: 01.09.2026. 10:15:32\nПФР број рачуна: JWX4K9PL-JWX4K9PL-1042\nБројач рачуна: 897/1042ПП\n========================================\n======== КРАЈ ФИСКАЛНОГ РАЧУНА ========="
},
"receipt": {
"textUrl": "/v1/fiscal-documents/9f8e7d6c-5b4a-4321-8765-0fedcba98761/representations/official-text",
"jsonUrl": "/v1/fiscal-documents/9f8e7d6c-5b4a-4321-8765-0fedcba98761/representations/canonical-json",
"pdfA4Url": "/v1/fiscal-documents/9f8e7d6c-5b4a-4321-8765-0fedcba98761/representations/pdf-a4",
"pdf80mmUrl": "/v1/fiscal-documents/9f8e7d6c-5b4a-4321-8765-0fedcba98761/representations/pdf-80mm",
"pdf58mmUrl": "/v1/fiscal-documents/9f8e7d6c-5b4a-4321-8765-0fedcba98761/representations/pdf-58mm",
"previewImageUrl": "/v1/fiscal-documents/9f8e7d6c-5b4a-4321-8765-0fedcba98761/representations/preview-png",
"qrImageUrl": "/v1/fiscal-documents/9f8e7d6c-5b4a-4321-8765-0fedcba98761/representations/qr-svg",
"verificationUrl": "https://sandbox.suf.purs.gov.rs/v/?vl=A0pXWDRLOVBMSldYNEs5UEwSBAAAEAQAAKCLPAAAAAAAAAABnAqJa1EAAAA...",
"preferredPaperFormat": "a4"
},
"createdAt": "2026-09-01T08:15:31.902Z",
"updatedAt": "2026-09-01T08:15:32.611Z"
}Ako isti zahtev (isti sadržaj, isti Idempotency-Key) pošaljete ponovo posle 201, dobijate 200 sa istim dokumentom i istim id: račun se ne izdaje drugi put. Novi račun postoji samo posle prvog 201 sa fiscalized: true; 200 samo potvrđuje već izdati.
| Polje | Značenje |
|---|---|
id | identifikator dokumenta u BokaPOS-u: sačuvajte ga uz porudžbinu; služi za kopije, refundacije, prikaze i dostavu |
status, fiscalized | FISCALIZED i true znače da račun postoji |
pfr.invoiceNumber | zvanični broj računa JID-JID-brojač |
pfr.sdcTime | zvanično vreme računa (potpis V-PFR-a) |
pfr.verificationUrl | link za proveru računa kod Poreske uprave; kupcu se prosleđuje u ovom obliku ili kao QR kod |
pfr.journal | zvanični tekst računa (žurnal); može se prikazati ili štampati kakav jeste |
pfr.totalAmount | ukupan iznos koji je V-PFR potpisao |
pfr.totalTax | ukupan porez koji je V-PFR potpisao (zbir poreza po oznakama); može biti null |
pfr.totalCounter, pfr.transactionTypeCounter, pfr.invoiceCounterExtension | potpisani brojači i zvanična oznaka vrste računa (ПП, ПР, АП, АР...); mogu biti null, pa ih tako i primite; brojač je uvek i u žurnalu |
receipt.* | adrese sedam prikaza; vidite Prikazi i dostava računa |
buyerDetails | naziv i adresa kupca iz registra NBS kada je kupac domaća firma; inače null |
Kupac, popust i više načina plaćanja
Isti poziv pokriva prodaju firmi sa PIB-om (buyer.id sa prefiksom 10:), popust na stavku (unitPriceBeforeDiscount samo za prikaz, unitPrice je ono što se fiskalizuje), decimalne količine, više stavki i podelu plaćanja na virman i karticu.
curl -X POST "https://api.bokapos.rs/v1/fiscal-documents" \
-H "Authorization: Bearer $BOKAPOS_TOKEN" \
-H "Idempotency-Key: order-4128-sale-1" \
-H "Content-Type: application/json" \
-d '{
"taxpayerId": "3f9c2a8e-6b1d-4e5a-9c47-1d2b8e6f0a11",
"businessPremiseId": "b7d4e2c1-9a3f-4c8e-8f21-6e5a0c9d3b22",
"clientReference": "ORDER-4128",
"invoiceType": "NORMAL",
"transactionType": "SALE",
"cashier": {
"id": "web-shop"
},
"buyer": {
"id": "10:106952811"
},
"items": [
{
"name": "Godišnja licenca",
"unitOfMeasure": "kom",
"quantity": 2,
"unitPrice": 12000,
"taxLabels": [
"F"
]
},
{
"name": "Instalacija",
"unitOfMeasure": "h",
"quantity": 1.5,
"unitPrice": 4000,
"unitPriceBeforeDiscount": 5000,
"taxLabels": [
"F"
]
}
],
"payments": [
{
"type": "WIRE_TRANSFER",
"amount": 20000
},
{
"type": "CARD",
"amount": 10000
}
],
"commercialFooter": "Hvala na kupovini. Reklamacije: podrska@primer.rs"
}'{
"id": "8e7d6c5b-4a39-4210-8765-fedcba987650",
"taxpayerId": "3f9c2a8e-6b1d-4e5a-9c47-1d2b8e6f0a11",
"businessPremiseId": "b7d4e2c1-9a3f-4c8e-8f21-6e5a0c9d3b22",
"idempotencyKey": "order-4128-sale-1",
"clientReference": "ORDER-4128",
"invoiceType": "NORMAL",
"transactionType": "SALE",
"cashierId": "web-shop",
"buyerId": "10:106952811",
"buyerDetails": {
"legalName": "PRIMER DOO BEOGRAD",
"taxIdentifier": "106952811",
"registrationNumber": "20712345",
"address": "Bulevar kralja Aleksandra 1",
"city": "Beograd",
"source": "nbs-jrr",
"resolvedAt": "2026-09-01T08:20:11.004Z"
},
"status": "FISCALIZED",
"fiscalized": true,
"failureCode": null,
"retryable": false,
"pfr": {
"invoiceNumber": "JWX4K9PL-JWX4K9PL-1043",
"sdcTime": "2026-09-01T10:15:32.483+02:00",
"requestedBy": "JWX4K9PL",
"signedBy": "JWX4K9PL",
"transactionTypeCounter": 898,
"totalCounter": 1043,
"invoiceCounterExtension": "ПП",
"totalAmount": 30000,
"totalTax": 2972.973,
"verificationUrl": "https://sandbox.suf.purs.gov.rs/v/?vl=A0pXWDRLOVBMSldYNEs5UEwSBAAAEAQAAKCLPAAAAAAAAAABnAqJa1EAAAA...",
"journal": "============ ФИСКАЛНИ РАЧУН ============\n...\nПФР број рачуна: JWX4K9PL-JWX4K9PL-1043\nБројач рачуна: 898/1043ПП\n========================================\n======== КРАЈ ФИСКАЛНОГ РАЧУНА ========="
},
"receipt": {
"textUrl": "/v1/fiscal-documents/8e7d6c5b-4a39-4210-8765-fedcba987650/representations/official-text",
"jsonUrl": "/v1/fiscal-documents/8e7d6c5b-4a39-4210-8765-fedcba987650/representations/canonical-json",
"pdfA4Url": "/v1/fiscal-documents/8e7d6c5b-4a39-4210-8765-fedcba987650/representations/pdf-a4",
"pdf80mmUrl": "/v1/fiscal-documents/8e7d6c5b-4a39-4210-8765-fedcba987650/representations/pdf-80mm",
"pdf58mmUrl": "/v1/fiscal-documents/8e7d6c5b-4a39-4210-8765-fedcba987650/representations/pdf-58mm",
"previewImageUrl": "/v1/fiscal-documents/8e7d6c5b-4a39-4210-8765-fedcba987650/representations/preview-png",
"qrImageUrl": "/v1/fiscal-documents/8e7d6c5b-4a39-4210-8765-fedcba987650/representations/qr-svg",
"verificationUrl": "https://sandbox.suf.purs.gov.rs/v/?vl=A0pXWDRLOVBMSldYNEs5UEwSBAAAEAQAAKCLPAAAAAAAAAABnAqJa1EAAAA...",
"preferredPaperFormat": "a4"
},
"createdAt": "2026-09-01T08:15:31.902Z",
"updatedAt": "2026-09-01T08:15:32.611Z"
}Popust je uvek deo cene: V-PFR ne poznaje polje za popust, pa BokaPOS šalje unitPrice kao konačnu cenu, a razliku prikazuje samo izvan fiskalnog dela računa. Popust na ceo račun rasporedite po stavkama pre slanja.
Šta sačuvati u svom sistemu
iddokumenta iIdempotency-Keykoji ste upotrebili (da biste mogli da ponovite isti zahtev posle prekida);pfr.invoiceNumber,pfr.sdcTimeipfr.verificationUrl(za prikaz kupcu, knjigovodstvo i reklamacije);- po potrebi PDF, ali ne morate: prikazi su trajno dostupni na
receipt.*adresama i noseETag.
Kopija računa
Копија je zvanični dokument koji ponavlja fiskalizovan račun (promet ili avans, prodaja ili refundacija) kad kupac traži novi primerak. BokaPOS je pravi iz sačuvanog originala; vi šaljete samo kasira. Kopija se potpisuje kao nov dokument, štampa ОВО НИЈЕ ФИСКАЛНИ РАЧУН i nosi referencu na original. Kopija refundacije ima liniju za potpis kupca. Predračun, obuka i kopija se ne kopiraju.
curl -X POST "https://api.bokapos.rs/v1/fiscal-documents/9f8e7d6c-5b4a-4321-8765-0fedcba98761/copies" \
-H "Authorization: Bearer $BOKAPOS_TOKEN" \
-H "Idempotency-Key: order-4127-copy-1" \
-H "Content-Type: application/json" \
-d '{
"cashier": {
"id": "web-shop"
}
}'{
"id": "b2c3d4e5-f6a7-4b8c-9d0e-1f2a3b4c5d6e",
"taxpayerId": "3f9c2a8e-6b1d-4e5a-9c47-1d2b8e6f0a11",
"businessPremiseId": "b7d4e2c1-9a3f-4c8e-8f21-6e5a0c9d3b22",
"idempotencyKey": "order-4127-copy-1",
"clientReference": "COPY-ORDER-4127",
"invoiceType": "COPY",
"transactionType": "SALE",
"cashierId": "web-shop",
"buyerId": null,
"buyerDetails": null,
"status": "FISCALIZED",
"fiscalized": true,
"failureCode": null,
"retryable": false,
"pfr": {
"invoiceNumber": "JWX4K9PL-JWX4K9PL-1044",
"sdcTime": "2026-09-01T10:15:32.483+02:00",
"requestedBy": "JWX4K9PL",
"signedBy": "JWX4K9PL",
"transactionTypeCounter": 899,
"totalCounter": 1044,
"invoiceCounterExtension": "КП",
"totalAmount": 8990,
"totalTax": 890.9009,
"verificationUrl": "https://sandbox.suf.purs.gov.rs/v/?vl=A0pXWDRLOVBMSldYNEs5UEwSBAAAEAQAAKCLPAAAAAAAAAABnAqJa1EAAAA...",
"journal": "============ ФИСКАЛНИ РАЧУН ============\n...\nПФР број рачуна: JWX4K9PL-JWX4K9PL-1044\nБројач рачуна: 899/1044КП\n========================================\n======== КРАЈ ФИСКАЛНОГ РАЧУНА ========="
},
"receipt": {
"textUrl": "/v1/fiscal-documents/b2c3d4e5-f6a7-4b8c-9d0e-1f2a3b4c5d6e/representations/official-text",
"jsonUrl": "/v1/fiscal-documents/b2c3d4e5-f6a7-4b8c-9d0e-1f2a3b4c5d6e/representations/canonical-json",
"pdfA4Url": "/v1/fiscal-documents/b2c3d4e5-f6a7-4b8c-9d0e-1f2a3b4c5d6e/representations/pdf-a4",
"pdf80mmUrl": "/v1/fiscal-documents/b2c3d4e5-f6a7-4b8c-9d0e-1f2a3b4c5d6e/representations/pdf-80mm",
"pdf58mmUrl": "/v1/fiscal-documents/b2c3d4e5-f6a7-4b8c-9d0e-1f2a3b4c5d6e/representations/pdf-58mm",
"previewImageUrl": "/v1/fiscal-documents/b2c3d4e5-f6a7-4b8c-9d0e-1f2a3b4c5d6e/representations/preview-png",
"qrImageUrl": "/v1/fiscal-documents/b2c3d4e5-f6a7-4b8c-9d0e-1f2a3b4c5d6e/representations/qr-svg",
"verificationUrl": "https://sandbox.suf.purs.gov.rs/v/?vl=A0pXWDRLOVBMSldYNEs5UEwSBAAAEAQAAKCLPAAAAAAAAAABnAqJa1EAAAA...",
"preferredPaperFormat": "a4"
},
"reference": {
"fiscalDocumentId": "9f8e7d6c-5b4a-4321-8765-0fedcba98761",
"pfrNumber": "JWX4K9PL-JWX4K9PL-1042",
"pfrTime": "2026-09-01T10:15:32.483+02:00"
},
"createdAt": "2026-09-01T08:15:31.902Z",
"updatedAt": "2026-09-01T08:15:32.611Z"
}Ponovljen isti zahtev sa istim Idempotency-Key vraća 200 sa već izdatom kopijom; nova kopija se ne potpisuje.
Šta ne ide kroz ovaj poziv
- Refundacija:
POST /v1/refund-workflows, jer traži proveru izvornih linija i automatsku kopiju kod gotovine (Refundacija). - Avans:
/v1/advance-cases, jer je lanac dokumenata sa referencama (Avans). - Predračun i obuka:
/v1/proforma-training-workflows(Predračun i obuka). - Prodaja licem u lice: zahteva L-PFR; prodajno mesto koje nije za prodaju na daljinu vraća
422 LPFR_REQUIRED_FOR_IN_PERSON_SALES.
Greške kod prodaje
| HTTP | Kod | Značenje | Šta uraditi | Ponavljanje |
|---|---|---|---|---|
| 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 | 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 |
| 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 |