| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434 |
- <?php
- /**
- * JEGY ADATOK
- *
- * 'bruttoAr': ha bundle-ben van, akkor hogyan adjak neki árat?
- * 'ervenyessegKezdete': kotelezo megadni, de nem tudom mikor fogja felhasznalni, milyen datum legyen?
- *
- * bundle jegy kedvezmenyt hogyan kell bekuldeni, mert ott csak a vegosszeg lesz kedvezmenyes, nem tetelenkent
- *
- * PROGRAM ADATOK
- *
- * helyszinAdatok: hogy kuldjem be, ha csak buszos/hajos jegyet vesz?
- * programKezdete ertelmezhetetlen - de kotelezo (szamla datuma legyen)
- */
- require_once DOL_DOCUMENT_ROOT.'/custom/ntak/class/ntakconnector/ntak_const.class.php';
- require_once DOL_DOCUMENT_ROOT.'/custom/ntak/class/ntakconnector/ntak_config.class.php';
- require_once DOL_DOCUMENT_ROOT.'/custom/ntak/class/ntakinvoice.class.php';
- require_once DOL_DOCUMENT_ROOT.'/custom/ntak/class/ntaksaleschannel.class.php';
- require_once DOL_DOCUMENT_ROOT.'/custom/ntak/class/ntakconnector/ntak_date.class.php';
- require_once DOL_DOCUMENT_ROOT.'/custom/ntak/class/ntaklogger.class.php';
- require_once DOL_DOCUMENT_ROOT.'/custom/ntak/class/ntaksendresult.class.php';
- require_once DOL_DOCUMENT_ROOT.'/custom/ntak/class/utils/moneyhandler.class.php';
- require_once DOL_DOCUMENT_ROOT.'/custom/bbus/class/bbticket.class.php';
- class NtakClient
- {
- private static $instance = null;
- const CERT_PEM = 'cert.pem';
- const CERT_B64 = 'cert_b64.txt';
- private $date;
- private $postFields;
- private $certDir;
- private NtakInvoice $invoice;
- private NtakLogger $ntakLogger;
- public static function getInstance(): NtakClient
- {
- if (self::$instance == null) {
- self::$instance = new NtakClient;
- }
- return self::$instance;
- }
- public function __construct()
- {
- $this->initCertDir();
- $this->checkFiles();
- $this->ntakLogger = NtakLogger::getInstance();
- }
- /**
- *
- */
- private function checkFiles(): void
- {
- $this->checkCertFile(self::CERT_PEM);
- $this->checkCertFile(self::CERT_B64);
- }
- /**
- *
- */
- private function checkCertFile(string $file): void
- {
- $fullPath = $this->certDir.$file;
- if (file_exists($fullPath)) {
- if (!is_file($fullPath)) {
- throw new \Exception('CERT FILE IS NOT FILE ('.$fullPath.')');
- }
- if (!is_readable($fullPath)) {
- throw new \Exception('CERT FILE IS NOT READABLE ('.$fullPath.')');
- }
- } else {
- throw new \Exception('CERT FILE MISSING ('.$fullPath.')');
- }
- }
- /**
- *
- */
- private function initCertDir(): void
- {
- $certPath = [
- __DIR__,
- '..',
- '..',
- 'cert'
- ];
- $this->certDir = implode(DIRECTORY_SEPARATOR, $certPath).DIRECTORY_SEPARATOR;
- }
- /**
- *
- */
- public function sendToServer(array $data): NtakSendResult
- {
- $this->postFields = $data;
- $logData = json_encode($data);
- $invoiceRefs = array_map(function ($item) {
- return $item['tranzakcioAzonosito'];
- }, $data['tranzakcioAdatok']);
- $this->ntakLogger->logIntoFile($logData, LOG_INFO);
- $curl = $this->getCurlResource(NtakConfig::URL_SALE);
- $response = curl_exec($curl);
-
- $this->ntakLogger->logIntoFile($response, LOG_INFO);
- $ntakSendResult = new NtakSendResult;
- if ($response) {
- $resultStatus = 0;
- $result = json_decode($response, true);
-
- if (!empty($result['feldolgozasAzonosito'])) {
- $ntakSendResult->ntakId = $result['feldolgozasAzonosito'];
- $checkResult = $this->check($result['feldolgozasAzonosito']);
- if (!empty($checkResult['uzenetValaszok'][0]['statusz'])) {
- $resultStatus = NtakConst::getDbResponseStatusByStatus($checkResult['uzenetValaszok'][0]['statusz']);
- $ntakSendResult->ntakStatus = $checkResult['uzenetValaszok'][0]['statusz'];
- $ntakSendResult->status = $resultStatus;
- }
- $this->ntakLogger->logIntoFile("Invoice sent successfully to NTAK (Ref: ".implode(', ', $invoiceRefs).")", LOG_INFO);
- $this->ntakLogger->logIntoFile("Invoice data: {$logData}", LOG_INFO);
- $this->ntakLogger->massDbLogByInvoiceRef($invoiceRefs, $resultStatus, curl_error($curl), $logData, $result['feldolgozasAzonosito']);
- } else {
- $this->ntakLogger->logIntoFile("Invoice sent failed to NTAK (Ref: ".implode(', ', $invoiceRefs).")", LOG_INFO);
- $this->ntakLogger->logIntoFile($response, LOG_INFO);
- $this->ntakLogger->massDbLogByInvoiceRef($invoiceRefs, $resultStatus, $response, $logData);
- }
- } else {
- $this->ntakLogger->logIntoFile("Cannot send invoice (Ref: ".implode(', ', $invoiceRefs).")", LOG_ALERT);
- $this->ntakLogger->massDbLogByInvoiceRef($invoiceRefs, NtakLog::STATUS_CANCELED, curl_error($curl), $logData);
- }
- curl_close($curl);
- return $ntakSendResult;
- }
- /**
- * @var bool $send If false, not send and return with the generated data
- */
- public function send(NtakInvoice $ntakInvoice, bool $send = true): NtakSendResult
- {
- $this->ntakLogger->logIntoFile("Send invoice to NTAK (Ref: {$ntakInvoice->ref})", LOG_INFO);
- $ntakSendResult = new NtakSendResult;
- $this->invoice = $ntakInvoice;
- $this->date = gmdate(DATE_RFC3339, time());
-
- $this->initServiceProvider();
- $this->initSenderData();
- $this->initMessageData();
- $this->setPostFieldsProgramData();
- $this->setPostFieldsTransactionData();
- if ($ntakInvoice->array_options['options_ntak_status'] == NtakConst::INVOICE_SENDING_RESPONSE_STATUS_SEND_AGAIN) {
- $origData = $this->ntakLogger->getOrigSentData($ntakInvoice->array_options['options_ntak_id']);
- if (!empty($origData)) {
- $this->postFields = $origData;
- }
- }
- if ($send) {
- //echo json_encode($this->postFields); die;
- //print_r($this->postFields); die;
- $ntakSendResult = $this->sendToServer($this->postFields);
-
- } else {
- $ntakSendResult->generatedData = $this->postFields;
- }
-
- return $ntakSendResult;
- }
- /**
- *
- */
- private function getCurlResource(string $url)
- {
- $curl = curl_init();
- curl_setopt_array(
- $curl,
- [
- CURLOPT_URL => $url,
- CURLOPT_RETURNTRANSFER => true,
- CURLOPT_SSLCERT => $this->certDir.self::CERT_PEM,
- CURLOPT_ENCODING => '',
- CURLOPT_MAXREDIRS => 10,
- CURLOPT_TIMEOUT => 0,
- CURLOPT_FOLLOWLOCATION => true,
- CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
- CURLOPT_SSL_VERIFYHOST => false,
- CURLOPT_SSL_VERIFYPEER => false,
- CURLOPT_CUSTOMREQUEST => 'POST',
- CURLOPT_POSTFIELDS => json_encode($this->postFields),
- CURLOPT_POST => 1,
- CURLOPT_HTTPHEADER => $this->getHttpHeader(),
- ]
- );
- return $curl;
- }
- /**
- *
- */
- private function base64url_encode($data) {
- return rtrim(strtr(base64_encode($data), '+/', '-_'), '=');
- }
- /**
- *
- */
- /*
- private function base64url_decode($data) {
- return base64_decode(str_pad(strtr($data, '-_', '+/'), strlen($data) % 4, '=', STR_PAD_RIGHT));
- }
- */
- /**
- *
- */
- private function setPostFieldsTransactionData(): void
- {
- //$prices = $this->invoice->getRoundedTransactionPrices();
- $prices = $this->invoice->getTotalTransaction();
- $ticketsSold = $this->invoice->ntakSoldTickets();
- $paymentMethods = $this->invoice->ntakPaymentMethods();
- if (!empty($ticketsSold)) {
- //$prices = array_sum(array_column($ticketsSold, 'bruttoAr'));
- array_walk($paymentMethods, function (&$item) use ($prices) {
- if (array_key_exists('fizetettOsszegHUF', $item) && $item['fizetesiMod'] == NtakConst::PAYMENT_METHOD_CASH_EUR) {
- //$item['fizetettOsszegHUF'] = $item[''];
- }
- });
- $this->postFields['tranzakcioAdatok'] = [
- [
- 'tranzakcioAzonosito' => $this->invoice->ref,
- 'tranzakcioIdopontja' => NtakDate::timestampToRfc3339($this->invoice->date_modification),
- 'osszesitett' => false,
- 'tranzakcioVegosszege' => $prices, //$prices['rounded'],
- 'ertekesitesiCsatorna' => NtakConst::SALES_CHANNEL_LOCAL, // ITT TISZTAZNI, HOGY MIT KELL A MOKUS ES A HOTEL ESETEN
- 'fizetesiModok' => $paymentMethods, //$this->invoice->ntakPaymentMethods(),
- 'latogatoiAdatok' => $this->invoice->ntakCustomerData(),
- 'eladottJegyek' => $ticketsSold, //$this->invoice->ntakSoldTickets(),
- 'egyebTetelek' => $this->invoice->ntakDiscount()
- ]
- ];
- }
- }
- /**
- *
- */
- private function setPostFieldsProgramData(): void
- {
- $this->postFields['programAdatok'] = $this->invoice->ntakProgramDetails();
- }
- /**
- *
- */
- private function initMessageData(): void
- {
- $this->postFields['uzenetAdatok'] = [
- 'uzenetKuldesIdeje' => $this->date
- ];
- }
- /**
- *
- */
- private function initSenderData(): void
- {
- $this->postFields['kuldoRendszerAdatok'] = [
- 'tssRendszerNTAKAzonosito' => NtakConfig::TSS_ID,
- 'tssRendszerVerzioszam' => NtakConfig::TSS_VERSION
- ];
- }
- /**
- *
- */
- private function initServiceProvider(): void
- {
- $this->postFields['szolgaltatoAdatok'] = [
- 'adoszam' => NtakConfig::TAX_NUMBER,
- 'szolgHelyRegisztraciosSzam' => NtakConfig::REGISTRATION_NUMBER
- ];
- }
- /**
- *
- */
- private function getHttpHeader(): array
- {
- $header = [
- "alg" => "RS256"
- ];
- $headerBase64URLencodedValue = 'eyJhbGciOiJSUzI1NiJ9';
- // CERT file
- $filenameCert = $this->certDir.self::CERT_B64;
- $handle = fopen($filenameCert, 'r');
- $certificateStr = fread($handle, filesize($filenameCert));
- fclose($handle);
- $headerBaseUrlEnc = json_encode($header);
- $token = $this->base64url_encode($headerBaseUrlEnc).'.'.$this->base64url_encode(json_encode($this->postFields)); // a json adat maga
- // PEM file
- $filenameSslCert = $this->certDir.self::CERT_PEM;
- $fileContent = file_get_contents($filenameSslCert);
- $privateKey = openssl_pkey_get_private($fileContent);
- openssl_sign("$token", $signature, $privateKey, "sha256");
- $signatureBase64 = $this->base64url_encode($signature);
-
- $payloadBase64URLencodedValue = '';
- return [
- 'Content-Type: application/json',
- 'x-jws-signature: '.$headerBase64URLencodedValue.'.'.$payloadBase64URLencodedValue.'.'.$signatureBase64,
- 'x-certificate: '.$certificateStr
- ];
- }
- /**
- *
- */
- public function validate(int $ticketId, string $factureRef, string $ntakId, string $productRef, string $productDate, string $logDate, int $factureId): void
- {
- $this->ntakLogger->logIntoFile('Validate start', LOG_INFO);
- $this->date = gmdate(DATE_RFC3339, time());
- $this->initServiceProvider();
- $this->initSenderData();
- $this->initMessageData();
- $this->postFields['jegyek'] = [];
- $this->postFields['jegyek'][] = [
- 'ervenyesitesiAzonosito' => $ntakId,
- 'belepettSzemelyekSzama' => 1,
- 'ervenyesitesIdopontja' => NtakDate::timestampToRfc3339(strtotime($logDate)),
- 'felhasznalasModja' => NtakConst::TICKET_USE_METHOD_ENTRY,
- 'jegyAzonosito' => 'J-'.$factureRef,
- 'programazonosito' => [
- 'tssProgramAzonosito' => $productRef,
- //'utolsoModositasIdeje' => NtakDate::timestampToRfc3339(strtotime($productDate))
- 'utolsoModositasIdeje' => NtakDate::timestampToRfc3339(strtotime('today midnight'))
- ]
- ];
- $curl = $this->getCurlResource(NtakConfig::URL_VALIDATE);
- $response = curl_exec($curl);
-
- $logData = json_encode($this->postFields);
- if ($response) {
- $result = json_decode($response, true);
-
- if (array_key_exists('feldolgozasAzonosito', $result)) {
- $this->ntakLogger->logIntoFile("Validate sent successfully to NTAK (Ticket ID: {$ticketId})", LOG_INFO);
- } else {
- $this->ntakLogger->logIntoFile("Validate sent failed to NTAK (Ticket ID: {$ticketId})", LOG_ERR);
- $this->ntakLogger->logIntoFile($logData, LOG_ERR);
- $this->ntakLogger->logIntoFile($response, LOG_ERR);
- }
- } else {
- $this->ntakLogger->logIntoFile("Validate sent failed to NTAK (Ticket ID: {$ticketId})", LOG_ERR);
- $this->ntakLogger->logIntoFile($logData, LOG_ERR);
- }
- curl_close($curl);
- }
- /**
- *
- */
- public function checkWithLog(string $ntakProcessId, int $invoiceId): array
- {
- $this->ntakLogger->logIntoFile("Check with log start ({$ntakProcessId})", LOG_INFO);
- $resultStatus = NtakLog::STATUS_DRAFT;
- $checkResult = $this->check($ntakProcessId);
- if (!empty($checkResult['uzenetValaszok'][0]['statusz'])) {
- $resultStatus = NtakConst::getDbResponseStatusByStatus($checkResult['uzenetValaszok'][0]['statusz']);
- }
- $this->ntakLogger->logIntoFile("Check successfully at NTAK (NTAK ID: {$ntakProcessId})", LOG_INFO);
- $this->ntakLogger->logIntoDb($invoiceId, $resultStatus, '', '', $ntakProcessId);
- $this->ntakLogger->logIntoFile("Check with log end ({$ntakProcessId})", LOG_INFO);
- return $checkResult;
- }
- /**
- *
- */
- public function check(string $ntakProcessId): array
- {
- $result = [];
- $this->ntakLogger->logIntoFile("Check sent data ({$ntakProcessId})", LOG_INFO);
- $this->postFields = [];
- $this->date = gmdate(DATE_RFC3339, time());
-
- $this->initServiceProvider();
- $this->initSenderData();
- $this->initMessageData();
- $this->postFields['feldolgozasAzonositok'] = [
- $ntakProcessId
- ];
- $this->ntakLogger->logIntoFile(json_encode($this->postFields), LOG_INFO);
- $curl = $this->getCurlResource(NtakConfig::URL_CHECK);
- $response = curl_exec($curl);
- if ($response) {
- $result = json_decode($response, true);
- $this->ntakLogger->logIntoFile("Check invoice process at NTAK (NTAK process ID: {$ntakProcessId})", LOG_INFO);
- $this->ntakLogger->logIntoFile($response, LOG_INFO);
- } else {
- $this->ntakLogger->logIntoFile("Cannot check invoice process at NTAK (NTAK process ID: {$ntakProcessId})", LOG_ALERT);
- }
- curl_close($curl);
- return $result;
- }
- }
|