/nav-online-invoice

A PHP interface for Online Invoice Data Reporting System of Hungarian Tax Office (NAV)

Primary LanguagePHPMIT LicenseMIT

NAV Online Invoice reporter

PHP interface for Online Invoice Data Reporting System of Hungarian Tax Office (NAV)

PHP interfész a NAV Online számla adatszolgáltatásához

Letöltés:

🔥 v3.0-ás API támogatás 🔥

A modul ezen verziója a NAV v3.0-ás API-ját támogatja. v2.0-ás API támogatáshoz használd a korábbi, v2.x verziót.

ℹ️ Frissítés v3.0-ás API-ra

Kattints ide a leírás megjelenítéséhez!

v3.0-ás nav-online-invoice modulra történő frissítés után - a modult érintően - csak az URL-t kell átírnod v3-asra, más teendőd nincs, de ajánlott elolvasni az itt lévő változásokat:

  • NavOnlineInvoice\Config példányosításakor:

    • apiUrl a következőre változott: https://api-test.onlineszamla.nav.gov.hu/invoiceService/v3, illetve "-test" rész nélkül éles környezetben,
    • Esetleg használhatod a beépített NavOnlineInvoice\Config::TEST_URL és NavOnlineInvoice\Config::PROD_URL változókat, így a jövőben nem kell bajlódni az URL átírásával,
  • Változások:

    • A boríték XML-ből a namespace-eket automatikusan törli a modul, erről (és segédletről a namespace-ekhez) itt találsz leírást: XML namespace-ek.
    • Elektronikus számlázásról (electronicInvoiceHash és completenessIndicator) lásd a manageInvoice_electronic_invoice.php példafájlt és az Elektronikus számlázás támogatása leírást.
    • ⚠️ Config osztályban a $verifySSL értéke alapértelmezetten true lett, így ha bármi rosszul beállított certificate miatt nem kapcsolódna a modul a NAV-hoz ("Connection error. CURL error code: 60" hibát kapnál), $config->verifySSL = false;-ra állításával ki tudod kapcsolni a cURL-ben az SSL ellenőrzést.
    • $reporter->getLastRequestData()-en belül a lastRequestId át lett nevezve requestId-ra.
  • Új funkció a nav-online-invoice modulban:

    • $reporter->getLastResponseXml() metódus, mely visszaadja az utolsó válasz XML-t (ez a namespace nélküli változat, lásd XML namespace-ek).

Ha ezekkel megvagy, akkor már csak az adatsémákat kell átírnod, melyhez segítséget a NAV-os dokumentációkban, illetve fórumokon találsz, de ha megpróbálod beküldeni a régi adat XML-t, akkor az interfész is ki fogja írni a sémavalidálási hibát. NAV-os changelog: CHANGELOG_3.0


Tartalom

Használat

A használathoz a NAV oldalán megfelelő regisztrációt követően létrehozott technikai felhasználó adatainak beállítása szükséges!

Inicializálás

Technikai felhasználó és szoftver adatok beállítása, Reporter példány létrehozása:

$userData = array(
    "login" => "username",
    "password" => "password",
    // "passwordHash" => "...", // Opcionális, a jelszó már SHA512 hashelt változata. Amennyiben létezik ez a változó, akkor az authentikáció során ezt használja
    "taxNumber" => "12345678",
    "signKey" => "sign-key",
    "exchangeKey" => "exchange-key",
);

$softwareData = array(
    "softwareId" => "123456789123456789",
    "softwareName" => "string",
    "softwareOperation" => "ONLINE_SERVICE",
    "softwareMainVersion" => "string",
    "softwareDevName" => "string",
    "softwareDevContact" => "string",
    "softwareDevCountryCode" => "HU",
    "softwareDevTaxNumber" => "string",
);

$apiUrl = "https://api-test.onlineszamla.nav.gov.hu/invoiceService/v3";

$config = new NavOnlineInvoice\Config($apiUrl, $userData, $softwareData);
$config->setCurlTimeout(70); // 70 másodperces cURL timeout (NAV szerver hívásnál), opcionális

// "Connection error. CURL error code: 60" hiba esetén add hozzá a következő sort:
// $config->verifySSL = false;

$reporter = new NavOnlineInvoice\Reporter($config);

Adószám ellenőrzése (queryTaxpayer)

A modul automatikusan eltávolítja a namespace-eket a válasz XML-ből (lásd XML namespace-ek), így kényelmesebben használható az XML válasz.

