/** * * Perform the actual send of the message, according to the HttpConfiguration, and get the response. * This will also check if only HTTPS is allowed, based on the {@link HttpConfiguration}, and will * throw a {@link RealexException} if HTTP is used when only HTTPS is allowed. A {@link RealexException} * is also thrown if the response from Realex is not success (ie. if it's not 200 status code). * * @param string $xml * @param HttpClient $httpClient * @param HttpConfiguration $httpConfiguration * * * @return string */ public static function sendMessage($xml, HttpClient $httpClient, HttpConfiguration $httpConfiguration) { self::getLogger(); self::$logger->debug("Setting endpoint of: " . $httpConfiguration->getEndpoint()); $httpPost = new HttpRequest($httpConfiguration->getEndpoint(), HttpRequest::METH_POST); $response = null; // Confirm protocol is HTTPS (ie. secure) if such is configured if ($httpConfiguration->isOnlyAllowHttps()) { $scheme = parse_url($httpPost->getUrl(), PHP_URL_SCHEME); if (!$scheme || strtolower($scheme) != strtolower(self::HTTPS_PROTOCOL)) { self::$logger->error("Protocol must be " . self::HTTPS_PROTOCOL); throw new RealexException("Protocol must be " . self::HTTPS_PROTOCOL); } } else { self::$logger->warn("Allowed send message over HTTP. This should NEVER be allowed in a production environment."); } try { self::$logger->debug("Setting entity in POST message."); $httpPost->setBody($xml); self::$logger->debug("Executing HTTP Post message to: " . $httpPost->getUrl()); $response = $httpClient->execute($httpPost, $httpConfiguration->isOnlyAllowHttps()); self::$logger->debug("Checking the HTTP response status code."); $statusCode = $response->getResponseCode(); if ($statusCode != 200) { if ($statusCode == 404) { throw new RealexException("Exception communicating with Realex"); } else { throw new RealexException("Unexpected http status code [" . $statusCode . "]"); } } self::$logger->debug("Converting HTTP entity (the xml response) back into a string."); $xmlResponse = $response->getBody(); return $xmlResponse; } catch (RealexException $e) { throw $e; } catch (Exception $e) { self::$logger->error("Exception communicating with Realex.", $e->getMessage()); throw new RealexException("Exception communicating with Realex", $e); } }
/** * Test sending a ThreeDSecure Verify Enrolled request and receiving a ThreeDSecure Verify Enrolled response. * * @expectedException com\realexpayments\remote\sdk\RealexException */ public function testSendThreeDSecureInvalidResponseHash() { //get sample response XML $path = SampleXmlValidationUtils::THREE_D_SECURE_VERIFY_ENROLLED_RESPONSE_XML_PATH; $prefix = __DIR__ . '/../../resources'; $xml = file_get_contents($prefix . $path); $fromXMLResponse = new ThreeDSecureResponse(); $fromXMLResponse = $fromXMLResponse->fromXml($xml); // add invalid hash $fromXMLResponse->setHash("invalid hash"); //mock HttpResponse /** @var HttpResponse $httpResponseMock */ $httpResponseMock = Phockito::mock("com\\realexpayments\\remote\\sdk\\http\\HttpResponse"); \Phockito::when($httpResponseMock->getBody())->return($fromXMLResponse->toXML()); \Phockito::when($httpResponseMock->getResponseCode())->return(200); // create empty request $request = new ThreeDSecureRequest(); $httpConfiguration = new HttpConfiguration(); $httpConfiguration->addOnlyAllowHttps(false)->addEndpoint("https://epage.payandshop.com/epage-remote.cgi"); // mock HttpClient instance $httpClientMock = Phockito::mock("com\\realexpayments\\remote\\sdk\\http\\HttpClient"); \Phockito::when($httpClientMock->execute(\Hamcrest_Core_IsAnything::anything(), \Hamcrest_Core_IsAnything::anything()))->return($httpResponseMock); // execute and send on client $realexClient = new RealexClient(SampleXmlValidationUtils::SECRET, $httpConfiguration, $httpClientMock); $realexClient->send($request); $this->fail("RealexException should have been thrown before this point."); }