Preskoči na sadržaj

Uputstvo za instalaciju i integraciju LPFR-a

Za tehničare koji instaliraju Harmony LPFR i programere koji na njega povezuju ESIR: sistemski zahtevi, instalacija na Windows, macOS i Linux, čitači kartica, mrežna podešavanja i REST API.

Ažurirano: Verzija dokumenta: 2.0Preuzmi PDF
Sadržaj

1. Sistemski zahtevi#

1.1 Hardver#

Komponenta Zahtev
Čitač pametnih kartica PC/SC kompatibilan (npr. HID Global OMNIKEY 3x21)
Pametna kartica GIDS/JavaCard sa SE apletom (državna fiskalna kartica)
USB port Za čitač pametnih kartica
Internet konekcija Za slanje revizorskih paketa i komunikaciju sa TaxCore-om

1.2 Softver po operativnom sistemu#

OS Verzija Dodatni zahtevi
Windows 10/11 (64-bit) OpenSC (instalira se automatski sa NSIS instalerom)
macOS 12+ (Monterey ili noviji) OpenSC (brew install opensc ili preuzmite sa opensc.org)
Linux Ubuntu 20.04+ / Debian 11+ pcscd, libpcsclite-dev, OpenSC

1.3 Mrežni zahtevi#

Protokol Port Namena Smer
TCP 8888 (podrazumevano, podesiv) ESIR ↔ L-PFR komunikacija Ulazni (lokalni)
HTTPS 443 L-PFR → TaxCore (mTLS) Izlazni
NTP 123/UDP Sinhronizacija vremena Izlazni
DNS 53 Rezolucija imena + provera interneta Izlazni

1.4 Prostor na disku#

Računajte oko 25 KB po računu: zapis u bazi lpfr.db i kopija paketa u folderu audit/. Primer: 300 računa dnevno je oko 7,5 MB dnevno, odnosno oko 2,7 GB godišnje. Aplikacija ne briše revizorske pakete, pa predvidite prostor za trajno čuvanje.

2. Instalacija po operativnom sistemu#

2.1 Windows#

Pomoću NSIS instalera (preporučeno):

  1. Pokrenite Harmony-LPFR-Setup-{VERZIJA}.exe
  2. Pratite instalacioni čarobnjak — podrazumevana putanja: C:\Program Files\Harmony-LPFR
  3. Instaler automatski postavlja:
    • lpfr.exe — glavni izvršni fajl
    • opensc-pkcs11.dll — OpenSC biblioteka za pametne kartice
    • opensc.dll — podrška za OpenSC
    • Prečicu na Desktop-u i u Start meniju
    • Unos u Add/Remove Programs za deinstalaciju

Ručna instalacija:

  1. Kopirajte lpfr.exe u željeni folder
  2. Instalirajte OpenSC sa https://github.com/OpenSC/OpenSC/releases
  3. Proverite da opensc-pkcs11.dll postoji u C:\Program Files\OpenSC\pkcs11\

Pokretanje:

"C:\Program Files\Harmony-LPFR\lpfr.exe"

2.2 macOS#

Pomoću DMG paketa:

  1. Otvorite Harmony-LPFR-{VERZIJA}.dmg
  2. Prevucite Harmony-LPFR.app u Applications folder
  3. Pri prvom pokretanju: desni klik → Open (zbog Gatekeeper zaštite)

Struktura App Bundle-a:

Harmony-LPFR.app/
└── Contents/
    ├── MacOS/
    │   └── lpfr          ← izvršni fajl
    └── Resources/
        └── lpfr.icns     ← ikona

Preduslovi:

brew install opensc
# Ili preuzmite PKG instaler sa https://github.com/OpenSC/OpenSC/releases

PKCS#11 biblioteka se traži na putanjama:

  • /usr/local/lib/opensc-pkcs11.so
  • /opt/homebrew/lib/opensc-pkcs11.so

2.3 Linux (Debian/Ubuntu)#

Pomoću .deb paketa:

sudo apt install pcscd libpcsclite-dev opensc
sudo dpkg -i harmony-lpfr_{VERZIJA}_amd64.deb

Paket instalira:

  • /usr/local/bin/lpfr — izvršni fajl
  • /usr/share/applications/harmony-lpfr.desktop — desktop entri
  • /usr/share/icons/hicolor/256x256/apps/lpfr.png — ikona

Pokretanje PC/SC servisa:

sudo systemctl enable pcscd
sudo systemctl start pcscd

Ručna instalacija:

sudo apt install pcscd opensc
chmod +x lpfr
sudo cp lpfr /usr/local/bin/

2.4 Upozorenja o neispravnoj instalaciji#

  • Samo zvanični instaler. Harmony-LPFR preuzimajte isključivo sa https://harmonypos.io. Instaler iz drugog izvora može biti izmenjen i ugroziti računar i fiskalne podatke.
  • Administratorska prava. Windows instaler traži administratorska prava. Ne menjajte ručno sadržaj instalacione foldera (lpfr.exe, opensc.dll, opensc-pkcs11.dll); bez OpenSC biblioteka aplikacija ne može da čita karticu.
  • Podaci ostaju pri deinstalaciji. Deinstalacija briše program, prečice i unose u registru, ali ne briše bazu i revizorske pakete u %APPDATA%\harmonypos.io\lpfr\. Ne brišite tu folder ručno pre nego što svi revizorski paketi budu poslati Poreskoj upravi.
  • Jedan L-PFR po čitaču. Ne pokrećite istovremeno drugi L-PFR program koji koristi isti čitač kartica. Harmony-LPFR ne dozvoljava dve svoje instance (vidi Aplikacija se ne pokreće).
  • Zauzet port. Ako drugi program već koristi port 8888, ESIR neće moći da se poveže. Promenite port u podešavanjima (vidi poglavlje 6).
  • Hardver. Instalacija ne zahteva otvaranje računara. Čitač se priključuje na USB port; koristite čitač i kabl u ispravnom stanju. Neispravan USB port ili kabl može prekidati vezu sa karticom tokom rada.