try {
    $result = $reporter->queryTaxpayer("12345678");

    if ($result) {
        print "Az adószám valid.\n";
        print "Az adószámhoz tartozó név: $result->taxpayerName\n";

        print "További lehetséges információk az adózóról:\n";
        print_r($result->taxpayerShortName);
        print_r($result->taxNumberDetail);
        print_r($result->vatGroupMembership);
        print_r($result->taxpayerAddressList);
    } else {
        print "Az adószám nem valid.";
    }

} catch(Exception $ex) {
    print get_class($ex) . ": " . $ex->getMessage();
}

Token kérése (tokenExchange)

Ezt a metódust célszerű használni a technikai felhasználó adatainak (és a program) tesztelésére is.

try {
    $token = $reporter->tokenExchange();
    print "Token: " . $token;

} catch(Exception $ex) {
    print get_class($ex) . ": " . $ex->getMessage();
}

Adatszolgáltatás (manageInvoice)

Új, módosító és sztornó számla beküldésére.

try {
    // Az $invoiceXml tartalmazza a számla (szakmai) SimpleXMLElement objektumot

    $transactionId = $reporter->manageInvoice($invoiceXml, "CREATE");

    print "Tranzakciós azonosító a státusz lekérdezéshez: " . $transactionId;

} catch(Exception $ex) {
    print get_class($ex) . ": " . $ex->getMessage();
}

Az adatszolgáltatás metódus automatikusan lekéri a tokent is (tokenExchange), így ezt nem kell külön megtenni.

Módosító vagy sztornó számlához használd a "MODIFY" és "STORNO" értéket a második paraméterben.

Több számla egyszerre való feladásához lásd a manageInvoice_multiple.php példát.

Elektronikus számlázásról (electronicInvoiceHash és completenessIndicator) lásd a manageInvoice_electronic_invoice.php példafájlt és az Elektronikus számlázás támogatása leírást.

ℹ️ Oké, beküldtem a számlát, de mit csináljak Exception esetén? ⁉️

  • Ha NavOnlineInvoice\XsdValidationError Exception-t kaptál, akkor valamelyik XML-ben lesz hiba! Lehet a szakmai (számla) XML hibás (bár ezt már számlakészítéskor is célszerű ellenőrizni), de a boríték XML is lehet hibás (pl. megadtad a software adatokat, de rossz a formátuma). Fontos megjegyezni, hogy ez az Exception még a küldés előtt jön a nav-online-invoice által generálva.
  • Ha NavOnlineInvoice\CurlError vagy NavOnlineInvoice\HttpResponseError Exception-t kaptál, akkor mindenképp próbáld újraküldeni a számlát pár perc múlva, mert lehet csak épp nincs interneted, vagy a NAV szervere nem elérhető/furcsaságokat válaszol.
  • Ha NavOnlineInvoice\GeneralErrorResponse vagy NavOnlineInvoice\GeneralExceptionResponse az Exception, akkor a NAV válaszolt egy XML üzenettel, viszont ebben - az Exception típusának megfelelő típusú - hibaüzenet volt. Mind a kettő exception esetén az errorCode az $ex->getErrorCode() metódussal lekérhető, melyek értelmezését megtaláljuk a NAV által kiadott interfész specifikációban. Ugyan nem minden hibakód esetén, de az esetek többségében itt is érdemes próbálkozni az újraküldéssel.
  • Más egyéb Exception esetén (NavOnlineInvoice\GeneralExceptionResponse, NavOnlineInvoice\GeneralErrorResponse és \Exception) valószínűleg felesleges az újra próbálkozás, naplózd és ellenőrizd a hibaüzenetet ($ex->getMessage())!

Technikai érvénytelenítés (manageAnnulment)

Technikai érvénytelenítés beküldése.

try {
    // Az $annulmentXml tartalmazza a technikai érvénytelenítést tartalmazó SimpleXMLElement objektumot

    $transactionId = $reporter->manageAnnulment($annulmentXml);

    print "Tranzakciós azonosító a státusz lekérdezéshez: " . $transactionId;

} catch(Exception $ex) {
    print get_class($ex) . ": " . $ex->getMessage();
}

Státusz lekérdezése (queryTransactionStatus)

Státusz lekérdezése a manageInvoice és manageAnnulment operációkhoz.

try {
    $transactionId = "...";
    $statusXml = $reporter->queryTransactionStatus($transactionId);

    print "Válasz XML objektum:\n";
    var_dump($statusXml);

} catch(Exception $ex) {
    print get_class($ex) . ": " . $ex->getMessage();
}

