/Cis.Fiscalization

.NET (C#) wrapper za pozivanje fiskalizacijskog servisa porezne uprave

Primary LanguageC#MIT LicenseMIT

Fiskalizacija API (CIS)

cis version build status nuget version

Napomena: Zbog promjene u minimalnoj verziji TLS enkripcije od CIS v1.3 ova komponenta zahtjeva .NET 4.5 za komunikaciju sa serverom (detaljnije).
Zbog ove promjene izdan je novi release COM komponente v1.2.1-com.

.NET (C#) wrapper oko generiranog SOAP klijenta za pozivanje fiskalizacijskog servisa porezne uprave CIS WSDL v1.4.

Sa Microsoft Wsdl.exe tool-om su generirane proxy klase sa strukturom po WSDL shemi koja je objavljena na stranicama porezne uprave Tehničke specifikacije i koja je uključena u source kôd projekta.
Preko generiranog SOAP klijenta FiskalizacijaService se rade svi SOAP pozivi prema CIS servisu. Kompletna implementacija je u Fiscalization klasi sa dodatkom async metoda u Fiscalization.Async.cs file-u. 😄

Runtime:

  • .NET 4.5 (CIS v1.3 zahtjeva TLS v1.1 ili TLS v1.2 HTTPS enkripciju)

Testirano i sa demo certifikatom Fina okoline 2014/2015.

Postoji release .NET COM komponente sa primjerima za VBA, VBScript i Access.

Cilj projekta

  • uključiti source kôd u postojeći projekt umjesto referenciranja third party dll-a, naravno dostupan i kao NuGet package
  • jednostavan upgrade u slučaju promjene sheme CIS servisa uz compile-time check
  • svaki poziv servisa treba automatski odraditi generiranje ZKI kôda i potpisivanje, isto tako i provjeru potpisa CIS odgovora, ali imati i opcije
    Sign(ICisRequest, X509Certificate2) i GenerateZki(RacunType, X509Certificate2)
  • sve greške koje šalje CIS servis pretvoriti u Exception-e, unificirati logiranje i imati pregled svih grešaka na jednak način
  • ne parsirati raw SOAP poruke, a istovremeno omogućiti potpisivanje i logiranje raw poruka

Instalacija

Kako najjednostavnije uključiti kôd u svoj projekt?!

NuGet

Instalacijom NuGet package-a kreira se Cis folder u projektu sa source kôdom.

PM> Install-Package Cis.Fiscalization

Nuget screenshot

Copy

Dovoljno je iskopirati FiskalizacijaService.cs, Fiscalization.cs i/ili Fiscalization.Async.cs.

API

Sastoji od dvije glavne metode (u dva okusa async i sync) za slanje podataka na servis

public static class Fiscalization
{
    // Async .NET 4.5 :: Fiscalization.Async.cs
    Task<RacunOdgovor> SendInvoiceAsync(RacunType invoice, X509Certificate2 cert);
    Task<ProvjeraOdgovor> CheckInvoiceAsync(RacunType invoice, X509Certificate2 cert)

    // Sync :: Fiscalization.cs
    RacunOdgovor SendInvoice(RacunType invoice, X509Certificate2 cert);
    ProvjeraOdgovor CheckInvoice(RacunType invoice, X509Certificate2 cert);
}

Svaka metoda još opcionalno prima funkciju Action<FiskalizacijaService> za postavljanje parametara generiranoj proxy klasi FiskalizacijaService (npr. url, timeout...).

Za RacunType, RacunOdgovor, ProvjeraOdgovor i ostale generirane proxy klase vidi source FiskalizacijaService.cs.

Primjer poziva servisa za slanje računa

// Kreiranje računa za za fiskalizaciju
var invoice = new RacunType()
{
    BrRac = new BrojRacunaType()
    {
        BrOznRac = "1",
        OznPosPr = "1",
        OznNapUr = "1"
    },
    DatVrijeme = DateTime.Now.ToString(Fiscalization.DATE_FORMAT_LONG),
    IznosUkupno = 3.ToString("N2", CultureInfo.InvariantCulture),
    NacinPlac = NacinPlacanjaType.G,
    NakDost = false,
    Oib = oib,
    OibOper = "98642375382",
    OznSlijed = OznakaSlijednostiType.N,
    Pdv = new[]
    {
        new PorezType
        {
            Stopa = 25.ToString("N2", CultureInfo.InvariantCulture),
            Osnovica = 2.34.ToString("N2", CultureInfo.InvariantCulture),
            Iznos = .56.ToString("N2", CultureInfo.InvariantCulture)
        }
    },
    USustPdv = true
};

X509Certificate2 certificate = ...;

// Generiraj ZKI, potpiši, pošalji račun i provjeri potpis CIS odgovora
RacunOdgovor response = await Fiscalization.SendInvoiceAsync(invoice, certificate);

// Odgovor sa JIR-om i zahtjevom (sa header podacima, potpisom) i poslanim računom
string jir = response.Jir;
RacunZahtjev request = (RacunZahtjev)response.Request; // ICisRequest
var isTrue = request.Racun == invoice;

// ili dodatno sa postavljanjem opcija
// fs == instanca generirane proxy klase FiskalizacijaService
RacunOdgovor response = await Fiscalization.SendInvoiceAsync(invoice, certificate, fs =>
{
    // SOAP service settings
    // Change service URL
    // default = Fiscalization.SERVICE_URL_PRODUCTION
    fs.Url = Fiscalization.SERVICE_URL_DEMO;

    // Set request timeout in miliseconds
    // default = 100s
    fs.Timeout = 2000;

    // Set response signature checking
    // default = true
    fs.CheckResponseSignature = true;
});

CIS v1.3 - TLS v1.1 & TLS v1.2

Od CIS v1.3 verzija protokola za enkripciju preko HTTPS-a je TLS v1.1 ili TLS v1.2.

Ova komponenta koristi System.Net za komunikaciju u kojoj su ti protokoli podržani od .NET 4.5 verzije. .NET 4.6 ima default postavljenu verziju TLS 1.2 dok .NET 4.5 nema pa se to može napraviti na sljedeći način:

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;

Logiranje raw SOAP poruka

Logiranje se radi preko implementacije partial metode na FiskalizacijaService klasi. Par linija kôda govori 1000 riječi - odlazna i dolazna SOAP poruka kao XmlDocument.

Ovako bi mogao izgledati trace ili file logger

// MyCisLogger.cs
// Implementacija mora biti u projektu gdje i Cis.FiskalizacijaService klasa
namespace Cis
{
    public partial class FiskalizacijaService
    {
        partial void LogResponseRaw(XmlDocument request, XmlDocument response)
        {
            // Trace logger
            Trace.WriteLine(request.OuterXml);
            Trace.WriteLine(response.OuterXml);

            // File logger
            File.AppendAllText(logFileName, request.OuterXml, Encoding.UTF8);
            File.AppendAllText(logFileName, response.OuterXml, Encoding.UTF8);
        }
    }
}

Testiranje

U test projektu je TestEnvironment klasa koja učitava demo certifikat koji nije uključen u projekt; moguće je

  • u source-u specificirati OIB, putanju do certifikata (.pfx), lozinku i/ili
  • postaviti FIS_OIB, CERT_BASE64 i CERT_PWD environment varijable
SET FIS_OIB=<OIB poslovnog subjekta>
SET CERT_BASE64=<certifikat poslovnog subjekta kao base64 enkodirani string>
SET CERT_PWD=<lozinka certifikata>

start Fiscalization.sln

License

The MIT License (MIT)