call('PELLOGINNEW', $params); } public function createVoucher(array $params): EltaResponse { return $this->call('PELVGNEW', $params); } public function listVouchers(array $params): EltaResponse { return $this->call('PELPARALVGNEW1', $params); } public function deleteVoucher(array $params): EltaResponse { return $this->call('PELVGDEL', $params); } public function getTracking(array $params): EltaResponse { return $this->call('PELTTNEW01', $params); } public function getStation(array $params): EltaResponse { return $this->call('PELTKNEW', $params); } private function call(string $operation, array $params): EltaResponse { $namespace = '/'.$operation; $body = ''; foreach ($params as $key => $value) { $body .= ''.htmlspecialchars((string) $value, ENT_XML1).''; } $envelope = '' .'' .''.$body.''; $response = Http::withHeaders([ 'SOAPAction' => 'Get', 'Content-Type' => 'text/xml', ]) ->timeout($this->config['timeout']) ->withBody($envelope, 'text/xml') ->post($this->config['service_location']); if ($response->failed()) { throw new EltaApiException('ELTA request failed: HTTP '.$response->status()); } return EltaResponse::fromSoapResult($this->parseEnvelope($response->body())); } private function parseEnvelope(string $xml): array { $dom = new DOMDocument(); if (! $dom->loadXML($xml)) { throw new EltaApiException('ELTA returned a response that could not be parsed as XML.'); } $xpath = new DOMXPath($dom); $xpath->registerNamespace('soapenv', 'http://schemas.xmlsoap.org/soap/envelope/'); $readResponse = $xpath->query('//soapenv:Body/*')->item(0); if (! $readResponse instanceof DOMElement) { throw new EltaApiException('ELTA response did not contain a SOAP body.'); } return $this->nodeToArray($readResponse); } private function nodeToArray(DOMElement $element): array { $data = []; foreach ($element->childNodes as $child) { if (! $child instanceof DOMElement) { continue; } $name = $child->localName; $hasElementChildren = false; foreach ($child->childNodes as $grandchild) { if ($grandchild instanceof DOMElement) { $hasElementChildren = true; break; } } $value = $hasElementChildren ? $this->nodeToArray($child) : trim($child->textContent); if (array_key_exists($name, $data)) { if (! is_array($data[$name]) || ! array_is_list($data[$name])) { $data[$name] = [$data[$name]]; } $data[$name][] = $value; } else { $data[$name] = $value; } } return $data; } }