xmlSecurityHelper = $xmlSecurityHelper; $this->logger = $logger; $this->httpClientFactory = $httpClientFactory; } /** * Get transaction information * * @param \Magento\Authorizenet\Model\Authorizenet $context * @param string $transactionId * @return \Magento\Framework\Simplexml\Element * @throws \Magento\Framework\Exception\LocalizedException */ public function getTransactionDetails(Authorizenet $context, $transactionId) { return isset($this->transactionDetails[$transactionId]) ? $this->transactionDetails[$transactionId] : $this->loadTransactionDetails($context, $transactionId); } /** * Load transaction details * * @param \Magento\Authorizenet\Model\Authorizenet $context * @param string $transactionId * @return \Magento\Framework\Simplexml\Element * @throws \Magento\Framework\Exception\LocalizedException */ protected function loadTransactionDetails(Authorizenet $context, $transactionId) { $requestBody = $this->getRequestBody( $context->getConfigData('login'), $context->getConfigData('trans_key'), $transactionId ); /** @var \Magento\Framework\HTTP\ZendClient $client */ $client = $this->httpClientFactory->create(); $url = $context->getConfigData('cgi_url_td') ?: self::CGI_URL_TD; $client->setUri($url); $client->setConfig(['timeout' => self::CONNECTION_TIMEOUT]); $client->setHeaders(['Content-Type: text/xml']); $client->setMethod(\Zend_Http_Client::POST); $client->setRawData($requestBody); $debugData = ['url' => $url, 'request' => $this->removePrivateDataFromXml($requestBody)]; try { $responseBody = $client->request()->getBody(); if (!$this->xmlSecurityHelper->scan($responseBody)) { $this->logger->critical('Attempt loading of external XML entities in response from Authorizenet.'); throw new \Exception(); } $debugData['response'] = $responseBody; libxml_use_internal_errors(true); $responseXmlDocument = new Element($responseBody); libxml_use_internal_errors(false); } catch (\Exception $e) { throw new LocalizedException(__('The transaction details are unavailable. Please try again later.')); } finally { $context->debugData($debugData); } if (!isset($responseXmlDocument->messages->resultCode) || $responseXmlDocument->messages->resultCode != static::PAYMENT_UPDATE_STATUS_CODE_SUCCESS ) { throw new LocalizedException(__('The transaction details are unavailable. Please try again later.')); } $this->transactionDetails[$transactionId] = $responseXmlDocument; return $responseXmlDocument; } /** * Create request body to get transaction details * * @param string $login * @param string $transactionKey * @param string $transactionId * @return string */ private function getRequestBody($login, $transactionKey, $transactionId) { $requestBody = sprintf( '' . '' . '%s%s' . '%s' . '', $login, $transactionKey, $transactionId ); return $requestBody; } /** * Remove nodes with private data from XML string * * Uses values from $_debugReplacePrivateDataKeys property * * @param string $xml * @return string */ private function removePrivateDataFromXml($xml) { foreach ($this->debugReplacePrivateDataKeys as $key) { $xml = preg_replace(sprintf('~(?<=<%s>).*?(?=)~', $key, $key), Logger::DEBUG_KEYS_MASK, $xml); } return $xml; } }