Idi na tekst

Integracija↵

Integracija funkcionalnost CRF servisa u druge informacione sisteme postiže se upotrebom CRF REST servisa (RCRF).

Napomena

Ciljna grupa za informacije iz ovog dokumenta su IT profesionalci. Informacije nisu od značaja za ostale učesnike sistema.

Napomena

U svrhu implementacije i lakšeg testiranja eksternih integrativnih servisa, podignuto je i stavljeno u funkciju javno testno okruženje CRF REST servisa, dostupno na adresi https://crfrtest.trezor.gov.rs. Servisi javnog testnog okruženja su funkcionalno identični produkcionim servisima (što ne uljučuje korisničke podatke) i potrebno ih je koristiti u ranim fazama integracije, obzirom da je masovan unos testnih podataka na produkcione servise zabranjen.

JSON Standardizacija↵

Napomena

Nakon nadogradnje servisa za 2020, prestala je podrška za stari tip serijalizacije JSON objekata.

Podrška za implicitnu konverziju tekstualnih tipova u okviru JSON objekta više nije omogućena. Stoga je neohpodno doslovce pratiti specifikaciju o integraciji kada se radi o tipovima podataka prosleđenim servisu.

Primer nevalidnog zahteva

$invoices = @(
    @{
        DebtorCompanyNumber = '10523'
        InvoiceNumber       = 'Racun 18/01'
        Amount              = '1001'
        IssueDate           = '2018-02-28'
        Comments            = 'Komentar 1'
    }
    @{
        DebtorCompanyNumber = '10523'
        InvoiceNumber       = 'Racun 18/02'
        Amount              = '1002.33'
        IssueDate           = '2018-02-28'
        Comments            = 'Komentar 2'
        Lifetime            = '88'
    }
) | ConvertTo-Json

irm "https://rcrf.trezor.gov.rs/api/invoice/register" @params -Body $invoices

Stara instanca JSON serijalizacije je u ovom slučaju propuštala zahtev, obzirom da je implicitna konverzija tekstualnih tipova prevodila vrednosti Amount i Lifetime iz string tipa u očekivane decimal, odnosno integer vrednosti. Aktuelna verzija servisa u ovom zahtevu eksplicitno očekuje tipove decimal i integer i vratiće odgovarajuću grešku o serijalizaciji, ukoliko taj kriterijum nije ispunjen.

Primer validnog zahteva

$invoices = @(
    @{
        DebtorCompanyNumber = '10523'
        InvoiceNumber       = 'Racun 18/01'
        Amount              = 1001
        IssueDate           = '2018-02-28'
        Comments            = 'Komentar 1'
    }
    @{
        DebtorCompanyNumber = '10523'
        InvoiceNumber       = 'Racun 18/02'
        Amount              = 1002.33
        IssueDate           = '2018-02-28'
        Comments            = 'Komentar 2'
        Lifetime            = 88
    }
) | ConvertTo-Json

irm "https://rcrf.trezor.gov.rs/api/invoice/register" @params -Body $invoices

Pristup↵

API funkcijama se pristupa preko adrese https://rcrf.trezor.gov.rs. Svaki poziv ima prefiks api i opciono verziju u putanji vX.Y:

  • /api/invoice/register
    Poziva poslednju verziju funkcije.
  • /api/v1.1/invoice/register
    Poziva verziju 1.1 funkcije.

Zaglavlje rezultata svakog poziva sadrži atribut api-supported-versions koji lista sve raspoložive verzije funkcije. Poslednja verzija API-ja je dodatno označena sufiksom current, npr. 1.1-current.

Neaktuelne verzije API-ja zastarevaju (eng: deprecation) i biće uklonjene. Uklanjanje se neće vršiti ranije od 3 meseca od trenutka raspoloživosti nove verzije.

Primer validnog zahteva:

curl "https://rcrf.trezor.gov.rs/api/login/ping"                # CLI
Invoke-RestMethod "https://rcrf.trezor.gov.rs/api/login/ping"   # Powershell

PowerShell napomena

U Microsoft PowerShell (do verzije 5), curl je alijas na Invoke-WebRequest koji nema iste parametre kao i curl.exe, native CLI aplikacija. U ovom kontekstu potrebno je dodati ekstenziju prilikom poziva - curl.exe.