3. Podešavanje čitača pametnih kartica#

3.1 Provera povezanosti čitača#

Linux:

# Proverite da li je pcscd pokrenut
sudo systemctl status pcscd

# Skenirajte za kartice
pcsc_scan

Windows:

  • Otvorite Device Manager → Smart card readers
  • Čitač treba da bude prikazan bez žutog znaka upozorenja

macOS:

# Listaj povezane čitače
pcsctest
# ili
system_profiler SPSmartCardsDataType

3.2 Podržani čitači#

Bilo koji PC/SC kompatibilan čitač. Testirani:

  • HID Global OMNIKEY 3x21
  • Gemalto IDBridge CT710
  • ACS ACR38U

3.3 Izbor čitača#

Čitač se detektuje automatski — aplikacija uzima prvi dostupni PC/SC čitač. U interfejsu nema liste čitača i izbor se nigde ne čuva.

Savet: Ako na računaru postoji više čitača, ostavite povezan samo onaj sa fiskalnom karticom. Trenutno aktivni čitač vidljiv je na kartici Status, u odeljku Pametna kartica (Čitač kartice pronađen).

4. Prvo pokretanje#

Aplikacija nema čarobnjak za podešavanje. Radi sa podrazumevanim vrednostima odmah nakon instalacije, a sve što treba izmeniti nalazi se u dijalogu Podešavanja (ikonica zupčanika u gornjoj traci) ili u promenljivama okruženja.

4.1 Tok pokretanja#

  1. Prozor za pokretanje sa indikatorom napretka i poslednjim porukama inicijalizacije
  2. Baza podataka → NTP → čitač i kartica → licenca → TaxCore → POS server
  3. Glavni prozor i ikonica u sistemskoj paleti

4.2 Podrazumevane vrednosti#

Polje Opis Podrazumevano Gde se menja
Bind adresa IP adresa za slušanje 0.0.0.0 (sve adrese) samo LPFR_BIND_ADDRESS
POS port TCP port za ESIR komunikaciju 8888 Podešavanja → Server
Folder fajl-interfejsa Ulaz/izlaz za .http fajlove ~/Harmony-LPFR Podešavanja → Fajl posmatrač (potreban restart)

Preporuke:

  • Ako je ESIR na istom računaru → localhost:8888
  • Ako je ESIR na drugom računaru u mreži → 0.0.0.0:8888 (ili konkretna IP adresa)
  • Port mora biti usklađen sa podešavanjima u ESIR softveru

4.3 Čitač i PIN#

  • Čitač se detektuje automatski — nema izbora iz liste
  • Ubacite fiskalnu karticu i kliknite Verifikuj PIN u gornjoj traci, ili verifikujte PIN preko POST /api/v3/pin iz ESIR-a
  • PIN se ne čuva — ni u bazi, ni u fajlu, ni u promenljivoj okruženja. Unosi se ponovo posle svakog vađenja kartice i posle svakog restarta aplikacije.

UPOZORENJE: Kartica se blokira posle 3 pogrešna unosa PIN-a. Za deblokadu potreban je PUK kod ili kontakt sa izdavaocem kartice.

4.4 Licenciranje#

Licenca se proverava po kartici, pri ubacivanju, ne pri pokretanju — aplikacija se uvek pokreće i uvek prikazuje status.

Tip kartice Ponašanje
Test / sandbox kartica Radi bez licence
Produkciona kartica sa važećom licencom Potpisivanje omogućeno
Produkciona kartica bez licence Potpisivanje blokirano + dijalog za licencu

U dijalogu se unosi token licence ili se pokreće probna verzija. Token je vezan za ID uređaja (prikazan u dijalogu, sa dugmetom za kopiranje) i čuva se u bezbednom skladištu operativnog sistema — Keychain na macOS-u, Credential Manager na Windows-u, Secret Service na Linux-u. Ne čuva se u fajlu i ne prenosi se kopiranjem baze.

Plaćena HarmonyPOS desktop licenca važi i za Harmony-LPFR. Stanje licence se ponovo proverava svakog sata.

4.5 Bezglavno (headless) podešavanje#

Mrežna podešavanja se mogu zadati promenljivim okruženja pre pokretanja:

export LPFR_BIND_ADDRESS="0.0.0.0"
export LPFR_POS_PORT=8888
./lpfr

Čitač i PIN se ne mogu zadati promenljivim okruženja: čitač se bira automatski, a PIN se unosi interaktivno ili preko POST /api/v3/pin.

5. Konfiguracija putem promenljivih okruženja#

Većina podešavanja se može zadati putem LPFR_* promenljivih okruženja. One se čitaju pri pokretanju, a zatim ih vrednosti sačuvane u bazi pregaze — ono što ste sačuvali u dijalogu Podešavanja važi i posle restarta, bez obzira na okruženje. PIN i čitač se ne podešavaju nigde: čitač se detektuje automatski, a PIN se unosi interaktivno i ne čuva se.

Svaka promenljiva ima i zastareli ESDC_ oblik iz vremena pre preimenovanja. On i dalje radi, ali upisuje upozorenje u log — preimenujte ga u LPFR_.

