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):
- Pokrenite
Harmony-LPFR-Setup-{VERZIJA}.exe - Pratite instalacioni čarobnjak — podrazumevana putanja:
C:\Program Files\Harmony-LPFR - Instaler automatski postavlja:
lpfr.exe— glavni izvršni fajlopensc-pkcs11.dll— OpenSC biblioteka za pametne karticeopensc.dll— podrška za OpenSC- Prečicu na Desktop-u i u Start meniju
- Unos u Add/Remove Programs za deinstalaciju
Ručna instalacija:
- Kopirajte
lpfr.exeu željeni folder - Instalirajte OpenSC sa https://github.com/OpenSC/OpenSC/releases
- Proverite da
opensc-pkcs11.dllpostoji uC:\Program Files\OpenSC\pkcs11\
Pokretanje:
"C:\Program Files\Harmony-LPFR\lpfr.exe"
2.2 macOS#
Pomoću DMG paketa:
- Otvorite
Harmony-LPFR-{VERZIJA}.dmg - Prevucite
Harmony-LPFR.appuApplicationsfolder - 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#
- Prozor za pokretanje sa indikatorom napretka i poslednjim porukama inicijalizacije
- Baza podataka → NTP → čitač i kartica → licenca → TaxCore → POS server
- 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/piniz 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#
- Vrednosti sačuvane u SQLite bazi (tabela
config) — najviši prioritet - Promenljive okruženja
- 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/jsoniliapplication/xml - Accept:
application/jsoniliapplication/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_KEYpostavljen, svaki zahtev bez ispravnog zaglavljaAuthorizationdobija401. Izuzete su samo stranice/docs,/openapi.json,/openapi.yamli/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
RequestIdpoš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 jetrue, potrebno je prvo verifikovati PINauditRequired—truekada je iščitavanje neophodno: revizorski paketi kasne ili je dostignut Limit iznosa na bezbednosnom elementugsc— 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
statusdogađaj ne postoji — za kompletan status pozoviteGET /api/v3/statuskada 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:clearedipin:requiredtako što ćete blokirati prodaju - Reagujte na
pin:verifiedtako š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#
- ESIR kreira
.httpfajl u./input/direktorijumu - L-PFR detektuje novi fajl (file watcher)
- Parsira HTTP zahtev iz fajla
- Obrađuje zahtev (isto kao REST API)
- Upisuje HTTP odgovor u
./output/{ime_fajla} - 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#
- Provera pri pokretanju, zatim svakih 30 minuta
- Preuzima se
<base>/<channel>/update.jsoni upoređuje verzija kanala sa tekućom - 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)
- Preuzeto se proverava prema
sha256iz manifesta pre nego što se bilo šta upiše — neproverena putanja ne postoji - Ažuriranje se primenjuje na disk, a korisniku se prikazuje obaveštenje
- 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#
Proverite da li je aplikacija pokrenuta:
curl http://localhost:8888/api/v3/attentionProverite port:
netstat -tlnp | grep 8888 # Linux netstat -an | findstr 8888 # Windows lsof -i :8888 # macOSProverite bind adresu — ako je
localhost, ESIR na drugom računaru ne može pristupitiAko je
LPFR_API_KEYpostavljen, ESIR mora slatiAuthorization: Bearer <ključ>; bez njega svaki zahtev vraća401Proverite fajervol (vidi Mrežna konfiguracija)
18.4 Zakasnela revizija (4+ dana)#
Proverite internet:
curl -I https://api.taxcore.rs # Ili vaš TaxCore URLProverite da li je kartica ubačena i PIN verifikovan
Pogledajte logove za greške slanja:
grep "audit" ~/.config/harmonypos.io/lpfr/logs/lpfr-$(date +%Y-%m-%d).logAko 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
pcscdservis - 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_KEYi ESIR šaljeAuthorization: Bearer(ako se koristi) - Podešen
LPFR_UPDATE_URLi kanal ažuriranja - Podešen
LPFR_LOG_LEVEL=info(ilidebugza 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