logger = $logger; $this->idContract = findModule(\Modules::CESKA_POSTA, 'idContract'); $this->customerID = findModule(\Modules::CESKA_POSTA, 'customerID'); $this->postCode = findModule(\Modules::CESKA_POSTA, 'postCode'); $this->locationNumber = findModule(\Modules::CESKA_POSTA, 'locationNumber'); } public function configure($idContract, $customerID, $postCode, $locationNumber) { $this->idContract = $idContract; $this->customerID = $customerID; $this->postCode = $postCode; $this->locationNumber = $locationNumber; } public function getHeader($type = '') { $this->idExtTransaction++; $header = '
'.$this->idExtTransaction.' '.date('Y-m-d\TH:i:s.vP').' '.$this->idContract.'
'; if ($type == 'getParcelsPrinting') { $header .= ' '.$this->customerID.' '.$this->idContract.' 0 0 '; } if ($type == 'sendParcels') { $header .= ' '.date('d.m.Y').' '.$this->customerID.' '.$this->postCode.' '.$this->locationNumber.' '; } $header .= '
'; $simple_xml = simplexml_load_string($header); return $simple_xml; } public function get_b2bRequest($order, $type = 'sendParcels') { $b2bRequest = $this->getHeader($type); $serviceData = $b2bRequest->serviceData; $doParcelParams = $serviceData->children('ns2', true)->sendParcels->doParcelData->doParcelParams; $doParcelParams->addChild('ns2:recordID', $order->id, $this->ns2); $doParcelParams->addChild('ns2:currency', $order->currency, $this->ns2); $delivery_address = !empty($order->delivery_street); // true - use delivery address, false - use invoice address // surname = name surname firm // surname - string50 $surname = ($delivery_address ? $order->delivery_name : $order->invoice_name).' '; $surname .= $delivery_address ? $order->delivery_surname.(!empty($order->delivery_firm) ? ' '.$order->delivery_firm : '') : $order->invoice_surname; // street - string40 $street = $delivery_address ? $order->delivery_street : $order->invoice_street; // firstName = custom_address (Address line 2 / Upřesnění adresy), if exists // firstName - string50 $custom_address = ($delivery_address && !empty($order->delivery_custom_address)) ? ', '.$order->delivery_custom_address : (!$delivery_address && !empty($order->invoice_custom_address) ? ', '.$order->invoice_custom_address : ''); // city = city, state // city - string40 $city = $delivery_address ? $order->delivery_city : $order->invoice_city; $city .= ($delivery_address && !empty($order->delivery_state)) ? ', '.$order->delivery_state : (!$delivery_address && !empty($order->invoice_state) ? ', '.$order->invoice_state : ''); // zipCode - string25 $zip = $delivery_address ? $order->delivery_zip : $order->invoice_zip; $country = $delivery_address ? $order->delivery_country : $order->invoice_country; if ($transliterator = \Transliterator::create('Russian-Latin/BGN')) { $surname = $transliterator->transliterate($surname); $street = $transliterator->transliterate($street); $custom_address = $transliterator->transliterate($custom_address); $city = $transliterator->transliterate($city); } if (mb_strlen($surname) > 50) { $surname = mb_substr($surname, 0, 50); } if (mb_strlen($city) > 40) { $city = mb_substr($city, 0, 40); } $doParcelAddress = $serviceData->children('ns2', true)->sendParcels->doParcelData->doParcelAddress; $doParcelAddress->addChild('ns2:surname', '', $this->ns2)[0] = trim($surname); if (!empty($custom_address)) { $doParcelAddress->addChild('ns2:firstName', '', $this->ns2)[0] = trim($custom_address); } $doParcelAddress->addChild('ns2:subject', 'F', $this->ns2); $doParcelAddress->addChild('ns2:street', '', $this->ns2)[0] = trim($street); $doParcelAddress->addChild('ns2:city', '', $this->ns2)[0] = trim($city); $doParcelAddress->addChild('ns2:zipCode', '', $this->ns2)[0] = trim($zip); $doParcelAddress->addChild('ns2:isoCountry', trim($country), $this->ns2); if (in_array($country, ['US', 'MX', 'AU', 'BR', 'CA', 'ES'])) { $state = ($delivery_address && !empty($order->delivery_state)) ? $order->delivery_state : $order->invoice_state; $doParcelAddress->addChild('ns2:subIsoCountry', trim($state), $this->ns2); } $doParcelAddress->addChild('ns2:emailAddress', $order->invoice_email, $this->ns2); $phone = trim($order->invoice_phone); if (mb_strlen($phone) > 13) { $phone = mb_substr($phone, mb_strlen($phone) - 13); } $doParcelAddress->addChild('ns2:mobileNumber', '', $this->ns2)[0] = trim($phone); return $b2bRequest; } public function sendParcels($b2bRequest) { $this->request_url = 'https://b2b.postaonline.cz/services/POLService/v1/sendParcels'; $this->request = $b2bRequest->asXML(); if (!$this->sendToCeskaPosta($this->request, $this->request_url)) { return false; } $parser = xml_parser_create(); xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0); if (!xml_parse_into_struct($parser, $this->response, $values, $index)) { $this->error = 'xml_parse error: '.xml_error_string(xml_get_error_code($parser)).' at line '.xml_get_current_line_number($parser); xml_parser_free($parser); return false; } xml_parser_free($parser); if (array_key_exists('v1:B2BFaultMessage', $index)) { $i = $index['v1:errorDetail'][0]; $v = $values[$i]['value']; $this->error = 'Error! B2BFaultMessage: '.$v; return false; } if (!array_key_exists('v1:b2bASyncResponse', $index)) { $this->error = 'Error! No b2bASyncResponse!'; return false; } if (!array_key_exists('v1:idTransaction', $index)) { $this->error = 'Error! No idTransaction!'; return false; } $i = $index['v1:idTransaction'][0]; $idTransaction = $values[$i]['value']; return $idTransaction; } public function getResultParcels($idTransaction) { $this->request_url = 'https://b2b.postaonline.cz/services/POLService/v1/getResultParcels'; $b2bRequest = $this->getHeader('getResultParcels'); $b2bRequest->addChild('idTransaction', $idTransaction); $this->request = $b2bRequest->asXML(); if (!$this->sendToCeskaPosta($this->request, $this->request_url)) { return false; } $parser = xml_parser_create(); xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0); if (!xml_parse_into_struct($parser, $this->response, $values, $index)) { $this->error = 'xml_parse error: '.xml_error_string(xml_get_error_code($parser)).' at line '.xml_get_current_line_number($parser); xml_parser_free($parser); return false; } xml_parser_free($parser); if (array_key_exists('v1:B2BFaultMessage', $index)) { $i = $index['v1:errorDetail'][0]; $v = $values[$i]['value']; $this->error = 'Error! B2BFaultMessage: '.$v; $i = $index['v1:errorCode'][0]; $errorCode = $values[$i]['value']; if ($errorCode == 10) { // 10 = UNFINISHED_PROCESS = Zpracování není ještě ukončeno sleep(1); return $this->getResultParcels($idTransaction); } return false; } if (!array_key_exists('v1_1:responseCode', $index)) { $this->error = 'Error! No responseCode!'; return false; } $i = $index['v1_1:responseCode'][0]; $responseCode = $values[$i]['value']; if ($responseCode != '1') { $this->error = 'Error! '; foreach ($index['v1_1:responseCode'] as $key => $i) { $responseCode = $values[$i]['value']; $i = $index['v1_1:responseText'][$key]; $v = $values[$i]['value']; $this->error .= $responseCode.': '.$v.'; '; } // ignore error // 09.03.2018: // getResultParcels vrati Error! 19: BATCH_INVALID, i kdyz je vsechno OK, // a vrati take parcelCode return false; } if (!array_key_exists('v1_1:parcelCode', $index)) { $this->error .= 'Error! No parcelCode!'; return false; } $parcelCode = []; foreach ($index['v1_1:parcelCode'] as $i) { $parcelCode[] = $values[$i]['value']; } return array_unique($parcelCode); } public function getParcelsPrinting($parcelCode, $idForm, $print_position = null) { $this->request_url = 'https://b2b.postaonline.cz/services/POLService/v1/getParcelsPrinting'; $b2bRequest = $this->getHeader('getParcelsPrinting'); $serviceData = $b2bRequest->serviceData; $doPrintingHeader = $serviceData->children('ns2', true)->getParcelsPrinting->doPrintingHeader; $doPrintingHeader->addChild('ns2:idForm', $idForm, $this->ns2); if ($print_position) { $doPrintingHeader->addChild('ns2:position', $print_position, $this->ns2); } $doPrintingData = $serviceData->children('ns2', true)->getParcelsPrinting->doPrintingData; foreach ($parcelCode as $code) { $doPrintingData->addChild('ns2:parcelCode', $code, $this->ns2); } $this->request = $b2bRequest->asXML(); if (!$this->sendToCeskaPosta($this->request, $this->request_url)) { return false; } $parser = xml_parser_create(); xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0); if (!xml_parse_into_struct($parser, $this->response, $values, $index)) { $this->error = 'xml_parse error: '.xml_error_string(xml_get_error_code($parser)).' at line '.xml_get_current_line_number($parser); xml_parser_free($parser); return false; } xml_parser_free($parser); if (array_key_exists('v1:B2BFaultMessage', $index)) { $i = $index['v1:errorDetail'][0]; $v = $values[$i]['value']; $this->error = 'Error! B2BFaultMessage: '.$v; return false; } if (!array_key_exists('v1_1:responseCode', $index)) { $this->error = 'Error! No responseCode!'; return false; } $i = $index['v1_1:responseCode'][0]; $responseCode = $values[$i]['value']; if ($responseCode != '1') { $i = $index['v1_1:responseText'][0]; $v = $values[$i]['value']; $this->error = 'Error! '.$responseCode.': '.$v; return false; } if (!array_key_exists('v1_1:file', $index)) { $this->error = 'Error! No file!'; return false; } $i = $index['v1_1:file'][0]; $f = $values[$i]['value']; $pdf = base64_decode($f); return $pdf; } public function sendToCeskaPosta($request = '', $url = null) { $this->logger->notice('Ceska Posta Podani Online', ['request_url' => $url, 'request' => $request]); $curl = $this->createCurl($request, $url); $this->response = curl_exec($curl); if ($this->response === false) { $this->error = 'curl_error: '.curl_error($curl); $this->logger->notice('Ceska Posta Podani Online', ['error' => $this->error]); return false; } else { $this->error = ''; $this->logger->notice('Ceska Posta Podani Online', ['response' => $this->response]); return true; } } public function createCurl($encodedBody, $url = null) { if (empty($url)) { $url = $this->request_url; } $curl = curl_init(); curl_setopt($curl, CURLOPT_URL, $url); curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); // curl_setopt($curl, CURLOPT_VERBOSE, true); // curl_setopt($curl, CURLOPT_CERTINFO, true); curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, true); curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 2); curl_setopt($curl, CURLOPT_CAINFO, __DIR__.DIRECTORY_SEPARATOR.'Resources/Certificates/postsignum_vca4.pem'); curl_setopt($curl, CURLOPT_SSLCERTTYPE, 'P12'); curl_setopt($curl, CURLOPT_SSLCERT, __DIR__.DIRECTORY_SEPARATOR.'Resources/Certificates/post_2024.p12'); curl_setopt($curl, CURLOPT_SSLCERTPASSWD, 'wpj'); curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'POST'); curl_setopt($curl, CURLOPT_POSTFIELDS, $encodedBody); return $curl; } }