Promenljiva Podrazumevano Opis
LPFR_POS_PORT 8888 TCP port za ESIR komunikaciju
LPFR_BIND_ADDRESS 0.0.0.0 Bind adresa HTTP servera
LPFR_TAXCORE_URL (iz sertifikata) Bazni URL TaxCore API-ja
LPFR_VERIFICATION_URL — Bazni URL za verifikaciju računa
LPFR_NTP_SERVER pool.ntp.org NTP server za sinhronizaciju vremena
LPFR_DB_PATH ~/.config/harmonypos.io/lpfr/lpfr.db Putanja do SQLite baze
LPFR_AUDIT_PATH {folder sa podacima}/audit Putanja za lokalnu reviziju (SD/USB)
LPFR_ENVIRONMENT production Okruženje: production ili sandbox
LPFR_LOG_LEVEL info Nivo logovanja: debug, info, warn, error
LPFR_UPDATE_URL — URL za automatsko ažuriranje (koren bucket-a)
LPFR_UPDATE_CHANNEL (prema tipu izdanja) Kanal ažuriranja: prod, release, release/vX.Y.x ili pr/<n>
LPFR_UNIX_SOCKET ~/.config/harmonypos.io/lpfr/lpfr.sock Putanja Unix socket-a
LPFR_MRC_PREFIX 89-0001 MRC prefiks (ProductCode-ProductVersionCode)
LPFR_API_KEY — Bearer token obavezan uz svaki POS API zahtev kada je postavljen
LPFR_FILE_WATCH_DIR ~/Harmony-LPFR Koreni folder fajl-baziranog interfejsa
LPFR_LICENSE_URL — Servis za registraciju probne licence

5.1 Prioritet konfiguracije#

  1. Vrednosti sačuvane u SQLite bazi (tabela config) — najviši prioritet
  2. Promenljive okruženja
  3. Podrazumevane vrednosti (najniži prioritet)

Iz baze se učitavaju: bind_address, pos_port, unix_socket, language, audit_path, api_key, file_watch_dir, ntp_server, mrc_prefix, file_sse_events, a komande Poreske uprave upisuju i verification_url i taxcore_config. Ostala podešavanja su isključivo iz okruženja. Ako želite da promenljiva okruženja ponovo ima efekat, obrišite odgovarajući ključ iz tabele config.

5.2 Primer: podešavanje Windows servisa#

set LPFR_POS_PORT=8888
set LPFR_BIND_ADDRESS=0.0.0.0
set LPFR_LOG_LEVEL=info
set LPFR_MRC_PREFIX=89-0001
"C:\Program Files\Harmony-LPFR\lpfr.exe"

5.3 Primer: podešavanje na Linux-u#

export LPFR_POS_PORT=8888
export LPFR_BIND_ADDRESS=0.0.0.0
export LPFR_ENVIRONMENT=production
export LPFR_MRC_PREFIX=89-0001
/usr/local/bin/lpfr

5.4 MRC (Machine Readable Code)#

MRC se formira kombinacijom prefiksa i UID-a kartice:

MRC = {LPFR_MRC_PREFIX}-{UID}
Primer: 89-0001-EKPDW8TH

MRC prefiks se dodeljuje prilikom akreditacije L-PFR softvera i mora se podesiti pre prve upotrebe.

6. Mrežna konfiguracija#

6.1 TCP server#

L-PFR pokreće HTTP server na konfigurisanoj adresi i portu.

http://{BIND_ADDRESS}:{POS_PORT}
Podrazumevano: http://0.0.0.0:8888

Tajmauti:

  • Read timeout: 30 sekundi
  • Write timeout: 5 minuta (SSE tok i duže operacije potpisivanja)
  • Idle timeout: 120 sekundi

6.2 Unix Socket (opciono)#

Za lokalnu komunikaciju bez TCP/IP steka:

Putanja: ~/.config/harmonypos.io/lpfr/lpfr.sock

Korisno kada ESIR i L-PFR rade na istom računaru — brža komunikacija i nema potrebe za otvaranjem porta.

6.3 Fajervol (Firewall)#

Ako ESIR pristupa preko mreže, potrebno je dozvoliti ulaznu konekciju na POS portu:

Windows:

netsh advfirewall firewall add rule name="Harmony-LPFR" dir=in action=allow protocol=tcp localport=8888

Linux (ufw):

sudo ufw allow 8888/tcp

Linux (firewalld):

sudo firewall-cmd --permanent --add-port=8888/tcp
sudo firewall-cmd --reload

6.4 Provera konekcije#

Iz ESIR-a ili bilo kog HTTP klijenta:

curl http://localhost:8888/api/v3/attention
# Očekivani odgovor: HTTP 200 OK (prazno telo)

6.5 Vrsta mrežne veze#

Harmony-LPFR koristi mrežnu vezu operativnog sistema i ne zavisi od njene vrste: bežična veza (Wi-Fi), mrežni kabl (Ethernet) ili mobilni internet. Potrebni su izlazni portovi iz odeljka 1.3. ESIR može da se poveže i preko bežične lokalne mreže, na POS port (podrazumevano 8888).

7. Integracija ESIR-a sa L-PFR-om (REST API)#

7.1 Bazni URL#

http://{adresa}:{port}/api/v3/
Podrazumevano: http://localhost:8888/api/v3/

7.2 API dokumentacija (Swagger UI)#

Interaktivna dokumentacija je dostupna na:

http://localhost:8888/docs

OpenAPI specifikacija:

http://localhost:8888/openapi.json
http://localhost:8888/openapi.yaml

Uputstvo za korisnike (ista stranica koju otvara kartica Pomoć):

http://localhost:8888/help

7.3 Pregled endpointa#

Metod Putanja Opis
GET /api/v3/attention Provera dostupnosti (ping)
POST /api/v3/pin Verifikacija PIN-a
GET /api/v3/status Status uređaja
GET /api/v3/configuration Konfiguracija i podaci o firmi
POST /api/v3/invoices Potpisivanje računa
GET /api/v3/invoices/{requestId} Preuzimanje računa po RequestId-u
GET /api/v3/reports/current Tekući izveštaj (presek stanja)
POST /api/v3/reports/daily Dnevni zaključak
GET /api/v3/reports/periodic?from=...&to=... Periodični izveštaj
GET /api/v3/events SSE tok događaja u realnom vremenu

7.4 Format zahteva i odgovora#

  • Content-Type: application/json ili application/xml
  • Accept: application/json ili application/xml
  • Podrazumevano: JSON

7.5 Zaglavlja (Headers)#

Zaglavlje Opis Primer
Content-Type Format tela zahteva application/json
Accept Željeni format odgovora application/json
RequestId Ključ idempotentnosti (maks. 32 karaktera) pos-001-20260304-1
Accept-Language Jezik fiskalnog isečka sr_cyrl, sr_latn, en
Authorization Obavezno kada je LPFR_API_KEY postavljen Bearer <ključ>