Számla lekérdezése (queryInvoiceData)

Számla lekérdezése számlaszám alapján, mely kiállító és vevő oldalról is használható. Második paraméterben true-t átadva a metódus a dekódolt számla XML-t adja vissza invoiceDataResult helyett.

try {
    $invoiceNumberQuery = [
        "invoiceNumber" => "T20190001",
        "invoiceDirection" => "OUTBOUND",
    ];

    // Lekérdezés
    $invoiceDataResult = $reporter->queryInvoiceData($invoiceNumberQuery);

    print "Query results XML elem:\n";
    var_dump($invoiceDataResult);

    // Számla kézi dekódolása
    $invoice = NavOnlineInvoice\InvoiceOperations::convertToXml($invoiceDataResult->invoiceData, $invoiceDataResult->compressedContentIndicator);

    // Számla:
    var_dump($invoice);

    // *** VAGY ***

    // Lekérdezés és számla automatikus dekódolása
    $invoice = $reporter->queryInvoiceData($invoiceNumberQuery, true); // 2. paraméter jelzi az automatikus dekódolást

    // Számla:
    var_dump($invoice);

} catch(Exception $ex) {
    print get_class($ex) . ": " . $ex->getMessage();
}

Számla keresése (queryInvoiceDigest)

Lekérdező operáció, mely kiállító és vevő oldalról is használható.

try {
    $invoiceQueryParams = [
        "mandatoryQueryParams" => [
            "invoiceIssueDate" => [
                "dateFrom" => "2021-01-01",
                "dateTo" => "2021-01-11",
            ],
        ],
        "relationalQueryParams" => [
            "invoiceDelivery" => [
                "queryOperator" => "GTE",
                "queryValue" => "2021-01-01",
            ],
            // Több feltétel esetén ugyanazon elemhez tömbben adjuk át a gyerek elemeket
            "paymentDate" => [
                [
                    "queryOperator" => "GTE",
                    "queryValue" => "2021-01-01",
                ],
                [
                    "queryOperator" => "LTE",
                    "queryValue" => "2021-01-28",
                ],
            ],
        ],
    ];

    $page = 1;

    $invoiceDigestResult = $reporter->queryInvoiceDigest($invoiceQueryParams, $page, "OUTBOUND");

    print "Query results XML elem:\n";
    var_dump($invoiceDigestResult);

} catch(Exception $ex) {
    print get_class($ex) . ": " . $ex->getMessage();
}

Tranzakciók lekérése (queryTransactionList)

A kérésben megadott időintervallumban, a technikai felhasználóhoz tartozó adószámhoz beküldött számlaadat-szolgáltatások listázására szolgál.

try {
    $config = new NavOnlineInvoice\Config($apiUrl, $userData, $softwareData);
    $reporter = new NavOnlineInvoice\Reporter($config);

    $insDate = [
        "dateTimeFrom" => "2020-03-01T06:00:00Z",
        "dateTimeTo" => "2020-03-05T18:00:00Z",
    ];
    $page = 1;

    $transactionListResult = $reporter->queryTransactionList($insDate, $page);

    print "Result:\n";
    print_r($transactionListResult);

} catch(Exception $ex) {
    print get_class($ex) . ": " . $ex->getMessage();
}

Számlalánc lekérése (queryInvoiceChainDigest)

A queryInvoiceChainDigest egy számlaszám alapján működő lekérdező operáció, amely a számlán szereplő kiállító és a vevő oldaláról is használható. Az operáció a megadott keresőfeltételeknek megfelelő, lapozható számlalistát ad vissza a válaszban. A lista elemei a megadott alapszámlához tartozó számlalánc elemei. A válasz nem tartalmazza a számlák összes üzleti adatát, hanem csak egy kivonatot (digest-et), elsősorban a módosításra és tételsorok számára vonatkozóan.

try {
    $config = new NavOnlineInvoice\Config($apiUrl, $userData, $softwareData);
    $reporter = new NavOnlineInvoice\Reporter($config);

    $invoiceChainQuery = [
        "invoiceNumber" => "SZML-123",
        "invoiceDirection" => "OUTBOUND", // OUTBOUND or INBOUND
        "taxNumber" => "12345678", // optional
    ];
    $page = 1;

    $invoiceChainDigestResult = $reporter->queryInvoiceChainDigest($invoiceChainQuery, $page);

    print "Result:\n";
    print_r($invoiceChainDigestResult);

} catch(Exception $ex) {
    print get_class($ex) . ": " . $ex->getMessage();
}