API koristi JSON format za razmenu podatka i osim ako je drugačije napomenuto, ContentType za svaki request je application/json. Većina funkcija vraća rezultat kao atribute payload objekta.

Upozorenje

Postoji maksimalna frekvencija upotrebe svake konkretne funkcije RCRF servisa (eng: Rate Limiter).

Na primer, neke funkcije je moguće koristiti maksimalno jednom u sekundi.

Navedeni primeri korišćenja zahtevaju minimalno PowerShell 3+ (provera lokalne verzije: $host.Version.Major -gt 3) koji dolazi preinstaliran na Windows 10 operativnom sistemu a može se instalirati i na Unix-like sistemima.

Autentikacija i autorizacija↵

Pristup sistemu zahteva autentikaciju. Pristup funkcionalnostima zahteva odgovarajuća aplikativna prava (autorizaciju).

RCRF koristi JWT1 standard za autentikaciju i autorizaciju. Pristup se ostvaruje preuzimanjem access tokena pozivom /api/login funkcije. Poziv svih drugih funkcija zahteva da u zaglavlju (eng: Headers) postoji Authorization atribut sa vrednošću Bearer <accessToken>.

Poruke o greškama koje se javljaju kod pristupa API funkcijama usled neodgovarajuće autentikacije ili autorizacije su:

Code Message Opis
401 Unauthenticated Korisnik nije autentikovan
403 Unauthorized Korisnik nema odgovarajuće ovlašćenje za korišćenje funkcionalnosti

/api/login↵

Preuzimanje pristupnog token koristeći korisnički nalog i lozinku.

Metod
POST
Atributi
login [string]
Korisnički nalog
password [string]
Korisnička lozinka
Rezultat
{creationTime, accessToken, refreshToken}
Primer poziva u PowerShell-u

$params = @{
    Method      = 'Post'
    Uri         = "https://rcrf.trezor.gov.rs/api/login"
    ContentType = 'application/json'
    Body        = @{ login = 'foo'; password = 'bar' } | ConvertTo-Json
}
Invoke-RestMethod @params
Izlaz
{
    "creationTime":  "2018-02-23T21:00:30.5262037+01:00",
    "accessToken":   "eyJ1ba1A3jdeC0....",
    "refreshToken":  "eyJ1bmlxdWVfbm...."
}

Ograničenja

Ograničenje Vrednost Komentar
Maksimalni broj neuspelih prijava 3 Pristup korisniku se blokira na 1 minut
Vreme trajanja accessToken-a u minutima 20

/api/login/refresh↵

Generisanje i preuzimanje JWT tokena pomoću refresh tokena generisanog prilikom poziva login funkcije.

Metod
GET
Rezultat
{creationTime, accessToken, refreshToken}
Primer poziva u PowerShell-u

$params = @{
    Method      = 'Get'
    Uri         = "https://rcrf.trezor.gov.rs/api/login/refresh"
    ContentType = 'application/json'
    Headers = @{Authorization = "Bearer $refreshToken"}
}
Invoke-RestMethod @params
Izlaz
{
    "creationTime":  "2018-02-23T21:00:30.5262037+01:00",
    "accessToken":   "eyJ1ba1A3jdeC0....",
    "refreshToken":  "eyJ1bmlxdWVfbm...."
}

Workflow autentikacije↵

Kako bi se krajnjem korisniku obezbedio nesmetan rad na servisu, kao i smanjio nepotreban broj poziva ka servisu, JWT pristup obezbeđuje mehanizam kontinualnog pristupa zaštićenim funkcijama upotrebom refresh workflow-a.

Inicijalnim pozivom pozivom /api/login javne pristupne tačke, sadržaj povratnog paketa uspešnog zahteva će sadržati polja:

  • accessToken - pristupni token kratkoročne validnosti - 20 minuta,
  • refreshToken - dugoročni token

Pristupni access token omogućava neposredno pozivanje zaštićenih funkcija u toku trajanja access sesije (20 minuta). Nakon isteka sesije, pozivi zaštićenih funkcija servisa sa istim access tokenom će rezultovati greškom 401 - Unauthorized.