NAPOMENA: Kada je LPFR_API_KEY postavljen, svaki zahtev bez ispravnog zaglavlja Authorization dobija 401. Izuzete su samo stranice /docs, /openapi.json, /openapi.yaml i /help.

7.6 Usklađenost sa tehničkim vodičem#

Revizorski paketi i URL za verifikaciju formiraju se prema tehničkom vodiču Poreske uprave (protokol POS-to-SDC v3). Paket se šifruje AES-256-CBC ključem, a ključ i IV javnim RSA ključem SUF-a. QR kod se ne stavlja u paket, a sdcDateTime u paketu je u UTC.

8. Verifikacija PIN-a preko API-ja#

8.1 Zahtev#

POST /api/v3/pin
Content-Type: application/json

PIN se može poslati u nekoliko formata:

JSON objekat:

{"pin": "1234"}

JSON string:

"1234"

Običan tekst:

1234

XML:

<PINRequest><pin>1234</pin></PINRequest>

8.2 Odgovor#

Odgovor je 4-cifreni statusni kod:

Kod Značenje
0100 PIN uspešno verifikovan
2100 Pogrešan PIN
2110 PIN blokiran (previše pogrešnih pokušaja)
2806 Neispravan format (PIN mora biti 4 cifre)
2220 Greška apleta na kartici
1300 Kartica nije prisutna / greška čitača
1999 Druga greška

8.3 Primer#

curl -X POST http://localhost:8888/api/v3/pin \
  -H "Content-Type: application/json" \
  -d '{"pin":"1234"}'

Odgovor:

"0100"

9. Potpisivanje računa — zahtev i odgovor#

9.1 Zahtev#

POST /api/v3/invoices
Content-Type: application/json
RequestId: unique-request-id-123
Accept-Language: sr_cyrl

9.2 Struktura zahteva (InvoiceRequest)#

{
  "dateAndTimeOfIssue": "2026-03-04T10:30:00+01:00",
  "cashier": "Марко",
  "buyerId": "",
  "buyerCostCenterId": "",
  "invoiceType": 0,
  "transactionType": 0,
  "payment": [
    {
      "paymentType": 0,
      "amount": 1500.00
    }
  ],
  "items": [
    {
      "name": "Производ А",
      "quantity": 2,
      "unitPrice": 500.00,
      "labels": ["A"],
      "totalAmount": 1000.00
    },
    {
      "name": "Производ Б",
      "quantity": 1,
      "unitPrice": 500.00,
      "labels": ["A"],
      "totalAmount": 500.00
    }
  ],
  "options": {
    "omitQRCodeGen": "0",
    "omitTextualRepresentation": "0"
  }
}

9.3 Polja zahteva#

Polje Tip Obavezno Opis
dateAndTimeOfIssue string (ISO 8601) Ne Datum i vreme izdavanja (podrazumevano: SDC vreme)
cashier string Ne Ime kasira
buyerId string Ne PIB kupca (za B2B račune)
buyerCostCenterId string Ne Mesto troška kupca
invoiceType number (0-4) Da Tip računa
transactionType number (0-1) Da Tip transakcije
payment array Da Lista plaćanja
payment[].paymentType number (0-6) Da Tip plaćanja
payment[].amount number Da Iznos plaćanja
items array Da Lista stavki (minimum 1)
items[].name string Da Naziv stavke
items[].quantity number Da Količina
items[].unitPrice number Da Jedinična cena
items[].totalAmount number Da Ukupan iznos stavke
items[].labels array of string Da Poreske oznake (npr. ["A"])
items[].discount number Ne Iznos popusta
items[].gtin string Ne GTIN/barkod
invoiceNumber string Ne Broj računa (ako se zadaje spolja)
referentDocumentNumber string Ne Referentni dokument (za Kopiju)
referentDocumentDT string Ne Datum referentnog dokumenta
options object Ne Opcije za generisanje odgovora
options.omitQRCodeGen string ("0"/"1") Ne Izostaviti QR kod iz odgovora
options.omitTextualRepresentation string ("0"/"1") Ne Izostaviti tekst isečka iz odgovora

9.4 Tipovi računa (invoiceType)#

Vrednost Tip Opis
0 Normalan Standardni fiskalni račun
1 Profaktura Nefiskalni pregled
2 Kopija Kopija prethodnog računa
3 Obuka Račun za obuku — ne evidentira se fiskalno
4 Avans Račun za avansno plaćanje

9.5 Tipovi transakcija (transactionType)#

Vrednost Tip
0 Prodaja
1 Refundacija

9.6 Tipovi plaćanja (paymentType)#

Vrednost Tip
0 Gotovina (Ostalo)
1 Kartica
2 Ček
3 Virman
4 Vaučer
5 Mobilni novac
6 Neodređeno

9.7 Struktura odgovora (InvoiceResult)#

{
  "requestedBy": "pos-001-20260304-1",
  "sdcDateTime": "2026-03-04T10:30:05+01:00",
  "invoiceCounter": "14/14НС",
  "invoiceCounterExtension": "НС",
  "invoiceNumber": "EKPDW8TH-EKPDW8TH-14",
  "taxItems": [
    {
      "categoryType": 1,
      "label": "A",
      "amount": 300.00,
      "rate": 20.00,
      "categoryName": "ECAL"
    }
  ],
  "verificationUrl": "https://suf.purs.gov.rs/inv?...",
  "verificationQRCode": "data:image/png;base64,iVBOR...",
  "journal": "========================================\n...",
  "messages": "",
  "signedBy": "EKPDW8TH",
  "encryptedInternalData": "...",
  "signature": "...",
  "totalCounter": 42,
  "transactionTypeCounter": 14,
  "totalAmount": 1500.00,
  "taxGroupRevision": 1,
  "businessName": "Фирма д.о.о.",
  "tin": "114952530",
  "locationName": "Пословница 1",
  "address": "Улица 1",
  "district": "Београд",
  "mrc": "89-0001-EKPDW8TH"
}