Számla (szakmai) XML validálása küldés nélkül

// Az $invoiceXml tartalmazza a számla (szakmai) SimpleXMLElement objektumot

$errorMsg = NavOnlineInvoice\Reporter::getInvoiceValidationError($invoiceXml);

if ($errorMsg) {
    print "A számla nem valid, hibaüzenet: " . $errorMsg;
} else {
    print "A számla valid.";
}

Számla validálásának másik módját lásd a validateInvoices.php példában.

REST hívás részletei

A REST hívások naplózása és hibakeresés végett lehetőség van az utolsó REST hívás adatainak lekérésére:

// Bármilyen operáció után, pl.:
// $reporter->manageInvoice($invoiceXml, "CREATE");
// hívható (Exception esetén is):

$data = $reporter->getLastRequestData();

print "<br /><br />Request URL: " . htmlspecialchars($data['requestUrl']);
print "<br /><br />Request body: " . htmlspecialchars($data['requestBody']);
print "<br /><br />Response body: " . htmlspecialchars($data['responseBody']);
print "<br /><br />Request ID: " . htmlspecialchars($data['requestId']);

A requestBody ezen modul által összeállított XML string-et tartalmazza, a responseBody pedig a NAV által visszaadott üzenetet, mely az esetek többségében egy XML string.


Dokumentáció

Config osztály

Config példány létrehozásakor a paraméterek megadása kötelező:

  • $baseUrl tipikusan a következő:
    • teszt környezetben: https://api-test.onlineszamla.nav.gov.hu/invoiceService/v3
    • éles környezetben: https://api.onlineszamla.nav.gov.hu/invoiceService/v3
  • $user array tartalmazza a NAV oldalán létrehozott technikai felhasználó adatait.
  • $software array tartalmazza a számlázó szoftver adatait. 2.0-ás verziótól ennek megadása kötelező, formátumát pedig a NAV által kiadott XSD biztosítja.

A $user és $software paraméter lehet 1-1 JSON fájl elérési útvonala is, ahol a JSON fájl tartalmazza a kívánt adatokat.

Metódusok

  • __construct(string $baseUrl, $user, $software)
  • setBaseUrl($baseUrl)
  • useApiSchemaValidation([$flag = true]): NAV szerverrel való kommunikáció előtt a kéréseket (envelop XML) validálja az XSD-vel. A példány alapértelmezett értéke szerint a validáció be van kapcsolva.
  • setSoftware($data)
  • loadSoftware($jsonFile)
  • setUser($data)
  • loadUser($jsonFile)
  • setCurlTimeout($timeoutSeconds): NAV szerver hívásánál (cURL hívás) timeout értéke másodpercben. Alapértelmezetten nincs timeout beállítva. Megjegyzés: manageInvoice hívásnál 2 szerver hívás is történik (token kérés és számlák beküldése), itt külön-külön kell érteni a timeout-ot.
  • setRequestIdGenerator(RequestIdGeneratorInterface $obj): opcionálisan egyedi request id generátor állítható be.

Reporter osztály

A Reporter osztály példányosításakor egyetlen paraméterben a korábban létrehozott Config példányt kell átadni.