Kako bi se izbegla potreba za ponovnim slanjem korisničkih kredencijala, postavljanjem Authorization atributa na vrednost Bearer <refreshToken> i pozivom refresh funkcije, omogućeno je pribavljanje novog aktivnog access tokena i time nastavljen neometan rad krajnjeg korisnika u trajanju nove access sesije.

Rezime workflow-a

  1. Pribavljanje access i refresh tokena pozivom login funkcije sa korisničkim kredencijalima,
  2. Rad sa zaštićenim funkcijama servisa upotrebom access tokena u trajanju kratkoročne sesije,
  3. Nakon isteka kratkoročne sesije, poziv zaštićene funkcije rezultuje greškom 401 - Unauthorized,
  4. Pribavljanje validnog access tokena pozivom refresh funkcije upotrebom refresh tokena,
  5. Nastavak rada sa zaštićenim funkcijama servisa upotrebom novog validnog access tokena

API↵

Verzija: 1.1

Funcija Opis
invoice/<idf> Detalji konkretne fakture
invoice/paged-liabilities Grupni pregled faktura
invoice/register Registrovanje jedne ili više faktura
invoice/assign Kreiranje asigancije
invoice/cancel Otkazivanje jedne ili više faktura
invoice/cancel-assign Otkazivanje asignacije
invoice/change-amount Izmena iznosa
invoice/revert-amount Otkaz izmene iznosa
invoice/validate Testiranje izmirenja fakture
invoice/settlement/register-user-settlement Korisničko izmirenja fakture

/api/invoice/<idf>↵

Detalji konkretne fakture.