9.8 Polja odgovora#

Polje Tip Opis
requestedBy string RequestId iz zaglavlja zahteva
sdcDateTime string Datum/vreme potpisivanja (ISO 8601)
invoiceCounter string Brojač računa za ovaj tip
invoiceCounterExtension string Ekstenzija brojača
invoiceNumber string Jedinstveni broj računa
taxItems array Poresko razbijanje po kategorijama
verificationUrl string URL za verifikaciju računa
verificationQRCode string QR kod (base64 PNG slika)
journal string Formatirani tekst fiskalnog isečka (40 karaktera)
messages string Dodatne poruke
signedBy string UID uređaja koji je potpisao
encryptedInternalData string Šifrovani interni podaci za reviziju
signature string Kriptografski potpis
totalCounter number Ukupni brojač svih računa
transactionTypeCounter number Brojač za tip transakcije
totalAmount number Ukupan iznos računa
taxGroupRevision number Revizija grupe poreskih stopa
businessName string Naziv firme
tin string PIB
locationName string Naziv lokacije
address string Adresa
district string Okrug
mrc string MRC (Machine Readable Code)

9.9 Idempotentnost (RequestId)#

  • Ako se isti RequestId pošalje ponovo, L-PFR automatski konvertuje zahtev u Kopiju prethodnog računa
  • Referencira se broj i datum originalnog računa
  • Maksimalna dužina: 32 karaktera
  • Preporuka: koristite jedinstven ID po računu (npr. UUID ili {kasa}-{datum}-{brojač})

9.10 HTTP status kodovi#

Kod Značenje
200 Račun uspešno potpisan
400 Greška validacije — detalji u ModelState
500 Serverska greška (kartica, potpisivanje, itd.)

9.11 Primer greške validacije (400)#

{
  "Message": "Validation failed",
  "ModelState": {
    "items": ["At least one item is required"],
    "payment.amount": ["Amount must be > 0"]
  }
}

9.12 Obračun poreza#

ESIR za svaku stavku šalje ukupan iznos (totalAmount) i poreske oznake (labels), a ne iznos poreza. L-PFR obračunava porez po stopama grupe koja važi u trenutku potpisivanja i vraća ga u polju taxItems.

10. Status i konfiguracija uređaja#

10.1 GET /api/v3/status — Status uređaja#

curl http://localhost:8888/api/v3/status
{
  "isPinRequired": false,
  "auditRequired": false,
  "sdcDateTime": "2026-03-04T10:30:00+01:00",
  "lastInvoiceNumber": "EKPDW8TH-EKPDW8TH-42",
  "protocolVersion": "1.0.0.0",
  "hardwareVersion": "1.0.0.0",
  "softwareVersion": "1.0.0",
  "deviceSerialNumber": "89-0001-EKPDW8TH",
  "make": "HarmonyPOS",
  "model": "Harmony-LPFR",
  "uid": "EKPDW8TH",
  "taxCoreApi": "https://api.taxcore.rs",
  "gsc": ["0100"],
  "currentTaxRates": {
    "validFrom": "2025-01-01T00:00:00",
    "groupId": 5,
    "taxCategories": [
      { "label": "A", "categoryType": 1, "categoryName": "ECAL", "rate": 20.0 },
      { "label": "Б", "categoryType": 1, "categoryName": "ECAL", "rate": 10.0 }
    ]
  }
}

Ključna polja za ESIR:

  • isPinRequired — ako je true, potrebno je prvo verifikovati PIN
  • auditRequired — true kada je iščitavanje neophodno: revizorski paketi kasne ili je dostignut Limit iznosa na bezbednosnom elementu
  • gsc — status kod: "0100" = spreman, "1500" = PIN potreban

10.2 GET /api/v3/configuration — Konfiguracija#

curl http://localhost:8888/api/v3/configuration
{
  "taxCoreUrl": "https://api.taxcore.rs",
  "verificationUrl": "https://suf.purs.gov.rs",
  "ntpServer": "pool.ntp.org",
  "taxRates": [
    { "label": "A", "categoryType": 1, "categoryName": "ECAL", "rate": 20.0, "orderId": 0 },
    { "label": "Б", "categoryType": 1, "categoryName": "ECAL", "rate": 10.0, "orderId": 1 }
  ],
  "tin": "114952530",
  "uid": "EKPDW8TH",
  "businessName": "Фирма д.о.о.",
  "locationName": "Пословница 1",
  "address": "Улица 1",
  "district": "Београд"
}

10.3 GET /api/v3/attention — Provera dostupnosti#

curl -I http://localhost:8888/api/v3/attention
# HTTP/1.1 200 OK

Ovaj endpoint ESIR treba da pozove pre svake prodaje da bi proverio da li je L-PFR dostupan. Ne vraća telo odgovora.

11. Izveštaji preko API-ja#

11.1 GET /api/v3/reports/current — Presek stanja#

curl http://localhost:8888/api/v3/reports/current

Vraća stanje od poslednjeg dnevnog zaključka.

11.2 POST /api/v3/reports/daily — Dnevni zaključak#

curl -X POST http://localhost:8888/api/v3/reports/daily

Zatvara tekući dan i generiše izveštaj. Nepovratna operacija — novi period počinje od trenutka zaključka.

11.3 GET /api/v3/reports/periodic — Periodični izveštaj#

curl "http://localhost:8888/api/v3/reports/periodic?from=2026-03-01T00:00:00&to=2026-03-04T23:59:59"

Parametri from i to su u ISO 8601 formatu.

11.4 Struktura odgovora izveštaja#

{
  "title": "Текући извештај",
  "periodFrom": "2026-03-04T00:00:00+01:00",
  "periodTo": "2026-03-04T18:30:00+01:00",
  "generatedAt": "2026-03-04T18:30:00+01:00",
  "invoiceCount": 42,
  "totalSales": 150000.00,
  "totalRefunds": 2500.00,
  "payments": {
    "Cash": 80000.00,
    "Card": 67500.00,
    "Voucher": 2500.00
  },
  "taxSummary": [
    { "label": "A", "rate": 20.0, "tax": 25000.00 }
  ],
  "text": "========================================\n..."
}