Ezen az osztályon érhetjük el a NAV interfészén biztosított szolgáltatásokat. A metódusok nevei megegyeznek a NAV által biztosított specifikációban szereplő operáció nevekkel.

  • __construct(Config $config)
  • manageInvoice($invoiceOperationsOrXml [, $operation]): A számla beküldésére szolgáló operáció. Visszatérési értékként a transactionId-t adja vissza string-ként. Paraméterben a beküldendő számla XML-t kell átadni, illetve a hozzá tartozó műveletet (ManageInvocieOperationType): CREATE, MODIFY, STORNO. Átadható egyszerre több számla is, ilyenkor első paraméterben InvoiceOperations példányt kell átadni (második paraméternek nincs szerepe ilyenkor).
  • manageAnnulment($invoiceOperationsOrXml): Technikai érvénytelenítés beküldésére szolgáló operáció. Paraméterben a technikai érvénytelenítést leíró XML-t, vagy egy InvoiceOperations példányt kell átadni. Utóbbi esetben az InvoiceOperations példány több XML-t is tartalmazhat. A metódus visszaadja a transactionId-t, mellyel lekérdezhető a tranzakció eredménye.
  • queryInvoiceData($invoiceNumberQuery [, $returnDecodedInvoiceData = false]): Számla lekérdezése számlaszám alapján, mely kiállító és vevő oldalról is használható. Paraméterben az invoiceNumberQuery-nek megfelelően összeállított lekérdezési adatokat kell átadni (SimpleXMLElement példány). Visszatérési értéke a visszakapott XML invoiceDataResult része (SimpleXMLElement példány), vagy a számla XML, ha 2. paraméterben true-t adtunk át.
  • queryInvoiceDigest($invoiceQueryParams, $page = 1, $direction = "OUTBOUND"): Lekérdező operáció, mely kiállító és vevő oldalról is használható. Paraméterben az invoiceQueryParams-nak megfelelően összeállított lekérdezési adatokat kell átadni (SimpleXMLElement), az oldalszámot és a keresés irányát (OUTBOUND, INBOUND). A válasz XML invoiceDigestResult része.
  • queryTransactionStatus(string $transactionId [, $returnOriginalRequest = false]): A számla adatszolgáltatás feldolgozás aktuális állapotának és eredményének lekérdezésére szolgáló operáció
  • queryTransactionList($insDate [, $page = 1]): A kérésben megadott időintervallumban, a technikai felhasználóhoz tartozó adószámhoz beküldött számlaadat-szolgáltatások listázására szolgál
  • queryInvoiceChainDigest($invoiceChainQuery [, $page = 1])
  • queryTaxpayer(string $taxNumber): Belföldi adószám validáló és címadat lekérdező operáció. Visszatérési éréke lehet null nem létező adószám esetén, false érvénytelen adószám esetén, vagy TaxpayerDataType XML elem név és címadatokkal valid adószám esetén
  • tokenExchange(): Token kérése manageInvoice művelethez (közvetlen használata nem szükséges, viszont lehet használni, mint teszt hívás). Visszatérési értékként a dekódolt tokent adja vissza string-ként.
  • getLastRequestData(): Utolsó REST hívás adatainak lekérdezése naplózási és hibakeresési céllal. A visszaadott array a következő elemeket tartalmazza: requestUrl, requestBody, responseBody és requestId. Megjegyzés: bizonyos műveletek (manageAnnulment és manageInvoice) kettő REST hívást is indítanak, a tokenExchange hívást, illetve magát az adatküldést. Sikeres hívás esetén csak a tényleges adatküldés eredménye érhető el, Exception esetén pedig mindig az utolsó hívás adata.
  • getLastResponseXml(): Utolsó válasz XML lekérdezése (operáció hívása után)

InvoiceOperations osztály

manageInvoice és manageAnnulment híváshoz használandó collection, melyhez a feladni kívánt számlákat lehet hozzáadni. Ez az osztály validálja is az átadott szakmai XML-t az XSD-vel. Elektronikus számlázáshoz lásd ezt a leírást.

  • __construct($compression = false): compression: gzip tömörítés engedélyezése, részletek: NAV dokumentáció, 1.6.5 Tömörítés és méretkorlát
  • useDataSchemaValidation([$flag = true]): Számla adat hozzáadásakor az XML-t (szakmai XML) validálja az XSD-vel. Alapértelmezetten be van kapcsolva a validáció.
  • add(SimpleXMLElement $xml [, $operation = "CREATE"][, $electronicInvoiceHash = null]): Számla XML hozzáadása a listához
  • isTechnicalAnnulment()
  • getInvoices()

Exception osztályok

  • XsdValidationError: XSD séma validáció esetén, ha hiba történt (a requestXML-ben vagy szakmai XML-ben; a válasz XML nincs vizsgálva). Ez az exception a kliens oldali XML ellenőrzéskor keletkezhet még a szerverrel való kommunikáció előtt.
  • CurlError: cURL hiba esetén, pl. nem tudott csatlakozni a szerverhez (pl. nincs internet, nem elérhető a szerver).
  • HttpResponseError: Ha nem XML válasz érkezett, vagy nem sikerült azt parse-olni.
  • GeneralExceptionResponse: NAV által visszaadott hibaüzenet, ha nem sikerült náluk technikailag valamit feldolgozni (lásd NAV-os leírás Hibakezelés fejezetét).
  • GeneralErrorResponse: NAV által visszaadott hibaüzenet, ha az XML válaszban GeneralErrorResponse érkezett, vagy ha a funcCode !== 'OK'.

PHP verzió és modulok

A NavOnlineInvoice modul tesztelve PHP 5.5 és 7.2 alatt.

Szükséges modulok:

Linkek

További modulok NAV API-hoz

License

MIT

Copyright (c) 2018-2021 github.com/pzs

https://github.com/pzs/nav-online-invoice