From f026982942f10fb1ddfa3309f60051848809cb09 Mon Sep 17 00:00:00 2001 From: Povilas Date: Sun, 16 Oct 2016 19:50:49 +0300 Subject: [PATCH] Big initial request --- .gitignore | 2 - phpunit.xml.dist | 29 +++ src/Common/Encoder.php | 37 +++ src/Common/PurchaseDataGenerator.php | 75 ++++++ src/Common/PurchaseParameterValidator.php | 82 ++++++ src/Common/SignatureGenerator.php | 28 ++ src/Common/SignatureValidator.php | 63 +++++ src/Customer.php | 240 ++++++++++++++++++ src/Gateway.php | 114 +++++++++ src/Message/AbstractRequest.php | 53 ++++ src/Message/AcceptNotificationRequest.php | 58 +++++ src/Message/AcceptNotificationResponse.php | 103 ++++++++ src/Message/PurchaseRequest.php | 104 ++++++++ src/Message/PurchaseResponse.php | 70 +++++ tests/GatewayTest.php | 73 ++++++ .../Message/AcceptNotificationRequestTest.php | 220 ++++++++++++++++ tests/Message/PurchaseRequestTest.php | 164 ++++++++++++ tests/Mock/PubKeyResponse.txt | 17 ++ 18 files changed, 1530 insertions(+), 2 deletions(-) create mode 100644 phpunit.xml.dist create mode 100644 src/Common/Encoder.php create mode 100644 src/Common/PurchaseDataGenerator.php create mode 100644 src/Common/PurchaseParameterValidator.php create mode 100644 src/Common/SignatureGenerator.php create mode 100644 src/Common/SignatureValidator.php create mode 100644 src/Customer.php create mode 100644 src/Gateway.php create mode 100644 src/Message/AbstractRequest.php create mode 100644 src/Message/AcceptNotificationRequest.php create mode 100644 src/Message/AcceptNotificationResponse.php create mode 100644 src/Message/PurchaseRequest.php create mode 100644 src/Message/PurchaseResponse.php create mode 100644 tests/GatewayTest.php create mode 100644 tests/Message/AcceptNotificationRequestTest.php create mode 100644 tests/Message/PurchaseRequestTest.php create mode 100644 tests/Mock/PubKeyResponse.txt diff --git a/.gitignore b/.gitignore index 1f4733d..0679353 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,3 @@ /vendor composer.lock -composer.phar -phpunit.xml .idea \ No newline at end of file diff --git a/phpunit.xml.dist b/phpunit.xml.dist new file mode 100644 index 0000000..b828e19 --- /dev/null +++ b/phpunit.xml.dist @@ -0,0 +1,29 @@ + + + + + + + ./tests + + + + + + ./src + + ./vendor + + + + + \ No newline at end of file diff --git a/src/Common/Encoder.php b/src/Common/Encoder.php new file mode 100644 index 0000000..299cd64 --- /dev/null +++ b/src/Common/Encoder.php @@ -0,0 +1,37 @@ + '-', '/' => '_']); + } + + /** + * @param $input + * + * @return string + */ + public static function decode($input) + { + return base64_decode(strtr($input, ['-' => '+', '_' => '/'])); + } +} diff --git a/src/Common/PurchaseDataGenerator.php b/src/Common/PurchaseDataGenerator.php new file mode 100644 index 0000000..d9b2d3a --- /dev/null +++ b/src/Common/PurchaseDataGenerator.php @@ -0,0 +1,75 @@ + $request->getProjectId(), + 'orderid' => $request->getTransactionId(), + 'accepturl' => $request->getReturnUrl(), + 'cancelurl' => $request->getCancelUrl(), + 'callbackurl' => $request->getNotifyUrl(), + 'version' => $request->getVersion(), + 'payment' => $request->getPaymentMethod(), + 'lang' => $request->getLanguage(), + 'amount' => $request->getAmountInteger(), + 'currency' => $request->getCurrency(), + 'test' => $request->getTestMode() ? '1' : '0', + ]; + + if(null !== $customer = $request->getCustomer()){ + $customerData = [ + 'p_firstname' => $customer->getFirstName(), + 'p_lastname' => $customer->getLastName(), + 'p_email' => $customer->getEmail(), + 'p_street' => $customer->getStreet(), + 'p_city' => $customer->getCity(), + 'p_state' => $customer->getState(), + 'p_zip' => $customer->getPostcode(), + 'p_countrycode' => $customer->getCountryCode(), + 'country' => $customer->getCountry(), + ]; + + $parameters = array_merge($parameters, $customerData); + } + + $filteredParameters = self::filterParameters($parameters); + + PurchaseParameterValidator::validate($filteredParameters); + + return Encoder::encode(http_build_query($filteredParameters, '', '&')); + } + + /** + * @param array $parameters + * + * @return array + */ + private static function filterParameters(array $parameters) + { + return array_filter($parameters, function ($value) { + return $value !== '' && $value !== null; + }); + } +} diff --git a/src/Common/PurchaseParameterValidator.php b/src/Common/PurchaseParameterValidator.php new file mode 100644 index 0000000..256bbc6 --- /dev/null +++ b/src/Common/PurchaseParameterValidator.php @@ -0,0 +1,82 @@ + $maxLength) { + throw new InvalidRequestException(sprintf( + "'%s' value is too long (%d), %d characters allowed.", + $name, + strlen($data[$name]), + $maxLength + )); + } + + if ($regexp !== '' && !preg_match($regexp, $data[$name])) { + throw new InvalidRequestException(sprintf("'%s' value '%s' is invalid.", $name, $data[$name])); + } + } + } + } + + /** + * Array structure: + * name – request parameter name + * maxLength – max allowed length for parameter + * required – is this parameter required + * regexp – regexp to test parameter value + * + * @return array + */ + protected static function getRequestSpecifications() + { + return [ + ['orderid', 40, true, ''], + ['accepturl', 255, true, ''], + ['cancelurl', 255, true, ''], + ['callbackurl', 255, true, ''], + ['lang', 3, false, '/^[a-z]{3}$/i'], + ['amount', 11, false, '/^\d+$/'], + ['currency', 3, false, '/^[a-z]{3}$/i'], + ['payment', 20, false, ''], + ['country', 2, false, '/^[a-z_]{2}$/i'], + ['p_firstname', 255, false, ''], + ['p_lastname', 255, false, ''], + ['p_email', 255, false, ''], + ['p_street', 255, false, ''], + ['p_city', 255, false, ''], + ['p_state', 20, false, ''], + ['p_zip', 20, false, ''], + ['p_countrycode', 2, false, '/^[a-z]{2}$/i'], + ['test', 1, false, '/^[01]$/'], + ]; + } +} diff --git a/src/Common/SignatureGenerator.php b/src/Common/SignatureGenerator.php new file mode 100644 index 0000000..f34b38a --- /dev/null +++ b/src/Common/SignatureGenerator.php @@ -0,0 +1,28 @@ +get(self::$endpoint)->send(); + if (200 === $response->getStatusCode() && false !== $publicKey = openssl_get_publickey($response->getBody())) { + return openssl_verify($data['data'], Encoder::decode($data['ss2']), $publicKey) === 1; + } + + return false; + } +} diff --git a/src/Customer.php b/src/Customer.php new file mode 100644 index 0000000..26bea09 --- /dev/null +++ b/src/Customer.php @@ -0,0 +1,240 @@ +initialize($parameters); + } + + /** + * @param array|null $parameters + * + * @return $this + */ + public function initialize(array $parameters = null) + { + $this->parameters = new ParameterBag; + + Helper::initialize($this, $parameters); + + return $this; + } + + /** + * @return array + */ + public function getParameters() + { + return $this->parameters->all(); + } + + /** + * @param string $key + * + * @return mixed + */ + protected function getParameter($key) + { + return $this->parameters->get($key); + } + + /** + * @param string $key + * @param mixed $value + * + * @return $this + */ + protected function setParameter($key, $value) + { + $this->parameters->set($key, $value); + + return $this; + } + + /** + * @return string + */ + public function getFirstName() + { + return $this->getParameter('firstName'); + } + + /** + * @param string $value + * + * @return Customer + */ + public function setFirstName($value) + { + return $this->setParameter('firstName', $value); + } + + /** + * @return string + */ + public function getLastName() + { + return $this->getParameter('lastName'); + } + + /** + * @param string $value + * + * @return Customer + */ + public function setLastName($value) + { + return $this->setParameter('lastName', $value); + } + + /** + * @return string + */ + public function getEmail() + { + return $this->getParameter('email'); + } + + /** + * @param string $value + * + * @return Customer + */ + public function setEmail($value) + { + return $this->setParameter('email', $value); + } + + /** + * @return string + */ + public function getCity() + { + return $this->getParameter('city'); + } + + /** + * @param string $value + * + * @return Customer + */ + public function setCity($value) + { + return $this->setParameter('city', $value); + } + + /** + * @return string + */ + public function getStreet() + { + return $this->getParameter('street'); + } + + /** + * @param string $value + * + * @return Customer + */ + public function setStreet($value) + { + return $this->setParameter('street', $value); + } + + /** + * @return string + */ + public function getPostcode() + { + return $this->getParameter('postCode'); + } + + /** + * @param string $value + * + * @return Customer + */ + public function setPostcode($value) + { + return $this->setParameter('postCode', $value); + } + + /** + * @return string + */ + public function getCountry() + { + return $this->getParameter('country'); + } + + /** + * @param string $value + * + * @return Customer + */ + public function setCountry($value) + { + return $this->setParameter('country', $value); + } + + /** + * @return string + */ + public function getCountryCode() + { + return $this->getParameter('countryCode'); + } + + /** + * @param string $value + * + * @return Customer + */ + public function setCountryCode($value) + { + return $this->setParameter('countryCode', $value); + } + + /** + * @return string + */ + public function getState() + { + return $this->getParameter('state'); + } + + /** + * @param string $value + * + * @return Customer + */ + public function setState($value) + { + return $this->setParameter('state', $value); + } +} diff --git a/src/Gateway.php b/src/Gateway.php new file mode 100644 index 0000000..748f1f4 --- /dev/null +++ b/src/Gateway.php @@ -0,0 +1,114 @@ + true, + 'version' => self::VERSION, + ]; + } + + /** + * @return string + */ + public function getProjectId() + { + return $this->getParameter('projectId'); + } + + /** + * @param string $value + * + * @return $this + */ + public function setProjectId($value) + { + return $this->setParameter('projectId', $value); + } + + /** + * @return string + */ + public function getPassword() + { + return $this->getParameter('password'); + } + + /** + * @param string $value + * + * @return $this + */ + public function setPassword($value) + { + return $this->setParameter('password', $value); + } + + /** + * @return string + */ + public function getVersion() + { + return $this->getParameter('version'); + } + + /** + * @param string $value + * + * @return $this + */ + public function setVersion($value) + { + return $this->setParameter('version', $value); + } + + /** + * @param array $parameters + * + * @return PurchaseRequest + */ + public function purchase(array $parameters = []) + { + return $this->createRequest(PurchaseRequest::class, $parameters); + } + + /** + * @return PurchaseRequest + */ + public function acceptNotification() + { + return $this->createRequest(AcceptNotificationRequest::class, []); + } +} diff --git a/src/Message/AbstractRequest.php b/src/Message/AbstractRequest.php new file mode 100644 index 0000000..8463fdb --- /dev/null +++ b/src/Message/AbstractRequest.php @@ -0,0 +1,53 @@ +getParameter('projectId'); + } + + /** + * @param string $value + * + * @return $this + */ + public function setProjectId($value) + { + return $this->setParameter('projectId', $value); + } + + /** + * @return string + */ + public function getPassword() + { + return $this->getParameter('password'); + } + + /** + * @param string $value + * + * @return $this + */ + public function setPassword($value) + { + return $this->setParameter('password', $value); + } +} diff --git a/src/Message/AcceptNotificationRequest.php b/src/Message/AcceptNotificationRequest.php new file mode 100644 index 0000000..03e0210 --- /dev/null +++ b/src/Message/AcceptNotificationRequest.php @@ -0,0 +1,58 @@ + $this->httpRequest->get('data'), + 'ss1' => $this->httpRequest->get('ss1'), + 'ss2' => $this->httpRequest->get('ss2'), + ]; + } + + /** + * @param array $data + * + * @return AcceptNotificationResponse + * @throws InvalidRequestException + */ + public function sendData($data) + { + if (false === SignatureValidator::isValid($data, $this->getPassword(), $this->httpClient)) { + throw new InvalidRequestException('Invalid signature'); + } + + return $this->response = new AcceptNotificationResponse($this, $this->parseData($data['data'])); + } + + /** + * @param string $data + * + * @return array + */ + protected function parseData($data) + { + $parameters = []; + parse_str(Encoder::decode($data), $parameters); + + return $parameters; + } +} diff --git a/src/Message/AcceptNotificationResponse.php b/src/Message/AcceptNotificationResponse.php new file mode 100644 index 0000000..a4a8b73 --- /dev/null +++ b/src/Message/AcceptNotificationResponse.php @@ -0,0 +1,103 @@ +getDataValueOrNull('type') !== 'macro') { + throw new InvalidResponseException('Only macro payment callbacks are accepted'); + } + + if ($this->isSuccessful()) { + echo 'OK'; + } + } + + /** + * @inheritdoc + */ + public function isSuccessful() + { + return '1' === $this->getCode(); + } + + /** + * @inheritdoc + */ + public function getTransactionReference() + { + return $this->getDataValueOrNull('orderid'); + } + + /** + * @inheritdoc + */ + public function getTransactionStatus() + { + switch ($this->getCode()) { + case '0': + return NotificationInterface::STATUS_FAILED; + case '1': + return NotificationInterface::STATUS_COMPLETED; + default: + return NotificationInterface::STATUS_PENDING; + } + } + + /** + * @inheritdoc + */ + public function getCode() + { + return $this->getDataValueOrNull('status'); + } + + /** + * @return bool + */ + public function isTestMode() + { + return $this->getDataValueOrNull('test') !== '0'; + } + + public function getMessage() + { + return $this->getDataValueOrNull('paytext'); + } + + /** + * @param string $name + * + * @return string + */ + protected function getDataValueOrNull($name) + { + return isset($this->data[$name]) ? $this->data[$name] : null; + } +} diff --git a/src/Message/PurchaseRequest.php b/src/Message/PurchaseRequest.php new file mode 100644 index 0000000..ae7c77e --- /dev/null +++ b/src/Message/PurchaseRequest.php @@ -0,0 +1,104 @@ +validate('projectId', 'password'); + + $data = PurchaseDataGenerator::generate($this); + + return [ + 'data' => $data, + 'sign' => SignatureGenerator::generate($data, $this->getPassword()), + ]; + } + + /** + * @param array $data + * + * @return PurchaseResponse + */ + public function sendData($data) + { + return $this->response = new PurchaseResponse($this, $data); + } + + /** + * @return string + */ + public function getVersion() + { + return $this->getParameter('version'); + } + + /** + * @param string $value + * + * @return $this + */ + public function setVersion($value) + { + return $this->setParameter('version', $value); + } + + /** + * @return string + */ + public function getLanguage() + { + return $this->getParameter('language'); + } + + /** + * @param string $value + * + * @return $this + */ + public function setLanguage($value) + { + return $this->setParameter('language', $value); + } + + /** + * @return Customer + */ + public function getCustomer() + { + return $this->getParameter('customer'); + } + + /** + * @param Customer $value + * + * @return $this + */ + public function setCustomer($value) + { + if ($value && false === $value instanceof Customer) { + $value = new Customer($value); + } + + return $this->setParameter('customer', $value); + } +} diff --git a/src/Message/PurchaseResponse.php b/src/Message/PurchaseResponse.php new file mode 100644 index 0000000..c14b0cf --- /dev/null +++ b/src/Message/PurchaseResponse.php @@ -0,0 +1,70 @@ +getEndpoint(); + } + + /** + * @return string + */ + public function getRedirectMethod() + { + return Request::METHOD_POST; + } + + /** + * @return array + */ + public function getRedirectData() + { + return $this->getData(); + } + + /** + * @return bool + */ + public function isRedirect() + { + return true; + } + + /** + * @return string + */ + protected function getEndpoint() + { + return 'https://www.paysera.com/pay/'; + } +} diff --git a/tests/GatewayTest.php b/tests/GatewayTest.php new file mode 100644 index 0000000..0d5aa81 --- /dev/null +++ b/tests/GatewayTest.php @@ -0,0 +1,73 @@ +projectId = uniqid('', true); + $this->password = uniqid('', true); + $this->gateway = new Gateway($this->getHttpClient(), $this->getHttpRequest()); + $this->gateway + ->setProjectId($this->projectId) + ->setPassword($this->password); + } + + public function testDefaultParameters() + { + $this->assertSame($this->projectId, $this->gateway->getProjectId()); + $this->assertSame($this->password, $this->gateway->getPassword()); + $this->assertTrue($this->gateway->getTestMode()); + } + + public function testPurchase() + { + $this->assertTrue($this->gateway->supportsPurchase()); + + $request = $this->gateway->purchase(['amount' => 10.5]); + $this->assertInstanceOf(PurchaseRequest::class, $request); + $this->assertSame(1050, $request->getAmountInteger()); + } + + public function testAcceptNotification() + { + $this->assertTrue($this->gateway->supportsAcceptNotification()); + + $request = $this->gateway->acceptNotification(); + $this->assertInstanceOf(AcceptNotificationRequest::class, $request); + } +} diff --git a/tests/Message/AcceptNotificationRequestTest.php b/tests/Message/AcceptNotificationRequestTest.php new file mode 100644 index 0000000..0a95a91 --- /dev/null +++ b/tests/Message/AcceptNotificationRequestTest.php @@ -0,0 +1,220 @@ +projectId = uniqid('', true); + $this->password = uniqid('', true); + + $this->httpRequest = $this->getHttpRequest(); + } + + public function testSendSuccess() + { + $this->httpRequest->attributes->replace($this->notifyData($this->getSuccessData())); + + /** @var AcceptNotificationResponse $response */ + $response = $this->createRequest()->send(); + + $this->assertTrue($response->isSuccessful()); + $this->assertSame($this->getSuccessData()['orderid'], $response->getTransactionReference()); + $this->assertSame(NotificationInterface::STATUS_COMPLETED, $response->getTransactionStatus()); + $this->assertSame('1', $response->getCode()); + $this->assertTrue($response->isTestMode()); + $this->assertSame($this->getSuccessData()['paytext'], $response->getMessage()); + } + + public function testSendFailed() + { + $failedData = $this->getSuccessData(); + $failedData['status'] = '0'; + + $this->httpRequest->attributes->replace($this->notifyData($failedData)); + + /** @var AcceptNotificationResponse $response */ + $response = $this->createRequest()->send(); + + $this->assertFalse($response->isSuccessful()); + $this->assertSame(NotificationInterface::STATUS_FAILED, $response->getTransactionStatus()); + $this->assertSame('0', $response->getCode()); + } + + public function testSendPending() + { + $pendingData = $this->getSuccessData(); + $pendingData['status'] = '2'; + + $this->httpRequest->attributes->replace($this->notifyData($pendingData)); + + /** @var AcceptNotificationResponse $response */ + $response = $this->createRequest()->send(); + + $this->assertFalse($response->isSuccessful()); + $this->assertSame(NotificationInterface::STATUS_PENDING, $response->getTransactionStatus()); + $this->assertSame('2', $response->getCode()); + } + + public function testSendFailure_SignatureIsInvalid_InvalidSS1() + { + $notifyData = $this->notifyData($this->getSuccessData()); + $notifyData['ss1'] = 'invalid_signature'; + + $this->httpRequest->attributes->replace($notifyData); + + $this->setExpectedException(InvalidRequestException::class, 'Invalid signature'); + $this->createRequest()->send(); + } + + public function testSendFailure_SignatureIsInvalid_InvalidSS2() + { + $notifyData = $this->notifyData($this->getSuccessData()); + $notifyData['ss2'] = 'invalid_signature'; + + $this->httpRequest->attributes->replace($notifyData); + + $this->setExpectedException(InvalidRequestException::class, 'Invalid signature'); + $this->createRequest()->send(); + } + + public function testSendFailure_SignatureIsInvalid_BadResponseForSS2() + { + $notifyData = $this->notifyData($this->getSuccessData()); + $notifyData['ss2'] = 'invalid_signature'; + + $this->httpRequest->attributes->replace($notifyData); + + $this->setExpectedException(InvalidRequestException::class, 'Invalid signature'); + $this->createRequest()->send(); + } + + public function testSendFailure_InvalidNotifyType() + { + $pendingData = $this->getSuccessData(); + $pendingData['type'] = 'not_macro'; + + $this->httpRequest->attributes->replace($this->notifyData($pendingData)); + + $this->setExpectedException(InvalidResponseException::class); + $this->createRequest()->send(); + } + + /** + * @param array $data + * + * @return array + */ + private function notifyData(array $data) + { + $encodedData = $this->getEncodedData($data); + + return [ + 'data' => $encodedData, + 'ss1' => SignatureGenerator::generate($encodedData, $this->password), + 'ss2' => $this->getSS2Signature($encodedData), + ]; + } + + /** + * @param array $data + * + * @return string + */ + private function getEncodedData(array $data) + { + return Encoder::encode(http_build_query($data, '', '&')); + } + + /** + * @param string $data + * + * @return string + */ + private function getSS2Signature($data) + { + $resource = openssl_pkey_new(); + openssl_pkey_export($resource, $privateKey); + + $privateKey = openssl_pkey_get_private($privateKey); + openssl_sign($data, $ss2, $privateKey); + + $publicKey = openssl_pkey_get_details($resource); + + $response = $this->getMockHttpResponse('PubKeyResponse.txt'); + $response->setBody($publicKey['key']); + $this->setMockHttpResponse([$response]); + + return Encoder::encode($ss2); + } + + /** + * @return array + */ + public function getSuccessData() + { + return [ + 'projectId' => $this->projectId, + 'orderid' => 'order_id', + 'version' => '1.6', + 'lang' => 'LIT', + 'type' => 'macro', + 'amount' => '1000', + 'currency' => 'EUR', + 'country' => 'LT', + 'paytext' => 'some information', + 'status' => '1', + 'test' => '1', + ]; + } + + /** + * @return AcceptNotificationRequest + */ + private function createRequest() + { + $request = new AcceptNotificationRequest($this->getHttpClient(), $this->httpRequest); + $request + ->setProjectId($this->projectId) + ->setPassword($this->password); + + return $request; + } +} diff --git a/tests/Message/PurchaseRequestTest.php b/tests/Message/PurchaseRequestTest.php new file mode 100644 index 0000000..d64e9a9 --- /dev/null +++ b/tests/Message/PurchaseRequestTest.php @@ -0,0 +1,164 @@ +request = new PurchaseRequest($this->getHttpClient(), $this->getHttpRequest()); + $this->projectId = uniqid('', true); + $this->password = uniqid('', true); + } + + public function testData() + { + $this->request->initialize($this->getValidParameters()); + + $this->assertEquals($this->request->getData(), $this->getData()); + } + + public function testSendSuccess() + { + $this->request->initialize($this->getValidParameters()); + + /** @var PurchaseResponse $response */ + $response = $this->request->send(); + + $this->assertFalse($response->isSuccessful()); + $this->assertTrue($response->isRedirect()); + $this->assertNull($response->getMessage()); + $this->assertSame($response->getRedirectUrl(), 'https://www.paysera.com/pay/'); + $this->assertSame($response->getRedirectData(), $this->request->getData()); + $this->assertSame($response->getRedirectMethod(), 'POST'); + } + + public function testSendFailure_InvalidParameter_MissingRequired() + { + $this->setExpectedException(InvalidRequestException::class); + $this->request->initialize($this->getParametersWithMissing()); + $this->request->send(); + } + + public function testSendFailure_InvalidParameter_TooLong() + { + $this->setExpectedException(InvalidRequestException::class); + $this->request->initialize($this->getParametersWithOneTooLong()); + $this->request->send(); + } + + public function testSendFailure_InvalidParameter_Regex() + { + $this->setExpectedException(InvalidRequestException::class); + $this->request->initialize($this->getParametersWithOneInvalidRegex()); + $this->request->send(); + } + + /** + * @return array + */ + private function getValidParameters() + { + return [ + 'projectId' => $this->projectId, + 'password' => $this->password, + 'transactionId' => 'order_id', + 'returnUrl' => 'http://return-url.com', + 'cancelUrl' => 'http://cancel-url.com', + 'notifyUrl' => 'http://notify-url.com', + 'language' => 'LIT', + 'currency' => 'EUR', + 'amount' => 10.0, + 'customer' => [ + 'firstName' => 'first_name', + 'lastName' => 'last_name', + 'email' => 'email@mail.com', + 'city' => 'city', + 'street' => 'street', + 'postCode' => 12345, + 'countryCode' => 'lt', + 'country' => 'lt', + 'state' => 'state', + ], + ]; + } + + /** + * @return array + */ + private function getParametersWithMissing() + { + return [ + 'projectId' => $this->projectId, + 'password' => $this->password, + ]; + } + + /** + * @return array + */ + private function getParametersWithOneTooLong() + { + $parameters = $this->getValidParameters(); + $parameters['language'] = 123; + + return $parameters; + } + + /** + * @return array + */ + private function getParametersWithOneInvalidRegex() + { + $parameters = $this->getValidParameters(); + $parameters['transactionId'] = str_repeat('really_too_long', 100); + + return $parameters; + } + + /** + * @return array + */ + private function getData() + { + $data = PurchaseDataGenerator::generate($this->request); + + return [ + 'data' => $data, + 'sign' => SignatureGenerator::generate($data, $this->password), + ]; + } +} diff --git a/tests/Mock/PubKeyResponse.txt b/tests/Mock/PubKeyResponse.txt new file mode 100644 index 0000000..1eb5482 --- /dev/null +++ b/tests/Mock/PubKeyResponse.txt @@ -0,0 +1,17 @@ +HTTP/1.1 200 Created +Date: Sun, 16 Oct 2016 08:49:36 GMT +X-Content-Type-Options: nosniff +Last-Modified: Fri, 14 Oct 2016 15:14:30 GMT +Server: nginx +ETag: "5800f656-5b5" +Strict-Transport-Security: max-age=16070400; includeSubDomains; preload +Content-Type: application/octet-stream +Connection: keep-alive +Accept-Ranges: bytes +X-Backend: pay-web2 +Content-Length: 1461 +X-XSS-Protection: 1; mode=block + +{ + +} \ No newline at end of file