12. Server-Sent Events (SSE)#

ESIR može da se pretplati na tok događaja u realnom vremenu:

GET /api/v3/events
Accept: text/event-stream

12.1 Tipovi događaja#

Događaj Interval Opis
heartbeat Svaka 15 sekundi Keepalive — { timestamp, uptime }
card:inserted Odmah Kartica ubačena — { reader }
card:removed Odmah Kartica izvađena — { reader }
pin:required Odmah Kartica je prisutna, ali PIN nije verifikovan
pin:verified Odmah PIN uspešno verifikovan
pin:failed Odmah Kartica je odbila uneti PIN
pin:cleared Odmah PIN verifikacija poništena (kartica izvađena)
invoice:signed Odmah Račun potpisan — { invoiceNumber, totalAmount, sdcDateTime }
audit:updated Odmah Promenjeno stanje revizije (poslato, ponovljeno ili novo na čekanju)

NAPOMENA: Periodični status događaj ne postoji — za kompletan status pozovite GET /api/v3/status kada vam zatreba, a na promene reagujte kroz događaje iznad.

12.2 Primer implementacije u JavaScript-u#

const evtSource = new EventSource('http://localhost:8888/api/v3/events');

evtSource.addEventListener('pin:required', () => {
  showPinDialog();
});

evtSource.addEventListener('card:removed', () => {
  disableSigning();
});

evtSource.addEventListener('invoice:signed', (event) => {
  const data = JSON.parse(event.data);
  console.log(`Рачун ${data.invoiceNumber} потписан`);
});

12.3 Preporuke za integraciju#

  • Koristite SSE umesto polling-a za efikasnije praćenje statusa
  • Reagujte na card:removed, pin:cleared i pin:required tako što ćete blokirati prodaju
  • Reagujte na pin:verified tako što ćete ponovo omogućiti prodaju
  • SSE konekcija je dugoročna — obradite prekid veze (EventSource automatski rekonektuje)

13. Fajl-bazirani interfejs#

Za ESIR sisteme koji ne podržavaju HTTP, L-PFR pruža fajl-bazirani interfejs.

13.1 Struktura direktorijuma#

Koreni folder je podrazumevano ~/Harmony-LPFR (promenljiva LPFR_FILE_WATCH_DIR):

~/Harmony-LPFR/
├── input/             ← ESIR ubacuje zahteve ovde
│   └── processed/     ← Obrađeni fajlovi se premeštaju ovde
└── output/            ← L-PFR upisuje odgovore ovde

Trenutna putanja je vidljiva na kartici Status, u odeljku Uređaj (Putanja fajlova), zajedno sa dugmetom za otvaranje foldera.

13.2 Format fajla (.http)#

Fajlovi koriste IntelliJ HTTP Client format:

POST /api/v3/invoices HTTP/1.1
Content-Type: application/json
RequestId: file-test-001

{
  "invoiceType": 0,
  "transactionType": 0,
  "cashier": "Марко",
  "payment": [{"paymentType": 0, "amount": 500.00}],
  "items": [
    {
      "name": "Производ",
      "quantity": 1,
      "unitPrice": 500.00,
      "labels": ["A"],
      "totalAmount": 500.00
    }
  ]
}

13.3 Proces obrade#

  1. ESIR kreira .http fajl u ./input/ direktorijumu
  2. L-PFR detektuje novi fajl (file watcher)
  3. Parsira HTTP zahtev iz fajla
  4. Obrađuje zahtev (isto kao REST API)
  5. Upisuje HTTP odgovor u ./output/{ime_fajla}
  6. Premešta originalni fajl u ./input/processed/

13.4 Čišćenje#

Obrađeni fajlovi se ne brišu automatski. Čišćenje se pokreće ručno, dugmetom Očisti obrađene (3+ dana) u dijalogu Podešavanja → Fajl posmatrač, koje briše fajlove iz input/processed/ starije od tri dana.

13.5 SSE događaji preko fajla#

Prekidač SSE događaji preko fajla u istom odeljku upisuje događaje i u fajl, za ESIR sisteme koji ne mogu da drže otvorenu SSE konekciju. Stanje se pamti pod ključem file_sse_events.

14. Automatsko pokretanje pri prijavi#

14.1 Windows#

Koristi Registry ključ:

HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run
Vrednost: Harmony-LPFR = "C:\Program Files\Harmony-LPFR\lpfr.exe"

Uključite kroz GUI: Podešavanja → Opšte → Pokreni pri prijavi. Isti prekidač važi na sva tri sistema.

14.2 macOS#

Koristi LaunchAgent:

~/Library/LaunchAgents/io.harmonypos.lpfr.plist

Sadržaj:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
  "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
  <key>Label</key>
  <string>io.harmonypos.lpfr</string>
  <key>ProgramArguments</key>
  <array>
    <string>/Applications/Harmony-LPFR.app/Contents/MacOS/lpfr</string>
  </array>
  <key>RunAtLoad</key>
  <true/>
</dict>
</plist>

14.3 Linux#

Koristi XDG autostart:

~/.config/autostart/harmony-lpfr.desktop

Sadržaj:

[Desktop Entry]
Type=Application
Name=Harmony-LPFR
Exec=/usr/local/bin/lpfr
X-GNOME-Autostart-enabled=true

15. Automatsko ažuriranje#

Ako je konfigurisan LPFR_UPDATE_URL, aplikacija prati kanal izdanja — ne konkretnu verziju. Kanal je jedan fajl u bucket-u koji kaže koju verziju svi uređaji na tom kanalu treba da imaju.

15.1 Podešavanje#

