Izdaj račun za promet
post/v1/fiscal-documents
Scope fiscal:writeZahteva Idempotency-Key
Glavni poziv. Šaljete stavke, plaćanja, kasira i po potrebi kupca; BokaPOS potpiše zahtev bezbednosnim elementom prodajnog mesta, pošalje ga V-PFR-u i vraća 201 tek kada je potpisani odgovor trajno sačuvan. Refundacije, avansi, predračun i obuka imaju svoje tokove i ovde se odbijaju.
Beleške iz ugovora (OpenAPI, engleski)
Accepts a business-level command and succeeds only after a signed V-PFR result has been durably recorded. A 503 response is not a fiscal receipt. When it carries `retryable: true`, nothing reached the V-PFR, and repeating the identical command under the same Idempotency-Key drives the same reserved operation (and RequestId) again after the same checks as a first attempt; the retry that finally issues the receipt answers 201. A 503 with `retryable: false` (an unknown outcome, or a deployment-side refusal) is answered from storage and is never resubmitted. Refund commands are rejected here and must use a server-managed workflow. Advance, Proforma, and Training chains must use their dedicated workflow APIs. An optional unitPriceBeforeDiscount is a Boka-local immutable display/audit fact; unitPrice is always the final reduced gross price sent to V-PFR. No discount field is invented in the supplier request. Repeating the identical command under the same Idempotency-Key after a 201 answers 200 with the stored document and never fiscalizes a second time; only the first 201 with fiscalized=true is the issuing of a receipt.
Telo zahteva application/json
| Polje | Tip | Opis |
|---|---|---|
taxpayerIdobavezno | uuid | |
businessPremiseIdobavezno | uuid | |
clientReferenceobavezno | string | Caller-owned order, invoice, or transaction reference. |
invoiceTypeobavezno | InvoiceType |
|
transactionTypeobavezno | TransactionType |
|
cashierobavezno | Cashier | |
idobavezno | string | |
displayNameopciono | string | |
buyeropciono | Buyer | |
idopciono | string | Official prefix and value, for example 10:123456789. |
optionalFieldopciono | string | Official buyer-cost-center prefix and value where applicable, printed as Опционо поље купца. Allowed only on a Normal Sale: any other invoice type or transaction type is rejected with 422, because the official manual testing procedure lists the field appearing on a receipt that is not a Промет Продаја as a reason to reject an ESIR. A Copy of a Normal Sale that carried it is issued without it for the same reason, and closing an advance case applies it only to the final Normal Sale, never to the closing Advance Refund. |
referenceopciono | ReferenceTarget | Jedna od varijanti: BokaDocumentReference | ExternalFiscalReference |
| BokaDocumentReference | ||
sourceobavezno | const "BOKA" | |
fiscalDocumentIdobavezno | uuid | |
| ExternalFiscalReference | ||
sourceobavezno | const "EXTERNAL" | |
pfrNumberobavezno | string | |
pfrTimeobavezno | date-time | |
invoiceTypeobavezno | InvoiceType |
|
transactionTypeobavezno | TransactionType |
|
transactionOccurredAtopciono | date-time | Accepted only for an Advance Sale containing a wire-transfer payment, where the official earlier-payment ESIR-time rule applies; it never overrides PFR time. |
itemsobavezno | array<LineItem> | min 1 items |
catalogProductIdopciono | uuid | Optional; arbitrary inline items are permitted. |
nameobavezno | string | min 1max 2048 |
unitOfMeasureopciono | string | Required on every item except the codebook advance literals (10: Аванс (Ђ) and siblings), which are prescribed verbatim without a unit. The API refuses any other item without one (422, Items.UnitOfMeasure) and composes it into the signed item name as name/unit. min 1max 50 |
quantityobavezno | number | V-PFR Decimal(14,3). >= 0.001<= 99999999999.999step 0.001 |
unitPriceobavezno | number | Final gross unit price sent to V-PFR as Decimal(28,4). Boka applies the mandated fiscal rounding rules. >= 0step 0.01 |
unitPriceBeforeDiscountopciono | number | Optional Boka-local immutable gross unit price before discount. When present it must be greater than unitPrice; it is displayed outside the exact PFR journal and is never sent as a supplier field. >= 0step 0.0001 |
gtinopciono | string | min 8max 14 |
taxLabelsobavezno | array<string> | min 1 itemsunique |
paymentsobavezno | array<Payment> | min 1 items |
typeobavezno | PaymentType |
|
amountobavezno | number | At most two decimals (the V-PFR rejects more with validation code 2804); the field type on the wire is Decimal(28,4). >= 0step 0.01 |
commercialFooteropciono | string | Non-fiscal text rendered only in the permitted area outside the fiscal boundary. |
metadataopciono | object | Non-fiscal caller metadata; never sent as a substitute for a mandated field. |
Primer
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"
}
}'Odgovori
| 200 OK | Idempotent replay of the already fiscalized document under the same Idempotency-Key; no new receipt was issuedFiscalDocument |
|---|---|
| 201 Created | Fiscalized documentFiscalDocument |
| 409 Conflict | The key was already used with different canonical contentIdempotencyConflict |
| 422 Unprocessable Content | The command violates a Boka or fiscal ruleErrorCode |
| 503 Service Unavailable | No fiscal receipt was issued because V-PFR was unavailable or its outcome requires reconciliationFiscalDocument |
{
"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"
}{
"code": "IDEMPOTENCY_KEY_REUSED_WITH_DIFFERENT_REQUEST",
"operationId": "9f8e7d6c-5b4a-4321-8765-0fedcba98761"
}{
"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."
]
}
}{
"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_SECURITY_ELEMENT_UNAVAILABLE",
"retryable": true,
"pfr": null,
"receipt": null,
"createdAt": "2026-09-01T08:15:31.902Z",
"updatedAt": "2026-09-01T08:15:32.611Z"
}Primeri
buyer
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"
}Odgovor: FiscalDocument
Opisi polja su preuzeti iz OpenAPI ugovora i na engleskom su; nazivi polja i vrednosti su isti u oba jezika.
| Polje | Tip | Opis |
|---|---|---|
idobavezno | uuid | |
taxpayerIdobavezno | uuid | |
businessPremiseIdobavezno | uuid | |
idempotencyKeyobavezno | string | |
clientReferenceobavezno | string | |
invoiceTypeobavezno | InvoiceType |
|
transactionTypeobavezno | TransactionType |
|
cashierIdobavezno | string | |
buyerIdopciono | string| null (može biti null) | |
buyerDetailsopciono | FiscalBuyerDetails| null (može biti null) | The buyer's company-registry facts stored with the document at reservation and printed under the buyer identification. Null when the buyer is not a domestic company (prefixes 10, 12, 14 with a valid PIB) or the register could not answer at issuance. |
legalNameobavezno | string | max 350 |
taxIdentifierobavezno | string | pattern ^[0-9]{9}$ |
registrationNumberopciono | string| null (može biti null) | pattern ^[0-9]{8}$ |
addressopciono | string| null (može biti null) | max 300 |
cityopciono | string| null (može biti null) | max 100 |
sourceobavezno | string |
|
resolvedAtobavezno | date-time | |
statusobavezno | FiscalDocumentStatus |
|
fiscalizedobavezno | boolean | |
failureCodeopciono | string| null (može biti null) | |
pfrRejectionopciono | object| null (može biti null) | Present only on a single-document read of a REJECTED operation. The V-PFR's own validation result, bounded to the property path of the caller's request and the supplier's numeric codes (2310 invalid tax label; 2800 to 2808 required, length, range, value, format and list-size validation). Lists never carry it. |
itemsobavezno | array<object> | max 10 items |
propertyobavezno | string | max 120 |
codesobavezno | array<string> | max 5 items |
retryableobavezno | boolean | |
pfropciono | PfrResult| null (može biti null) | |
invoiceNumberobavezno | string | |
sdcTimeobavezno | date-time | |
requestedByobavezno | string | |
signedByobavezno | string | |
transactionTypeCounteropciono | integer| null (može biti null) | V-PFR transaction-type counter (the left half of the printed counter). Null when the stored receipt does not carry it; the printed counter is always in the journal text. |
totalCounteropciono | integer| null (može biti null) | V-PFR total counter (the right half of the printed counter and the last segment of invoiceNumber). Null under the same condition as transactionTypeCounter. |
invoiceCounterExtensionopciono | string| null (može biti null) | Official Cyrillic invoice/transaction type pair printed after the counter (ПП, ПР, АП, АР, КП, КР, ОП, ОР, РП, РР). Null under the same condition as transactionTypeCounter. |
totalAmountobavezno | number | |
totalTaxopciono | number| null (može biti null) | Sum of the V-PFR signed tax amounts of the document (the printed "Укупан износ пореза" before its two-decimal display rounding). Null under the same condition as transactionTypeCounter. |
verificationUrlobavezno | uri | |
journalobavezno | string | |
receiptopciono | ReceiptRepresentations| null (može biti null) | |
textUrlobavezno | uri-reference | |
jsonUrlobavezno | uri-reference | |
pdfA4Urlobavezno | uri-reference | |
pdf80mmUrlobavezno | uri-reference | |
pdf58mmUrlobavezno | uri-reference | |
previewImageUrlobavezno | uri-reference | |
qrImageUrlobavezno | uri-reference | |
verificationUrlobavezno | uri | |
preferredPaperFormatobavezno | string | Immutable preferred print/PDF format captured when this fiscal operation was reserved.
|
referenceopciono | ResolvedReference | |
fiscalDocumentIdopciono | uuid | |
pfrNumberobavezno | string | |
pfrTimeobavezno | date-time | |
createdAtobavezno | date-time | |
updatedAtobavezno | date-time |