Metod
GET
Rezultat
invoice [object]
JSON objekat koji sadrži sve detalje fakture
Primer poziva u PowerShell-u
irm "https://rcrf.trezor.gov.rs/api/invoice/285F" -Headers @{Authorization = "Bearer $accessToken"}
{
"status":  {
               "message":  "Success",
               "code":  0
           },
"liability":  {
                "id":  2309,
                "createdId":  2550,
                "invoiceId":  "285F",
                "creditorId":  1618,
                "creditorName":  "Specijalna bolnica za ...",
                "creditorCompanyNumber":  "17512579",
                "creditorTaxIdNumber":  "103079070",
                "debtorName":  "MF-UPRAVA ZA TREZOR",
                "debtorCompanyNumber":  "10523",
                "invoiceNumber":  "Racun 18/02",
                "issueDate":  "2018-02-23T12:48:00",
                "creationDate":  "2018-02-23T12:48:56.5633333",
                "importDate":  "2018-02-26T12:48:56.5633333",
                "dueDate":  "2018-04-27T12:48:56.5633333",
                "amount":  1000.00,
                "settledAmount":  0.00,
                "status":  1,
                "settled":  false,
              ...
            }

Statusi fakture

Vrednost Status Opis
1 Aktivna Aktivna registrovana faktura
2 Nevalidna Faktura je odbijena od strane dužnika - dostupno samo za eFakture
3 Otkazana Fakturu je otkazao poverilac
4 Delimično izmirena Faktura je delimično izmirena u parcijalnom iznosu
5 Izmirena Faktura je izmirena
6 Asignirana Dužnik je asignirao fakturu drugom dužniku
7 Profaktura Profaktura

/api/invoice/paged-liabilities↵

Grupni pregled faktura sa paginacijom, filtriranjem i sortiranjem. Zahtev implementira standardizovan query parametarski model pretrage. Odgovor je niz invoice objekata.

Metod
Get
Parametri
debtorCompanyNumber [string]
JBKJS dužnika
creditorName [string]
Naziv poverioca
debtorName [string]
Naziv dužnika
side [string]
Pretraga dužnika/poverilaca, vrednosti debtor, creditor
formattedInvoiceNumber [string]
Broj fakture
amount [decimal]
Iznos
settledAmount [decimal]
Izmireni iznos
status [int]
Status fakture
creationDate [string]
Datum kreiranja, YYYY-MM-DD format
dueDate [string]
Zakonski rok izmirenja, YYYY-MM-DD format
currentPageSize [int]
Broj faktura po paginaciji
currentPage [int]
Strana paginacije

Napomena

Obavezno je navesti parametar side, kako bi se utvrdila strana pretrage. Za datumske i parametre sa iznosima, neophodno je dodati sufiks -from ili -to‚ kako bi se označio početak odnosno kraj opsega, npr. settledAmount-from.

Rezultat
invoice [object]
Niz JSON objekata sa informacijama o fakturi.
Primer poziva u PowerShell-u
$Page    = 1
$PerPage = 5
$Side    = 'debtor'
$QueryParams = @{
    debtorCompanyNumber = '10523'
    "amount-From"       = 10
    "amount-To"         = 1000
} 

$query = $QueryParams.GetEnumerator() | % { 'filter[{0}]={1}' -f $_.Key, $_.Value }
$params = @{
    Uri     = "https://rcrf.trezor.gov.rs/api/invoice/paged-liabilities?$($query -join '&')&page=$Page&perPage=$PerPage&side=$Side"
    Headers = @{Authorization = "Bearer $accessToken"}
}
Invoke-RestMethod @params
Primer sirovog query upita
invoice/paged-liabilities?filter%5Bside%5D=creditor&filter%5BdebtorCompanyNumber%5D=10523&perPage=5&side=creditor

Ograničenja

Ograničenje Vrednost Komentar
currentPageSize 50 Maksimalni broj faktura po upitu

/api/invoice/register↵

Registrovanje jedne ili više faktura. Telo zahteva je niz invoice objekata.

Metod
Post
Atributi fakture
DebtorCompanyNumber [string]
JBKJS dužnika
InvoiceNumber [string]
Broj fakture
Amount [decimal]
Iznos
IssueDate [string]
Datum izdavanja, YYYY-MM-DD format
Comments [string]
Komentar (opciono)
Lifetime [integer]
Rok važenja profakture (opciono - ako postoji objekat se tretira kao profaktura)
Rezultat
v1.0 - IDFList [string[]]
Niz IDF brojeva u istom redosledu kao i ulazne fakture
v1.1 - Result [object[]]
Niz JSON objekata od kojih svaki sadrži 2 JSON objekta - liability i liabilityError pri čemu je drugi null ukoliko faktura nema grešaka.
Primer poziva u PowerShell-u

Prikazuje registrovanje jedne fakture i jedne profakture.

$invoices = @(
    @{
        DebtorCompanyNumber = '10523'
        InvoiceNumber       = 'Racun 18/01'
        Amount              = 1001
        IssueDate           = '2018-02-28'
        Comments            = 'Komentar 1'
    }
    @{
        DebtorCompanyNumber = '10523'
        InvoiceNumber       = 'Racun 18/02'
        Amount              = 1002.33
        IssueDate           = '2018-02-28'
        Comments            = 'Komentar 2'
        Lifetime            = 88
    }
) | ConvertTo-Json

irm "https://rcrf.trezor.gov.rs/api/invoice/register" @params -Body $invoices

Ograničenja

Ograničenje Vrednost Komentar
Maksimalni broj zahteva u sekundi 1
Maksimalni broj faktura po zahtevu 1000
Maksimalni broj faktura u toku meseca 30.000 podrazumevani, veći se može dobiti po zahtevu UT

/api/invoice/assign↵

Kreiranje asignacije.

Metod
Post
Atributi
InvoiceID [string]
IDF fakture
AssignmentContractNumber [string]
JBKJS asignatora
DebtorCompanyNumber [string]
JBKJS asignanta (novog dužnika)

/api/invoice/cancel↵

Otkazivanje jedne ili više faktura. Telo zahteva je niz objekata otkaza.

Metod
Post
Atributi otkaza
invoiceId [string]
IDF fakture koju treba otkazati
cancelComments [string]
Komentar otkaza

/api/invoice/cancel-assign↵

Otkazivanje asignacije.

Metod
Post
Atributi
invoiceId [string]
IDF asignirane fakture za koju treba otkazati asignaciju

/api/invoice/change-amount↵

Izmena iznosa konkretne fakture

Metod
Post
Atributi
invoiceId [string]
IDF fakture
amount [decimal]
Iznos izmene
comments [string]
Komentar
Rezultat
id [integer]
Identifikator izmene iznosa

/api/invoice/revert-amount↵

Otkaz izmene iznosa konkretne fakture

Metod
Post
Atributi
id [integer]
Identifikator izmene iznosa
cancelComments [string]
Komentar

/api/invoice/validate↵

Testiranje izmirenja jedne ili više faktura koristeći elemente naloga za prenos. Telo zahteva je niz settlement objekata.

Izmirenje se ne smatra validnim ako bilo šta od navedenih stavki nije zadovoljeno:

  1. nije moguće identifikovati fakturu koja se odnosi na datog poverioca (MB,PIB) i dužnika (JBKJS) sa datim pozivom na broj odobrenja (PBO) (set ovih atributa jednoznačno određuje fakturu i može se koristiti umesto IDF-a); KJS se može identifikovati upotrebom MB/PIB kombinacije ako je jedinstvena odnosno JBKJS/PIB kombinacijom. Ukoliko prosleđeni MB/PIB odgovara više KJS
  2. atribut settledAmount (sr: Izmireni iznos) premašuje preostali iznos na fakturi
  3. faktura je već zatvorena (izmirena ili otkazana)

Ukoliko je testiranje izmirenja uspešno, korisnik među podacima dobija IDF odgovarajuće fakture.

Atributi identifikacije poverioca - PIB i MB - moraju da budu asocirani sa računom odobrenja u RIR NBS. Funkcija ne radi ovu kontrolu i odgovornost korisnika je da ovo proveri - ukoliko se prilikom obrade naloga u platnom prometu UT ispostavi da nije tako, nalog će biti odbijen.

Metod
Post
Atributi izmirenja
debtorCompanyNumber [string]
Identifikator dužnika - JBKJS
creditorCompanyNumber [string]
Identifikator poverioca - MB ili JBKJS
creditorTaxIdNumber [string]
Poreski identifikator poverioca - PIB
invoiceNumber [string]
Broj fakture, ne mora biti prečišćen od simbola već kao na nalogu za prenos u polju PBO
settledAmount [decimal]
Iznos izmirenja koji se testira
bank [string]
Broj banke, trenutno jedino 840
Rezultat
Result [object]
Rezultat sadrži 2 objekta, settlement i settlementError. Validacija je uspešna ako settlementError == null, inače objekat settlement sadrži IDF (invoiceId)

Ograničenja:

Ograničenje Vrednost
Maksimalni broj zahteva u sekundi 10
Maksimalni broj faktura po zahtevu 1000

/api/invoice/settlement/register-user-settlement↵

Korisničko izmirenja jedne ili više faktura koristeći elemente naloga za prenos. Telo zahteva je niz settlement objekata.

Korisničko izmirenje se neće realizovati ako bilo šta od navedenih stavki nije zadovoljeno:

  1. nije moguće identifikovati fakturu na osnovu dostavljenog identifikatora fakture
  2. atribut settledAmount (sr: Izmireni iznos) premašuje preostali iznos na fakturi
  3. faktura je već zatvorena (izmirena ili otkazana)
Metod
Post
Atributi izmirenja
invoiceId [string]
Identifikator fakture
settledAmount [decimal]
Iznos izmirenja
settlementDate [string]
Datum izmirenja
bank [string]
Broj (šifra) banke
debitAccount [string]
Račun zaduženja na nalogu za prenos izmirenja
creditAccount [string]
Račun odobrenja na nalogu za prenos izmirenja
referenceNumber [string]
Referenca realizovanog plaćanja
isCompensationSettlement [bool]
Izmirenje je kompenzacija (da/ne)
Rezultat
Result [object]
Rezultat sadrži 2 objekta, settlement i settlementError. Registrovanje korisničkog izmirenja je uspešno ako je settlementError == null.

Ograničenja:

Ograničenje Vrednost
Maksimalni broj zahteva u sekundi 10
Maksimalni broj izmirenja po zahtevu 1000

Elementi koji se niza izmirenja, koji se šalju API metodi, moraju da zadovolje ista poslovna pravila kao i prilikom učitavanja struktuiranog fajla za korisničko izmirenje.