export LPFR_UPDATE_URL="https://your-bucket.s3.amazonaws.com/lpfr"
export LPFR_UPDATE_CHANNEL="prod"     # opciono
Kanal Ko ga prati
prod Izdanja označena git tagom — ovde idu produkcioni uređaji
release Niko podrazumevano; ovde stiže svako tagiranje, pre promocije
release/vX.Y.x Pregledni bildovi grane release/X.Y.x
pr/<n> Pregledni bildovi pull request-a <n>

Ako LPFR_UPDATE_CHANNEL nije postavljen, tagirani bild prati prod, a pregledni bild svoj kanal. Bild sa main grane i lokalni make build ne ažuriraju se uopšte.

15.2 Proces ažuriranja#

  1. Provera pri pokretanju, zatim svakih 30 minuta
  2. Preuzima se <base>/<channel>/update.json i upoređuje verzija kanala sa tekućom
  3. Ako se razlikuju, preuzima se paket za tekući OS — i nadogradnja i povratak na stariju verziju (uređaj uzima ono što kanal kaže)
  4. Preuzeto se proverava prema sha256 iz manifesta pre nego što se bilo šta upiše — neproverena putanja ne postoji
  5. Ažuriranje se primenjuje na disk, a korisniku se prikazuje obaveštenje
  6. Restart se odlaže do 03:00 po lokalnom vremenu, da uređaj ne bude restartovan usred prodaje

Na macOS-u se kod .app instalacije menja ceo potpisani bundle, a ne binarni fajl u njemu (zamena samo binarnog fajla poništava potpis bundle-a). Nova kopija mora da zadovolji designated requirement postojeće — Apple-ov test za „ista aplikacija, noviji bild" — a sama zamena je jedna RENAME_SWAP transakcija.

16. Lokacije fajlova i baza podataka#

16.1 Po operativnom sistemu#

OS Data direktorijum
Windows %APPDATA%\harmonypos.io\lpfr\
macOS ~/Library/Application Support/harmonypos.io/lpfr/
Linux ~/.config/harmonypos.io/lpfr/

16.2 Fajlovi#

Fajl Putanja (relativno od Data direktorijuma) Opis
Baza podataka lpfr.db SQLite baza sa svim podešavanjima i računima
Unix Socket lpfr.sock Alternativni interfejs za lokalnu komunikaciju
Logovi logs/lpfr-GGGG-MM-DD.log Dnevni log fajlovi (čuvaju se 30 dana)
Lock fajl lpfr.lock Zaključavanje jedne instance
Revizorski paketi audit/ Lokalni revizorski paketi (kada LPFR_AUDIT_PATH nije postavljen)

Folder fajl-baziranog interfejsa nije u ovom direktorijumu — podrazumevano je ~/Harmony-LPFR.

Licenca se ne čuva u fajlu: drži se u skladištu tajni operativnog sistema (Keychain, Credential Manager, Secret Service).

Ako na sistemu postoji pre-preimenovanja esdc.db, pri pokretanju se automatski premešta na lpfr.db.

16.3 SQLite tabele#

Tabela Namena
config Skladište podešavanja (ključ-vrednost)
audit_records Revizorski paketi (neposlati i poslati)
tax_rate_groups Istorijske grupe poreskih stopa
invoices Evidencija računa za izveštavanje
last_invoice Poslednji potpisani račun (za idempotentnost)
commands Evidencija izvršavanja TaxCore komandi

16.4 Provera integriteta baze#

sqlite3 ~/.config/harmonypos.io/lpfr/lpfr.db "PRAGMA integrity_check;"
# Očekivani odgovor: ok

16.5 Trajnost podataka#

Baza lpfr.db i folder audit/ nalaze se na disku računara i ne zahtevaju napajanje: podaci ostaju posle gašenja aplikacije, računara ili nestanka struje. Poreske stope se upisuju u bazu pre nego što se komanda potvrdi SUF-u.

17. Dijagnostika i logovi#

17.1 Lokacija logova#

{Data direktorijum}/logs/lpfr-GGGG-MM-DD.log

Logovi se rotiraju dnevno i čuvaju 30 dana.

17.2 Nivoi logovanja#

Nivo Opis Kad koristiti
debug Detaljne tehničke poruke Dijagnostika problema
info Informacije o normalnom radu Standardno
warn Upozorenja (nekritična) Monitoring
error Greške koje sprečavaju rad Hitno

Podesite nivo:

export LPFR_LOG_LEVEL=debug

17.3 Važne log poruke#

Uspešno pokretanje:

NTP sync started
Smart card reader connected: HID Global OMNIKEY 3x21
TIN: 114952530, UID: EKPDW8TH, Business: Firma d.o.o.
TaxCore client initialized: https://…
Auth token acquired (…)
MRC prefix: 89-0001 (full MRC: 89-0001-EKPDW8TH)
POS HTTP server listening on 0.0.0.0:8888
Auto-update channel: prod
Initialization complete (TCP: 0.0.0.0:8888)

Problemi:

Failed to initialize smart card reader: ...          ← Čitač nije povezan
Failed to select SE applet: ...                      ← Kartica nije ubačena ili neispravna
PIN required — use status page button or POS API…    ← Čeka se unos PIN-a
Production card … has no valid license; signing blocked  ← Nedostaje licenca
Failed to submit audit: ...                          ← Problem sa internetom/TaxCore
… is deprecated; rename it to LPFR_…                 ← Koristi se stari ESDC_ naziv promenljive

17.4 GUI logovi#

Kartica Logovi u aplikaciji omogućava:

  • Praćenje logova u realnom vremenu (izvor: „Uživo")
  • Pregled istorijskih log fajlova po datumu
  • Filtriranje po nivou (DEBUG, INFO, WARN, ERROR)
  • Pretragu teksta
  • Osveži — ponovno učitavanje izabranog izvora
  • Otvori folder logova — otvara folder sa log fajlovima

18. Rešavanje problema#

18.1 Aplikacija se ne pokreće#

Simptom: "App Already Running" greška.

Rešenje:

# Proverite da li postoji proces
ps aux | grep lpfr          # Linux/macOS
tasklist | findstr lpfr     # Windows

# Ako proces ne postoji, obrišite lock fajl
rm ~/.config/harmonypos.io/lpfr/lpfr.lock    # Linux/macOS
del %APPDATA%\harmonypos.io\lpfr\lpfr.lock   # Windows

18.2 Čitač se ne detektuje#

Linux:

# Pokrenite/restartujte pcscd
sudo systemctl restart pcscd

# Proverite čitač
pcsc_scan

Windows:

  • Device Manager → Smart card readers → Uninstall i reinstall drajver

macOS:

# Restartujte smart card daemon
sudo killall -9 com.apple.ifdreader

18.3 ESIR ne može da se poveže#

  1. Proverite da li je aplikacija pokrenuta:

    curl http://localhost:8888/api/v3/attention
    
  2. Proverite port:

    netstat -tlnp | grep 8888    # Linux
    netstat -an | findstr 8888   # Windows
    lsof -i :8888                # macOS
    
  3. Proverite bind adresu — ako je localhost, ESIR na drugom računaru ne može pristupiti

  4. Ako je LPFR_API_KEY postavljen, ESIR mora slati Authorization: Bearer <ključ>; bez njega svaki zahtev vraća 401

  5. Proverite fajervol (vidi Mrežna konfiguracija)

18.4 Zakasnela revizija (4+ dana)#

  1. Proverite internet:

    curl -I https://api.taxcore.rs    # Ili vaš TaxCore URL
    
  2. Proverite da li je kartica ubačena i PIN verifikovan

  3. Pogledajte logove za greške slanja:

    grep "audit" ~/.config/harmonypos.io/lpfr/logs/lpfr-$(date +%Y-%m-%d).log
    
  4. Ako internet nije dostupan — izvršite Lokalno iščitavanje: kartica Status → odeljak Revizija → drugo dugme (spoljni disk) u redu Neophodan audit. Prvo dugme (oblak) odmah pokušava onlajn slanje.

18.5 PIN blokada#

Kartica se blokira posle 3 pogrešna pokušaja. L-PFR ne može deblokirati karticu. Potreban je PUK kod ili kontakt sa izdavaocem kartice.

18.6 Istek sertifikata#

  • Status ekran prikazuje datum isteka i preostali broj dana
  • Upozorenje se prikazuje ako je ostalo manje od 30 dana
  • Kontaktirajte nadležnu službu za zamenu kartice pre isteka

18.7 Potpisivanje je blokirano, a kartica i PIN su u redu#

Produkciona kartica bez važeće licence — u logu stoji Production card … has no valid license; signing blocked. Unesite token u dijalogu za licencu koji se prikazuje pri ubacivanju kartice, ili pokrenite probnu verziju. Test i sandbox kartice rade bez licence. Vidi Licenciranje.

18.8 Korumpirana baza#

# Proverite integritet
sqlite3 ~/.config/harmonypos.io/lpfr/lpfr.db "PRAGMA integrity_check;"

# Ako je baza korumpirana, napravite backup i resetujte
cp lpfr.db lpfr.db.backup
rm lpfr.db
# Restartujte aplikaciju — kreira se nova baza
# NAPOMENA: gube se lokalni podaci o računima i podešavanja

18.9 Provera verzije#

curl http://localhost:8888/api/v3/status | jq '.softwareVersion'

Ili u GUI-ju: kartica Status → odeljak Uređaj → Verzija softvera.

Dodatak — Lista provera za instalaciju#

Koristite ovu listu pri instalaciji L-PFR-a:

  • Instaliran čitač pametnih kartica i drajveri
  • Instaliran OpenSC (za PKCS#11 podršku)
  • Na Linux-u: pokrenut pcscd servis
  • Instaliran Harmony-LPFR (instaler ili ručno)
  • Podešen LPFR_MRC_PREFIX (ako se razlikuje od podrazumevanog)
  • Pokrenuta aplikacija i prikazan glavni prozor
  • Čitač detektovan (Status → Pametna kartica → Čitač kartice pronađen: DA)
  • Ubačena fiskalna kartica i verifikovan PIN
  • Licenca važeća za produkcionu karticu (ili se koristi test kartica)
  • Potvrđen status: zeleni indikator spremnosti
  • Konfigurisan ESIR za komunikaciju (http://{adresa}:{port})
  • ESIR uspešno poziva GET /api/v3/attention (200 OK)
  • ESIR uspešno verifikuje PIN preko POST /api/v3/pin
  • ESIR uspešno potpisuje test račun preko POST /api/v3/invoices
  • Proveren QR kod na test računu (skeniranje)
  • Fajervol dozvoljava konekciju (ako ESIR na drugom računaru)
  • Uključeno automatsko pokretanje pri prijavi (Podešavanja → Opšte)
  • Podešen LPFR_API_KEY i ESIR šalje Authorization: Bearer (ako se koristi)
  • Podešen LPFR_UPDATE_URL i kanal ažuriranja
  • Podešen LPFR_LOG_LEVEL=info (ili debug za dijagnostiku)
  • Proverena sinhronizacija vremena (NTP)
  • Provereno slanje revizorskih paketa (internet konekcija)

Autorska prava#

© 2026 One Click 2025, Novi Pazar. Sva prava zadržana.

Autorska prava na ovo uputstvo i na softver Harmony-LPFR ima HAMZA BIŠEVAC PREDUZETNIK RAČUNARSKO PROGRAMIRANJE ONE CLICK 2025 NOVI PAZAR (PIB 114952530, MB 67978943), u daljem tekstu One Click 2025. Harmony, HarmonyPOS i Harmony-LPFR su nazivi proizvoda One Click 2025.

Uputstvo smete da preuzmete, odštampate i prosledite u neizmenjenom obliku, radi rada sa Harmony-LPFR-om. Za svako drugo umnožavanje, izmenu ili objavljivanje teksta i snimaka ekrana potrebna je pismena saglasnost One Click 2025.

Kontakt: [email protected], https://harmonypos.io