diff --git a/.travis.yml b/.travis.yml index c5b23e1..34dd93c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,16 +11,57 @@ addons: hosts: - magento2.travis language: php -php: - - 7.1 +matrix: + include: + - php: 7.1 + env: + - MAGENTO_VERSION=2.3-develop + - TEST_SUITE=unit + - php: 7.1 + env: + - MAGENTO_VERSION=2.2-develop + - TEST_SUITE=unit + - php: 7.1 + env: + - MAGENTO_VERSION=2.2-develop + - TEST_SUITE=integration + - php: 7.1 + env: + - MAGENTO_VERSION=2.2.2 + - TEST_SUITE=unit + - php: 7.1 + env: + - MAGENTO_VERSION=2.2.2 + - TEST_SUITE=integration + - php: 7.0 + env: + - MAGENTO_VERSION=2.3-develop + - TEST_SUITE=unit + - php: 7.0 + env: + - MAGENTO_VERSION=2.2-develop + - TEST_SUITE=unit + - php: 7.0 + env: + - MAGENTO_VERSION=2.2-develop + - TEST_SUITE=integration + - php: 7.0 + env: + - MAGENTO_VERSION=2.2.2 + - TEST_SUITE=unit + - php: 7.0 + env: + - MAGENTO_VERSION=2.2.2 + - TEST_SUITE=integration env: global: - COMPOSER_BIN_DIR=~/bin - matrix: - - TEST_SUITE=unit + - STRIPE_MOCK_VERSION=0.5.0 + - COMPOSER_PACKAGE_NAME=pmclain/module-stripe cache: apt: true directories: - $HOME/.composer/cache + - stripe-mock before_script: ./.travis/before_script.sh script: phpunit -c magento2/dev/tests/$TEST_SUITE diff --git a/.travis/before_script.sh b/.travis/before_script.sh index 0b2b1aa..55a31a5 100755 --- a/.travis/before_script.sh +++ b/.travis/before_script.sh @@ -3,6 +3,17 @@ set -e trap '>&2 echo Error: Command \`$BASH_COMMAND\` on line $LINENO failed with exit code $?' ERR +# download stripe mock +if [ ! -d "stripe-mock/stripe-mock_${STRIPE_MOCK_VERSION}" ]; then + mkdir -p stripe-mock/stripe-mock_${STRIPE_MOCK_VERSION}/ + curl -L "https://github.com/stripe/stripe-mock/releases/download/v${STRIPE_MOCK_VERSION}/stripe-mock_${STRIPE_MOCK_VERSION}_linux_amd64.tar.gz" -o "stripe-mock/stripe-mock_${STRIPE_MOCK_VERSION}_linux_amd64.tar.gz" + tar -zxf "stripe-mock/stripe-mock_${STRIPE_MOCK_VERSION}_linux_amd64.tar.gz" -C "stripe-mock/stripe-mock_${STRIPE_MOCK_VERSION}/" +fi + +# start stripe mock +stripe-mock/stripe-mock_${STRIPE_MOCK_VERSION}/stripe-mock > /dev/null & +STRIPE_MOCK_PID=$! + # mock mail sudo service postfix stop echo # print a newline @@ -17,20 +28,20 @@ phpenv rehash; composer selfupdate # clone main magento github repository -git clone --branch 2.2.2 --depth=1 https://github.com/magento/magento2 +git clone --branch $MAGENTO_VERSION --depth=1 https://github.com/magento/magento2 # install Magento cd magento2 # add composer package under test, composer require will trigger update/install composer config minimum-stability dev -composer config repositories.travis_to_test git https://github.com/pmclain/module-stripe.git -composer require pmclain/module-stripe:dev-master#$TRAVIS_COMMIT +composer config repositories.travis_to_test git https://github.com/$TRAVIS_REPO_SLUG.git +composer require $COMPOSER_PACKAGE_NAME:dev-$TRAVIS_BRANCH#$TRAVIS_COMMIT # prepare for test suite case $TEST_SUITE in integration) - cp vendor/pmclain/module-stripe/Test/Integration/phpunit.xml.dist dev/tests/integration/phpunit.xml + cp vendor/$COMPOSER_PACKAGE_NAME/Test/Integration/phpunit.xml.dist dev/tests/integration/phpunit.xml cd dev/tests/integration @@ -58,6 +69,6 @@ case $TEST_SUITE in cd ../../.. ;; unit) - cp vendor/pmclain/module-stripe/Test/Unit/phpunit.xml.dist dev/tests/unit/phpunit.xml + cp vendor/$COMPOSER_PACKAGE_NAME/Test/Unit/phpunit.xml.dist dev/tests/unit/phpunit.xml ;; esac diff --git a/Block/Customer/CardRenderer.php b/Block/Customer/CardRenderer.php index e75a82e..f5cc0d6 100644 --- a/Block/Customer/CardRenderer.php +++ b/Block/Customer/CardRenderer.php @@ -13,6 +13,7 @@ * @copyright Copyright (c) 2017-2018 * @license Open Software License (OSL 3.0) */ + namespace Pmclain\Stripe\Block\Customer; use Pmclain\Stripe\Model\Ui\ConfigProvider; @@ -21,54 +22,54 @@ class CardRenderer extends AbstractCardRenderer { - /** - * Can render specified token - * - * @param PaymentTokenInterface $token - * @return boolean - */ - public function canRender(PaymentTokenInterface $token) - { - return $token->getPaymentMethodCode() === ConfigProvider::CODE; - } + /** + * Can render specified token + * + * @param PaymentTokenInterface $token + * @return boolean + */ + public function canRender(PaymentTokenInterface $token) + { + return $token->getPaymentMethodCode() === ConfigProvider::CODE; + } - /** - * @return string - */ - public function getNumberLast4Digits() - { - return $this->getTokenDetails()['maskedCC']; - } + /** + * @return string + */ + public function getNumberLast4Digits() + { + return $this->getTokenDetails()['maskedCC']; + } - /** - * @return string - */ - public function getExpDate() - { - return $this->getTokenDetails()['expirationDate']; - } + /** + * @return string + */ + public function getExpDate() + { + return $this->getTokenDetails()['expirationDate']; + } - /** - * @return string - */ - public function getIconUrl() - { - return $this->getIconForType($this->getTokenDetails()['type'])['url']; - } + /** + * @return string + */ + public function getIconUrl() + { + return $this->getIconForType($this->getTokenDetails()['type'])['url']; + } - /** - * @return int - */ - public function getIconHeight() - { - return $this->getIconForType($this->getTokenDetails()['type'])['height']; - } + /** + * @return int + */ + public function getIconHeight() + { + return $this->getIconForType($this->getTokenDetails()['type'])['height']; + } - /** - * @return int - */ - public function getIconWidth() - { - return $this->getIconForType($this->getTokenDetails()['type'])['width']; - } + /** + * @return int + */ + public function getIconWidth() + { + return $this->getIconForType($this->getTokenDetails()['type'])['width']; + } } diff --git a/Block/Form.php b/Block/Form.php index 8f826e2..596c414 100755 --- a/Block/Form.php +++ b/Block/Form.php @@ -13,6 +13,7 @@ * @copyright Copyright (c) 2017-2018 * @license Open Software License (OSL 3.0) */ + namespace Pmclain\Stripe\Block; use Pmclain\Stripe\Gateway\Config\Config as GatewayConfig; @@ -21,48 +22,60 @@ use Magento\Payment\Model\Config; use Magento\Payment\Helper\Data as Helper; use Pmclain\Stripe\Model\Ui\ConfigProvider; +use Magento\Vault\Model\VaultPaymentInterface; class Form extends Cc { - /** @var GatewayConfig $gatewayConfig */ - protected $gatewayConfig; + /** @var GatewayConfig $gatewayConfig */ + protected $gatewayConfig; - /** @var Helper $paymentDataHelper */ - private $paymentDataHelper; + /** @var Helper $paymentDataHelper */ + private $paymentDataHelper; - public function __construct( - Context $context, - Config $paymentConfig, - GatewayConfig $gatewayConfig, - Helper $helper, - array $data = [] - ) { - parent::__construct($context, $paymentConfig, $data); - $this->gatewayConfig = $gatewayConfig; - $this->paymentDataHelper = $helper; - } + /** + * Form constructor. + * @param Context $context + * @param Config $paymentConfig + * @param GatewayConfig $gatewayConfig + * @param Helper $helper + * @param array $data + */ + public function __construct( + Context $context, + Config $paymentConfig, + GatewayConfig $gatewayConfig, + Helper $helper, + array $data = [] + ) { + parent::__construct($context, $paymentConfig, $data); + $this->gatewayConfig = $gatewayConfig; + $this->paymentDataHelper = $helper; + } - public function useCcv() { - return $this->gatewayConfig->isCcvEnabled(); - } + /** + * @return bool + */ + public function useCcv() + { + return $this->gatewayConfig->isCcvEnabled(); + } - /** - * Check if vault enabled - * @return bool - */ - public function isVaultEnabled() - { - $storeId = $this->_storeManager->getStore()->getId(); - $vaultPayment = $this->getVaultPayment(); - return $vaultPayment->isActive($storeId); - } + /** + * Check if vault enabled + * @return bool + */ + public function isVaultEnabled() + { + $storeId = $this->_storeManager->getStore()->getId(); + $vaultPayment = $this->getVaultPayment(); + return $vaultPayment->isActive($storeId); + } - /** - * Get configured vault payment for Braintree - * @return VaultPaymentInterface - */ - private function getVaultPayment() - { - return $this->paymentDataHelper->getMethodInstance(ConfigProvider::CC_VAULT_CODE); - } -} \ No newline at end of file + /** + * @return VaultPaymentInterface + */ + private function getVaultPayment() + { + return $this->paymentDataHelper->getMethodInstance(ConfigProvider::CC_VAULT_CODE); + } +} diff --git a/Block/Info.php b/Block/Info.php index dbac897..73109d7 100755 --- a/Block/Info.php +++ b/Block/Info.php @@ -13,6 +13,7 @@ * @copyright Copyright (c) 2017-2018 * @license Open Software License (OSL 3.0) */ + namespace Pmclain\Stripe\Block; use Magento\Framework\Phrase; @@ -20,14 +21,14 @@ class Info extends ConfigurableInfo { - /** - * Returns label - * - * @param string $field - * @return Phrase - */ - protected function getLabel($field) - { - return __($field); - } -} \ No newline at end of file + /** + * Returns label + * + * @param string $field + * @return Phrase + */ + protected function getLabel($field) + { + return __($field); + } +} diff --git a/Block/Payment.php b/Block/Payment.php index 05eca0d..55bb9bd 100644 --- a/Block/Payment.php +++ b/Block/Payment.php @@ -13,6 +13,7 @@ * @copyright Copyright (c) 2017-2018 * @license Open Software License (OSL 3.0) */ + namespace Pmclain\Stripe\Block; use Pmclain\Stripe\Model\Ui\ConfigProvider; @@ -24,43 +25,43 @@ */ class Payment extends Template { - /** - * @var ConfigProvider - */ - private $config; + /** + * @var ConfigProvider + */ + private $config; - /** - * Constructor - * - * @param Context $context - * @param ConfigProvider $config - * @param array $data - */ - public function __construct( - Context $context, - ConfigProvider $config, - array $data = [] - ) { - parent::__construct($context, $data); - $this->config = $config; - } + /** + * Constructor + * + * @param Context $context + * @param ConfigProvider $config + * @param array $data + */ + public function __construct( + Context $context, + ConfigProvider $config, + array $data = [] + ) { + parent::__construct($context, $data); + $this->config = $config; + } - /** - * @return string - */ - public function getPaymentConfig() - { - $payment = $this->config->getConfig()['payment']; - $config = $payment[$this->getCode()]; - $config['code'] = $this->getCode(); - return json_encode($config, JSON_UNESCAPED_SLASHES); - } + /** + * @return string + */ + public function getPaymentConfig() + { + $payment = $this->config->getConfig()['payment']; + $config = $payment[$this->getCode()]; + $config['code'] = $this->getCode(); + return json_encode($config, JSON_UNESCAPED_SLASHES); + } - /** - * @return string - */ - public function getCode() - { - return ConfigProvider::CODE; - } + /** + * @return string + */ + public function getCode() + { + return ConfigProvider::CODE; + } } diff --git a/Controller/ThreeDSecure/Redirect.php b/Controller/ThreeDSecure/Redirect.php new file mode 100644 index 0000000..ea61a27 --- /dev/null +++ b/Controller/ThreeDSecure/Redirect.php @@ -0,0 +1,79 @@ +session = $session; + $this->orderPlace = $orderPlace; + } + + public function execute() + { + $resultRedirect = $this->resultRedirectFactory->create(); + + $quote = $this->session->getQuote(); + + try { + $this->validateQuote($quote); + + $this->orderPlace->execute( + $quote, + $this->getRequest()->getParam('source'), + $this->getRequest()->getParam('client_secret') + ); + + $resultRedirect->setPath('checkout/onepage/success', ['_secure' => true]); + } catch (\InvalidArgumentException $e) { + $this->messageManager->addErrorMessage($e->getMessage()); + $resultRedirect->setPath('checkout/cart', ['_secure' => true]); + } catch (\Exception $e) { + $this->messageManager->addErrorMessage($e->getMessage()); + $resultRedirect->setPath('checkout/cart', ['_secure' => true]); + } + + return $resultRedirect; + } + + private function validateQuote($quote) + { + if (!$quote || !$quote->getItemsCount()) { + throw new \InvalidArgumentException(__('We can\'t initialize checkout.')); + } + } +} diff --git a/Gateway/Command/CaptureStrategyCommand.php b/Gateway/Command/CaptureStrategyCommand.php index 38471e1..6244867 100755 --- a/Gateway/Command/CaptureStrategyCommand.php +++ b/Gateway/Command/CaptureStrategyCommand.php @@ -13,6 +13,7 @@ * @copyright Copyright (c) 2017-2018 * @license Open Software License (OSL 3.0) */ + namespace Pmclain\Stripe\Gateway\Command; use Pmclain\Stripe\Model\Adapter\StripeAdapter; @@ -30,75 +31,116 @@ class CaptureStrategyCommand implements CommandInterface { - const SALE = 'sale'; - - const CAPTURE = 'settlement'; + const SALE = 'sale'; - private $commandPool; - private $transactionRepository; - private $filterBuilder; - private $searchCriteriaBuilder; - private $subjectReader; - private $stripeAdapter; + const CAPTURE = 'settlement'; - public function __construct( - CommandPoolInterface $commandPool, - TransactionRepositoryInterface $repository, - FilterBuilder $filterBuilder, - SearchCriteriaBuilder $searchCriteriaBuilder, - SubjectReader $subjectReader, - StripeAdapter $stripeAdapter - ) { - $this->commandPool = $commandPool; - $this->transactionRepository = $repository; - $this->filterBuilder = $filterBuilder; - $this->searchCriteriaBuilder = $searchCriteriaBuilder; - $this->subjectReader = $subjectReader; - $this->stripeAdapter = $stripeAdapter; - } + /** + * @var CommandPoolInterface + */ + private $commandPool; + /** + * @var TransactionRepositoryInterface + */ + private $transactionRepository; + /** + * @var FilterBuilder + */ + private $filterBuilder; + /** + * @var SearchCriteriaBuilder + */ + private $searchCriteriaBuilder; + /** + * @var SubjectReader + */ + private $subjectReader; + /** + * @var StripeAdapter + */ + private $stripeAdapter; - public function execute(array $commandSubject) { - $paymentDataObject = $this->subjectReader->readPayment($commandSubject); - $paymentInfo = $paymentDataObject->getPayment(); - ContextHelper::assertOrderPayment($paymentInfo); + /** + * CaptureStrategyCommand constructor. + * @param CommandPoolInterface $commandPool + * @param TransactionRepositoryInterface $repository + * @param FilterBuilder $filterBuilder + * @param SearchCriteriaBuilder $searchCriteriaBuilder + * @param SubjectReader $subjectReader + * @param StripeAdapter $stripeAdapter + */ + public function __construct( + CommandPoolInterface $commandPool, + TransactionRepositoryInterface $repository, + FilterBuilder $filterBuilder, + SearchCriteriaBuilder $searchCriteriaBuilder, + SubjectReader $subjectReader, + StripeAdapter $stripeAdapter + ) { + $this->commandPool = $commandPool; + $this->transactionRepository = $repository; + $this->filterBuilder = $filterBuilder; + $this->searchCriteriaBuilder = $searchCriteriaBuilder; + $this->subjectReader = $subjectReader; + $this->stripeAdapter = $stripeAdapter; + } - $command = $this->getCommand($paymentInfo); - $this->commandPool->get($command)->execute($commandSubject); - } + /** + * @param array $commandSubject + */ + public function execute(array $commandSubject) + { + $paymentDataObject = $this->subjectReader->readPayment($commandSubject); + $paymentInfo = $paymentDataObject->getPayment(); + ContextHelper::assertOrderPayment($paymentInfo); - private function getCommand(OrderPaymentInterface $payment) { - $existsCapture = $this->isExistsCaptureTransaction($payment); - if(!$payment->getAuthorizationTransaction() && !$existsCapture) { - return self::SALE; + $command = $this->getCommand($paymentInfo); + $this->commandPool->get($command)->execute($commandSubject); } - if(!$existsCapture) { - return self::CAPTURE; + /** + * @param OrderPaymentInterface $payment + * @return string + */ + private function getCommand(OrderPaymentInterface $payment) + { + $existsCapture = $this->isExistsCaptureTransaction($payment); + if (!$payment->getAuthorizationTransaction() && !$existsCapture) { + return self::SALE; + } + + if (!$existsCapture) { + return self::CAPTURE; + } } - } - private function isExistsCaptureTransaction(OrderPaymentInterface $payment) { - $this->searchCriteriaBuilder->addFilters( - [ - $this->filterBuilder - ->setField('payment_id') - ->setValue($payment->getId()) - ->create() - ] - ); + /** + * @param OrderPaymentInterface $payment + * @return bool + */ + private function isExistsCaptureTransaction(OrderPaymentInterface $payment) + { + $this->searchCriteriaBuilder->addFilters( + [ + $this->filterBuilder + ->setField('payment_id') + ->setValue($payment->getId()) + ->create() + ] + ); - $this->searchCriteriaBuilder->addFilters( - [ - $this->filterBuilder - ->setField('txn_type') - ->setValue(TransactionInterface::TYPE_CAPTURE) - ->create() - ] - ); + $this->searchCriteriaBuilder->addFilters( + [ + $this->filterBuilder + ->setField('txn_type') + ->setValue(TransactionInterface::TYPE_CAPTURE) + ->create() + ] + ); - $searchCriteria = $this->searchCriteriaBuilder->create(); + $searchCriteria = $this->searchCriteriaBuilder->create(); - $count = $this->transactionRepository->getList($searchCriteria)->getTotalCount(); - return (boolean) $count; - } -} \ No newline at end of file + $count = $this->transactionRepository->getList($searchCriteria)->getTotalCount(); + return (boolean)$count; + } +} diff --git a/Gateway/Config/CanVoidHandler.php b/Gateway/Config/CanVoidHandler.php index a0c4a99..06ae60b 100755 --- a/Gateway/Config/CanVoidHandler.php +++ b/Gateway/Config/CanVoidHandler.php @@ -13,6 +13,7 @@ * @copyright Copyright (c) 2017-2018 * @license Open Software License (OSL 3.0) */ + namespace Pmclain\Stripe\Gateway\Config; use Pmclain\Stripe\Gateway\Helper\SubjectReader; @@ -21,18 +22,31 @@ class CanVoidHandler implements ValueHandlerInterface { - private $subjectReader; + /** + * @var SubjectReader + */ + private $subjectReader; - public function __construct( - SubjectReader $subjectReader - ) { - $this->subjectReader = $subjectReader; - } + /** + * CanVoidHandler constructor. + * @param SubjectReader $subjectReader + */ + public function __construct( + SubjectReader $subjectReader + ) { + $this->subjectReader = $subjectReader; + } - public function handle(array $subject, $storeId = NULL) { - $paymentDataObject = $this->subjectReader->readPayment($subject); - $payment = $paymentDataObject->getPayment(); + /** + * @param array $subject + * @param null $storeId + * @return bool + */ + public function handle(array $subject, $storeId = null) + { + $paymentDataObject = $this->subjectReader->readPayment($subject); + $payment = $paymentDataObject->getPayment(); - return $payment instanceof Payment && !(bool)$payment->getAmountPaid(); - } -} \ No newline at end of file + return $payment instanceof Payment && !(bool)$payment->getAmountPaid(); + } +} diff --git a/Gateway/Config/Config.php b/Gateway/Config/Config.php index 491f8aa..696215e 100755 --- a/Gateway/Config/Config.php +++ b/Gateway/Config/Config.php @@ -13,104 +13,133 @@ * @copyright Copyright (c) 2017-2018 * @license Open Software License (OSL 3.0) */ + namespace Pmclain\Stripe\Gateway\Config; class Config extends \Magento\Payment\Gateway\Config\Config { - const KEY_ENVIRONMENT = 'test_mode'; - const KEY_ACTIVE = 'active'; - const KEY_LIVE_PUBLISHABLE_KEY = 'live_publishable_key'; - const KEY_LIVE_SECRET_KEY = 'live_secret_key'; - const KEY_TEST_PUBLISHABLE_KEY = 'test_publishable_key'; - const KEY_TEST_SECRET_KEY = 'test_secret_key'; - const KEY_CURRENCY = 'currency'; - const KEY_CC_TYPES = 'cctypes'; - const KEY_CC_TYPES_STRIPE_MAPPER = 'cctypes_stripe_mapper'; - const KEY_USE_CCV = 'useccv'; - const KEY_ALLOW_SPECIFIC = 'allowspecific'; - const KEY_SPECIFIC_COUNTRY = 'specificcountry'; - const KEY_DEBUG = 'debug'; - - /** - * @return array - */ - public function getAvailableCardTypes() { - $ccTypes = $this->getValue(self::KEY_CC_TYPES); - - return !empty($ccTypes) ? explode(',', $ccTypes) : []; - } - - /** - * @return array|mixed - */ - public function getCcTypesMapper() { - $result = json_decode( - $this->getValue(self::KEY_CC_TYPES_STRIPE_MAPPER), - true - ); - - return is_array($result) ? $result : []; - } - - /** - * @return mixed - */ - public function getCurrency() { - return $this->getValue(self::KEY_CURRENCY); - } - - /** - * @return bool - */ - public function isCcvEnabled() { - return (bool) $this->getValue(self::KEY_USE_CCV); - } - - /** - * @return mixed - */ - public function getEnvironment() { - return $this->getValue(Config::KEY_ENVIRONMENT); - } - - /** - * @return bool - */ - public function isActive() { - return (bool) $this->getValue(self::KEY_ACTIVE); - } - - /** - * @return mixed - */ - public function getPublishableKey() { - if($this->isTestMode()) { - return $this->getValue(self::KEY_TEST_PUBLISHABLE_KEY); + const KEY_ENVIRONMENT = 'test_mode'; + const KEY_ACTIVE = 'active'; + const KEY_LIVE_PUBLISHABLE_KEY = 'live_publishable_key'; + const KEY_LIVE_SECRET_KEY = 'live_secret_key'; + const KEY_TEST_PUBLISHABLE_KEY = 'test_publishable_key'; + const KEY_TEST_SECRET_KEY = 'test_secret_key'; + const KEY_CURRENCY = 'currency'; + const KEY_CC_TYPES = 'cctypes'; + const KEY_CC_TYPES_STRIPE_MAPPER = 'cctypes_stripe_mapper'; + const KEY_USE_CCV = 'useccv'; + const KEY_ALLOW_SPECIFIC = 'allowspecific'; + const KEY_SPECIFIC_COUNTRY = 'specificcountry'; + const KEY_DEBUG = 'debug'; + const KEY_VERIFY_3D_SECURE = 'verify_3dsecure'; + const KEY_3D_SECURE_THRESHOLD = 'threshold_amount'; + + /** + * @return array + */ + public function getAvailableCardTypes() + { + $ccTypes = $this->getValue(self::KEY_CC_TYPES); + + return !empty($ccTypes) ? explode(',', $ccTypes) : []; } - return $this->getValue(self::KEY_LIVE_PUBLISHABLE_KEY); - } - - /** - * @return mixed - */ - public function getSecretKey() { - if($this->isTestMode()) { - return $this->getValue(self::KEY_TEST_SECRET_KEY); + + /** + * @return array|mixed + */ + public function getCcTypesMapper() + { + $result = json_decode( + $this->getValue(self::KEY_CC_TYPES_STRIPE_MAPPER), + true + ); + + return is_array($result) ? $result : []; + } + + /** + * @return mixed + */ + public function getCurrency() + { + return $this->getValue(self::KEY_CURRENCY); + } + + /** + * @return bool + */ + public function isCcvEnabled() + { + return (bool)$this->getValue(self::KEY_USE_CCV); + } + + /** + * @return mixed + */ + public function getEnvironment() + { + return $this->getValue(Config::KEY_ENVIRONMENT); + } + + /** + * @return bool + */ + public function isActive() + { + return (bool)$this->getValue(self::KEY_ACTIVE); + } + + /** + * @return mixed + */ + public function getPublishableKey() + { + if ($this->isTestMode()) { + return $this->getValue(self::KEY_TEST_PUBLISHABLE_KEY); + } + return $this->getValue(self::KEY_LIVE_PUBLISHABLE_KEY); + } + + /** + * @return mixed + */ + public function getSecretKey() + { + if ($this->isTestMode()) { + return $this->getValue(self::KEY_TEST_SECRET_KEY); + } + return $this->getValue(self::KEY_LIVE_SECRET_KEY); + } + + /** + * @return bool + */ + public function isTestMode() + { + return (bool)$this->getValue(self::KEY_ENVIRONMENT); + } + + /** + * @return bool + */ + public function isDebugOn() + { + return (bool)$this->getValue(self::KEY_DEBUG); + } + + /** + * @return bool + */ + public function isRequireThreeDSecure() + { + return (bool)$this->getValue(self::KEY_VERIFY_3D_SECURE); + } + + /** + * @return float + */ + public function getThreeDSecureThreshold() + { + return (float)$this->getValue(self::KEY_3D_SECURE_THRESHOLD); } - return $this->getValue(self::KEY_LIVE_SECRET_KEY); - } - - /** - * @return bool - */ - public function isTestMode() { - return (bool) $this->getValue(self::KEY_ENVIRONMENT); - } - - /** - * @return bool - */ - public function isDebugOn() { - return (bool) $this->getValue(self::KEY_DEBUG); - } -} \ No newline at end of file +} diff --git a/Gateway/Helper/SubjectReader.php b/Gateway/Helper/SubjectReader.php index 7442980..1a4b83f 100755 --- a/Gateway/Helper/SubjectReader.php +++ b/Gateway/Helper/SubjectReader.php @@ -13,54 +13,76 @@ * @copyright Copyright (c) 2017-2018 * @license Open Software License (OSL 3.0) */ + namespace Pmclain\Stripe\Gateway\Helper; use Magento\Payment\Gateway\Helper; class SubjectReader { - /** - * @param array $subject - * @return array - */ - public function readResponseObject(array $subject) { - $response = Helper\SubjectReader::readResponse($subject); + /** + * @param array $subject + * @return array + */ + public function readResponseObject(array $subject) + { + $response = Helper\SubjectReader::readResponse($subject); - if(!is_object($response['object'])) { - throw new \InvalidArgumentException('Response object does not exist'); - } + if (!is_object($response['object'])) { + throw new \InvalidArgumentException('Response object does not exist'); + } + + if ($response['object'] instanceof \Stripe\Error\Card) { + return [ + 'error' => true, + 'message' => __($response['object']->getMessage()) + ]; + } - if($response['object'] instanceof \Stripe\Error\Card) { - return [ - 'error' => true, - 'message' => __($response['object']->getMessage()) - ]; + return $response['object']->__toArray(); } - return $response['object']->__toArray(); - } + /** + * @param array $subject + * @return \Magento\Payment\Gateway\Data\PaymentDataObjectInterface + */ + public function readPayment(array $subject) + { + return Helper\SubjectReader::readPayment($subject); + } - public function readPayment(array $subject) { - return Helper\SubjectReader::readPayment($subject); - } + /** + * @param array $subject + * @return mixed + */ + public function readTransaction(array $subject) + { + if (!is_object($subject['object'])) { + throw new \InvalidArgumentException('Response object does not exist'); + } - public function readTransaction(array $subject) { - if(!is_object($subject['object'])) { - throw new \InvalidArgumentException('Response object does not exist'); + return $subject['object']->__toArray(); } - return $subject['object']->__toArray(); - } + /** + * @param array $subject + * @return mixed + */ + public function readAmount(array $subject) + { + return Helper\SubjectReader::readAmount($subject); + } - public function readAmount(array $subject) { - return Helper\SubjectReader::readAmount($subject); - } + /** + * @param array $subject + * @return int + */ + public function readCustomerId(array $subject) + { + if (!isset($subject['customer_id'])) { + throw new \InvalidArgumentException('The customerId field does not exist'); + } - public function readCustomerId(array $subject) { - if(!isset($subject['customer_id'])) { - throw new \InvalidArgumentException('The customerId field does not exist'); + return (int)$subject['customer_id']; } - - return (int) $subject['customer_id']; - } -} \ No newline at end of file +} diff --git a/Gateway/Http/Client/AbstractTransaction.php b/Gateway/Http/Client/AbstractTransaction.php index 8f42216..4dcdf73 100755 --- a/Gateway/Http/Client/AbstractTransaction.php +++ b/Gateway/Http/Client/AbstractTransaction.php @@ -13,6 +13,7 @@ * @copyright Copyright (c) 2017-2018 * @license Open Software License (OSL 3.0) */ + namespace Pmclain\Stripe\Gateway\Http\Client; use Pmclain\Stripe\Model\Adapter\StripeAdapter; @@ -26,60 +27,89 @@ abstract class AbstractTransaction implements ClientInterface { - protected $logger; + /** + * @var LoggerInterface + */ + protected $logger; + + /** + * @var Logger + */ + protected $customLogger; - protected $customLogger; + /** + * @var StripeAdapter + */ + protected $adapter; - protected $adapter; + /** + * @var Config + */ + protected $config; - protected $config; + /** + * AbstractTransaction constructor. + * @param LoggerInterface $logger + * @param Logger $customLogger + * @param StripeAdapter $adapter + * @param Config $config + */ + public function __construct( + LoggerInterface $logger, + Logger $customLogger, + StripeAdapter $adapter, + Config $config = null + ) { + $this->logger = $logger; + $this->customLogger = $customLogger; + $this->adapter = $adapter; + $this->config = $config ?: ObjectManager::getInstance()->get(Config::class); + } - public function __construct( - LoggerInterface $logger, - Logger $customLogger, - StripeAdapter $adapter, - Config $config = null - ) { - $this->logger = $logger; - $this->customLogger = $customLogger; - $this->adapter = $adapter; - $this->config = $config ?: ObjectManager::getInstance()->get(Config::class); - } + /** + * @param TransferInterface $transferObject + * @return mixed + * @throws ClientException + */ + public function placeRequest( + TransferInterface $transferObject + ) + { + $data = $transferObject->getBody(); + $log = [ + 'request' => $data, + 'client' => static::class + ]; + $response['object'] = []; - public function placeRequest( - TransferInterface $transferObject - ) { - $data = $transferObject->getBody(); - $log = [ - 'request' => $data, - 'client' => static::class - ]; - $response['object'] = []; + try { + $response['object'] = $this->process($data); + } catch (\Exception $e) { + $message = __($e->getMessage() ?: 'Sorry, but something went wrong.'); + $this->logger->critical($e); + throw new ClientException($message); + } finally { + if ($response['object'] instanceof \Stripe\Error\Base + || $response['object'] instanceof \Stripe\StripeObject + ) { + $log['response'] = $response['object']->__toString(); + } else { + $log['response'] = $response['object']; + } - try { - $response['object'] = $this->process($data); - }catch (\Exception $e) { - $message = __($e->getMessage() ?: 'Sorry, but something went wrong.'); - $this->logger->critical($e); - throw new ClientException($message); - }finally { - if ($response['object'] instanceof \Stripe\Error\Base - || $response['object'] instanceof \Stripe\StripeObject - ) { - $log['response'] = $response['object']->__toString(); - } else { - $log['response'] = $response['object']; - } + if ($this->config->isDebugOn()) { + $this->logger->warning(var_export($log, true)); + } - if ($this->config->isDebugOn()) { - $this->logger->warning(var_export($log, true)); - } + $this->customLogger->debug($log); + } - $this->customLogger->debug($log); + return $response; } - return $response; - } - - abstract protected function process(array $data); -} \ No newline at end of file + /** + * @param array $data + * @return mixed + */ + abstract protected function process(array $data); +} diff --git a/Gateway/Http/Client/TransactionRefund.php b/Gateway/Http/Client/TransactionRefund.php index 294baee..c322be7 100755 --- a/Gateway/Http/Client/TransactionRefund.php +++ b/Gateway/Http/Client/TransactionRefund.php @@ -13,16 +13,22 @@ * @copyright Copyright (c) 2017-2018 * @license Open Software License (OSL 3.0) */ + namespace Pmclain\Stripe\Gateway\Http\Client; use Pmclain\Stripe\Gateway\Request\PaymentDataBuilder; class TransactionRefund extends AbstractTransaction { - protected function process(array $data) { - return $this->adapter->refund( - $data['transaction_id'], - $data[PaymentDataBuilder::AMOUNT] - ); - } -} \ No newline at end of file + /** + * @param array $data + * @return \Stripe\ApiOperations\ApiResource + */ + protected function process(array $data) + { + return $this->adapter->refund( + $data['transaction_id'], + $data[PaymentDataBuilder::AMOUNT] + ); + } +} diff --git a/Gateway/Http/Client/TransactionSale.php b/Gateway/Http/Client/TransactionSale.php index e793071..e875000 100755 --- a/Gateway/Http/Client/TransactionSale.php +++ b/Gateway/Http/Client/TransactionSale.php @@ -13,11 +13,17 @@ * @copyright Copyright (c) 2017-2018 * @license Open Software License (OSL 3.0) */ + namespace Pmclain\Stripe\Gateway\Http\Client; class TransactionSale extends AbstractTransaction { - protected function process(array $data) { - return $this->adapter->sale($data); - } -} \ No newline at end of file + /** + * @param array $data + * @return array|\Exception|\Stripe\ApiOperations\ApiResource|\Stripe\Error\Card + */ + protected function process(array $data) + { + return $this->adapter->sale($data); + } +} diff --git a/Gateway/Http/Client/TransactionSubmitForSettlement.php b/Gateway/Http/Client/TransactionSubmitForSettlement.php index 4b9ef33..975cca3 100755 --- a/Gateway/Http/Client/TransactionSubmitForSettlement.php +++ b/Gateway/Http/Client/TransactionSubmitForSettlement.php @@ -13,6 +13,7 @@ * @copyright Copyright (c) 2017-2018 * @license Open Software License (OSL 3.0) */ + namespace Pmclain\Stripe\Gateway\Http\Client; use Magento\Sales\Model\Order\Payment; @@ -21,10 +22,15 @@ class TransactionSubmitForSettlement extends AbstractTransaction { - protected function process(array $data) { - return $this->adapter->submitForSettlement( - $data[CaptureDataBuilder::TRANSACTION_ID], - $data[PaymentDataBuilder::AMOUNT] - ); - } -} \ No newline at end of file + /** + * @param array $data + * @return mixed + */ + protected function process(array $data) + { + return $this->adapter->submitForSettlement( + $data[CaptureDataBuilder::TRANSACTION_ID], + $data[PaymentDataBuilder::AMOUNT] + ); + } +} diff --git a/Gateway/Http/Client/TransactionVoid.php b/Gateway/Http/Client/TransactionVoid.php index 52e4617..37b563b 100755 --- a/Gateway/Http/Client/TransactionVoid.php +++ b/Gateway/Http/Client/TransactionVoid.php @@ -13,11 +13,17 @@ * @copyright Copyright (c) 2017-2018 * @license Open Software License (OSL 3.0) */ + namespace Pmclain\Stripe\Gateway\Http\Client; class TransactionVoid extends AbstractTransaction { - protected function process(array $data) { - return $this->adapter->void($data['transaction_id']); - } -} \ No newline at end of file + /** + * @param array $data + * @return \Stripe\ApiOperations\ApiResource + */ + protected function process(array $data) + { + return $this->adapter->void($data['transaction_id']); + } +} diff --git a/Gateway/Http/TransferFactory.php b/Gateway/Http/TransferFactory.php index a3412bb..477223d 100755 --- a/Gateway/Http/TransferFactory.php +++ b/Gateway/Http/TransferFactory.php @@ -13,6 +13,7 @@ * @copyright Copyright (c) 2017-2018 * @license Open Software License (OSL 3.0) */ + namespace Pmclain\Stripe\Gateway\Http; use Magento\Payment\Gateway\Http\TransferBuilder; @@ -21,17 +22,29 @@ class TransferFactory implements TransferFactoryInterface { - private $transferBuilder; + /** + * @var TransferBuilder + */ + private $transferBuilder; - public function __construct( - TransferBuilder $transferBuilder - ) { - $this->transferBuilder = $transferBuilder; - } + /** + * TransferFactory constructor. + * @param TransferBuilder $transferBuilder + */ + public function __construct( + TransferBuilder $transferBuilder + ) { + $this->transferBuilder = $transferBuilder; + } - public function create(array $request) { - return $this->transferBuilder - ->setBody($request) - ->build(); - } + /** + * @param array $request + * @return TransferInterface + */ + public function create(array $request) + { + return $this->transferBuilder + ->setBody($request) + ->build(); + } } diff --git a/Gateway/Request/AddressDataBuilder.php b/Gateway/Request/AddressDataBuilder.php index 74dd675..52c7fe9 100755 --- a/Gateway/Request/AddressDataBuilder.php +++ b/Gateway/Request/AddressDataBuilder.php @@ -13,6 +13,7 @@ * @copyright Copyright (c) 2017-2018 * @license Open Software License (OSL 3.0) */ + namespace Pmclain\Stripe\Gateway\Request; use Magento\Payment\Gateway\Request\BuilderInterface; @@ -20,46 +21,58 @@ class AddressDataBuilder implements BuilderInterface { - const SHIPPING_ADDRESS = 'shipping'; - const STREET_ADDRESS = 'line1'; - const EXTENDED_ADDRESS = 'line2'; - const LOCALITY = 'city'; - const REGION = 'state'; - const POSTAL_CODE = 'postal_code'; - const COUNTRY_CODE = 'country'; - const NAME = 'name'; - const PHONE = 'phone'; + const SHIPPING_ADDRESS = 'shipping'; + const STREET_ADDRESS = 'line1'; + const EXTENDED_ADDRESS = 'line2'; + const LOCALITY = 'city'; + const REGION = 'state'; + const POSTAL_CODE = 'postal_code'; + const COUNTRY_CODE = 'country'; + const NAME = 'name'; + const PHONE = 'phone'; + + /** + * @var SubjectReader + */ + private $subjectReader; - private $subjectReader; + /** + * AddressDataBuilder constructor. + * @param SubjectReader $subjectReader + */ + public function __construct( + SubjectReader $subjectReader + ) { + $this->subjectReader = $subjectReader; + } - public function __construct( - SubjectReader $subjectReader - ) { - $this->subjectReader = $subjectReader; - } + /** + * @param array $buildSubject + * @return array + */ + public function build(array $buildSubject) + { + $paymentDataObject = $this->subjectReader->readPayment($buildSubject); - public function build(array $buildSubject) { - $paymentDataObject = $this->subjectReader->readPayment($buildSubject); + $order = $paymentDataObject->getOrder(); + $result = []; - $order = $paymentDataObject->getOrder(); - $result = []; + $shippingAddress = $order->getShippingAddress(); + if ($shippingAddress) { + $result[self::SHIPPING_ADDRESS] = [ + 'address' => [ + self::STREET_ADDRESS => $shippingAddress->getStreetLine1(), + self::EXTENDED_ADDRESS => $shippingAddress->getStreetLine2(), + self::LOCALITY => $shippingAddress->getCity(), + self::REGION => $shippingAddress->getRegionCode(), + self::POSTAL_CODE => $shippingAddress->getPostcode(), + self::COUNTRY_CODE => $shippingAddress->getCountryId() + ], + self::NAME => $shippingAddress->getFirstname() . ' ' . $shippingAddress->getLastname(), + self::PHONE => $shippingAddress->getTelephone() + ]; + } - $shippingAddress = $order->getShippingAddress(); - if ($shippingAddress) { - $result[self::SHIPPING_ADDRESS] = [ - 'address' => [ - self::STREET_ADDRESS => $shippingAddress->getStreetLine1(), - self::EXTENDED_ADDRESS => $shippingAddress->getStreetLine2(), - self::LOCALITY => $shippingAddress->getCity(), - self::REGION => $shippingAddress->getRegionCode(), - self::POSTAL_CODE => $shippingAddress->getPostcode(), - self::COUNTRY_CODE => $shippingAddress->getCountryId() - ], - self::NAME => $shippingAddress->getFirstname() . ' ' . $shippingAddress->getLastname(), - self::PHONE => $shippingAddress->getTelephone() - ]; + return $result; } - - return $result; - } -} \ No newline at end of file +} diff --git a/Gateway/Request/CaptureDataBuilder.php b/Gateway/Request/CaptureDataBuilder.php index 6628a8d..c427e92 100755 --- a/Gateway/Request/CaptureDataBuilder.php +++ b/Gateway/Request/CaptureDataBuilder.php @@ -13,9 +13,10 @@ * @copyright Copyright (c) 2017-2018 * @license Open Software License (OSL 3.0) */ + namespace Pmclain\Stripe\Gateway\Request; -use Magento\Braintree\Gateway\Request\PaymentDataBuilder; +use Pmclain\Stripe\Gateway\Request\PaymentDataBuilder; use Magento\Framework\Exception\LocalizedException; use Pmclain\Stripe\Gateway\Helper\SubjectReader; use Magento\Payment\Gateway\Request\BuilderInterface; @@ -23,30 +24,43 @@ class CaptureDataBuilder implements BuilderInterface { - use Formatter; + use Formatter; + + const TRANSACTION_ID = 'transaction_id'; - const TRANSACTION_ID = 'transaction_id'; + /** + * @var SubjectReader + */ + private $subjectReader; - private $subjectReader; + /** + * CaptureDataBuilder constructor. + * @param SubjectReader $subjectReader + */ + public function __construct( + SubjectReader $subjectReader + ) { + $this->subjectReader = $subjectReader; + } - public function __construct( - SubjectReader $subjectReader - ) { - $this->subjectReader = $subjectReader; - } + /** + * @param array $subject + * @return array + * @throws LocalizedException + */ + public function build(array $subject) + { + $paymentDataObject = $this->subjectReader->readPayment($subject); + $payment = $paymentDataObject->getPayment(); + $transactionId = $payment->getCcTransId(); - public function build(array $subject) { - $paymentDataObject = $this->subjectReader->readPayment($subject); - $payment = $paymentDataObject->getPayment(); - $transactionId = $payment->getCcTransId(); + if (!$transactionId) { + throw new LocalizedException(__('No Authorization Transaction to capture')); + } - if(!$transactionId) { - throw new LocalizedException(__('No Authorization Transaction to capture')); + return [ + self::TRANSACTION_ID => $transactionId, + PaymentDataBuilder::AMOUNT => $this->formatPrice($this->subjectReader->readAmount($subject)) + ]; } - - return [ - self::TRANSACTION_ID => $transactionId, - PaymentDataBuilder::AMOUNT => $this->formatPrice($this->subjectReader->readAmount($subject)) - ]; - } -} \ No newline at end of file +} diff --git a/Gateway/Request/CustomerDataBuilder.php b/Gateway/Request/CustomerDataBuilder.php index f209bbd..97067c5 100755 --- a/Gateway/Request/CustomerDataBuilder.php +++ b/Gateway/Request/CustomerDataBuilder.php @@ -13,6 +13,7 @@ * @copyright Copyright (c) 2017-2018 * @license Open Software License (OSL 3.0) */ + namespace Pmclain\Stripe\Gateway\Request; use Magento\Payment\Gateway\Request\BuilderInterface; @@ -23,84 +24,121 @@ class CustomerDataBuilder implements BuilderInterface { - const CUSTOMER = 'customer'; - const FIRST_NAME = 'firstName'; - const LAST_NAME = 'lastName'; - const COMPANY = 'company'; - const EMAIL = 'email'; - const PHONE = 'phone'; - - private $subjectReader; - private $adapter; - private $customerSession; - - /** @var CustomerRepositoryInterface */ - private $customerRepository; - - public function __construct( - SubjectReader $subjectReader, - Session $customerSession, - CustomerRepositoryInterface $customerRepository - ) { - $this->subjectReader = $subjectReader; - $this->customerSession = $customerSession; - $this->customerRepository = $customerRepository; - } - - public function build(array $subject) { - $paymentDataObject = $this->subjectReader->readPayment($subject); - - if(!$this->isSavePaymentInformation($paymentDataObject)) { - return false; + const CUSTOMER = 'customer'; + const FIRST_NAME = 'firstName'; + const LAST_NAME = 'lastName'; + const COMPANY = 'company'; + const EMAIL = 'email'; + const PHONE = 'phone'; + + /** + * @var SubjectReader + */ + private $subjectReader; + + /** + * @var Session + */ + private $customerSession; + + /** @var CustomerRepositoryInterface */ + private $customerRepository; + + /** + * CustomerDataBuilder constructor. + * @param SubjectReader $subjectReader + * @param Session $customerSession + * @param CustomerRepositoryInterface $customerRepository + */ + public function __construct( + SubjectReader $subjectReader, + Session $customerSession, + CustomerRepositoryInterface $customerRepository + ) { + $this->subjectReader = $subjectReader; + $this->customerSession = $customerSession; + $this->customerRepository = $customerRepository; } - $stripeCustomerId = $this->getStripeCustomerId(); - - - $order = $paymentDataObject->getOrder(); - $billingAddress = $order->getBillingAddress(); + /** + * @param array $subject + * @return bool + */ + public function build(array $subject) + { + $paymentDataObject = $this->subjectReader->readPayment($subject); - return false; - } + if (!$this->isSavePaymentInformation($paymentDataObject)) { + return false; + } + $stripeCustomerId = $this->getStripeCustomerId(); - protected function isSavePaymentInformation($paymentDataObject) { - $payment = $paymentDataObject->getPayment(); - $additionalInfo = $payment->getAdditionalInformation(); - - if(isset($additionalInfo['is_active_payment_token_enabler'])) { - return $additionalInfo['is_active_payment_token_enabler']; - } - return false; - } + $order = $paymentDataObject->getOrder(); + $billingAddress = $order->getBillingAddress(); - protected function getStripeCustomerId() { - if(!$this->customerSession->isLoggedIn()) { - return false; + return false; } - $customer = $this->customerRepository->getById($this->customerSession->getCustomerId()); - $stripeCustomerId = $customer->getCustomAttribute('stripe_customer_id'); + /** + * @param $paymentDataObject + * @return bool + */ + protected function isSavePaymentInformation($paymentDataObject) + { + $payment = $paymentDataObject->getPayment(); + $additionalInfo = $payment->getAdditionalInformation(); - if(!$stripeCustomerId) { - $stripeCustomerId = $this->createNewStripeCustomer($customer->getEmail()); - $customer->setCustomAttribute('stripe_customer_id', $stripeCustomerId); + if (isset($additionalInfo['is_active_payment_token_enabler'])) { + return $additionalInfo['is_active_payment_token_enabler']; + } - $this->customerRepository->save($customer); + return false; } - return $stripeCustomerId; - } - - protected function createNewStripeCustomer($email) { - $result = Customer::create([ - 'description' => 'Customer for ' . $email, - ]); + /** + * @return bool|\Magento\Framework\Api\AttributeInterface|null + */ + protected function getStripeCustomerId() + { + if (!$this->customerSession->isLoggedIn()) { + return false; + } + + $customer = $this->customerRepository->getById($this->customerSession->getCustomerId()); + $stripeCustomerId = $customer->getCustomAttribute('stripe_customer_id'); + + if (!$stripeCustomerId) { + $stripeCustomerId = $this->createNewStripeCustomer($customer->getEmail()); + $customer->setCustomAttribute( + 'stripe_customer_id', + $stripeCustomerId + ); + + $this->customerRepository->save($customer); + } + + return $stripeCustomerId; + } - return $result->id; - } + /** + * @param $email + * @return mixed + */ + protected function createNewStripeCustomer($email) + { + $result = Customer::create([ + 'description' => 'Customer for ' . $email, + ]); + + return $result->id; + } - protected function verifyStripeCustomer($stripeCustomerId) { + /** + * @param $stripeCustomerId + */ + protected function verifyStripeCustomer($stripeCustomerId) + { - } -} \ No newline at end of file + } +} diff --git a/Gateway/Request/PaymentDataBuilder.php b/Gateway/Request/PaymentDataBuilder.php index dc2563c..79f1146 100755 --- a/Gateway/Request/PaymentDataBuilder.php +++ b/Gateway/Request/PaymentDataBuilder.php @@ -13,6 +13,7 @@ * @copyright Copyright (c) 2017-2018 * @license Open Software License (OSL 3.0) */ + namespace Pmclain\Stripe\Gateway\Request; use Pmclain\Stripe\Gateway\Config\Config; @@ -27,141 +28,136 @@ class PaymentDataBuilder implements BuilderInterface { - use Formatter; - - const AMOUNT = 'amount'; - const SOURCE = 'source'; - const ORDER_ID = 'description'; - const CURRENCY = 'currency'; - const CAPTURE = 'capture'; - const CUSTOMER = 'customer'; - const SAVE_IN_VAULT = 'save_in_vault'; - - /** @var Config */ - protected $config; - - /** @var SubjectReader */ - protected $subjectReader; - - /** @var Session */ - protected $customerSession; - - /** @var CustomerRepositoryInterface */ - protected $customerRepository; - - /** @var LoggerInterface */ - protected $logger; - - /** - * PaymentDataBuilder constructor. - * @param Config $config - * @param SubjectReader $subjectReader - * @param Session $customerSession - * @param CustomerRepositoryInterface $customerRepository - * @param LoggerInterface $logger - */ - public function __construct( - Config $config, - SubjectReader $subjectReader, - Session $customerSession, - CustomerRepositoryInterface $customerRepository, - LoggerInterface $logger = null - ) { - $this->config = $config; - $this->subjectReader = $subjectReader; - $this->customerSession = $customerSession; - $this->customerRepository = $customerRepository; - $this->logger = $logger ?: ObjectManager::getInstance()->get(LoggerInterface::class); - } - - /** - * @param array $subject - * @return array - * @throws \Magento\Framework\Validator\Exception - */ - public function build(array $subject) { - $paymentDataObject = $this->subjectReader->readPayment($subject); - $payment = $paymentDataObject->getPayment(); - $order = $paymentDataObject->getOrder(); - - $result = [ - self::AMOUNT => $this->formatPrice($this->subjectReader->readAmount($subject)), - self::ORDER_ID => $order->getOrderIncrementId(), - self::CURRENCY => $this->config->getCurrency(), - self::SOURCE => $this->getPaymentSource($payment), - self::CAPTURE => 'false' - ]; - - if($this->isSavePaymentInformation($payment)) { - $stripeCustomerId = $this->getStripeCustomerId(); - if ($stripeCustomerId) { - $result[self::CUSTOMER] = $stripeCustomerId; - $result[self::SAVE_IN_VAULT] = true; - } + use Formatter; + + const AMOUNT = 'amount'; + const SOURCE = 'source'; + const ORDER_ID = 'description'; + const CURRENCY = 'currency'; + const CAPTURE = 'capture'; + const CUSTOMER = 'customer'; + const SAVE_IN_VAULT = 'save_in_vault'; + + /** @var Config */ + protected $config; + + /** @var SubjectReader */ + protected $subjectReader; + + /** @var Session */ + protected $customerSession; + + /** @var CustomerRepositoryInterface */ + protected $customerRepository; + + /** @var LoggerInterface */ + protected $logger; + + /** + * PaymentDataBuilder constructor. + * @param Config $config + * @param SubjectReader $subjectReader + * @param Session $customerSession + * @param CustomerRepositoryInterface $customerRepository + * @param LoggerInterface $logger + */ + public function __construct( + Config $config, + SubjectReader $subjectReader, + Session $customerSession, + CustomerRepositoryInterface $customerRepository, + LoggerInterface $logger = null + ) { + $this->config = $config; + $this->subjectReader = $subjectReader; + $this->customerSession = $customerSession; + $this->customerRepository = $customerRepository; + $this->logger = $logger ?: ObjectManager::getInstance()->get(LoggerInterface::class); } - return $result; - } - - /** - * @return string - */ - protected function getStripeCustomerId() { - $customer = $this->customerRepository->getById($this->customerSession->getCustomerId()); - $stripeCustomerId = $customer->getCustomAttribute('stripe_customer_id'); - - if(!$stripeCustomerId) { - $stripeCustomerId = $this->createNewStripeCustomer($customer->getEmail()); - $customer->setCustomAttribute('stripe_customer_id', $stripeCustomerId); - - $this->customerRepository->save($customer); + /** + * @param array $subject + * @return array + * @throws \Magento\Framework\Validator\Exception + */ + public function build(array $subject) + { + $paymentDataObject = $this->subjectReader->readPayment($subject); + $payment = $paymentDataObject->getPayment(); + $order = $paymentDataObject->getOrder(); + + $result = [ + self::AMOUNT => $this->formatPrice($this->subjectReader->readAmount($subject)), + self::ORDER_ID => $order->getOrderIncrementId(), + self::CURRENCY => $this->config->getCurrency(), + self::SOURCE => $payment->getAdditionalInformation('cc_token'), + self::CAPTURE => 'false' + ]; + + if ($this->isSavePaymentInformation($payment)) { + $stripeCustomerId = $this->getStripeCustomerId(); + if ($stripeCustomerId) { + $result[self::CUSTOMER] = $stripeCustomerId; + $result[self::SAVE_IN_VAULT] = true; + } + } + + return $result; + } - return $stripeCustomerId; + /** + * @return \Magento\Framework\Api\AttributeInterface|mixed|null|string + * @throws \Magento\Framework\Exception\InputException + * @throws \Magento\Framework\Exception\LocalizedException + * @throws \Magento\Framework\Exception\NoSuchEntityException + * @throws \Magento\Framework\Exception\State\InputMismatchException + * @throws \Magento\Framework\Validator\Exception + */ + protected function getStripeCustomerId() + { + $customer = $this->customerRepository->getById($this->customerSession->getCustomerId()); + $stripeCustomerId = $customer->getCustomAttribute('stripe_customer_id'); + + if (!$stripeCustomerId) { + $stripeCustomerId = $this->createNewStripeCustomer($customer->getEmail()); + $customer->setCustomAttribute( + 'stripe_customer_id', + $stripeCustomerId + ); + + $this->customerRepository->save($customer); + + return $stripeCustomerId; + } + + return $stripeCustomerId->getValue(); } - return $stripeCustomerId->getValue(); - } - - /** - * @param $email - * @return string|null - * @throws \Magento\Framework\Validator\Exception - */ - protected function createNewStripeCustomer($email) { - try { - $result = Customer::create([ - 'description' => 'Customer for ' . $email, - ]); - }catch (\Exception $e) { - $this->logger->critical($e); - throw new \Magento\Framework\Validator\Exception(__($e->getMessage())); + /** + * @param $email + * @return string|null + * @throws \Magento\Framework\Validator\Exception + */ + protected function createNewStripeCustomer($email) + { + try { + $result = Customer::create([ + 'description' => 'Customer for ' . $email, + ]); + } catch (\Exception $e) { + $this->logger->critical($e); + throw new \Magento\Framework\Validator\Exception(__($e->getMessage())); + } + + return $result->id; } - return $result->id; - } - - /** - * @param \Magento\Payment\Model\InfoInterface $payment - * @return mixed - */ - protected function isSavePaymentInformation($payment) { - return $payment->getAdditionalInformation('is_active_payment_token_enabler'); - } - - /** - * @param $payment - * @return array - */ - protected function getPaymentSource($payment) { - if($token = $payment->getAdditionalInformation('cc_token')) { - return $token; + /** + * @param \Magento\Payment\Model\InfoInterface $payment + * @return mixed + */ + protected function isSavePaymentInformation($payment) + { + return $payment->getAdditionalInformation('is_active_payment_token_enabler'); } - return [ - 'exp_month' => $payment->getCcExpMonth(), - 'exp_year' => $payment->getCcExpYear(), - 'number' => $payment->getCcNumber(), - 'object' => 'card', - 'cvc' => $payment->getCcCid(), - ]; - } -} \ No newline at end of file +} diff --git a/Gateway/Request/PaymentDataBuilder/Admin.php b/Gateway/Request/PaymentDataBuilder/Admin.php index e1cfeb6..6af71ce 100644 --- a/Gateway/Request/PaymentDataBuilder/Admin.php +++ b/Gateway/Request/PaymentDataBuilder/Admin.php @@ -13,6 +13,7 @@ * @copyright Copyright (c) 2017-2018 * @license Open Software License (OSL 3.0) */ + namespace Pmclain\Stripe\Gateway\Request\PaymentDataBuilder; use Pmclain\Stripe\Gateway\Request\PaymentDataBuilder; @@ -24,44 +25,53 @@ class Admin extends PaymentDataBuilder { - /** @var Quote $adminSession */ - private $adminSession; + /** @var Quote $adminSession */ + private $adminSession; + + /** + * Admin constructor. + * @param Config $config + * @param SubjectReader $subjectReader + * @param Session $customerSession + * @param CustomerRepositoryInterface $customerRepository + * @param Quote $session + */ + public function __construct( + Config $config, + SubjectReader $subjectReader, + Session $customerSession, + CustomerRepositoryInterface $customerRepository, + Quote $session + ) { + parent::__construct( + $config, + $subjectReader, + $customerSession, + $customerRepository + ); + $this->adminSession = $session; + } - /** - * Admin constructor. - * @param Config $config - * @param SubjectReader $subjectReader - * @param Session $customerSession - * @param CustomerRepositoryInterface $customerRepository - * @param Quote $session - */ - public function __construct( - Config $config, - SubjectReader $subjectReader, - Session $customerSession, - CustomerRepositoryInterface $customerRepository, - Quote $session - ) { - parent::__construct($config, $subjectReader, $customerSession, $customerRepository); - $this->adminSession = $session; - } + /** + * @return string + */ + protected function getStripeCustomerId() + { + $customer = $this->customerRepository->getById($this->adminSession->getCustomerId()); + $stripeCustomerId = $customer->getCustomAttribute('stripe_customer_id'); - /** - * @return string - */ - protected function getStripeCustomerId() { - $customer = $this->customerRepository->getById($this->adminSession->getCustomerId()); - $stripeCustomerId = $customer->getCustomAttribute('stripe_customer_id'); + if (!$stripeCustomerId) { + $stripeCustomerId = $this->createNewStripeCustomer($customer->getEmail()); + $customer->setCustomAttribute( + 'stripe_customer_id', + $stripeCustomerId + ); - if(!$stripeCustomerId) { - $stripeCustomerId = $this->createNewStripeCustomer($customer->getEmail()); - $customer->setCustomAttribute('stripe_customer_id', $stripeCustomerId); + $this->customerRepository->save($customer); - $this->customerRepository->save($customer); + return $stripeCustomerId; + } - return $stripeCustomerId; + return $stripeCustomerId->getValue(); } - - return $stripeCustomerId->getValue(); - } -} \ No newline at end of file +} diff --git a/Gateway/Request/PaymentDataBuilder/Vault.php b/Gateway/Request/PaymentDataBuilder/Vault.php index 19059b3..b853a96 100755 --- a/Gateway/Request/PaymentDataBuilder/Vault.php +++ b/Gateway/Request/PaymentDataBuilder/Vault.php @@ -13,32 +13,37 @@ * @copyright Copyright (c) 2017-2018 * @license Open Software License (OSL 3.0) */ + namespace Pmclain\Stripe\Gateway\Request\PaymentDataBuilder; use Pmclain\Stripe\Gateway\Request\PaymentDataBuilder; - class Vault extends PaymentDataBuilder { - public function build(array $subject) { - $paymentDataObject = $this->subjectReader->readPayment($subject); - $payment = $paymentDataObject->getPayment(); - $order = $paymentDataObject->getOrder(); + /** + * @param array $subject + * @return array + */ + public function build(array $subject) + { + $paymentDataObject = $this->subjectReader->readPayment($subject); + $payment = $paymentDataObject->getPayment(); + $order = $paymentDataObject->getOrder(); + + $extensionAttributes = $payment->getExtensionAttributes(); + $paymentToken = $extensionAttributes->getVaultPaymentToken(); - $extensionAttributes = $payment->getExtensionAttributes(); - $paymentToken = $extensionAttributes->getVaultPaymentToken(); + $stripeCustomerId = $this->getStripeCustomerId(); - $stripeCustomerId = $this->getStripeCustomerId(); - - $result = [ - self::AMOUNT => $this->formatPrice($this->subjectReader->readAmount($subject)), - self::ORDER_ID => $order->getOrderIncrementId(), - self::CURRENCY => $this->config->getCurrency(), - self::SOURCE => $paymentToken->getGatewayToken(), - self::CAPTURE => 'false', - self::CUSTOMER => $stripeCustomerId - ]; + $result = [ + self::AMOUNT => $this->formatPrice($this->subjectReader->readAmount($subject)), + self::ORDER_ID => $order->getOrderIncrementId(), + self::CURRENCY => $this->config->getCurrency(), + self::SOURCE => $paymentToken->getGatewayToken(), + self::CAPTURE => 'false', + self::CUSTOMER => $stripeCustomerId + ]; - return $result; - } -} \ No newline at end of file + return $result; + } +} diff --git a/Gateway/Request/PaymentDataBuilder/Vault/Admin.php b/Gateway/Request/PaymentDataBuilder/Vault/Admin.php index f6d159e..7fcb29a 100644 --- a/Gateway/Request/PaymentDataBuilder/Vault/Admin.php +++ b/Gateway/Request/PaymentDataBuilder/Vault/Admin.php @@ -13,6 +13,7 @@ * @copyright Copyright (c) 2017-2018 * @license Open Software License (OSL 3.0) */ + namespace Pmclain\Stripe\Gateway\Request\PaymentDataBuilder\Vault; use Pmclain\Stripe\Gateway\Request\PaymentDataBuilder\Vault; @@ -24,42 +25,53 @@ class Admin extends Vault { - /** @var Quote $adminSession */ - private $adminSession; + /** @var Quote $adminSession */ + private $adminSession; - /** - * Admin constructor. - * @param Config $config - * @param SubjectReader $subjectReader - * @param Session $customerSession - * @param CustomerRepositoryInterface $customerRepository - * @param Quote $session - */ - public function __construct( - Config $config, - SubjectReader $subjectReader, - Session $customerSession, - CustomerRepositoryInterface $customerRepository, - Quote $session - ) { - parent::__construct($config, $subjectReader, $customerSession, $customerRepository); - $this->adminSession = $session; - } + /** + * Admin constructor. + * @param Config $config + * @param SubjectReader $subjectReader + * @param Session $customerSession + * @param CustomerRepositoryInterface $customerRepository + * @param Quote $session + */ + public function __construct( + Config $config, + SubjectReader $subjectReader, + Session $customerSession, + CustomerRepositoryInterface $customerRepository, + Quote $session + ) { + parent::__construct( + $config, + $subjectReader, + $customerSession, + $customerRepository + ); + $this->adminSession = $session; + } - /** - * @return \Magento\Framework\Api\AttributeInterface|mixed|null - */ - protected function getStripeCustomerId() { - $customer = $this->customerRepository->getById($this->adminSession->getCustomerId()); - $stripeCustomerId = $customer->getCustomAttribute('stripe_customer_id'); + /** + * @return \Magento\Framework\Api\AttributeInterface|mixed|null + */ + protected function getStripeCustomerId() + { + $customer = $this->customerRepository->getById($this->adminSession->getCustomerId()); + $stripeCustomerId = $customer->getCustomAttribute('stripe_customer_id'); - if(!$stripeCustomerId) { - $stripeCustomerId = $this->createNewStripeCustomer($customer->getEmail()); - $customer->setCustomAttribute('stripe_customer_id', $stripeCustomerId); + if (!$stripeCustomerId) { + $stripeCustomerId = $this->createNewStripeCustomer($customer->getEmail()); + $customer->setCustomAttribute( + 'stripe_customer_id', + $stripeCustomerId + ); - $this->customerRepository->save($customer); - } + $this->customerRepository->save($customer); - return $stripeCustomerId; - } -} \ No newline at end of file + return $stripeCustomerId; + } + + return $stripeCustomerId->getValue(); + } +} diff --git a/Gateway/Request/RefundDataBuilder.php b/Gateway/Request/RefundDataBuilder.php index f85e0b1..e18e933 100755 --- a/Gateway/Request/RefundDataBuilder.php +++ b/Gateway/Request/RefundDataBuilder.php @@ -13,6 +13,7 @@ * @copyright Copyright (c) 2017-2018 * @license Open Software License (OSL 3.0) */ + namespace Pmclain\Stripe\Gateway\Request; use Pmclain\Stripe\Gateway\Request\PaymentDataBuilder; @@ -22,37 +23,50 @@ use Magento\Sales\Api\Data\TransactionInterface; use Magento\Sales\Model\Order\Payment; -class RefundDataBuilder implements BuilderInterface { - use Formatter; +class RefundDataBuilder implements BuilderInterface +{ + use Formatter; - private $subjectReader; + /** + * @var SubjectReader + */ + private $subjectReader; - public function __construct( - SubjectReader $subjectReader - ) { - $this->subjectReader = $subjectReader; - } + /** + * RefundDataBuilder constructor. + * @param SubjectReader $subjectReader + */ + public function __construct( + SubjectReader $subjectReader + ) { + $this->subjectReader = $subjectReader; + } - public function build(array $subject) { - $paymentDataObject = $this->subjectReader->readPayment($subject); - $payment = $paymentDataObject->getPayment(); - $amount = null; + /** + * @param array $subject + * @return array + */ + public function build(array $subject) + { + $paymentDataObject = $this->subjectReader->readPayment($subject); + $payment = $paymentDataObject->getPayment(); + $amount = null; - try { - $amount = $this->formatPrice($this->subjectReader->readAmount($subject)); - }catch (\InvalidArgumentException $e) { - //nothing - } + try { + $amount = $this->formatPrice($this->subjectReader->readAmount($subject)); + } catch (\InvalidArgumentException $e) { + //nothing + } - $txnId = str_replace( - '-' . TransactionInterface::TYPE_CAPTURE, - '', - $payment->getParentTransactionId() - ); - - return [ - 'transaction_id' => $txnId, - PaymentDataBuilder::AMOUNT => $amount - ]; - } -} \ No newline at end of file + $txnId = str_replace( + '-' . TransactionInterface::TYPE_CAPTURE, + '', + $payment->getParentTransactionId() + ); + + return [ + 'transaction_id' => $txnId, + PaymentDataBuilder::AMOUNT => $amount + ]; + } +} diff --git a/Gateway/Request/SettlementDataBuilder.php b/Gateway/Request/SettlementDataBuilder.php index f063ae7..eb1c74c 100755 --- a/Gateway/Request/SettlementDataBuilder.php +++ b/Gateway/Request/SettlementDataBuilder.php @@ -13,15 +13,21 @@ * @copyright Copyright (c) 2017-2018 * @license Open Software License (OSL 3.0) */ + namespace Pmclain\Stripe\Gateway\Request; use Magento\Payment\Gateway\Request\BuilderInterface; class SettlementDataBuilder implements BuilderInterface { - const SUBMIT_FOR_SETTLEMENT = 'capture'; + const SUBMIT_FOR_SETTLEMENT = 'capture'; - public function build(array $subject) { - return [self::SUBMIT_FOR_SETTLEMENT => true]; - } -} \ No newline at end of file + /** + * @param array $subject + * @return array + */ + public function build(array $subject) + { + return [self::SUBMIT_FOR_SETTLEMENT => true]; + } +} diff --git a/Gateway/Request/ThreeDSecureBuilder.php b/Gateway/Request/ThreeDSecureBuilder.php new file mode 100644 index 0000000..4a3d0a8 --- /dev/null +++ b/Gateway/Request/ThreeDSecureBuilder.php @@ -0,0 +1,92 @@ +config = $config; + $this->subjectReader = $subjectReader; + } + + /** + * @param array $subject + * @return array + * @throws \Magento\Framework\Validator\Exception + */ + public function build(array $subject) + { + $result = []; + if (!$this->config->isRequireThreeDSecure() + || (float)$this->subjectReader->readAmount($subject) < $this->config->getThreeDSecureThreshold() + ) { + return $result; + } + + Stripe::setApiKey($this->config->getSecretKey()); + + $paymentDataObject = $this->subjectReader->readPayment($subject); + $payment = $paymentDataObject->getPayment(); + + $source = $this->getSourceForCharge($payment); + if ($source) { + $result[self::SOURCE] = $source; + $result[self::SOURCE_FOR_VAULT] = $payment->getAdditionalInformation('cc_src'); + } + + return $result; + } + + /** + * @param InfoInterface $payment + * @return string|false + */ + private function getSourceForCharge($payment) + { + /** @var Source $threeDSource */ + $threeDSource = Source::retrieve($payment->getAdditionalInformation('three_d_src')); + if ($threeDSource->status === 'failed') { + return $payment->getAdditionalInformation('cc_src') ?: false; + } + + return $payment->getAdditionalInformation('three_d_src'); + } +} diff --git a/Gateway/Request/VoidDataBuilder.php b/Gateway/Request/VoidDataBuilder.php index e8e0162..5a2b954 100755 --- a/Gateway/Request/VoidDataBuilder.php +++ b/Gateway/Request/VoidDataBuilder.php @@ -13,6 +13,7 @@ * @copyright Copyright (c) 2017-2018 * @license Open Software License (OSL 3.0) */ + namespace Pmclain\Stripe\Gateway\Request; use Pmclain\Stripe\Gateway\Helper\SubjectReader; @@ -21,20 +22,32 @@ class VoidDataBuilder implements BuilderInterface { - private $subjectReader; + /** + * @var SubjectReader + */ + private $subjectReader; - public function __construct( - SubjectReader $subjectReader - ) { - $this->subjectReader = $subjectReader; - } + /** + * VoidDataBuilder constructor. + * @param SubjectReader $subjectReader + */ + public function __construct( + SubjectReader $subjectReader + ) { + $this->subjectReader = $subjectReader; + } - public function build(array $subject) { - $paymentDataObject = $this->subjectReader->readPayment($subject); - $payment = $paymentDataObject->getPayment(); + /** + * @param array $subject + * @return array + */ + public function build(array $subject) + { + $paymentDataObject = $this->subjectReader->readPayment($subject); + $payment = $paymentDataObject->getPayment(); - return [ - 'transaction_id' => $payment->getParentTransactionId() ?: $payment->getLastTransId() - ]; - } -} \ No newline at end of file + return [ + 'transaction_id' => $payment->getParentTransactionId() ?: $payment->getLastTransId() + ]; + } +} diff --git a/Gateway/Response/CardDetailsHandler.php b/Gateway/Response/CardDetailsHandler.php index 4cd1318..1964081 100755 --- a/Gateway/Response/CardDetailsHandler.php +++ b/Gateway/Response/CardDetailsHandler.php @@ -13,6 +13,7 @@ * @copyright Copyright (c) 2017-2018 * @license Open Software License (OSL 3.0) */ + namespace Pmclain\Stripe\Gateway\Response; use Pmclain\Stripe\Gateway\Config\Config; @@ -23,32 +24,48 @@ class CardDetailsHandler implements HandlerInterface { - const CARD_TYPE = 'brand'; - const CARD_EXP_MONTH = 'exp_month'; - const CARD_EXP_YEAR = 'exp_year'; - const CARD_LAST4 = 'last4'; + const CARD_TYPE = 'brand'; + const CARD_EXP_MONTH = 'exp_month'; + const CARD_EXP_YEAR = 'exp_year'; + const CARD_LAST4 = 'last4'; - private $config; - private $subjectReader; + /** + * @var Config + */ + private $config; + /** + * @var SubjectReader + */ + private $subjectReader; - public function __construct( - Config $config, - SubjectReader $subjectReader - ) { - $this->config = $config; - $this->subjectReader = $subjectReader; - } + /** + * CardDetailsHandler constructor. + * @param Config $config + * @param SubjectReader $subjectReader + */ + public function __construct( + Config $config, + SubjectReader $subjectReader + ) { + $this->config = $config; + $this->subjectReader = $subjectReader; + } - public function handle(array $subject, array $response) { - $paymentDataObject = $this->subjectReader->readPayment($subject); - $transaction = $this->subjectReader->readTransaction($response); - $payment = $paymentDataObject->getPayment(); - ContextHelper::assertOrderPayment($payment); + /** + * @param array $subject + * @param array $response + */ + public function handle(array $subject, array $response) + { + $paymentDataObject = $this->subjectReader->readPayment($subject); + $transaction = $this->subjectReader->readTransaction($response); + $payment = $paymentDataObject->getPayment(); + ContextHelper::assertOrderPayment($payment); - $creditCard = $transaction['source']->__toArray(); - $payment->setCcLast4($creditCard[self::CARD_LAST4]); - $payment->setCcExpMonth($creditCard[self::CARD_EXP_MONTH]); - $payment->setCcExpYear($creditCard[self::CARD_EXP_YEAR]); - $payment->setCcType($creditCard[self::CARD_TYPE]); - } -} \ No newline at end of file + $creditCard = $transaction['source']->__toArray(); + $payment->setCcLast4($creditCard[self::CARD_LAST4]); + $payment->setCcExpMonth($creditCard[self::CARD_EXP_MONTH]); + $payment->setCcExpYear($creditCard[self::CARD_EXP_YEAR]); + $payment->setCcType($creditCard[self::CARD_TYPE]); + } +} diff --git a/Gateway/Response/PaymentDetailsHandler.php b/Gateway/Response/PaymentDetailsHandler.php index 996bbd7..7d94781 100755 --- a/Gateway/Response/PaymentDetailsHandler.php +++ b/Gateway/Response/PaymentDetailsHandler.php @@ -13,6 +13,7 @@ * @copyright Copyright (c) 2017-2018 * @license Open Software License (OSL 3.0) */ + namespace Pmclain\Stripe\Gateway\Response; use Pmclain\Stripe\Observer\DataAssignObserver; @@ -23,40 +24,55 @@ class PaymentDetailsHandler implements HandlerInterface { - const RISK_LEVEL = 'risk_level'; - const SELLER_MESSAGE = 'seller_message'; - const CAPTURE = 'captured'; - const TYPE = 'type'; - - protected $additionalInformationMapping = [ - self::RISK_LEVEL, - self::SELLER_MESSAGE, - self::CAPTURE, - self::TYPE - ]; - - private $subjectReader; - - public function __construct( - SubjectReader $subjectReader - ) { - $this->subjectReader = $subjectReader; - } - - public function handle(array $subject, array $response) { - $paymentDataObject = $this->subjectReader->readPayment($subject); - $transaction = $this->subjectReader->readTransaction($response); - $payment = $paymentDataObject->getPayment(); - - $payment->setCcTransId($transaction['id']); - $payment->setLastTransId($transaction['id']); - - $outcome = $transaction['outcome']->__toArray(); - foreach ($this->additionalInformationMapping as $item) { - if(!isset($outcome[$item])) { - continue; - } - $payment->setAdditionalInformation($item, $outcome[$item]); + const RISK_LEVEL = 'risk_level'; + const SELLER_MESSAGE = 'seller_message'; + const CAPTURE = 'captured'; + const TYPE = 'type'; + + /** + * @var array + */ + protected $additionalInformationMapping = [ + self::RISK_LEVEL, + self::SELLER_MESSAGE, + self::CAPTURE, + self::TYPE + ]; + + /** + * @var SubjectReader + */ + private $subjectReader; + + /** + * PaymentDetailsHandler constructor. + * @param SubjectReader $subjectReader + */ + public function __construct( + SubjectReader $subjectReader + ) { + $this->subjectReader = $subjectReader; + } + + /** + * @param array $subject + * @param array $response + */ + public function handle(array $subject, array $response) + { + $paymentDataObject = $this->subjectReader->readPayment($subject); + $transaction = $this->subjectReader->readTransaction($response); + $payment = $paymentDataObject->getPayment(); + + $payment->setCcTransId($transaction['id']); + $payment->setLastTransId($transaction['id']); + + $outcome = $transaction['outcome']->__toArray(); + foreach ($this->additionalInformationMapping as $item) { + if (!isset($outcome[$item])) { + continue; + } + $payment->setAdditionalInformation($item, $outcome[$item]); + } } - } -} \ No newline at end of file +} diff --git a/Gateway/Response/RefundHandler.php b/Gateway/Response/RefundHandler.php index c19622c..9cc73db 100755 --- a/Gateway/Response/RefundHandler.php +++ b/Gateway/Response/RefundHandler.php @@ -13,13 +13,19 @@ * @copyright Copyright (c) 2017-2018 * @license Open Software License (OSL 3.0) */ + namespace Pmclain\Stripe\Gateway\Response; use Magento\Sales\Model\Order\Payment; class RefundHandler extends VoidHandler { - protected function shouldCloseParentTransaction(Payment $orderPayment) { - return !(bool)$orderPayment->getCreditmemo()->getInvoice()->canRefund(); - } -} \ No newline at end of file + /** + * @param Payment $orderPayment + * @return bool + */ + protected function shouldCloseParentTransaction(Payment $orderPayment) + { + return !(bool)$orderPayment->getCreditmemo()->getInvoice()->canRefund(); + } +} diff --git a/Gateway/Response/TransactionIdHandler.php b/Gateway/Response/TransactionIdHandler.php index d82625f..5842414 100755 --- a/Gateway/Response/TransactionIdHandler.php +++ b/Gateway/Response/TransactionIdHandler.php @@ -13,6 +13,7 @@ * @copyright Copyright (c) 2017-2018 * @license Open Software License (OSL 3.0) */ + namespace Pmclain\Stripe\Gateway\Response; use Pmclain\Stripe\Gateway\Helper\SubjectReader; @@ -21,41 +22,67 @@ class TransactionIdHandler implements HandlerInterface { - private $subjectReader; + /** + * @var SubjectReader + */ + private $subjectReader; - public function __construct( - SubjectReader $subjectReader - ) { - $this->subjectReader = $subjectReader; - } + /** + * TransactionIdHandler constructor. + * @param SubjectReader $subjectReader + */ + public function __construct( + SubjectReader $subjectReader + ) { + $this->subjectReader = $subjectReader; + } - public function handle(array $subject, array $response) { - $paymentDataObject = $this->subjectReader->readPayment($subject); + /** + * @param array $subject + * @param array $response + */ + public function handle(array $subject, array $response) + { + $paymentDataObject = $this->subjectReader->readPayment($subject); - if($paymentDataObject->getPayment() instanceof Payment) { - $transaction = $this->subjectReader->readTransaction($response); - $orderPayment = $paymentDataObject->getPayment(); + if ($paymentDataObject->getPayment() instanceof Payment) { + $transaction = $this->subjectReader->readTransaction($response); + $orderPayment = $paymentDataObject->getPayment(); - $this->setTransactionId( - $orderPayment, - $transaction - ); + $this->setTransactionId( + $orderPayment, + $transaction + ); - $orderPayment->setIsTransactionClosed($this->shouldCloseTransaction()); - $closed = $this->shouldCloseParentTransaction($orderPayment); - $orderPayment->setShouldCloseParentTransaction($closed); + $orderPayment->setIsTransactionClosed($this->shouldCloseTransaction()); + $closed = $this->shouldCloseParentTransaction($orderPayment); + $orderPayment->setShouldCloseParentTransaction($closed); + } } - } - protected function setTransactionId(Payment $orderPayment, $transaction) { - $orderPayment->setTransactionId($transaction['id']); - } + /** + * @param Payment $orderPayment + * @param $transaction + */ + protected function setTransactionId(Payment $orderPayment, $transaction) + { + $orderPayment->setTransactionId($transaction['id']); + } - protected function shouldCloseTransaction() { - return false; - } + /** + * @return bool + */ + protected function shouldCloseTransaction() + { + return false; + } - protected function shouldCloseParentTransaction(Payment $orderPayment) { - return false; - } -} \ No newline at end of file + /** + * @param Payment $orderPayment + * @return bool + */ + protected function shouldCloseParentTransaction(Payment $orderPayment) + { + return false; + } +} diff --git a/Gateway/Response/VaultDetailsHandler.php b/Gateway/Response/VaultDetailsHandler.php index 8aff058..0a944d0 100644 --- a/Gateway/Response/VaultDetailsHandler.php +++ b/Gateway/Response/VaultDetailsHandler.php @@ -13,8 +13,10 @@ * @copyright Copyright (c) 2017-2018 * @license Open Software License (OSL 3.0) */ + namespace Pmclain\Stripe\Gateway\Response; +use Magento\Sales\Api\Data\OrderPaymentInterface; use Pmclain\Stripe\Gateway\Helper\SubjectReader; use Magento\Payment\Gateway\Response\HandlerInterface; use Magento\Payment\Model\InfoInterface; @@ -26,147 +28,149 @@ class VaultDetailsHandler implements HandlerInterface { - /** - * @var CreditCardTokenFactory - */ - protected $paymentTokenFactory; - - /** - * @var OrderPaymentExtensionInterfaceFactory - */ - protected $paymentExtensionFactory; - - /** - * @var SubjectReader - */ - protected $subjectReader; - - /** @var Config */ - protected $config; - - /** - * Constructor - * - * @param CreditCardTokenFactory $paymentTokenFactory - * @param OrderPaymentExtensionInterfaceFactory $paymentExtensionFactory - * @param Config $config - * @param SubjectReader $subjectReader - */ - public function __construct( - CreditCardTokenFactory $paymentTokenFactory, - OrderPaymentExtensionInterfaceFactory $paymentExtensionFactory, - Config $config, - SubjectReader $subjectReader - ) { - $this->paymentTokenFactory = $paymentTokenFactory; - $this->paymentExtensionFactory = $paymentExtensionFactory; - $this->subjectReader = $subjectReader; - $this->config = $config; - } - - /** - * @inheritdoc - */ - public function handle(array $handlingSubject, array $response) - { - $paymentDO = $this->subjectReader->readPayment($handlingSubject); - $transaction = $this->subjectReader->readTransaction($response); - $payment = $paymentDO->getPayment(); - - if(!$payment->getAdditionalInformation('is_active_payment_token_enabler')) { - return; + /** + * @var CreditCardTokenFactory + */ + protected $paymentTokenFactory; + + /** + * @var OrderPaymentExtensionInterfaceFactory + */ + protected $paymentExtensionFactory; + + /** + * @var SubjectReader + */ + protected $subjectReader; + + /** @var Config */ + protected $config; + + /** + * Constructor + * + * @param CreditCardTokenFactory $paymentTokenFactory + * @param OrderPaymentExtensionInterfaceFactory $paymentExtensionFactory + * @param Config $config + * @param SubjectReader $subjectReader + */ + public function __construct( + CreditCardTokenFactory $paymentTokenFactory, + OrderPaymentExtensionInterfaceFactory $paymentExtensionFactory, + Config $config, + SubjectReader $subjectReader + ) { + $this->paymentTokenFactory = $paymentTokenFactory; + $this->paymentExtensionFactory = $paymentExtensionFactory; + $this->subjectReader = $subjectReader; + $this->config = $config; + } + + /** + * @inheritdoc + */ + public function handle(array $handlingSubject, array $response) + { + $paymentDO = $this->subjectReader->readPayment($handlingSubject); + $transaction = $this->subjectReader->readTransaction($response); + $payment = $paymentDO->getPayment(); + + if (!$payment->getAdditionalInformation('is_active_payment_token_enabler')) { + return; + } + + $paymentToken = $this->getVaultPaymentToken($payment, $transaction); + if (null !== $paymentToken) { + $extensionAttributes = $this->getExtensionAttributes($payment); + $extensionAttributes->setVaultPaymentToken($paymentToken); + } + } + + /** + * @param OrderPaymentInterface $payment + * @param array $transaction + * @return PaymentTokenInterface|null + */ + private function getVaultPaymentToken($payment, $transaction) + { + // Check token existing in gateway response + $source = $transaction['source']->__toArray(); + if (!isset($source['id']) && !$payment->getAdditionalInformation('cc_src')) { + return null; + } + + /** @var PaymentTokenInterface $paymentToken */ + $paymentToken = $this->paymentTokenFactory->create(); + $paymentToken->setGatewayToken($payment->getAdditionalInformation('cc_src') ?: $source['id']); + $paymentToken->setExpiresAt($this->getExpirationDate($payment)); + + $paymentToken->setTokenDetails($this->convertDetailsToJSON([ + 'type' => $this->getCreditCardType($payment->getCcType()), + 'maskedCC' => $payment->getCcLast4(), + 'expirationDate' => $payment->getCcExpMonth() . '/' . $payment->getCcExpYear(), + 'threeDSecure' => $payment->getAdditionalInformation('cc_src') ? true : false, + ])); + + return $paymentToken; + } + + /** + * @param OrderPaymentInterface $payment + * @return string + */ + private function getExpirationDate($payment) + { + $expDate = new \DateTime( + $payment->getCcExpYear() + . '-' + . $payment->getCcExpMonth() + . '-' + . '01' + . ' ' + . '00:00:00', + new \DateTimeZone('UTC') + ); + $expDate->add(new \DateInterval('P1M')); + return $expDate->format('Y-m-d 00:00:00'); } - $paymentToken = $this->getVaultPaymentToken($transaction); - if (null !== $paymentToken) { - $extensionAttributes = $this->getExtensionAttributes($payment); - $extensionAttributes->setVaultPaymentToken($paymentToken); + /** + * Convert payment token details to JSON + * @param array $details + * @return string + */ + private function convertDetailsToJSON($details) + { + $json = \Zend_Json::encode($details); + return $json ? $json : '{}'; } - } - - /** - * @param $transaction - * @return PaymentTokenInterface|null - */ - private function getVaultPaymentToken($transaction) - { - // Check token existing in gateway response - $source = $transaction['source']->__toArray(); - if (!isset($source['id'])) { - return null; + + /** + * Get type of credit card mapped from Stripe + * + * @param string $type + * @return array + */ + private function getCreditCardType($type) + { + $replaced = str_replace(' ', '-', strtolower($type)); + $mapper = $this->config->getCctypesMapper(); + + return $mapper[$replaced]; } - /** @var PaymentTokenInterface $paymentToken */ - $paymentToken = $this->paymentTokenFactory->create(); - $paymentToken->setGatewayToken($source['id']); - $paymentToken->setExpiresAt($this->getExpirationDate($source)); - - $paymentToken->setTokenDetails($this->convertDetailsToJSON([ - 'type' => $this->getCreditCardType($source['brand']), - 'maskedCC' => $source['last4'], - 'expirationDate' => $source['exp_month'] . '/' . $source['exp_year'] - ])); - - return $paymentToken; - } - - /** - * @param array $source - * @return string - */ - private function getExpirationDate($source) - { - $expDate = new \DateTime( - $source['exp_year'] - . '-' - . $source['exp_month'] - . '-' - . '01' - . ' ' - . '00:00:00', - new \DateTimeZone('UTC') - ); - $expDate->add(new \DateInterval('P1M')); - return $expDate->format('Y-m-d 00:00:00'); - } - - /** - * Convert payment token details to JSON - * @param array $details - * @return string - */ - private function convertDetailsToJSON($details) - { - $json = \Zend_Json::encode($details); - return $json ? $json : '{}'; - } - - /** - * Get type of credit card mapped from Stripe - * - * @param string $type - * @return array - */ - private function getCreditCardType($type) - { - $replaced = str_replace(' ', '-', strtolower($type)); - $mapper = $this->config->getCctypesMapper(); - - return $mapper[$replaced]; - } - - /** - * Get payment extension attributes - * @param InfoInterface $payment - * @return OrderPaymentExtensionInterface - */ - private function getExtensionAttributes(InfoInterface $payment) - { - $extensionAttributes = $payment->getExtensionAttributes(); - if (null === $extensionAttributes) { - $extensionAttributes = $this->paymentExtensionFactory->create(); - $payment->setExtensionAttributes($extensionAttributes); + /** + * Get payment extension attributes + * @param InfoInterface $payment + * @return OrderPaymentExtensionInterface + */ + private function getExtensionAttributes(InfoInterface $payment) + { + $extensionAttributes = $payment->getExtensionAttributes(); + if (null === $extensionAttributes) { + $extensionAttributes = $this->paymentExtensionFactory->create(); + $payment->setExtensionAttributes($extensionAttributes); + } + return $extensionAttributes; } - return $extensionAttributes; - } -} \ No newline at end of file +} diff --git a/Gateway/Response/VoidHandler.php b/Gateway/Response/VoidHandler.php index da4d376..571ca52 100755 --- a/Gateway/Response/VoidHandler.php +++ b/Gateway/Response/VoidHandler.php @@ -13,6 +13,7 @@ * @copyright Copyright (c) 2017-2018 * @license Open Software License (OSL 3.0) */ + namespace Pmclain\Stripe\Gateway\Response; use Magento\Sales\Model\Order\Payment; @@ -20,15 +21,29 @@ class VoidHandler extends TransactionIdHandler { - protected function setTransactionId(Payment $orderPayment, $transaction) { - return; - } + /** + * @param Payment $orderPayment + * @param $transaction + */ + protected function setTransactionId(Payment $orderPayment, $transaction) + { + return; + } - protected function shouldCloseTransaction() { - return true; - } + /** + * @return bool + */ + protected function shouldCloseTransaction() + { + return true; + } - protected function shouldCloseParentTransaction(Payment $orderPayment) { - return true; - } -} \ No newline at end of file + /** + * @param Payment $orderPayment + * @return bool + */ + protected function shouldCloseParentTransaction(Payment $orderPayment) + { + return true; + } +} diff --git a/Gateway/Validator/GeneralResponseValidator.php b/Gateway/Validator/GeneralResponseValidator.php index 251698b..aadbd88 100755 --- a/Gateway/Validator/GeneralResponseValidator.php +++ b/Gateway/Validator/GeneralResponseValidator.php @@ -13,6 +13,7 @@ * @copyright Copyright (c) 2017-2018 * @license Open Software License (OSL 3.0) */ + namespace Pmclain\Stripe\Gateway\Validator; use Magento\Payment\Gateway\Validator\AbstractValidator; @@ -21,49 +22,69 @@ class GeneralResponseValidator extends AbstractValidator { - protected $subjectReader; + /** + * @var SubjectReader + */ + protected $subjectReader; - public function __construct( - ResultInterfaceFactory $resultFactory, - SubjectReader $subjectReader - ) { - parent::__construct($resultFactory); - $this->subjectReader = $subjectReader; - } + /** + * GeneralResponseValidator constructor. + * @param ResultInterfaceFactory $resultFactory + * @param SubjectReader $subjectReader + */ + public function __construct( + ResultInterfaceFactory $resultFactory, + SubjectReader $subjectReader + ) { + parent::__construct($resultFactory); + $this->subjectReader = $subjectReader; + } - public function validate(array $subject) { - $response = $this->subjectReader->readResponseObject($subject); + /** + * @param array $subject + * @return \Magento\Payment\Gateway\Validator\ResultInterface + */ + public function validate(array $subject) + { + $response = $this->subjectReader->readResponseObject($subject); - $isValid = true; - $errorMessages = []; + $isValid = true; + $errorMessages = []; - foreach ($this->getResponseValidators() as $validator) { - $validationResult = $validator($response); + foreach ($this->getResponseValidators() as $validator) { + $validationResult = $validator($response); - if(!$validationResult[0]) { - $isValid = $validationResult[0]; - $errorMessages = array_merge($errorMessages, $validationResult[1]); - break; - } - } + if (!$validationResult[0]) { + $isValid = $validationResult[0]; + $errorMessages = array_merge( + $errorMessages, + $validationResult[1] + ); + break; + } + } - return $this->createResult($isValid, $errorMessages); - } + return $this->createResult($isValid, $errorMessages); + } - protected function getResponseValidators() { - return [ - function ($response) { - if(isset($response['error'])) { - return [ - false, - [$response['message']] - ]; - } + /** + * @return array + */ + protected function getResponseValidators() + { return [ - $response['status'] === 'succeeded', - [__('Stripe error response.')] + function ($response) { + if (isset($response['error'])) { + return [ + false, + [$response['message']] + ]; + } + return [ + $response['status'] === 'succeeded', + [__('Stripe error response.')] + ]; + } ]; - } - ]; - } -} \ No newline at end of file + } +} diff --git a/Gateway/Validator/ResponseValidator.php b/Gateway/Validator/ResponseValidator.php index ac6f968..3a82a93 100755 --- a/Gateway/Validator/ResponseValidator.php +++ b/Gateway/Validator/ResponseValidator.php @@ -13,31 +13,36 @@ * @copyright Copyright (c) 2017-2018 * @license Open Software License (OSL 3.0) */ + namespace Pmclain\Stripe\Gateway\Validator; class ResponseValidator extends GeneralResponseValidator { - protected function getResponseValidators() { - return array_merge( - parent::getResponseValidators(), - [ - function ($response) { - if(isset($response['error'])) { - return [false, [$response['message']]]; - } - return [ - in_array( - $response['status'], - [ - 'succeeded', - 'pending', - 'failed' - ] - ), - [__('Wrong transaction status')] - ]; - } - ] - ); - } -} \ No newline at end of file + /** + * @return array + */ + protected function getResponseValidators() + { + return array_merge( + parent::getResponseValidators(), + [ + function ($response) { + if (isset($response['error'])) { + return [false, [$response['message']]]; + } + return [ + in_array( + $response['status'], + [ + 'succeeded', + 'pending', + 'failed' + ] + ), + [__('Wrong transaction status')] + ]; + } + ] + ); + } +} diff --git a/Gateway/Validator/ResponseValidator/Authorize.php b/Gateway/Validator/ResponseValidator/Authorize.php index 4844bbd..cf93074 100755 --- a/Gateway/Validator/ResponseValidator/Authorize.php +++ b/Gateway/Validator/ResponseValidator/Authorize.php @@ -13,23 +13,28 @@ * @copyright Copyright (c) 2017-2018 * @license Open Software License (OSL 3.0) */ + namespace Pmclain\Stripe\Gateway\Validator\ResponseValidator; use Pmclain\Stripe\Gateway\Validator\ResponseValidator; class Authorize extends ResponseValidator { - protected function getResponseValidators() { - return array_merge( - parent::getResponseValidators(), - [ - function ($response) { - return [ - $response['outcome']->__toArray()['network_status'] === 'approved_by_network', - [__('Transaction has been declined')] - ]; - } - ] - ); - } -} \ No newline at end of file + /** + * @return array + */ + protected function getResponseValidators() + { + return array_merge( + parent::getResponseValidators(), + [ + function ($response) { + return [ + $response['outcome']->__toArray()['network_status'] === 'approved_by_network', + [__('Transaction has been declined')] + ]; + } + ] + ); + } +} diff --git a/Helper/CcType.php b/Helper/CcType.php index 307bab3..2cb0397 100755 --- a/Helper/CcType.php +++ b/Helper/CcType.php @@ -13,25 +13,41 @@ * @copyright Copyright (c) 2017-2018 * @license Open Software License (OSL 3.0) */ + namespace Pmclain\Stripe\Helper; use Pmclain\Stripe\Model\Adminhtml\Source\Cctype as CcTypeSource; class CcType { - private $ccTypes = []; - private $ccTypeSource; + /** + * @var array + */ + private $ccTypes = []; + + /** + * @var CcTypeSource + */ + private $ccTypeSource; - public function __construct( - CcTypeSource $ccTypeSource - ) { - $this->ccTypeSource = $ccTypeSource; - } + /** + * CcType constructor. + * @param CcTypeSource $ccTypeSource + */ + public function __construct( + CcTypeSource $ccTypeSource + ) { + $this->ccTypeSource = $ccTypeSource; + } - public function getCcTypes() { - if(!$this->ccTypes) { - $this->ccTypes = $this->ccTypeSource->toOptionArray(); + /** + * @return array + */ + public function getCcTypes() + { + if (!$this->ccTypes) { + $this->ccTypes = $this->ccTypeSource->toOptionArray(); + } + return $this->ccTypes; } - return $this->ccTypes; - } -} \ No newline at end of file +} diff --git a/Helper/Payment/Formatter.php b/Helper/Payment/Formatter.php index d37c86f..ad15e0e 100755 --- a/Helper/Payment/Formatter.php +++ b/Helper/Payment/Formatter.php @@ -13,14 +13,19 @@ * @copyright Copyright (c) 2017-2018 * @license Open Software License (OSL 3.0) */ -namespace Pmclain\Stripe\Helper\Payment; -use Magento\Payment\Helper\Formatter as PaymentFormatter; +namespace Pmclain\Stripe\Helper\Payment; -trait Formatter { - public function formatPrice($price) { - $price = sprintf('%.2F', $price); +trait Formatter +{ + /** + * @param string $price + * @return string + */ + public function formatPrice($price) + { + $price = sprintf('%.2F', $price); - return str_replace('.', '', $price); - } -} \ No newline at end of file + return str_replace('.', '', $price); + } +} diff --git a/Model/Adapter/StripeAdapter.php b/Model/Adapter/StripeAdapter.php index a49aea1..003b43c 100755 --- a/Model/Adapter/StripeAdapter.php +++ b/Model/Adapter/StripeAdapter.php @@ -13,6 +13,7 @@ * @copyright Copyright (c) 2017-2018 * @license Open Software License (OSL 3.0) */ + namespace Pmclain\Stripe\Model\Adapter; use Stripe\Customer; @@ -20,80 +21,118 @@ use Stripe\Charge; use Stripe\Refund; use Pmclain\Stripe\Gateway\Config\Config; -use Magento\Framework\Encryption\EncryptorInterface; use Pmclain\Stripe\Gateway\Request\PaymentDataBuilder; +use Pmclain\Stripe\Gateway\Request\ThreeDSecureBuilder; class StripeAdapter { - private $config; - - protected $encryptor; - - public function __construct( - Config $config, - EncryptorInterface $encryptorInterface - ) { - $this->encryptor = $encryptorInterface; - $this->config = $config; - $this->initCredentials(); - } - - protected function initCredentials() { - Stripe::setApiKey($this->encryptor->decrypt($this->config->getSecretKey())); - } - - public function refund($transactionId, $amount = null) { - return Refund::create([ - 'charge' => $transactionId, - 'amount' => $amount - ]); - } - - public function sale($attributes) { - if(isset($attributes[PaymentDataBuilder::SAVE_IN_VAULT])) { - unset($attributes[PaymentDataBuilder::SAVE_IN_VAULT]); - $attributes = $this->_saveCustomerCard($attributes); - - if($attributes instanceof \Stripe\Error\Card) { - return $attributes; - } + /** + * @var Config + */ + private $config; + + /** + * StripeAdapter constructor. + * @param Config $config + */ + public function __construct( + Config $config + ) { + $this->config = $config; + $this->initCredentials(); + } + + protected function initCredentials() + { + Stripe::setApiKey($this->config->getSecretKey()); + } + + /** + * @param $transactionId + * @param null $amount + * @return \Stripe\ApiOperations\ApiResource + */ + public function refund($transactionId, $amount = null) + { + return Refund::create([ + 'charge' => $transactionId, + 'amount' => $amount, + ]); + } + + /** + * @param $attributes + * @return array|\Exception|\Stripe\ApiOperations\ApiResource|\Stripe\Error\Card + */ + public function sale($attributes) + { + if (isset($attributes[PaymentDataBuilder::SAVE_IN_VAULT])) { + unset($attributes[PaymentDataBuilder::SAVE_IN_VAULT]); + $attributes = $this->saveCustomerCard($attributes); + + if ($attributes instanceof \Stripe\Error\Card) { + return $attributes; + } + } elseif (isset($attributes[ThreeDSecureBuilder::SOURCE_FOR_VAULT])) { + unset($attributes[ThreeDSecureBuilder::SOURCE_FOR_VAULT]); + } + + try { + return Charge::create($attributes); + } catch (\Stripe\Error\Card $e) { + return $e; + } } - try { - return Charge::create($attributes); - }catch (\Stripe\Error\Card $e) { - return $e; + + /** + * @param $transactionId + * @param null $amount + * @return mixed + */ + public function submitForSettlement($transactionId, $amount = null) + { + $charge = Charge::retrieve($transactionId); + return $charge->capture(['amount' => $amount]); } - } - - public function submitForSettlement($transactionId, $amount = null) { - $charge = Charge::retrieve($transactionId); - return $charge->capture(['amount' => $amount]); - } - - public function void($transactionId) { - return Refund::create(['charge' => $transactionId]); - } - - /** - * @param $attributes - * @return \Exception|\Stripe\Error\Card|array - * @throws \Magento\Framework\Validator\Exception - */ - protected function _saveCustomerCard($attributes) { - try { - $stripeCustomer = Customer::retrieve($attributes[PaymentDataBuilder::CUSTOMER]); - - $card = $stripeCustomer->sources->create([ - 'source' => $attributes[PaymentDataBuilder::SOURCE] - ]); - - $attributes[PaymentDataBuilder::SOURCE] = $card->id; - - return $attributes; - }catch (\Stripe\Error\Card $e) { - return $e; - }catch (\Exception $e) { - throw new \Magento\Framework\Validator\Exception(__($e->getMessage())); + + /** + * @param $transactionId + * @return \Stripe\ApiOperations\ApiResource + */ + public function void($transactionId) + { + return Refund::create(['charge' => $transactionId]); + } + + /** + * @param $attributes + * @return \Exception|\Stripe\Error\Card|array + * @throws \Magento\Framework\Validator\Exception + */ + protected function saveCustomerCard($attributes) + { + try { + $stripeCustomer = Customer::retrieve($attributes[PaymentDataBuilder::CUSTOMER]); + + if (isset($attributes[ThreeDSecureBuilder::SOURCE_FOR_VAULT])) { + $stripeCustomer->sources->create([ + 'source' => $attributes[ThreeDSecureBuilder::SOURCE_FOR_VAULT] + ]); + + unset($attributes[ThreeDSecureBuilder::SOURCE_FOR_VAULT]); + } else { + $card = $stripeCustomer->sources->create([ + 'source' => $attributes[PaymentDataBuilder::SOURCE] + ]); + + $attributes[PaymentDataBuilder::SOURCE] = $card->id; + } + + return $attributes; + } catch (\Stripe\Error\Card $e) { + return $e; + } catch (\Exception $e) { + throw new \Magento\Framework\Validator\Exception(__($e->getMessage())); + } } - } -} \ No newline at end of file +} diff --git a/Model/Adminhtml/Source/Cctype.php b/Model/Adminhtml/Source/Cctype.php index 0d2d6d7..9a3addb 100755 --- a/Model/Adminhtml/Source/Cctype.php +++ b/Model/Adminhtml/Source/Cctype.php @@ -13,13 +13,22 @@ * @copyright Copyright (c) 2017-2018 * @license Open Software License (OSL 3.0) */ + namespace Pmclain\Stripe\Model\Adminhtml\Source; use Magento\Payment\Model\Source\Cctype as PaymentCctype; class Cctype extends PaymentCctype { - public function getAllowedTypes() { - return ['VI', 'MC', 'AE', 'DI', 'JCB', 'DN']; - } -} \ No newline at end of file + public function getAllowedTypes() + { + return [ + 'VI', + 'MC', + 'AE', + 'DI', + 'JCB', + 'DN', + ]; + } +} diff --git a/Model/Adminhtml/Source/PaymentAction.php b/Model/Adminhtml/Source/PaymentAction.php index 1571552..dc9138d 100755 --- a/Model/Adminhtml/Source/PaymentAction.php +++ b/Model/Adminhtml/Source/PaymentAction.php @@ -13,6 +13,7 @@ * @copyright Copyright (c) 2017-2018 * @license Open Software License (OSL 3.0) */ + namespace Pmclain\Stripe\Model\Adminhtml\Source; use Magento\Payment\Model\Method\AbstractMethod; @@ -20,16 +21,17 @@ class PaymentAction implements ArrayInterface { - public function toOptionArray() { - return [ - [ - 'value' => AbstractMethod::ACTION_AUTHORIZE, - 'label' => __('Authorize Only') - ], - [ - 'value' => AbstractMethod::ACTION_AUTHORIZE_CAPTURE, - 'label' => __('Authorize and Capture') - ] - ]; - } -} \ No newline at end of file + public function toOptionArray() + { + return [ + [ + 'value' => AbstractMethod::ACTION_AUTHORIZE, + 'label' => __('Authorize Only'), + ], + [ + 'value' => AbstractMethod::ACTION_AUTHORIZE_CAPTURE, + 'label' => __('Authorize and Capture'), + ] + ]; + } +} diff --git a/Model/Helper/OrderPlace.php b/Model/Helper/OrderPlace.php new file mode 100644 index 0000000..9b1c1f9 --- /dev/null +++ b/Model/Helper/OrderPlace.php @@ -0,0 +1,131 @@ +cartManagement = $cartManagement; + $this->customerSession = $session; + $this->checkoutHelper = $helper; + } + + /** + * @param Quote $quote + * @param string $src + * @param string $clientSecret + * @throws LocalizedException + * @throws \InvalidArgumentException + */ + public function execute(Quote $quote, $src, $clientSecret) + { + $this->validatePaymentInformation($quote->getPayment(), $src, $clientSecret); + + if ($this->getCheckoutMethod($quote) === Onepage::METHOD_GUEST) { + $this->prepareGuestQuote($quote); + } + + $quote->collectTotals(); + $this->cartManagement->placeOrder($quote->getId()); + } + + /** + * @param \Magento\Payment\Model\InfoInterface $payment + * @param string $src + * @param string $clientSecret + * @throws \InvalidArgumentException + */ + private function validatePaymentInformation($payment, $src, $clientSecret) + { + if ($payment->getAdditionalInformation('three_d_client_secret') !== $clientSecret + || $payment->getAdditionalInformation('three_d_src') !== $src + ) { + throw new \InvalidArgumentException( + __('Your payment information could not be validated. Please try again.') + ); + } + } + + /** + * Get checkout method + * + * @param Quote $quote + * @return string + */ + private function getCheckoutMethod(Quote $quote) + { + if ($this->customerSession->isLoggedIn()) { + return Onepage::METHOD_CUSTOMER; + } + if (!$quote->getCheckoutMethod()) { + if ($this->checkoutHelper->isAllowedGuestCheckout($quote)) { + $quote->setCheckoutMethod(Onepage::METHOD_GUEST); + } else { + $quote->setCheckoutMethod(Onepage::METHOD_REGISTER); + } + } + + return $quote->getCheckoutMethod(); + } + + /** + * Prepare quote for guest checkout order submit + * + * @param Quote $quote + * @return void + */ + private function prepareGuestQuote(Quote $quote) + { + $quote->setCustomerId(null) + ->setCustomerEmail($quote->getBillingAddress()->getEmail()) + ->setCustomerIsGuest(true) + ->setCustomerGroupId(Group::NOT_LOGGED_IN_ID); + } +} diff --git a/Model/Ui/Adminhtml/TokenUiComponentProvider.php b/Model/Ui/Adminhtml/TokenUiComponentProvider.php index 2cd5d6e..759bdfe 100644 --- a/Model/Ui/Adminhtml/TokenUiComponentProvider.php +++ b/Model/Ui/Adminhtml/TokenUiComponentProvider.php @@ -13,6 +13,7 @@ * @copyright Copyright (c) 2017-2018 * @license Open Software License (OSL 3.0) */ + namespace Pmclain\Stripe\Model\Ui\Adminhtml; use Pmclain\Stripe\Model\Ui\ConfigProvider; @@ -22,54 +23,64 @@ use Magento\Vault\Model\Ui\TokenUiComponentProviderInterface; use Magento\Vault\Model\Ui\TokenUiComponentInterfaceFactory; use Magento\Framework\UrlInterface; +use Magento\Framework\Json\DecoderInterface; /** * Class TokenUiComponentProvider */ class TokenUiComponentProvider implements TokenUiComponentProviderInterface { - /** - * @var TokenUiComponentInterfaceFactory - */ - private $componentFactory; + /** + * @var TokenUiComponentInterfaceFactory + */ + private $componentFactory; + + /** + * @var \Magento\Framework\UrlInterface + */ + private $urlBuilder; + + /** + * @var DecoderInterface + */ + private $jsonDecoder; - /** - * @var \Magento\Framework\UrlInterface - */ - private $urlBuilder; + /** + * @param TokenUiComponentInterfaceFactory $componentFactory + * @param UrlInterface $urlBuilder + * @param DecoderInterface $decoder + */ + public function __construct( + TokenUiComponentInterfaceFactory $componentFactory, + UrlInterface $urlBuilder, + DecoderInterface $decoder + ) { + $this->componentFactory = $componentFactory; + $this->urlBuilder = $urlBuilder; + $this->jsonDecoder = $decoder; + } - /** - * @param TokenUiComponentInterfaceFactory $componentFactory - * @param UrlInterface $urlBuilder - */ - public function __construct( - TokenUiComponentInterfaceFactory $componentFactory, - UrlInterface $urlBuilder - ) { - $this->componentFactory = $componentFactory; - $this->urlBuilder = $urlBuilder; - } + /** + * Get UI component for token + * @param PaymentTokenInterface $paymentToken + * @return TokenUiComponentInterface + */ + public function getComponentForToken(PaymentTokenInterface $paymentToken) + { + $jsonDetails = $this->jsonDecoder->decode($paymentToken->getTokenDetails() ?: '{}'); - /** - * Get UI component for token - * @param PaymentTokenInterface $paymentToken - * @return TokenUiComponentInterface - */ - public function getComponentForToken(PaymentTokenInterface $paymentToken) - { - $jsonDetails = json_decode($paymentToken->getTokenDetails() ?: '{}', true); - $component = $this->componentFactory->create( - [ - 'config' => [ - 'code' => ConfigProvider::CC_VAULT_CODE, - TokenUiComponentProviderInterface::COMPONENT_DETAILS => $jsonDetails, - TokenUiComponentProviderInterface::COMPONENT_PUBLIC_HASH => $paymentToken->getPublicHash(), - 'template' => 'Pmclain_Stripe::form/vault.phtml' - ], - 'name' => Template::class - ] - ); + $component = $this->componentFactory->create( + [ + 'config' => [ + 'code' => ConfigProvider::CC_VAULT_CODE, + TokenUiComponentProviderInterface::COMPONENT_DETAILS => $jsonDetails, + TokenUiComponentProviderInterface::COMPONENT_PUBLIC_HASH => $paymentToken->getPublicHash(), + 'template' => 'Pmclain_Stripe::form/vault.phtml', + ], + 'name' => Template::class, + ] + ); - return $component; - } -} \ No newline at end of file + return $component; + } +} diff --git a/Model/Ui/ConfigProvider.php b/Model/Ui/ConfigProvider.php index c427585..818cd41 100755 --- a/Model/Ui/ConfigProvider.php +++ b/Model/Ui/ConfigProvider.php @@ -13,58 +13,89 @@ * @copyright Copyright (c) 2017-2018 * @license Open Software License (OSL 3.0) */ + namespace Pmclain\Stripe\Model\Ui; use Magento\Checkout\Model\ConfigProviderInterface; use Magento\Framework\App\Config\ScopeConfigInterface; -use Magento\Framework\Encryption\EncryptorInterface; use Magento\Store\Model\ScopeInterface; +use Pmclain\Stripe\Gateway\Config\Config; +use Magento\Framework\UrlInterface; class ConfigProvider implements ConfigProviderInterface { - const CODE = 'pmclain_stripe'; - const CC_VAULT_CODE = 'pmclain_stripe_vault'; + const CODE = 'pmclain_stripe'; + const CC_VAULT_CODE = 'pmclain_stripe_vault'; - protected $_config; - protected $_encryptor; + /** + * @var ScopeConfigInterface + */ + protected $config; - public function __construct( - ScopeConfigInterface $configInterface, - EncryptorInterface $encryptorInterface - ){ - $this->_config = $configInterface; - $this->_encryptor = $encryptorInterface; - } + /** + * @var UrlInterface + */ + protected $url; - public function getConfig() - { - return [ - 'payment' => [ - self::CODE => [ - 'publishableKey' => $this->getPublishableKey(), - 'vaultCode' => self::CC_VAULT_CODE, - ] - ] - ]; - } + /** + * ConfigProvider constructor. + * @param ScopeConfigInterface $configInterface + * @param UrlInterface $url + */ + public function __construct( + ScopeConfigInterface $configInterface, + UrlInterface $url + ) { + $this->config = $configInterface; + $this->url = $url; + } - public function getPublishableKey() { - if ($this->_isTestMode()) { - return $this->_getEncryptedConfig('test_publishable_key'); + /** + * @return array + */ + public function getConfig() + { + return [ + 'payment' => [ + self::CODE => [ + 'publishableKey' => $this->getPublishableKey(), + 'threeDSecure' => (int)$this->getStoreConfig(Config::KEY_VERIFY_3D_SECURE), + 'threeDThreshold' => (float)$this->getStoreConfig(Config::KEY_3D_SECURE_THRESHOLD), + 'threeDRedirectUrl' => $this->url->getUrl('pmstripe/threedsecure/redirect'), + 'vaultCode' => self::CC_VAULT_CODE, + ], + ], + ]; } - return $this->_getEncryptedConfig('live_publishable_key'); - } - protected function _isTestMode() { - return $this->_getConfig('test_mode'); - } + /** + * @return string + */ + public function getPublishableKey() + { + if ($this->isTestMode()) { + return $this->getStoreConfig(Config::KEY_TEST_PUBLISHABLE_KEY); + } + return $this->getStoreConfig(Config::KEY_LIVE_PUBLISHABLE_KEY); + } - protected function _getEncryptedConfig($value) { - $config = $this->_getConfig($value); - return $this->_encryptor->decrypt($config); - } + /** + * @return int + */ + protected function isTestMode() + { + return (int)$this->getStoreConfig(Config::KEY_ENVIRONMENT); + } - protected function _getConfig($value) { - return $this->_config->getValue('payment/pmclain_stripe/' . $value, ScopeInterface::SCOPE_STORE); - } -} \ No newline at end of file + /** + * @param string $value + * @return mixed + */ + protected function getStoreConfig($value) + { + return $this->config->getValue( + 'payment/pmclain_stripe/' . $value, + ScopeInterface::SCOPE_STORE + ); + } +} diff --git a/Model/Ui/TokenUiComponentProvider.php b/Model/Ui/TokenUiComponentProvider.php index 84f5b76..e667521 100644 --- a/Model/Ui/TokenUiComponentProvider.php +++ b/Model/Ui/TokenUiComponentProvider.php @@ -13,61 +13,95 @@ * @copyright Copyright (c) 2017-2018 * @license Open Software License (OSL 3.0) */ + namespace Pmclain\Stripe\Model\Ui; use Pmclain\Stripe\Model\Ui\ConfigProvider; +use Pmclain\Stripe\Gateway\Config\Config; use Magento\Vault\Api\Data\PaymentTokenInterface; use Magento\Vault\Model\Ui\TokenUiComponentInterface; use Magento\Vault\Model\Ui\TokenUiComponentProviderInterface; use Magento\Vault\Model\Ui\TokenUiComponentInterfaceFactory; use Magento\Framework\UrlInterface; +use Magento\Framework\Json\DecoderInterface; /** * Class TokenUiComponentProvider */ class TokenUiComponentProvider implements TokenUiComponentProviderInterface { - /** - * @var TokenUiComponentInterfaceFactory - */ - private $componentFactory; + /** + * @var TokenUiComponentInterfaceFactory + */ + private $componentFactory; + + /** + * @var \Magento\Framework\UrlInterface + */ + private $urlBuilder; + + /** + * @var DecoderInterface + */ + private $jsonDecoder; + + /** + * @var Config + */ + private $config; + + /** + * @param TokenUiComponentInterfaceFactory $componentFactory + * @param UrlInterface $urlBuilder + * @param DecoderInterface $decoder + * @param Config $config + */ + public function __construct( + TokenUiComponentInterfaceFactory $componentFactory, + UrlInterface $urlBuilder, + DecoderInterface $decoder, + Config $config + ) { + $this->componentFactory = $componentFactory; + $this->urlBuilder = $urlBuilder; + $this->jsonDecoder = $decoder; + $this->config = $config; + } + + /** + * Get UI component for token + * @param PaymentTokenInterface $paymentToken + * @return TokenUiComponentInterface + */ + public function getComponentForToken(PaymentTokenInterface $paymentToken) + { + $jsonDetails = $this->jsonDecoder->decode($paymentToken->getTokenDetails() ?: '{}'); + $jsonDetails['source'] = $this->getSource($paymentToken); - /** - * @var \Magento\Framework\UrlInterface - */ - private $urlBuilder; + $component = $this->componentFactory->create( + [ + 'config' => [ + 'code' => ConfigProvider::CC_VAULT_CODE, + TokenUiComponentProviderInterface::COMPONENT_DETAILS => $jsonDetails, + TokenUiComponentProviderInterface::COMPONENT_PUBLIC_HASH => $paymentToken->getPublicHash(), + ], + 'name' => 'Pmclain_Stripe/js/view/payment/method-renderer/vault', + ] + ); - /** - * @param TokenUiComponentInterfaceFactory $componentFactory - * @param UrlInterface $urlBuilder - */ - public function __construct( - TokenUiComponentInterfaceFactory $componentFactory, - UrlInterface $urlBuilder - ) { - $this->componentFactory = $componentFactory; - $this->urlBuilder = $urlBuilder; - } + return $component; + } - /** - * Get UI component for token - * @param PaymentTokenInterface $paymentToken - * @return TokenUiComponentInterface - */ - public function getComponentForToken(PaymentTokenInterface $paymentToken) - { - $jsonDetails = json_decode($paymentToken->getTokenDetails() ?: '{}', true); - $component = $this->componentFactory->create( - [ - 'config' => [ - 'code' => ConfigProvider::CC_VAULT_CODE, - TokenUiComponentProviderInterface::COMPONENT_DETAILS => $jsonDetails, - TokenUiComponentProviderInterface::COMPONENT_PUBLIC_HASH => $paymentToken->getPublicHash() - ], - 'name' => 'Pmclain_Stripe/js/view/payment/method-renderer/vault' - ] - ); + /** + * @param PaymentTokenInterface $paymentToken + * @return string + */ + private function getSource($paymentToken) + { + if ($this->config->isRequireThreeDSecure()) { + return $paymentToken->getGatewayToken(); + } - return $component; - } -} \ No newline at end of file + return ''; + } +} diff --git a/Observer/DataAssignObserver.php b/Observer/DataAssignObserver.php index 18c4abd..a9dc04c 100755 --- a/Observer/DataAssignObserver.php +++ b/Observer/DataAssignObserver.php @@ -13,27 +13,60 @@ * @copyright Copyright (c) 2017-2018 * @license Open Software License (OSL 3.0) */ + namespace Pmclain\Stripe\Observer; use Magento\Framework\Event\Observer; use Magento\Payment\Observer\AbstractDataAssignObserver; +use Magento\Quote\Api\Data\PaymentInterface; +use Magento\Framework\DataObject; +use Magento\Payment\Model\InfoInterface; +use Magento\Framework\Exception\LocalizedException; class DataAssignObserver extends AbstractDataAssignObserver { - /** - * @param Observer $observer - * @return void - */ - public function execute(Observer $observer) - { - $method = $this->readMethodArgument($observer); - $data = $this->readDataArgument($observer); - $paymentInfo = $method->getInfoInstance(); - if (key_exists('cc_token', $data->getDataByKey('additional_data'))) { - $paymentInfo->setAdditionalInformation( - 'cc_token', - $data->getDataByKey('additional_data')['cc_token'] - ); + /** + * @param Observer $observer + * @return void + * @throws LocalizedException + */ + public function execute(Observer $observer) + { + $data = $this->readDataArgument($observer); + + $additionalData = $data->getData(PaymentInterface::KEY_ADDITIONAL_DATA); + if (!is_array($additionalData)) { + return; + } + + $additionalData = new DataObject($additionalData); + $paymentMethod = $this->readMethodArgument($observer); + + $payment = $observer->getPaymentModel(); + if (!$payment instanceof InfoInterface) { + $payment = $paymentMethod->getInfoInstance(); + } + + if (!$payment instanceof InfoInterface) { + throw new LocalizedException(__('Payment model does not provided.')); + } + + $payment->setCcLast4($additionalData->getData('cc_last4')); + $payment->setCcType($additionalData->getData('cc_type')); + $payment->setCcExpMonth($additionalData->getData('cc_exp_month')); + $payment->setCcExpYear($additionalData->getData('cc_exp_year')); + + if ($additionalData->getData('cc_token')) { + $payment->setAdditionalInformation('cc_token', $additionalData->getData('cc_token')); + } + if ($additionalData->getData('cc_src')) { + $payment->setAdditionalInformation('cc_src', $additionalData->getData('cc_src')); + } + if ($additionalData->getData('three_d_src')) { + $payment->setAdditionalInformation('three_d_src', $additionalData->getData('three_d_src')); + } + if ($additionalData->getData('three_d_client_secret')) { + $payment->setAdditionalInformation('three_d_client_secret', $additionalData->getData('three_d_client_secret')); + } } - } -} \ No newline at end of file +} diff --git a/Observer/VaultTokenObserver.php b/Observer/VaultTokenObserver.php index a2c668e..a09cdd1 100644 --- a/Observer/VaultTokenObserver.php +++ b/Observer/VaultTokenObserver.php @@ -13,64 +13,69 @@ * @copyright Copyright (c) 2017-2018 * @license Open Software License (OSL 3.0) */ + namespace Pmclain\Stripe\Observer; use Magento\Framework\Event\ObserverInterface; use Magento\Framework\Event\Observer; use Magento\Customer\Api\CustomerRepositoryInterface; use Pmclain\Stripe\Gateway\Config\Config; -use Magento\Framework\Encryption\EncryptorInterface; use Stripe\Stripe; use Stripe\Customer; class VaultTokenObserver implements ObserverInterface { - /** @var CustomerRepositoryInterface */ - private $customerRepository; - - /** @var Config */ - private $config; - - /** @var EncryptorInterface */ - private $encryptor; - - public function __construct( - Config $config, - EncryptorInterface $encryptor, - CustomerRepositoryInterface $customerRepository - ) { - $this->encryptor = $encryptor; - $this->config = $config; - $this->customerRepository = $customerRepository; - $this->initCredentials(); - } + /** @var CustomerRepositoryInterface */ + private $customerRepository; - protected function initCredentials() { - Stripe::setApiKey($this->encryptor->decrypt($this->config->getSecretKey())); - } + /** @var Config */ + private $config; - public function execute(Observer $observer) { - $token = $observer->getObject(); - if ($token->getIsActive()) { - return; + /** + * VaultTokenObserver constructor. + * @param Config $config + * @param CustomerRepositoryInterface $customerRepository + */ + public function __construct( + Config $config, + CustomerRepositoryInterface $customerRepository + ) { + $this->config = $config; + $this->customerRepository = $customerRepository; + $this->initCredentials(); } - try { - $customer = $this->customerRepository->getById($token->getCustomerId()); - }catch (\Exception $e) { - return; + protected function initCredentials() + { + Stripe::setApiKey($this->config->getSecretKey()); } - $stripeCustomerId = $customer->getCustomAttribute('stripe_customer_id'); - if (!$stripeCustomerId) { - return; - } + /** + * @param Observer $observer + */ + public function execute(Observer $observer) + { + $token = $observer->getObject(); + if ($token->getIsActive()) { + return; + } + + try { + $customer = $this->customerRepository->getById($token->getCustomerId()); + } catch (\Exception $e) { + return; + } + + $stripeCustomerId = $customer->getCustomAttribute('stripe_customer_id'); + if (!$stripeCustomerId) { + return; + } - try { - $stripeCustomer = Customer::retrieve($stripeCustomerId->getValue()); - $stripeCustomer->sources->retrieve($token->getGatewayToken())->delete(); - }catch (\Exception $e) { - return; + try { + $stripeCustomer = Customer::retrieve($stripeCustomerId->getValue()); + $stripeCustomer->sources->retrieve($token->getGatewayToken())->delete(); + } catch (\Exception $e) { + return; + } } - } -} \ No newline at end of file +} diff --git a/Setup/InstallData.php b/Setup/InstallData.php index 6240934..0f3391f 100644 --- a/Setup/InstallData.php +++ b/Setup/InstallData.php @@ -11,45 +11,54 @@ class InstallData implements InstallDataInterface { - /** @var EavSetupFactory */ - private $_eavSetupFactory; + /** @var EavSetupFactory */ + private $eavSetupFactory; - /** @var Config */ - private $_eavConfig; + /** @var Config */ + private $eavConfig; - /** - * InstallData constructor. - * @param EavSetupFactory $eavSetupFactory - * @param Config $config - */ - public function __construct( - EavSetupFactory $eavSetupFactory, - Config $config - ) - { - $this->_eavSetupFactory = $eavSetupFactory; - $this->_eavConfig = $config; - } + /** + * InstallData constructor. + * @param EavSetupFactory $eavSetupFactory + * @param Config $config + */ + public function __construct( + EavSetupFactory $eavSetupFactory, + Config $config + ) { + $this->eavSetupFactory = $eavSetupFactory; + $this->eavConfig = $config; + } - public function install(ModuleDataSetupInterface $setup, ModuleContextInterface $context) - { - $eavSetup = $this->_eavSetupFactory->create(['setup' => $setup]); - $eavSetup->addAttribute( - Customer::ENTITY, - 'stripe_customer_id', - [ - 'type' => 'varchar', - 'label' => 'Stripe Customer ID', - 'input' => 'text', - 'required' => false, - 'sort_order' => 100, - 'system' => false, - 'position' => 100 - ] - ); + public function install( + ModuleDataSetupInterface $setup, + ModuleContextInterface $context + ) { + $eavSetup = $this->eavSetupFactory->create(['setup' => $setup]); + $eavSetup->addAttribute( + Customer::ENTITY, + 'stripe_customer_id', + [ + 'type' => 'varchar', + 'label' => 'Stripe Customer ID', + 'input' => 'text', + 'required' => false, + 'sort_order' => 100, + 'system' => false, + 'position' => 100, + ] + ); - $stripeCustomerIdAttribute = $this->_eavConfig->getAttribute(Customer::ENTITY, 'stripe_customer_id'); - $stripeCustomerIdAttribute->setData('used_in_forms', ['adminhtml_customer']); - $stripeCustomerIdAttribute->save(); - } -} \ No newline at end of file + $stripeCustomerIdAttribute = $this->eavConfig->getAttribute( + Customer::ENTITY, + 'stripe_customer_id' + ); + $stripeCustomerIdAttribute->setData( + 'used_in_forms', + [ + 'adminhtml_customer', + ] + ); + $stripeCustomerIdAttribute->save(); + } +} diff --git a/Setup/UpgradeData.php b/Setup/UpgradeData.php index a9d8828..d72ca2b 100644 --- a/Setup/UpgradeData.php +++ b/Setup/UpgradeData.php @@ -11,47 +11,60 @@ class UpgradeData implements UpgradeDataInterface { - /** @var EavSetupFactory */ - private $_eavSetupFactory; + /** @var EavSetupFactory */ + private $eavSetupFactory; - /** @var Config */ - private $_eavConfig; + /** @var Config */ + private $eavConfig; - /** - * InstallData constructor. - * @param EavSetupFactory $eavSetupFactory - * @param Config $config - */ - public function __construct( - EavSetupFactory $eavSetupFactory, - Config $config - ) - { - $this->_eavSetupFactory = $eavSetupFactory; - $this->_eavConfig = $config; - } + /** + * InstallData constructor. + * @param EavSetupFactory $eavSetupFactory + * @param Config $config + */ + public function __construct( + EavSetupFactory $eavSetupFactory, + Config $config + ) { + $this->eavSetupFactory = $eavSetupFactory; + $this->eavConfig = $config; + } - public function upgrade(ModuleDataSetupInterface $setup, ModuleContextInterface $context) - { - if(version_compare($context->getVersion(), '0.0.2') < 0){ - $eavSetup = $this->_eavSetupFactory->create(['setup' => $setup]); - $eavSetup->addAttribute( - Customer::ENTITY, - 'stripe_customer_id', - [ - 'type' => 'varchar', - 'label' => 'Strip Customer ID', - 'input' => 'text', - 'required' => false, - 'sort_order' => 100, - 'system' => false, - 'position' => 100 - ] - ); + /** + * @param ModuleDataSetupInterface $setup + * @param ModuleContextInterface $context + */ + public function upgrade( + ModuleDataSetupInterface $setup, + ModuleContextInterface $context + ) { + if (version_compare($context->getVersion(), '0.0.2') < 0) { + $eavSetup = $this->eavSetupFactory->create(['setup' => $setup]); + $eavSetup->addAttribute( + Customer::ENTITY, + 'stripe_customer_id', + [ + 'type' => 'varchar', + 'label' => 'Strip Customer ID', + 'input' => 'text', + 'required' => false, + 'sort_order' => 100, + 'system' => false, + 'position' => 100, + ] + ); - $stripeCustomerIdAttribute = $this->_eavConfig->getAttribute(Customer::ENTITY, 'stripe_customer_id'); - $stripeCustomerIdAttribute->setData('used_in_forms', ['adminhtml_customer']); - $stripeCustomerIdAttribute->save(); + $stripeCustomerIdAttribute = $this->eavConfig->getAttribute( + Customer::ENTITY, + 'stripe_customer_id' + ); + $stripeCustomerIdAttribute->setData( + 'used_in_forms', + [ + 'adminhtml_customer', + ] + ); + $stripeCustomerIdAttribute->save(); + } } - } -} \ No newline at end of file +} diff --git a/Test/Acceptance/ActionGroup/CompleteGuestAddressFormActionGroup.xml b/Test/Acceptance/ActionGroup/CompleteGuestAddressFormActionGroup.xml new file mode 100644 index 0000000..011a057 --- /dev/null +++ b/Test/Acceptance/ActionGroup/CompleteGuestAddressFormActionGroup.xml @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + + + + diff --git a/Test/Acceptance/ActionGroup/CompleteStripePaymentFormActionGroup.xml b/Test/Acceptance/ActionGroup/CompleteStripePaymentFormActionGroup.xml new file mode 100644 index 0000000..ad69b6d --- /dev/null +++ b/Test/Acceptance/ActionGroup/CompleteStripePaymentFormActionGroup.xml @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + + + + diff --git a/Test/Acceptance/ActionGroup/GetToCheckoutActionGroup.xml b/Test/Acceptance/ActionGroup/GetToCheckoutActionGroup.xml new file mode 100644 index 0000000..804204c --- /dev/null +++ b/Test/Acceptance/ActionGroup/GetToCheckoutActionGroup.xml @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/Test/Acceptance/ActionGroup/ValidateOrderActionGroup.xml b/Test/Acceptance/ActionGroup/ValidateOrderActionGroup.xml new file mode 100644 index 0000000..6cd5470 --- /dev/null +++ b/Test/Acceptance/ActionGroup/ValidateOrderActionGroup.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/Test/Acceptance/Data/CardData.xml b/Test/Acceptance/Data/CardData.xml new file mode 100644 index 0000000..be5b8f8 --- /dev/null +++ b/Test/Acceptance/Data/CardData.xml @@ -0,0 +1,30 @@ + + + + + 4111111111111111 + 03/25 + 123 + + + 4000000000003055 + 03/25 + 123 + + diff --git a/Test/Acceptance/Data/StripeConfigData.xml b/Test/Acceptance/Data/StripeConfigData.xml new file mode 100644 index 0000000..65015c2 --- /dev/null +++ b/Test/Acceptance/Data/StripeConfigData.xml @@ -0,0 +1,66 @@ + + + + + SampleActive + SampleTestMode + SampleSecretKey + SamplePublishableKey + SampleVerify3dSecure + + + 1 + + + 1 + + + sk_test_aODtklwVgFxCRNfctGuc2zr9 + + + pk_test_QWPtpvIqEoG51jNCWqO9HZOC + + + 1 + + + + + DefaultActive + DefaultTestMode + SampleSecretKey + SamplePublishableKey + DefaultVerify3dSecure + + + 0 + + + 0 + + + + + + + + + 0 + + diff --git a/Test/Acceptance/Metadata/stripe_config-meta.xml b/Test/Acceptance/Metadata/stripe_config-meta.xml new file mode 100644 index 0000000..300f563 --- /dev/null +++ b/Test/Acceptance/Metadata/stripe_config-meta.xml @@ -0,0 +1,43 @@ + + + + + + + + + integer + + + integer + + + string + + + string + + + integer + + + + + + diff --git a/Test/Acceptance/Section/CheckoutPaymentSection.xml b/Test/Acceptance/Section/CheckoutPaymentSection.xml new file mode 100644 index 0000000..63d6291 --- /dev/null +++ b/Test/Acceptance/Section/CheckoutPaymentSection.xml @@ -0,0 +1,28 @@ + + + +
+ + + + + + +
+
diff --git a/Test/Acceptance/Section/StripeIframeSection.xml b/Test/Acceptance/Section/StripeIframeSection.xml new file mode 100644 index 0000000..ae64f07 --- /dev/null +++ b/Test/Acceptance/Section/StripeIframeSection.xml @@ -0,0 +1,25 @@ + + + +
+ + + +
+
diff --git a/Test/Acceptance/Section/ThreeDConfirmationSection.xml b/Test/Acceptance/Section/ThreeDConfirmationSection.xml new file mode 100644 index 0000000..08028b0 --- /dev/null +++ b/Test/Acceptance/Section/ThreeDConfirmationSection.xml @@ -0,0 +1,23 @@ + + + +
+ +
+
diff --git a/Test/Acceptance/Test/StorefrontStripeCustomerCheckoutTest.xml b/Test/Acceptance/Test/StorefrontStripeCustomerCheckoutTest.xml new file mode 100644 index 0000000..f7420e3 --- /dev/null +++ b/Test/Acceptance/Test/StorefrontStripeCustomerCheckoutTest.xml @@ -0,0 +1,75 @@ + + + + + + + + + <description value="Checkout as customer using Stripe"/> + <severity value="CRITICAL"/> + <group value="pmclain_stripe"/> + </annotations> + <before> + <createData entity="SampleStripeConfig" stepKey="createSampleStripeConfig" /> + <createData entity="_defaultCategory" stepKey="createCategory"/> + <createData entity="_defaultProduct" stepKey="createProduct"> + <requiredEntity createDataKey="createCategory"/> + </createData> + <createData entity="Simple_US_Customer" stepKey="simpleuscustomer"/> + </before> + <after> + <amOnPage url="admin/admin/auth/logout/" stepKey="amOnLogoutPage"/> + <deleteData createDataKey="createCategory" stepKey="deleteCategory"/> + <deleteData createDataKey="createProduct" stepKey="deleteProduct"/> + <createData entity="DefaultStripeConfig" stepKey="restoreDefaultStripeConfig" /> + <deleteData createDataKey="simpleuscustomer" stepKey="deleteCustomer" /> + </after> + + <actionGroup ref="CustomerLoginOnStorefront" stepKey="customerLogin"> + <argument name="customer" value="$$simpleuscustomer$$" /> + </actionGroup> + + <actionGroup ref="GetToCheckout" stepKey="proceedToCheckout"> + <argument name="category" value="$$createCategory$$" /> + </actionGroup> + + <waitForElement selector="{{CheckoutShippingMethodsSection.next}}" time="30" stepKey="waitForNextButton"/> + <click selector="{{CheckoutShippingMethodsSection.next}}" stepKey="clickNext"/> + + <actionGroup ref="CompleteStripePaymentForm" stepKey="enterPaymentDetails"> + <argument name="card" value="stripeCardValid" /> + </actionGroup> + + <click selector="{{CheckoutPaymentSection.saveInVault}}" stepKey="uncheckSaveInVault" /> + <click selector="{{CheckoutPaymentSection.stripePlaceOrder}}" stepKey="clickPlaceOrderButton" /> + <waitForPageLoad stepKey="waitForSuccessPage" time="60" /> + + <grabTextFrom stepKey="grabOrderNumber" selector="{{CheckoutSuccessMainSection.orderNumber22}}"/> + <see stepKey="seeOrderConfirmation" selector="{{CheckoutSuccessMainSection.success}}" userInput="Your order number is:" /> + + <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin1"/> + + <actionGroup ref="ValidateOrder" stepKey="adminCheckOrder"> + <argument name="ordernumber" value="$grabOrderNumber" /> + <argument name="email" value="$$simpleuscustomer.email$$" /> + <argument name="product" value="_defaultProduct" /> + </actionGroup> + </test> +</tests> diff --git a/Test/Acceptance/Test/StorefrontStripeCustomerSaveVault3dSecureCheckoutTest.xml b/Test/Acceptance/Test/StorefrontStripeCustomerSaveVault3dSecureCheckoutTest.xml new file mode 100644 index 0000000..233a57c --- /dev/null +++ b/Test/Acceptance/Test/StorefrontStripeCustomerSaveVault3dSecureCheckoutTest.xml @@ -0,0 +1,109 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/** + * Pmclain_Stripe extension + * NOTICE OF LICENSE + * + * This source file is subject to the OSL 3.0 License + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * https://opensource.org/licenses/osl-3.0.php + * + * @category Pmclain + * @package Pmclain_Stripe + * @copyright Copyright (c) 2017-2018 + * @license Open Software License (OSL 3.0) + */ +--> +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="../../../../../../../dev/tests/acceptance/vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> + <test name="StorefrontStripeCustomerSaveVault3dSecureCheckout"> + <annotations> + <features value="Checkout"/> + <stories value="Checkout via Customer Checkout Save Method in Vault"/> + <title value="Customer Checkout"/> + <description value="Checkout as customer using Stripe 3D Secure and store method in Vault"/> + <severity value="CRITICAL"/> + <group value="pmclain_stripe"/> + </annotations> + <before> + <createData entity="SampleStripeConfig" stepKey="createSampleStripeConfig" /> + <createData entity="_defaultCategory" stepKey="createCategory"/> + <createData entity="_defaultProduct" stepKey="createProduct"> + <requiredEntity createDataKey="createCategory"/> + </createData> + <createData entity="Simple_US_Customer" stepKey="simpleuscustomer"/> + </before> + <after> + <amOnPage url="admin/admin/auth/logout/" stepKey="amOnLogoutPage"/> + <deleteData createDataKey="createCategory" stepKey="deleteCategory"/> + <deleteData createDataKey="createProduct" stepKey="deleteProduct"/> + <createData entity="DefaultStripeConfig" stepKey="restoreDefaultStripeConfig" /> + <deleteData createDataKey="simpleuscustomer" stepKey="deleteCustomer" /> + </after> + + <actionGroup ref="CustomerLoginOnStorefront" stepKey="customerLogin"> + <argument name="customer" value="$$simpleuscustomer$$" /> + </actionGroup> + + <actionGroup ref="GetToCheckout" stepKey="proceedToCheckout"> + <argument name="category" value="$$createCategory$$" /> + </actionGroup> + + <waitForElement selector="{{CheckoutShippingMethodsSection.next}}" time="30" stepKey="waitForNextButton"/> + <click selector="{{CheckoutShippingMethodsSection.next}}" stepKey="clickNext"/> + + <actionGroup ref="CompleteStripePaymentForm" stepKey="enterPaymentDetails"> + <argument name="card" value="stripe3dCard" /> + </actionGroup> + + <click selector="{{CheckoutPaymentSection.stripePlaceOrder}}" stepKey="clickPlaceOrderButton" /> + <waitForElement selector="{{CheckoutPaymentSection.stripeRedirectNotice}}" stepKey="waitFrom3DSecureNotification" time="30" /> + <click selector="{{CheckoutPaymentSection.stripeRedirectNotice}}" stepKey="click3DSecureRedirctAccept" /> + + <click selector="{{StripeThreeDConfirmation.authorize}}" stepKey="clickAuthorizeButton" /> + + <waitForPageLoad stepKey="waitForSuccessPage" time="60" /> + + <grabTextFrom stepKey="grabOrderNumberOne" selector="{{CheckoutSuccessMainSection.orderNumber22}}"/> + <see stepKey="seeOrderConfirmation" selector="{{CheckoutSuccessMainSection.success}}" userInput="Your order number is:" /> + + <!-- NOW WE CHECKOUT WITH STORED PAYMENT METHOD --> + <actionGroup ref="GetToCheckout" stepKey="returnToCheckout"> + <argument name="category" value="$$createCategory$$" /> + </actionGroup> + + <waitForElement selector="{{CheckoutShippingMethodsSection.next}}" time="30" stepKey="waitForNextButton2"/> + <waitForLoadingMaskToDisappear stepKey="waitForPaymentLoad2" /> + <click selector="{{CheckoutShippingMethodsSection.next}}" stepKey="clickNext2"/> + + <waitForElement selector="{{CheckoutPaymentSection.stripeSaved}}" time="30" stepKey="waitForSavedCards" /> + <click selector="{{CheckoutPaymentSection.stripeSaved}}" stepKey="selectSavedCard" /> + + <click selector="{{CheckoutPaymentSection.stripePlaceOrder}}" stepKey="clickPlaceOrderButton2" /> + <waitForElement selector="{{CheckoutPaymentSection.stripeRedirectNotice}}" stepKey="waitFrom3DSecureNotification2" time="30" /> + <click selector="{{CheckoutPaymentSection.stripeRedirectNotice}}" stepKey="click3DSecureRedirctAccept2" /> + + <click selector="{{StripeThreeDConfirmation.authorize}}" stepKey="clickAuthorizeButton2" /> + + <waitForPageLoad stepKey="waitForSuccessPage2" time="60" /> + + <grabTextFrom stepKey="grabOrderNumberTwo" selector="{{CheckoutSuccessMainSection.orderNumber22}}"/> + <see stepKey="seeOrderConfirmation2" selector="{{CheckoutSuccessMainSection.success}}" userInput="Your order number is:" /> + + <!-- Validate both orders in Admin --> + <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin1"/> + + <actionGroup ref="ValidateOrder" stepKey="adminCheckOrderOne"> + <argument name="ordernumber" value="$grabOrderNumberOne" /> + <argument name="email" value="$$simpleuscustomer.email$$" /> + <argument name="product" value="_defaultProduct" /> + </actionGroup> + + <actionGroup ref="ValidateOrder" stepKey="adminCheckOrderTwo"> + <argument name="ordernumber" value="$grabOrderNumberTwo" /> + <argument name="email" value="$$simpleuscustomer.email$$" /> + <argument name="product" value="_defaultProduct" /> + </actionGroup> + </test> +</tests> diff --git a/Test/Acceptance/Test/StorefrontStripeCustomerSaveVaultCheckoutTest.xml b/Test/Acceptance/Test/StorefrontStripeCustomerSaveVaultCheckoutTest.xml new file mode 100644 index 0000000..7549a36 --- /dev/null +++ b/Test/Acceptance/Test/StorefrontStripeCustomerSaveVaultCheckoutTest.xml @@ -0,0 +1,99 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/** + * Pmclain_Stripe extension + * NOTICE OF LICENSE + * + * This source file is subject to the OSL 3.0 License + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * https://opensource.org/licenses/osl-3.0.php + * + * @category Pmclain + * @package Pmclain_Stripe + * @copyright Copyright (c) 2017-2018 + * @license Open Software License (OSL 3.0) + */ +--> +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="../../../../../../../dev/tests/acceptance/vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> + <test name="StorefrontStripeCustomerSaveVaultCheckout"> + <annotations> + <features value="Checkout"/> + <stories value="Checkout via Customer Checkout Save Method in Vault"/> + <title value="Customer Checkout"/> + <description value="Checkout as customer using Stripe and store method in Vault"/> + <severity value="CRITICAL"/> + <group value="pmclain_stripe"/> + </annotations> + <before> + <createData entity="SampleStripeConfig" stepKey="createSampleStripeConfig" /> + <createData entity="_defaultCategory" stepKey="createCategory"/> + <createData entity="_defaultProduct" stepKey="createProduct"> + <requiredEntity createDataKey="createCategory"/> + </createData> + <createData entity="Simple_US_Customer" stepKey="simpleuscustomer"/> + </before> + <after> + <amOnPage url="admin/admin/auth/logout/" stepKey="amOnLogoutPage"/> + <deleteData createDataKey="createCategory" stepKey="deleteCategory"/> + <deleteData createDataKey="createProduct" stepKey="deleteProduct"/> + <createData entity="DefaultStripeConfig" stepKey="restoreDefaultStripeConfig" /> + <deleteData createDataKey="simpleuscustomer" stepKey="deleteCustomer" /> + </after> + + <actionGroup ref="CustomerLoginOnStorefront" stepKey="customerLogin"> + <argument name="customer" value="$$simpleuscustomer$$" /> + </actionGroup> + + <actionGroup ref="GetToCheckout" stepKey="proceedToCheckout"> + <argument name="category" value="$$createCategory$$" /> + </actionGroup> + + <waitForElement selector="{{CheckoutShippingMethodsSection.next}}" time="30" stepKey="waitForNextButton"/> + <click selector="{{CheckoutShippingMethodsSection.next}}" stepKey="clickNext"/> + + <actionGroup ref="CompleteStripePaymentForm" stepKey="enterPaymentDetails"> + <argument name="card" value="stripeCardValid" /> + </actionGroup> + + <click selector="{{CheckoutPaymentSection.stripePlaceOrder}}" stepKey="clickPlaceOrderButton" /> + <waitForPageLoad stepKey="waitForSuccessPage" time="60" /> + + <grabTextFrom stepKey="grabOrderNumberOne" selector="{{CheckoutSuccessMainSection.orderNumber22}}"/> + <see stepKey="seeOrderConfirmation" selector="{{CheckoutSuccessMainSection.success}}" userInput="Your order number is:" /> + + <!-- NOW WE CHECKOUT WITH STORED PAYMENT METHOD --> + <actionGroup ref="GetToCheckout" stepKey="returnToCheckout"> + <argument name="category" value="$$createCategory$$" /> + </actionGroup> + + <waitForElement selector="{{CheckoutShippingMethodsSection.next}}" time="30" stepKey="waitForNextButton2"/> + <waitForLoadingMaskToDisappear stepKey="waitForPaymentLoad2" /> + <click selector="{{CheckoutShippingMethodsSection.next}}" stepKey="clickNext2"/> + + <waitForElement selector="{{CheckoutPaymentSection.stripeSaved}}" time="30" stepKey="waitForSavedCards" /> + <click selector="{{CheckoutPaymentSection.stripeSaved}}" stepKey="selectSavedCard" /> + + <click selector="{{CheckoutPaymentSection.stripePlaceOrder}}" stepKey="clickPlaceOrderButton2" /> + <waitForPageLoad stepKey="waitForSuccessPage2" time="60" /> + + <grabTextFrom stepKey="grabOrderNumberTwo" selector="{{CheckoutSuccessMainSection.orderNumber22}}"/> + <see stepKey="seeOrderConfirmation2" selector="{{CheckoutSuccessMainSection.success}}" userInput="Your order number is:" /> + + <!-- Validate both orders in Admin --> + <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin1"/> + + <actionGroup ref="ValidateOrder" stepKey="adminCheckOrderOne"> + <argument name="ordernumber" value="$grabOrderNumberOne" /> + <argument name="email" value="$$simpleuscustomer.email$$" /> + <argument name="product" value="_defaultProduct" /> + </actionGroup> + + <actionGroup ref="ValidateOrder" stepKey="adminCheckOrderTwo"> + <argument name="ordernumber" value="$grabOrderNumberTwo" /> + <argument name="email" value="$$simpleuscustomer.email$$" /> + <argument name="product" value="_defaultProduct" /> + </actionGroup> + </test> +</tests> diff --git a/Test/Acceptance/Test/StorefrontStripeGuestCheckout3dSecureTest.xml b/Test/Acceptance/Test/StorefrontStripeGuestCheckout3dSecureTest.xml new file mode 100644 index 0000000..bda79ea --- /dev/null +++ b/Test/Acceptance/Test/StorefrontStripeGuestCheckout3dSecureTest.xml @@ -0,0 +1,81 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/** + * Pmclain_Stripe extension + * NOTICE OF LICENSE + * + * This source file is subject to the OSL 3.0 License + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * https://opensource.org/licenses/osl-3.0.php + * + * @category Pmclain + * @package Pmclain_Stripe + * @copyright Copyright (c) 2017-2018 + * @license Open Software License (OSL 3.0) + */ +--> +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="../../../../../../../dev/tests/acceptance/vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> + <test name="StorefrontStripeGuestCheckout3dSecure"> + <annotations> + <features value="Checkout"/> + <stories value="Checkout via Guest Checkout"/> + <title value="Guest Checkout"/> + <description value="Should be able to place an order as a Guest using Stripe with 3D Secure."/> + <severity value="CRITICAL"/> + <group value="pmclain_stripe"/> + </annotations> + <before> + <createData entity="SampleStripeConfig" stepKey="createSampleStripeConfig" /> + <createData entity="_defaultCategory" stepKey="createCategory"/> + <createData entity="_defaultProduct" stepKey="createProduct"> + <requiredEntity createDataKey="createCategory"/> + </createData> + </before> + <after> + <amOnPage url="admin/admin/auth/logout/" stepKey="amOnLogoutPage"/> + <deleteData createDataKey="createCategory" stepKey="deleteCategory"/> + <deleteData createDataKey="createProduct" stepKey="deleteProduct"/> + <createData entity="DefaultStripeConfig" stepKey="restoreDefaultStripeConfig" /> + </after> + + <actionGroup ref="GetToCheckout" stepKey="proceedToCheckout"> + <argument name="category" value="$$createCategory$$" /> + </actionGroup> + + <actionGroup ref="CompleteGuestAddressForm" stepKey="completeGuestAddressForm"> + <argument name="customer" value="CustomerEntityOne" /> + <argument name="address" value="CustomerAddressSimple" /> + </actionGroup> + + <waitForLoadingMaskToDisappear stepKey="waitForLoadingMask"/> + <click selector="{{GuestCheckoutShippingSection.firstShippingMethod}}" stepKey="selectFirstShippingMethod"/> + <waitForElement selector="{{GuestCheckoutShippingSection.next}}" time="30" stepKey="waitForNextButton"/> + <click selector="{{GuestCheckoutShippingSection.next}}" stepKey="clickNext"/> + + <actionGroup ref="CompleteStripePaymentForm" stepKey="enterPaymentDetails"> + <argument name="card" value="stripe3dCard" /> + </actionGroup> + + <click selector="{{CheckoutPaymentSection.stripePlaceOrder}}" stepKey="clickPlaceOrderButton" /> + <waitForElement selector="{{CheckoutPaymentSection.stripeRedirectNotice}}" stepKey="waitFrom3DSecureNotification" time="30" /> + <click selector="{{CheckoutPaymentSection.stripeRedirectNotice}}" stepKey="click3DSecureRedirctAccept" /> + + <click selector="{{StripeThreeDConfirmation.authorize}}" stepKey="clickAuthorizeButton" /> + + <waitForPageLoad stepKey="waitForSuccessPage" /> + + <grabTextFrom selector="{{CheckoutSuccessMainSection.orderNumber}}" stepKey="grabOrderNumber"/> + <see selector="{{CheckoutSuccessMainSection.success}}" userInput="Your order # is:" stepKey="seeOrderNumber"/> + <see selector="{{CheckoutSuccessMainSection.success}}" userInput="We'll email you an order confirmation with details and tracking info." stepKey="seeEmailYou"/> + + <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin1"/> + + <actionGroup ref="ValidateOrder" stepKey="adminCheckOrder"> + <argument name="ordernumber" value="$grabOrderNumber" /> + <argument name="email" value="{{CustomerEntityOne.email}}" /> + <argument name="product" value="_defaultProduct" /> + </actionGroup> + </test> +</tests> diff --git a/Test/Acceptance/Test/StorefrontStripeGuestCheckoutTest.xml b/Test/Acceptance/Test/StorefrontStripeGuestCheckoutTest.xml new file mode 100644 index 0000000..9adba33 --- /dev/null +++ b/Test/Acceptance/Test/StorefrontStripeGuestCheckoutTest.xml @@ -0,0 +1,76 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/** + * Pmclain_Stripe extension + * NOTICE OF LICENSE + * + * This source file is subject to the OSL 3.0 License + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * https://opensource.org/licenses/osl-3.0.php + * + * @category Pmclain + * @package Pmclain_Stripe + * @copyright Copyright (c) 2017-2018 + * @license Open Software License (OSL 3.0) + */ +--> +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="../../../../../../../dev/tests/acceptance/vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd"> + <test name="StorefrontStripeGuestCheckout"> + <annotations> + <features value="Checkout"/> + <stories value="Checkout via Guest Checkout"/> + <title value="Guest Checkout"/> + <description value="Should be able to place an order as a Guest with Stripe."/> + <severity value="CRITICAL"/> + <group value="pmclain_stripe"/> + </annotations> + <before> + <createData entity="SampleStripeConfig" stepKey="createSampleStripeConfig" /> + <createData entity="_defaultCategory" stepKey="createCategory"/> + <createData entity="_defaultProduct" stepKey="createProduct"> + <requiredEntity createDataKey="createCategory"/> + </createData> + </before> + <after> + <amOnPage url="admin/admin/auth/logout/" stepKey="amOnLogoutPage"/> + <deleteData createDataKey="createCategory" stepKey="deleteCategory"/> + <deleteData createDataKey="createProduct" stepKey="deleteProduct"/> + <createData entity="DefaultStripeConfig" stepKey="restoreDefaultStripeConfig" /> + </after> + + <actionGroup ref="GetToCheckout" stepKey="proceedToCheckout"> + <argument name="category" value="$$createCategory$$" /> + </actionGroup> + + <actionGroup ref="CompleteGuestAddressForm" stepKey="completeGuestAddressForm"> + <argument name="customer" value="CustomerEntityOne" /> + <argument name="address" value="CustomerAddressSimple" /> + </actionGroup> + + <waitForLoadingMaskToDisappear stepKey="waitForLoadingMask"/> + <click selector="{{GuestCheckoutShippingSection.firstShippingMethod}}" stepKey="selectFirstShippingMethod"/> + <waitForElement selector="{{GuestCheckoutShippingSection.next}}" time="30" stepKey="waitForNextButton"/> + <click selector="{{GuestCheckoutShippingSection.next}}" stepKey="clickNext"/> + + <actionGroup ref="CompleteStripePaymentForm" stepKey="enterPaymentDetails"> + <argument name="card" value="stripeCardValid" /> + </actionGroup> + + <click selector="{{CheckoutPaymentSection.stripePlaceOrder}}" stepKey="clickPlaceOrderButton" /> + <waitForPageLoad stepKey="waitForSuccessPage" time="60" /> + + <grabTextFrom selector="{{CheckoutSuccessMainSection.orderNumber}}" stepKey="grabOrderNumber"/> + <see selector="{{CheckoutSuccessMainSection.success}}" userInput="Your order # is:" stepKey="seeOrderNumber"/> + <see selector="{{CheckoutSuccessMainSection.success}}" userInput="We'll email you an order confirmation with details and tracking info." stepKey="seeEmailYou"/> + + <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin1"/> + + <actionGroup ref="ValidateOrder" stepKey="adminCheckOrder"> + <argument name="ordernumber" value="$grabOrderNumber" /> + <argument name="email" value="{{CustomerEntityOne.email}}" /> + <argument name="product" value="_defaultProduct" /> + </actionGroup> + </test> +</tests> diff --git a/Test/Integration/Model/StripeAdapterTest.php b/Test/Integration/Model/StripeAdapterTest.php new file mode 100644 index 0000000..3770877 --- /dev/null +++ b/Test/Integration/Model/StripeAdapterTest.php @@ -0,0 +1,112 @@ +<?php +/** + * Pmclain_Stripe extension + * NOTICE OF LICENSE + * + * This source file is subject to the OSL 3.0 License + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * https://opensource.org/licenses/osl-3.0.php + * + * @category Pmclain + * @package Pmclain_Stripe + * @copyright Copyright (c) 2017-2018 + * @license Open Software License (OSL 3.0) + */ +namespace Pmclain\Stripe\Unit\Integration\Model; + +use PHPUnit\Framework\TestCase; +use PHPUnit_Framework_MockObject_MockObject as MockObject; +use Magento\TestFramework\Helper\Bootstrap; +use Magento\Framework\ObjectManagerInterface; +use Pmclain\Stripe\Gateway\Request\PaymentDataBuilder; +use Stripe\Stripe; +use Pmclain\Stripe\Model\Adapter\StripeAdapter; +use Pmclain\Stripe\Gateway\Config\Config; +use Pmclain\Stripe\Helper\Payment\Formatter; + +class StripeAdapterTest extends TestCase +{ + use Formatter; + + const STRIPE_MOCK_URL = 'http://localhost:12111'; + const STRIPE_MOCK_API_KEY = 'sk_test_123'; + + /** + * @var ObjectManagerInterface + */ + private $objectManager; + + /** + * @var StripeAdapter + */ + private $adapter; + + /** + * @var Config|MockObject + */ + private $configMock; + + protected function setUp() + { + $this->objectManager = Bootstrap::getObjectManager(); + Stripe::$apiBase = self::STRIPE_MOCK_URL; + + $this->configMock = $this->createMock(Config::class); + $this->configMock->method('getSecretKey') + ->willReturn(self::STRIPE_MOCK_API_KEY); + + $this->adapter = $this->objectManager->create( + StripeAdapter::class, + [ + 'config' => $this->configMock, + ] + ); + } + + public function testRefund() + { + $result = $this->adapter->refund('ch_1Bh7'); + + $this->assertInstanceOf(\Stripe\Refund::class, $result); + } + + public function testSale() + { + $attributes = [ + PaymentDataBuilder::CAPTURE => false, + PaymentDataBuilder::AMOUNT => $this->formatPrice(10.00), + PaymentDataBuilder::CURRENCY => 'USD', + PaymentDataBuilder::ORDER_ID => '100000001', + PaymentDataBuilder::SOURCE => 'tok_visa', + ]; + + $result = $this->adapter->sale($attributes); + + $this->assertInstanceOf(\Stripe\Charge::class, $result); + } + + public function testSaleSaveInVault() + { + $attributes = [ + PaymentDataBuilder::SAVE_IN_VAULT => true, + PaymentDataBuilder::CAPTURE => false, + PaymentDataBuilder::CUSTOMER => 'cus_C5IP3', + PaymentDataBuilder::AMOUNT => $this->formatPrice(10.00), + PaymentDataBuilder::CURRENCY => 'USD', + PaymentDataBuilder::ORDER_ID => '100000001', + PaymentDataBuilder::SOURCE => 'tok_visa', + ]; + + $result = $this->adapter->sale($attributes); + + $this->assertInstanceOf(\Stripe\Charge::class, $result); + } + + public function testSubmitForSettlement() + { + $result = $this->adapter->submitForSettlement('ch_1Bh7'); + + $this->assertInstanceOf(\Stripe\Charge::class, $result); + } +} diff --git a/Test/Integration/phpunit.xml.dist b/Test/Integration/phpunit.xml.dist new file mode 100644 index 0000000..3d53322 --- /dev/null +++ b/Test/Integration/phpunit.xml.dist @@ -0,0 +1,73 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/6.2/phpunit.xsd" + colors="true" + beStrictAboutTestsThatDoNotTestAnything="false" + bootstrap="./framework/bootstrap.php" + stderr="true" +> + <!-- Test suites definition --> + <testsuites> + <testsuite name="Pmclain Stripe Integration Tests"> + <directory suffix="Test.php">../../../vendor/pmclain/module-stripe/Test/Integration</directory> + </testsuite> + </testsuites> + <!-- Code coverage filters --> + <filter> + <whitelist addUncoveredFilesFromWhiteList="true"> + <directory suffix=".php">../../../vendor/pmclain/module-stripe</directory> + <exclude> + <directory>../../../vendor/pmclain/module-stripe/Test</directory> + </exclude> + </whitelist> + </filter> + <!-- PHP INI settings and constants definition --> + <php> + <includePath>.</includePath> + <includePath>testsuite</includePath> + <ini name="date.timezone" value="America/Los_Angeles"/> + <ini name="xdebug.max_nesting_level" value="200"/> + <!-- Local XML configuration file ('.dist' extension will be added, if the specified file doesn't exist) --> + <const name="TESTS_INSTALL_CONFIG_FILE" value="etc/install-config-mysql.php"/> + <!-- Local XML configuration file ('.dist' extension will be added, if the specified file doesn't exist) --> + <const name="TESTS_GLOBAL_CONFIG_FILE" value="etc/config-global.php"/> + <!-- Semicolon-separated 'glob' patterns, that match global XML configuration files --> + <const name="TESTS_GLOBAL_CONFIG_DIR" value="../../../app/etc"/> + <!-- Whether to cleanup the application before running tests or not --> + <!--<const name="TESTS_CLEANUP" value="enabled"/>--> + <const name="TESTS_CLEANUP" value="disabled" /> + <!-- Memory usage and estimated leaks thresholds --> + <!--<const name="TESTS_MEM_USAGE_LIMIT" value="1024M"/>--> + <const name="TESTS_MEM_LEAK_LIMIT" value=""/> + <!-- Whether to output all CLI commands executed by the bootstrap and tests --> + <!--<const name="TESTS_EXTRA_VERBOSE_LOG" value="1"/>--> + <!-- Path to Percona Toolkit bin directory --> + <!--<const name="PERCONA_TOOLKIT_BIN_DIR" value=""/>--> + <!-- CSV Profiler Output file --> + <!--<const name="TESTS_PROFILER_FILE" value="profiler.csv"/>--> + <!-- Bamboo compatible CSV Profiler Output file name --> + <!--<const name="TESTS_BAMBOO_PROFILER_FILE" value="profiler.csv"/>--> + <!-- Metrics for Bamboo Profiler Output in PHP file that returns array --> + <!--<const name="TESTS_BAMBOO_PROFILER_METRICS_FILE" value="../../build/profiler_metrics.php"/>--> + <!-- Whether to output all CLI commands executed by the bootstrap and tests --> + <const name="TESTS_EXTRA_VERBOSE_LOG" value="1"/> + <!-- Magento mode for tests execution. Possible values are "default", "developer" and "production". --> + <const name="TESTS_MAGENTO_MODE" value="developer"/> + <!-- Minimum error log level to listen for. Possible values: -1 ignore all errors, and level constants form http://tools.ietf.org/html/rfc5424 standard --> + <const name="TESTS_ERROR_LOG_LISTENER_LEVEL" value="-1"/> + <!-- Connection parameters for MongoDB library tests --> + <!--<const name="MONGODB_CONNECTION_STRING" value="mongodb://localhost:27017"/>--> + <!--<const name="MONGODB_DATABASE_NAME" value="magento_integration_tests"/>--> + </php> + <!-- Test listeners --> + <listeners> + <listener class="Magento\TestFramework\Event\PhpUnit"/> + <listener class="Magento\TestFramework\ErrorLog\Listener"/> + </listeners> +</phpunit> diff --git a/Test/Unit/Block/Customer/CardRendererTest.php b/Test/Unit/Block/Customer/CardRendererTest.php index a3b7667..f3ca192 100644 --- a/Test/Unit/Block/Customer/CardRendererTest.php +++ b/Test/Unit/Block/Customer/CardRendererTest.php @@ -13,6 +13,7 @@ * @copyright Copyright (c) 2017-2018 * @license Open Software License (OSL 3.0) */ + namespace Pmclain\Stripe\Test\Unit\Block\Customer; use Pmclain\Stripe\Block\Customer\CardRenderer; @@ -23,108 +24,115 @@ class CardRendererTest extends \PHPUnit\Framework\TestCase { - /** @var PaymentTokenInterface|MockObject */ - private $paymentTokenMock; - - /** @var CcConfigProvider|MockObject */ - private $ccConfigProviderMock; - - /** @var array */ - private $token = [ - 'type' => 'VI', - 'maskedCC' => '4242', - 'expirationDate' => '2/2018' - ]; - - /** @var array */ - private $icons = [ - 'VI' => [ - 'url' => 'http://url', - 'width' => '60', - 'height' => '80' - ] - ]; - - /** @var CardRenderer */ - private $cardRenderer; - - protected function setUp() { - $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); - - $this->paymentTokenMock = $this->getMockBuilder(PaymentTokenInterface::class) - ->getMockForAbstractClass(); - - $this->ccConfigProviderMock = $this->getMockBuilder(CcConfigProvider::class) - ->disableOriginalConstructor() - ->getMock(); - - $this->cardRenderer = $objectManager->getObject( - CardRenderer::class, - [ - 'tokenDetails' => $this->token, - 'iconsProvider' => $this->ccConfigProviderMock - ] - ); - } - - public function testCanRender() { - $this->paymentTokenMock->expects($this->once()) - ->method('getPaymentMethodCode') - ->willReturn(ConfigProvider::CODE); - - $this->assertEquals( - $this->cardRenderer->canRender($this->paymentTokenMock), - true - ); - } - - public function testGetNumberLast4Digits() { - $this->assertEquals( - $this->token['maskedCC'], - $this->cardRenderer->getNumberLast4Digits() - ); - } - - public function testGetExpDate() { - $this->assertEquals( - $this->token['expirationDate'], - $this->cardRenderer->getExpDate() - ); - } - - public function testGetIconUrl() { - $this->ccConfigProviderMock->expects($this->any()) - ->method('getIcons') - ->with() - ->willReturn($this->icons); - - $this->assertEquals( - $this->icons['VI']['url'], - $this->cardRenderer->getIconUrl() - ); - } - - public function testGetIconHeight() { - $this->ccConfigProviderMock->expects($this->any()) - ->method('getIcons') - ->with() - ->willReturn($this->icons); - - $this->assertEquals( - $this->icons['VI']['height'], - $this->cardRenderer->getIconHeight() - ); - } - - public function testGetIconWidth() { - $this->ccConfigProviderMock->expects($this->any()) - ->method('getIcons') - ->with() - ->willReturn($this->icons); - - $this->assertEquals( - $this->icons['VI']['width'], - $this->cardRenderer->getIconWidth() - ); - } -} \ No newline at end of file + /** @var PaymentTokenInterface|MockObject */ + private $paymentTokenMock; + + /** @var CcConfigProvider|MockObject */ + private $ccConfigProviderMock; + + /** @var array */ + private $token = [ + 'type' => 'VI', + 'maskedCC' => '4242', + 'expirationDate' => '2/2018' + ]; + + /** @var array */ + private $icons = [ + 'VI' => [ + 'url' => 'http://url', + 'width' => '60', + 'height' => '80' + ] + ]; + + /** @var CardRenderer */ + private $cardRenderer; + + protected function setUp() + { + $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); + + $this->paymentTokenMock = $this->getMockBuilder(PaymentTokenInterface::class) + ->getMockForAbstractClass(); + + $this->ccConfigProviderMock = $this->getMockBuilder(CcConfigProvider::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->cardRenderer = $objectManager->getObject( + CardRenderer::class, + [ + 'tokenDetails' => $this->token, + 'iconsProvider' => $this->ccConfigProviderMock + ] + ); + } + + public function testCanRender() + { + $this->paymentTokenMock->expects($this->once()) + ->method('getPaymentMethodCode') + ->willReturn(ConfigProvider::CODE); + + $this->assertEquals( + $this->cardRenderer->canRender($this->paymentTokenMock), + true + ); + } + + public function testGetNumberLast4Digits() + { + $this->assertEquals( + $this->token['maskedCC'], + $this->cardRenderer->getNumberLast4Digits() + ); + } + + public function testGetExpDate() + { + $this->assertEquals( + $this->token['expirationDate'], + $this->cardRenderer->getExpDate() + ); + } + + public function testGetIconUrl() + { + $this->ccConfigProviderMock->expects($this->any()) + ->method('getIcons') + ->with() + ->willReturn($this->icons); + + $this->assertEquals( + $this->icons['VI']['url'], + $this->cardRenderer->getIconUrl() + ); + } + + public function testGetIconHeight() + { + $this->ccConfigProviderMock->expects($this->any()) + ->method('getIcons') + ->with() + ->willReturn($this->icons); + + $this->assertEquals( + $this->icons['VI']['height'], + $this->cardRenderer->getIconHeight() + ); + } + + public function testGetIconWidth() + { + $this->ccConfigProviderMock->expects($this->any()) + ->method('getIcons') + ->with() + ->willReturn($this->icons); + + $this->assertEquals( + $this->icons['VI']['width'], + $this->cardRenderer->getIconWidth() + ); + } +} diff --git a/Test/Unit/Block/FormTest.php b/Test/Unit/Block/FormTest.php index b45b898..636b8fd 100755 --- a/Test/Unit/Block/FormTest.php +++ b/Test/Unit/Block/FormTest.php @@ -13,6 +13,7 @@ * @copyright Copyright (c) 2017-2018 * @license Open Software License (OSL 3.0) */ + namespace Pmclain\Stripe\Test\Unit\Block; use Pmclain\Stripe\Block\Form; @@ -25,92 +26,96 @@ class FormTest extends \PHPUnit\Framework\TestCase { - /** @var GatewayConfig|MockObject */ - private $gatewayConfigMock; - - /** @var Data|MockObject */ - private $helperMock; - - /** @var StoreManagerInterface|MockObject */ - private $storeManagerMock; - - /** @var StoreInterface|MockObject */ - private $storeMock; - - /** @var MethodInterface|MockObject */ - private $paymentMethodMock; - - /** @var Form */ - private $block; - - protected function setUp() { - $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); - - $this->gatewayConfigMock = $this->getMockBuilder(GatewayConfig::class) - ->disableOriginalConstructor() - ->getMock(); - - $this->helperMock = $this->getMockBuilder(Data::class) - ->disableOriginalConstructor() - ->getMock(); - - $this->storeManagerMock = $this->getMockBuilder(StoreManagerInterface::class) - ->getMockForAbstractClass(); - - $this->storeMock = $this->getMockBuilder(StoreInterface::class) - ->getMockForAbstractClass(); - - $this->paymentMethodMock = $this->getMockBuilder(MethodInterface::class) - ->getMockForAbstractClass(); - - $this->block = $objectManager->getObject( - Form::class, - [ - 'gatewayConfig' => $this->gatewayConfigMock, - 'paymentDataHelper' => $this->helperMock, - '_storeManager' => $this->storeManagerMock, - ] - ); - } - - /** - * @param $config boolean The configuration value - * @param $expectedResult boolean Expected result based on configuration - * - * @dataProvider providerTestUseCcv - **/ - public function testUseCcv($config, $expectedResult) { - $this->gatewayConfigMock->expects($this->once()) - ->method('isCcvEnabled') - ->will($this->returnValue($config)); - - $this->assertEquals($this->block->useCcv(), $expectedResult); - } - - public function providerTestUseCcv() { - return [ - [true, true], - [false, false] - ]; - } - - public function testIsVaultEnabled() { - $this->storeManagerMock->expects($this->once()) - ->method('getStore') - ->willReturn($this->storeMock); - - $this->storeMock->expects($this->once()) - ->method('getId') - ->willReturn(1); - - $this->helperMock->expects($this->once()) - ->method('getMethodInstance') - ->willReturn($this->paymentMethodMock); - - $this->paymentMethodMock->expects($this->once()) - ->method('isActive') - ->willReturn(true); - - $this->block->isVaultEnabled(); - } -} \ No newline at end of file + /** @var GatewayConfig|MockObject */ + private $gatewayConfigMock; + + /** @var Data|MockObject */ + private $helperMock; + + /** @var StoreManagerInterface|MockObject */ + private $storeManagerMock; + + /** @var StoreInterface|MockObject */ + private $storeMock; + + /** @var MethodInterface|MockObject */ + private $paymentMethodMock; + + /** @var Form */ + private $block; + + protected function setUp() + { + $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); + + $this->gatewayConfigMock = $this->getMockBuilder(GatewayConfig::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->helperMock = $this->getMockBuilder(Data::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->storeManagerMock = $this->getMockBuilder(StoreManagerInterface::class) + ->getMockForAbstractClass(); + + $this->storeMock = $this->getMockBuilder(StoreInterface::class) + ->getMockForAbstractClass(); + + $this->paymentMethodMock = $this->getMockBuilder(MethodInterface::class) + ->getMockForAbstractClass(); + + $this->block = $objectManager->getObject( + Form::class, + [ + 'gatewayConfig' => $this->gatewayConfigMock, + 'paymentDataHelper' => $this->helperMock, + '_storeManager' => $this->storeManagerMock, + ] + ); + } + + /** + * @param $config boolean The configuration value + * @param $expectedResult boolean Expected result based on configuration + * + * @dataProvider providerTestUseCcv + **/ + public function testUseCcv($config, $expectedResult) + { + $this->gatewayConfigMock->expects($this->once()) + ->method('isCcvEnabled') + ->will($this->returnValue($config)); + + $this->assertEquals($this->block->useCcv(), $expectedResult); + } + + public function providerTestUseCcv() + { + return [ + [true, true], + [false, false] + ]; + } + + public function testIsVaultEnabled() + { + $this->storeManagerMock->expects($this->once()) + ->method('getStore') + ->willReturn($this->storeMock); + + $this->storeMock->expects($this->once()) + ->method('getId') + ->willReturn(1); + + $this->helperMock->expects($this->once()) + ->method('getMethodInstance') + ->willReturn($this->paymentMethodMock); + + $this->paymentMethodMock->expects($this->once()) + ->method('isActive') + ->willReturn(true); + + $this->block->isVaultEnabled(); + } +} diff --git a/Test/Unit/Block/InfoTest.php b/Test/Unit/Block/InfoTest.php index 74c3314..bdaf0a4 100755 --- a/Test/Unit/Block/InfoTest.php +++ b/Test/Unit/Block/InfoTest.php @@ -13,6 +13,7 @@ * @copyright Copyright (c) 2017-2018 * @license Open Software License (OSL 3.0) */ + namespace Pmclain\Stripe\Test\Unit\Block; use Pmclain\Stripe\Block\Info; @@ -21,25 +22,26 @@ class InfoTest extends \PHPUnit\Framework\TestCase { - public function testGetLabel() { - $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); + public function testGetLabel() + { + $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); - $context = $this->getMockBuilder(Context::class) - ->disableOriginalConstructor() - ->getMock(); - $config = $this->getMockBuilder(ConfigInterface::class) - ->disableOriginalConstructor() - ->getMock(); + $context = $this->getMockBuilder(Context::class) + ->disableOriginalConstructor() + ->getMock(); + $config = $this->getMockBuilder(ConfigInterface::class) + ->disableOriginalConstructor() + ->getMock(); - $block = $objectManager->getObject(Info::class); + $block = $objectManager->getObject(Info::class); - $reflection = new \ReflectionClass(get_class($block)); - $method = $reflection->getMethod('getLabel'); - $method->setAccessible(true); + $reflection = new \ReflectionClass(get_class($block)); + $method = $reflection->getMethod('getLabel'); + $method->setAccessible(true); - $this->assertEquals( - $method->invokeArgs($block, ['testing']), - 'testing' - ); - } -} \ No newline at end of file + $this->assertEquals( + $method->invokeArgs($block, ['testing']), + 'testing' + ); + } +} diff --git a/Test/Unit/Block/PaymentTest.php b/Test/Unit/Block/PaymentTest.php index 36b5f32..47a03a1 100644 --- a/Test/Unit/Block/PaymentTest.php +++ b/Test/Unit/Block/PaymentTest.php @@ -13,6 +13,7 @@ * @copyright Copyright (c) 2017-2018 * @license Open Software License (OSL 3.0) */ + namespace Pmclain\Stripe\Test\Unit\Block; use Pmclain\Stripe\Block\Payment; @@ -21,38 +22,41 @@ class PaymentTest extends \PHPUnit\Framework\TestCase { - /** @var ConfigProvider|MockObject */ - private $configProviderMock; - - /** @var Payment */ - private $block; - - protected function setUp() { - $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); - - $this->configProviderMock = $this->getMockBuilder(ConfigProvider::class) - ->disableOriginalConstructor() - ->getMock(); - - $this->block = $objectManager->getObject( - Payment::class, - [ - 'config' => $this->configProviderMock - ] - ); - } - - public function testGetPaymentConfig() { - $this->configProviderMock->expects($this->once()) - ->method('getConfig'); - - $this->block->getPaymentConfig(); - } - - public function testGetCode() { - $this->assertEquals( - ConfigProvider::CODE, - $this->block->getCode() - ); - } -} \ No newline at end of file + /** @var ConfigProvider|MockObject */ + private $configProviderMock; + + /** @var Payment */ + private $block; + + protected function setUp() + { + $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); + + $this->configProviderMock = $this->getMockBuilder(ConfigProvider::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->block = $objectManager->getObject( + Payment::class, + [ + 'config' => $this->configProviderMock + ] + ); + } + + public function testGetPaymentConfig() + { + $this->configProviderMock->expects($this->once()) + ->method('getConfig'); + + $this->block->getPaymentConfig(); + } + + public function testGetCode() + { + $this->assertEquals( + ConfigProvider::CODE, + $this->block->getCode() + ); + } +} diff --git a/Test/Unit/Gateway/Command/CaptureStrategyCommandTest.php b/Test/Unit/Gateway/Command/CaptureStrategyCommandTest.php index 0755b67..83621eb 100755 --- a/Test/Unit/Gateway/Command/CaptureStrategyCommandTest.php +++ b/Test/Unit/Gateway/Command/CaptureStrategyCommandTest.php @@ -13,6 +13,7 @@ * @copyright Copyright (c) 2017-2018 * @license Open Software License (OSL 3.0) */ + namespace Pmclain\Stripe\Test\Unit\Gateway\Command; use Pmclain\Stripe\Gateway\Command\CaptureStrategyCommand; @@ -32,244 +33,252 @@ class CaptureStrategyCommandTest extends \PHPUnit\Framework\TestCase { - /** - * @var CaptureStrategyCommand - */ - private $strategyCommand; - - /** - * @var CommandPoolInterface|\PHPUnit_Framework_MockObject_MockObject - */ - private $commandPool; - - /** - * @var TransactionRepositoryInterface|\PHPUnit_Framework_MockObject_MockObject - */ - private $transactionRepository; - - /** - * @var FilterBuilder|\PHPUnit_Framework_MockObject_MockObject - */ - private $filterBuilder; - - /** - * @var SearchCriteriaBuilder|\PHPUnit_Framework_MockObject_MockObject - */ - private $searchCriteriaBuilder; - - /** - * @var Payment|\PHPUnit_Framework_MockObject_MockObject - */ - private $payment; - - /** - * @var GatewayCommand|\PHPUnit_Framework_MockObject_MockObject - */ - private $command; - - /** - * @var SubjectReader|\PHPUnit_Framework_MockObject_MockObject - */ - private $subjectReaderMock; - - /** - * @var BraintreeAdapter|\PHPUnit_Framework_MockObject_MockObject - */ - private $stripeAdapter; - - protected function setUp() - { - $this->commandPool = $this->getMockBuilder(CommandPoolInterface::class) - ->disableOriginalConstructor() - ->setMethods(['get', '__wakeup']) - ->getMock(); - - $this->subjectReaderMock = $this->getMockBuilder(SubjectReader::class) - ->disableOriginalConstructor() - ->getMock(); - - $this->initCommandMock(); - $this->initTransactionRepositoryMock(); - $this->initFilterBuilderMock(); - $this->initSearchCriteriaBuilderMock(); - - $this->stripeAdapter = $this->getMockBuilder(StripeAdapter::class) - ->disableOriginalConstructor() - ->getMock(); - - $this->strategyCommand = new CaptureStrategyCommand( - $this->commandPool, - $this->transactionRepository, - $this->filterBuilder, - $this->searchCriteriaBuilder, - $this->subjectReaderMock, - $this->stripeAdapter - ); - } - - /** - * @covers \Pmclain\Stripe\Gateway\Command\CaptureStrategyCommand::execute - */ - public function testSaleExecute() - { - $paymentData = $this->getPaymentDataObjectMock(); - $subject['payment'] = $paymentData; - - $this->subjectReaderMock->expects(self::once()) - ->method('readPayment') - ->with($subject) - ->willReturn($paymentData); - - $this->payment->expects(static::once()) - ->method('getAuthorizationTransaction') - ->willReturn(false); - - $this->payment->expects(static::once()) - ->method('getId') - ->willReturn(1); - - $this->buildSearchCriteria(); - - $this->transactionRepository->expects(static::once()) - ->method('getTotalCount') - ->willReturn(0); - - $this->commandPool->expects(static::once()) - ->method('get') - ->with(CaptureStrategyCommand::SALE) - ->willReturn($this->command); - - $this->strategyCommand->execute($subject); - } - - /** - * @covers \Magento\Braintree\Gateway\Command\CaptureStrategyCommand::execute - */ - public function testCaptureExecute() - { - $paymentData = $this->getPaymentDataObjectMock(); - $subject['payment'] = $paymentData; - - $this->subjectReaderMock->expects(self::once()) - ->method('readPayment') - ->with($subject) - ->willReturn($paymentData); - - $this->payment->expects(static::once()) - ->method('getAuthorizationTransaction') - ->willReturn(true); - - $this->payment->expects(static::once()) - ->method('getId') - ->willReturn(1); - - $this->buildSearchCriteria(); - - $this->transactionRepository->expects(static::once()) - ->method('getTotalCount') - ->willReturn(0); - - $this->commandPool->expects(static::once()) - ->method('get') - ->with(CaptureStrategyCommand::CAPTURE) - ->willReturn($this->command); - - $this->strategyCommand->execute($subject); - } - - /** - * Create mock for payment data object and order payment - * @return \PHPUnit_Framework_MockObject_MockObject - */ - private function getPaymentDataObjectMock() - { - $this->payment = $this->getMockBuilder(Payment::class) - ->disableOriginalConstructor() - ->getMock(); - - $mock = $this->getMockBuilder(PaymentDataObject::class) - ->setMethods(['getPayment']) - ->disableOriginalConstructor() - ->getMock(); - - $mock->expects(static::once()) - ->method('getPayment') - ->willReturn($this->payment); - - return $mock; - } - - /** - * Create mock for gateway command object - */ - private function initCommandMock() - { - $this->command = $this->getMockBuilder(GatewayCommand::class) - ->disableOriginalConstructor() - ->setMethods(['execute']) - ->getMock(); - - $this->command->expects(static::once()) - ->method('execute') - ->willReturn([]); - } - - /** - * Create mock for filter object - */ - private function initFilterBuilderMock() - { - $this->filterBuilder = $this->getMockBuilder(FilterBuilder::class) - ->disableOriginalConstructor() - ->setMethods(['setField', 'setValue', 'create', '__wakeup']) - ->getMock(); - } - - /** - * Build search criteria - */ - private function buildSearchCriteria() - { - $this->filterBuilder->expects(static::exactly(2)) - ->method('setField') - ->willReturnSelf(); - $this->filterBuilder->expects(static::exactly(2)) - ->method('setValue') - ->willReturnSelf(); - - $searchCriteria = new SearchCriteria(); - $this->searchCriteriaBuilder->expects(static::exactly(2)) - ->method('addFilters') - ->willReturnSelf(); - $this->searchCriteriaBuilder->expects(static::once()) - ->method('create') - ->willReturn($searchCriteria); - - $this->transactionRepository->expects(static::once()) - ->method('getList') - ->with($searchCriteria) - ->willReturnSelf(); - } - - /** - * Create mock for search criteria object - */ - private function initSearchCriteriaBuilderMock() - { - $this->searchCriteriaBuilder = $this->getMockBuilder(SearchCriteriaBuilder::class) - ->disableOriginalConstructor() - ->setMethods(['addFilters', 'create', '__wakeup']) - ->getMock(); - } - - /** - * Create mock for transaction repository - */ - private function initTransactionRepositoryMock() - { - $this->transactionRepository = $this->getMockBuilder(TransactionRepositoryInterface::class) - ->disableOriginalConstructor() - ->setMethods(['getList', 'getTotalCount', 'delete', 'get', 'save', 'create', '__wakeup']) - ->getMock(); - } -} \ No newline at end of file + /** + * @var CaptureStrategyCommand + */ + private $strategyCommand; + + /** + * @var CommandPoolInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $commandPool; + + /** + * @var TransactionRepositoryInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $transactionRepository; + + /** + * @var FilterBuilder|\PHPUnit_Framework_MockObject_MockObject + */ + private $filterBuilder; + + /** + * @var SearchCriteriaBuilder|\PHPUnit_Framework_MockObject_MockObject + */ + private $searchCriteriaBuilder; + + /** + * @var Payment|\PHPUnit_Framework_MockObject_MockObject + */ + private $payment; + + /** + * @var GatewayCommand|\PHPUnit_Framework_MockObject_MockObject + */ + private $command; + + /** + * @var SubjectReader|\PHPUnit_Framework_MockObject_MockObject + */ + private $subjectReaderMock; + + /** + * @var StripeAdapter|\PHPUnit_Framework_MockObject_MockObject + */ + private $stripeAdapter; + + protected function setUp() + { + $this->commandPool = $this->getMockBuilder(CommandPoolInterface::class) + ->disableOriginalConstructor() + ->setMethods(['get', '__wakeup']) + ->getMock(); + + $this->subjectReaderMock = $this->getMockBuilder(SubjectReader::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->initCommandMock(); + $this->initTransactionRepositoryMock(); + $this->initFilterBuilderMock(); + $this->initSearchCriteriaBuilderMock(); + + $this->stripeAdapter = $this->getMockBuilder(StripeAdapter::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->strategyCommand = new CaptureStrategyCommand( + $this->commandPool, + $this->transactionRepository, + $this->filterBuilder, + $this->searchCriteriaBuilder, + $this->subjectReaderMock, + $this->stripeAdapter + ); + } + + /** + * @covers \Pmclain\Stripe\Gateway\Command\CaptureStrategyCommand::execute + */ + public function testSaleExecute() + { + $paymentData = $this->getPaymentDataObjectMock(); + $subject['payment'] = $paymentData; + + $this->subjectReaderMock->expects(self::once()) + ->method('readPayment') + ->with($subject) + ->willReturn($paymentData); + + $this->payment->expects(static::once()) + ->method('getAuthorizationTransaction') + ->willReturn(false); + + $this->payment->expects(static::once()) + ->method('getId') + ->willReturn(1); + + $this->buildSearchCriteria(); + + $this->transactionRepository->expects(static::once()) + ->method('getTotalCount') + ->willReturn(0); + + $this->commandPool->expects(static::once()) + ->method('get') + ->with(CaptureStrategyCommand::SALE) + ->willReturn($this->command); + + $this->strategyCommand->execute($subject); + } + + /** + * @covers \Pmclain\Stripe\Gateway\Command\CaptureStrategyCommand::execute + */ + public function testCaptureExecute() + { + $paymentData = $this->getPaymentDataObjectMock(); + $subject['payment'] = $paymentData; + + $this->subjectReaderMock->expects(self::once()) + ->method('readPayment') + ->with($subject) + ->willReturn($paymentData); + + $this->payment->expects(static::once()) + ->method('getAuthorizationTransaction') + ->willReturn(true); + + $this->payment->expects(static::once()) + ->method('getId') + ->willReturn(1); + + $this->buildSearchCriteria(); + + $this->transactionRepository->expects(static::once()) + ->method('getTotalCount') + ->willReturn(0); + + $this->commandPool->expects(static::once()) + ->method('get') + ->with(CaptureStrategyCommand::CAPTURE) + ->willReturn($this->command); + + $this->strategyCommand->execute($subject); + } + + /** + * Create mock for payment data object and order payment + * @return \PHPUnit_Framework_MockObject_MockObject + */ + private function getPaymentDataObjectMock() + { + $this->payment = $this->getMockBuilder(Payment::class) + ->disableOriginalConstructor() + ->getMock(); + + $mock = $this->getMockBuilder(PaymentDataObject::class) + ->setMethods(['getPayment']) + ->disableOriginalConstructor() + ->getMock(); + + $mock->expects(static::once()) + ->method('getPayment') + ->willReturn($this->payment); + + return $mock; + } + + /** + * Create mock for gateway command object + */ + private function initCommandMock() + { + $this->command = $this->getMockBuilder(GatewayCommand::class) + ->disableOriginalConstructor() + ->setMethods(['execute']) + ->getMock(); + + $this->command->expects(static::once()) + ->method('execute') + ->willReturn([]); + } + + /** + * Create mock for filter object + */ + private function initFilterBuilderMock() + { + $this->filterBuilder = $this->getMockBuilder(FilterBuilder::class) + ->disableOriginalConstructor() + ->setMethods(['setField', 'setValue', 'create', '__wakeup']) + ->getMock(); + } + + /** + * Build search criteria + */ + private function buildSearchCriteria() + { + $this->filterBuilder->expects(static::exactly(2)) + ->method('setField') + ->willReturnSelf(); + $this->filterBuilder->expects(static::exactly(2)) + ->method('setValue') + ->willReturnSelf(); + + $searchCriteria = new SearchCriteria(); + $this->searchCriteriaBuilder->expects(static::exactly(2)) + ->method('addFilters') + ->willReturnSelf(); + $this->searchCriteriaBuilder->expects(static::once()) + ->method('create') + ->willReturn($searchCriteria); + + $this->transactionRepository->expects(static::once()) + ->method('getList') + ->with($searchCriteria) + ->willReturnSelf(); + } + + /** + * Create mock for search criteria object + */ + private function initSearchCriteriaBuilderMock() + { + $this->searchCriteriaBuilder = $this->getMockBuilder(SearchCriteriaBuilder::class) + ->disableOriginalConstructor() + ->setMethods(['addFilters', 'create', '__wakeup']) + ->getMock(); + } + + /** + * Create mock for transaction repository + */ + private function initTransactionRepositoryMock() + { + $this->transactionRepository = $this->getMockBuilder(TransactionRepositoryInterface::class) + ->disableOriginalConstructor() + ->setMethods([ + 'getList', + 'getTotalCount', + 'delete', + 'get', + 'save', + 'create', + '__wakeup' + ]) + ->getMock(); + } +} diff --git a/Test/Unit/Gateway/Config/CanVoidHandlerTest.php b/Test/Unit/Gateway/Config/CanVoidHandlerTest.php index 3b0d566..10bf8de 100755 --- a/Test/Unit/Gateway/Config/CanVoidHandlerTest.php +++ b/Test/Unit/Gateway/Config/CanVoidHandlerTest.php @@ -13,6 +13,7 @@ * @copyright Copyright (c) 2017-2018 * @license Open Software License (OSL 3.0) */ + namespace Pmclain\Stripe\Test\Unit\Gateway\Config; use Pmclain\Stripe\Gateway\Config\CanVoidHandler; @@ -23,55 +24,57 @@ class CanVoidHandlerTest extends \PHPUnit\Framework\TestCase { - public function testHandleNotOrderPayment() { - $paymentDataObject = $this->createMock(PaymentDataObjectInterface::class); - $subject = ['payment' => $paymentDataObject]; + public function testHandleNotOrderPayment() + { + $paymentDataObject = $this->createMock(PaymentDataObjectInterface::class); + $subject = ['payment' => $paymentDataObject]; - $subjectReader = $this->getMockBuilder(SubjectReader::class) - ->disableOriginalConstructor() - ->getMock(); + $subjectReader = $this->getMockBuilder(SubjectReader::class) + ->disableOriginalConstructor() + ->getMock(); - $subjectReader->expects(static::once()) - ->method('readPayment') - ->willReturn($paymentDataObject); + $subjectReader->expects(static::once()) + ->method('readPayment') + ->willReturn($paymentDataObject); - $paymentMock = $this->createMock(InfoInterface::class); + $paymentMock = $this->createMock(InfoInterface::class); - $paymentDataObject->expects(static::once()) - ->method('getPayment') - ->willReturn($paymentMock); + $paymentDataObject->expects(static::once()) + ->method('getPayment') + ->willReturn($paymentMock); - $voidHandler = new CanVoidHandler($subjectReader); + $voidHandler = new CanVoidHandler($subjectReader); - $this->assertFalse($voidHandler->handle($subject)); - } + $this->assertFalse($voidHandler->handle($subject)); + } - public function testHandleSomeAmountWasPaid() { - $paymentDataObject = $this->createMock(PaymentDataObjectInterface::class); - $subject = ['payment' => $paymentDataObject]; + public function testHandleSomeAmountWasPaid() + { + $paymentDataObject = $this->createMock(PaymentDataObjectInterface::class); + $subject = ['payment' => $paymentDataObject]; - $subjectReader = $this->getMockBuilder(SubjectReader::class) - ->disableOriginalConstructor() - ->getMock(); + $subjectReader = $this->getMockBuilder(SubjectReader::class) + ->disableOriginalConstructor() + ->getMock(); - $subjectReader->expects(static::once()) - ->method('readPayment') - ->willReturn($paymentDataObject); + $subjectReader->expects(static::once()) + ->method('readPayment') + ->willReturn($paymentDataObject); - $paymentMock = $this->getMockBuilder(Payment::class) - ->disableOriginalConstructor() - ->getMock(); + $paymentMock = $this->getMockBuilder(Payment::class) + ->disableOriginalConstructor() + ->getMock(); - $paymentDataObject->expects(static::once()) - ->method('getPayment') - ->willReturn($paymentMock); + $paymentDataObject->expects(static::once()) + ->method('getPayment') + ->willReturn($paymentMock); - $paymentMock->expects(static::once()) - ->method('getAmountPaid') - ->willReturn(1.00); + $paymentMock->expects(static::once()) + ->method('getAmountPaid') + ->willReturn(1.00); - $voidHandler = new CanVoidHandler($subjectReader); + $voidHandler = new CanVoidHandler($subjectReader); - $this->assertFalse($voidHandler->handle($subject)); - } -} \ No newline at end of file + $this->assertFalse($voidHandler->handle($subject)); + } +} diff --git a/Test/Unit/Gateway/Config/ConfigTest.php b/Test/Unit/Gateway/Config/ConfigTest.php index 8969fd9..ea385f1 100755 --- a/Test/Unit/Gateway/Config/ConfigTest.php +++ b/Test/Unit/Gateway/Config/ConfigTest.php @@ -13,6 +13,7 @@ * @copyright Copyright (c) 2017-2018 * @license Open Software License (OSL 3.0) */ + namespace Pmclain\Stripe\Test\Unit\Gateway\Config; use Pmclain\Stripe\Gateway\Config\Config; @@ -21,184 +22,255 @@ class ConfigTest extends \PHPUnit\Framework\TestCase { - const METHOD_CODE = 'pmclain_stripe'; - - /** - * @var Config - */ - private $model; - - /** - * @var ScopeConfigInterface|\PHPUnit_Framework_MockObject_MockObject - */ - private $scopeConfigMock; - - protected function setUp() { - $this->scopeConfigMock = $this->createMock(ScopeConfigInterface::class); - - $this->model = new Config($this->scopeConfigMock, self::METHOD_CODE); - } - - /** - * @param $value - * @param $expected - * @dataProvider getAvailableCardTypesProvider - */ - public function testGetAvailableCardTypes($value, $expected) { - $this->scopeConfigMock->expects(static::once()) - ->method('getValue') - ->with($this->getPath(Config::KEY_CC_TYPES), ScopeInterface::SCOPE_STORE, null) - ->willReturn($value); - - $this->assertEquals($expected, $this->model->getAvailableCardTypes()); - } - - public function getAvailableCardTypesProvider() { - return [ - ['VI,MC,AE,DI,JCB,DN', ['VI', 'MC', 'AE', 'DI', 'JCB', 'DN']], - ['', []] - ]; - } - - /** - * @param $value - * @param $expected - * @dataProvider getCcTypesMapperDataProvider - */ - public function testGetCcTypesMapper($value, $expected) { - $this->scopeConfigMock->expects(static::once()) - ->method('getValue') - ->with($this->getPath(Config::KEY_CC_TYPES_STRIPE_MAPPER), ScopeInterface::SCOPE_STORE, null) - ->willReturn($value); - - $this->assertEquals($expected, $this->model->getCcTypesMapper()); - } - - public function getCcTypesMapperDataProvider() { - return [ - [ - '{"visa":"VI","american-express":"AE"}', - ['visa' => 'VI', 'american-express' => 'AE'] - ], - [ - '{invalid json}', - [] - ], - [ - '', - [] - ] - ]; - } - - /** - * @param $value - * @param $expected - * @dataProvider yesNoDataProvider - */ - public function testIsCcvEnabled($value, $expected) { - $this->scopeConfigMock->expects(static::once()) - ->method('getValue') - ->with($this->getPath(Config::KEY_USE_CCV), ScopeInterface::SCOPE_STORE, null) - ->willReturn($value); - - $this->assertEquals($expected, $this->model->isCcvEnabled()); - } - - /** - * @param $value - * @param $expected - * @dataProvider yesNoDataProvider - */ - public function testGetEnvironment($value, $expected) { - $this->scopeConfigMock->expects(static::once()) - ->method('getValue') - ->with($this->getPath(Config::KEY_ENVIRONMENT), ScopeInterface::SCOPE_STORE, null) - ->willReturn($value); - - $this->assertEquals($expected, $this->model->getEnvironment()); - } - - /** - * @param $value - * @param $expected - * @dataProvider yesNoDataProvider - */ - public function testIsActive($value, $expected) { - $this->scopeConfigMock->expects(static::once()) - ->method('getValue') - ->with($this->getPath(Config::KEY_ACTIVE), ScopeInterface::SCOPE_STORE, null) - ->willReturn($value); - - $this->assertEquals($expected, $this->model->isActive()); - } - - public function testGetPublishableKeyTestMode() { - $result = 'pub_key'; - $this->scopeConfigMock->expects($this->exactly(2)) - ->method('getValue') - ->withConsecutive( - [$this->getPath(Config::KEY_ENVIRONMENT), ScopeInterface::SCOPE_STORE, null], - [$this->getPath(Config::KEY_TEST_PUBLISHABLE_KEY), ScopeInterface::SCOPE_STORE, null] - )->willReturnOnConsecutiveCalls(true, $result); - $this->assertEquals($result, $this->model->getPublishableKey()); - } - - public function testGetPublishableKeyLiveMode() { - $result = 'pub_key'; - $this->scopeConfigMock->expects($this->exactly(2)) - ->method('getValue') - ->withConsecutive( - [$this->getPath(Config::KEY_ENVIRONMENT), ScopeInterface::SCOPE_STORE, null], - [$this->getPath(Config::KEY_LIVE_PUBLISHABLE_KEY), ScopeInterface::SCOPE_STORE, null] - )->willReturnOnConsecutiveCalls(false, $result); - $this->assertEquals($result, $this->model->getPublishableKey()); - } - - public function testGetSecretKeyTestMode() { - $result = 'sec_key'; - $this->scopeConfigMock->expects($this->exactly(2)) - ->method('getValue') - ->withConsecutive( - [$this->getPath(Config::KEY_ENVIRONMENT), ScopeInterface::SCOPE_STORE, null], - [$this->getPath(Config::KEY_TEST_SECRET_KEY), ScopeInterface::SCOPE_STORE, null] - )->willReturnOnConsecutiveCalls(true, $result); - $this->assertEquals($result, $this->model->getSecretKey()); - } - - public function testGetSecretKeyLiveMode() { - $result = 'sec_key'; - $this->scopeConfigMock->expects($this->exactly(2)) - ->method('getValue') - ->withConsecutive( - [$this->getPath(Config::KEY_ENVIRONMENT), ScopeInterface::SCOPE_STORE, null], - [$this->getPath(Config::KEY_LIVE_SECRET_KEY), ScopeInterface::SCOPE_STORE, null] - )->willReturnOnConsecutiveCalls(false, $result); - $this->assertEquals($result, $this->model->getSecretKey()); - } - - /** - * @param $value - * @param $expected - * @dataProvider yesNoDataProvider - */ - public function testIsTestMode($value, $expected) { - $this->scopeConfigMock->expects(static::once()) - ->method('getValue') - ->with($this->getPath(Config::KEY_ENVIRONMENT), ScopeInterface::SCOPE_STORE, null) - ->willReturn($value); - - $this->assertEquals($expected, $this->model->isTestMode()); - } - - public function yesNoDataProvider() { - return [ - [true, true], - [false, false] - ]; - } - - private function getPath($field) { - return sprintf(Config::DEFAULT_PATH_PATTERN, self::METHOD_CODE, $field); - } -} \ No newline at end of file + const METHOD_CODE = 'pmclain_stripe'; + + /** + * @var Config + */ + private $model; + + /** + * @var ScopeConfigInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $scopeConfigMock; + + protected function setUp() + { + $this->scopeConfigMock = $this->createMock(ScopeConfigInterface::class); + + $this->model = new Config($this->scopeConfigMock, self::METHOD_CODE); + } + + /** + * @param $value + * @param $expected + * @dataProvider getAvailableCardTypesProvider + */ + public function testGetAvailableCardTypes($value, $expected) + { + $this->scopeConfigMock->expects(static::once()) + ->method('getValue') + ->with( + $this->getPath(Config::KEY_CC_TYPES), + ScopeInterface::SCOPE_STORE, + null + ) + ->willReturn($value); + + $this->assertEquals($expected, $this->model->getAvailableCardTypes()); + } + + public function getAvailableCardTypesProvider() + { + return [ + ['VI,MC,AE,DI,JCB,DN', ['VI', 'MC', 'AE', 'DI', 'JCB', 'DN']], + ['', []] + ]; + } + + /** + * @param $value + * @param $expected + * @dataProvider getCcTypesMapperDataProvider + */ + public function testGetCcTypesMapper($value, $expected) + { + $this->scopeConfigMock->expects(static::once()) + ->method('getValue') + ->with( + $this->getPath(Config::KEY_CC_TYPES_STRIPE_MAPPER), + ScopeInterface::SCOPE_STORE, + null + ) + ->willReturn($value); + + $this->assertEquals($expected, $this->model->getCcTypesMapper()); + } + + public function getCcTypesMapperDataProvider() + { + return [ + [ + '{"visa":"VI","american-express":"AE"}', + ['visa' => 'VI', 'american-express' => 'AE'] + ], + [ + '{invalid json}', + [] + ], + [ + '', + [] + ] + ]; + } + + /** + * @param $value + * @param $expected + * @dataProvider yesNoDataProvider + */ + public function testIsCcvEnabled($value, $expected) + { + $this->scopeConfigMock->expects(static::once()) + ->method('getValue') + ->with( + $this->getPath(Config::KEY_USE_CCV), + ScopeInterface::SCOPE_STORE, + null + ) + ->willReturn($value); + + $this->assertEquals($expected, $this->model->isCcvEnabled()); + } + + /** + * @param $value + * @param $expected + * @dataProvider yesNoDataProvider + */ + public function testGetEnvironment($value, $expected) + { + $this->scopeConfigMock->expects(static::once()) + ->method('getValue') + ->with( + $this->getPath(Config::KEY_ENVIRONMENT), + ScopeInterface::SCOPE_STORE, + null + ) + ->willReturn($value); + + $this->assertEquals($expected, $this->model->getEnvironment()); + } + + /** + * @param $value + * @param $expected + * @dataProvider yesNoDataProvider + */ + public function testIsActive($value, $expected) + { + $this->scopeConfigMock->expects(static::once()) + ->method('getValue') + ->with( + $this->getPath(Config::KEY_ACTIVE), + ScopeInterface::SCOPE_STORE, + null + ) + ->willReturn($value); + + $this->assertEquals($expected, $this->model->isActive()); + } + + public function testGetPublishableKeyTestMode() + { + $result = 'pub_key'; + $this->scopeConfigMock->expects($this->exactly(2)) + ->method('getValue') + ->withConsecutive( + [ + $this->getPath(Config::KEY_ENVIRONMENT), + ScopeInterface::SCOPE_STORE, + null + ], + [ + $this->getPath(Config::KEY_TEST_PUBLISHABLE_KEY), + ScopeInterface::SCOPE_STORE, + null + ] + )->willReturnOnConsecutiveCalls(true, $result); + $this->assertEquals($result, $this->model->getPublishableKey()); + } + + public function testGetPublishableKeyLiveMode() + { + $result = 'pub_key'; + $this->scopeConfigMock->expects($this->exactly(2)) + ->method('getValue') + ->withConsecutive( + [ + $this->getPath(Config::KEY_ENVIRONMENT), + ScopeInterface::SCOPE_STORE, + null + ], + [ + $this->getPath(Config::KEY_LIVE_PUBLISHABLE_KEY), + ScopeInterface::SCOPE_STORE, + null + ] + )->willReturnOnConsecutiveCalls(false, $result); + $this->assertEquals($result, $this->model->getPublishableKey()); + } + + public function testGetSecretKeyTestMode() + { + $result = 'sec_key'; + $this->scopeConfigMock->expects($this->exactly(2)) + ->method('getValue') + ->withConsecutive( + [ + $this->getPath(Config::KEY_ENVIRONMENT), + ScopeInterface::SCOPE_STORE, + null + ], + [ + $this->getPath(Config::KEY_TEST_SECRET_KEY), + ScopeInterface::SCOPE_STORE, + null + ] + )->willReturnOnConsecutiveCalls(true, $result); + $this->assertEquals($result, $this->model->getSecretKey()); + } + + public function testGetSecretKeyLiveMode() + { + $result = 'sec_key'; + $this->scopeConfigMock->expects($this->exactly(2)) + ->method('getValue') + ->withConsecutive( + [ + $this->getPath(Config::KEY_ENVIRONMENT), + ScopeInterface::SCOPE_STORE, + null + ], + [ + $this->getPath(Config::KEY_LIVE_SECRET_KEY), + ScopeInterface::SCOPE_STORE, + null + ] + )->willReturnOnConsecutiveCalls(false, $result); + $this->assertEquals($result, $this->model->getSecretKey()); + } + + /** + * @param $value + * @param $expected + * @dataProvider yesNoDataProvider + */ + public function testIsTestMode($value, $expected) + { + $this->scopeConfigMock->expects(static::once()) + ->method('getValue') + ->with( + $this->getPath(Config::KEY_ENVIRONMENT), + ScopeInterface::SCOPE_STORE, + null + ) + ->willReturn($value); + + $this->assertEquals($expected, $this->model->isTestMode()); + } + + public function yesNoDataProvider() + { + return [ + [true, true], + [false, false] + ]; + } + + private function getPath($field) + { + return sprintf(Config::DEFAULT_PATH_PATTERN, self::METHOD_CODE, $field); + } +} diff --git a/Test/Unit/Gateway/Helper/SubjectReaderTest.php b/Test/Unit/Gateway/Helper/SubjectReaderTest.php index 34be8b4..bd80746 100755 --- a/Test/Unit/Gateway/Helper/SubjectReaderTest.php +++ b/Test/Unit/Gateway/Helper/SubjectReaderTest.php @@ -13,6 +13,7 @@ * @copyright Copyright (c) 2017-2018 * @license Open Software License (OSL 3.0) */ + namespace Pmclain\Stripe\Test\Unit\Gateway\Helper; use InvalidArgumentException; @@ -20,27 +21,33 @@ class SubjectReaderTest extends \PHPUnit\Framework\TestCase { - /** - * @var SubjectReader - */ - private $subjectReader; + /** + * @var SubjectReader + */ + private $subjectReader; - protected function setUp() { - $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); + protected function setUp() + { + $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); - $this->subjectReader = $objectManager->getObject(SubjectReader::class); - } + $this->subjectReader = $objectManager->getObject(SubjectReader::class); + } - /** - * @expectedException InvalidArgumentException - * @expectedExceptionMessage The customerId field does not exist - */ - public function testReadCustomerIdWithException() { - $this->subjectReader->readCustomerId([]); - } + /** + * @expectedException InvalidArgumentException + * @expectedExceptionMessage The customerId field does not exist + */ + public function testReadCustomerIdWithException() + { + $this->subjectReader->readCustomerId([]); + } - public function testReadCustomerId() { - $customerId = 1; - $this->assertEquals($customerId, $this->subjectReader->readCustomerId(['customer_id' => $customerId])); - } -} \ No newline at end of file + public function testReadCustomerId() + { + $customerId = 1; + $this->assertEquals( + $customerId, + $this->subjectReader->readCustomerId(['customer_id' => $customerId]) + ); + } +} diff --git a/Test/Unit/Gateway/Http/Client/TransactionSaleTest.php b/Test/Unit/Gateway/Http/Client/TransactionSaleTest.php index 3456c58..6a2861f 100755 --- a/Test/Unit/Gateway/Http/Client/TransactionSaleTest.php +++ b/Test/Unit/Gateway/Http/Client/TransactionSaleTest.php @@ -13,6 +13,7 @@ * @copyright Copyright (c) 2017-2018 * @license Open Software License (OSL 3.0) */ + namespace Pmclain\Stripe\Test\Unit\Gateway\Http\Client; use Pmclain\Stripe\Gateway\Http\Client\TransactionSale; @@ -23,92 +24,102 @@ class TransactionSaleTest extends \PHPUnit\Framework\TestCase { - /** - * @var TransactionSale - */ - private $model; - - /** - * @var Logger|\PHPUnit_Framework_MockObject_MockObject - */ - private $loggerMock; - - /** - * @var StripeAdapter|\PHPUnit_Framework_MockObject_MockObject - */ - private $adapter; - - protected function setUp() { - $criticalLoggerMock = $this->getMockForAbstractClass(LoggerInterface::class); - $this->loggerMock = $this->getMockBuilder(Logger::class) - ->disableOriginalConstructor() - ->getMock(); - $this->adapter = $this->getMockBuilder(StripeAdapter::class) - ->disableOriginalConstructor() - ->getMock(); - - $this->model = new TransactionSale($criticalLoggerMock, $this->loggerMock, $this->adapter); - } - - /** - * @expectedException \Magento\Payment\Gateway\Http\ClientException - * @expectedExceptionMessage Test message - */ - public function testPlaceRequestException() { - $this->loggerMock->expects($this->once()) - ->method('debug') - ->with( - [ - 'request' => $this->getTransferData(), - 'client' => TransactionSale::class, - 'response' => [] - ] - ); - - $this->adapter->expects($this->once()) - ->method('sale') - ->willThrowException(new \Exception('Test message')); - - $transferObjectMock = $this->getTransferObjectMock(); - - $this->model->placeRequest($transferObjectMock); - } - - public function testPlaceRequestSuccess() { - $response = $this->getResponseObject(); - $this->adapter->expects($this->once()) - ->method('sale') - ->willReturn($response); - - $this->loggerMock->expects($this->once()) - ->method('debug') - ->with( - [ - 'request' => $this->getTransferData(), - 'client' => TransactionSale::class, - 'response' => ['success' => 1] - ] - ); - - $actualResult = $this->model->placeRequest($this->getTransferObjectMock()); - - $this->assertEquals(['object' => $response], $actualResult); - } - - private function getTransferData() { - return ['test-data-key' => 'test-data-value']; - } - - private function getTransferObjectMock() { - $transferObjectMock = $this->createMock(TransferInterface::class); - $transferObjectMock->expects($this->once()) - ->method('getBody') - ->willReturn($this->getTransferData()); - - return $transferObjectMock; - } - - private function getResponseObject() { - return ['success' => true]; - } -} \ No newline at end of file + /** + * @var TransactionSale + */ + private $model; + + /** + * @var Logger|\PHPUnit_Framework_MockObject_MockObject + */ + private $loggerMock; + + /** + * @var StripeAdapter|\PHPUnit_Framework_MockObject_MockObject + */ + private $adapter; + + protected function setUp() + { + $criticalLoggerMock = $this->getMockForAbstractClass(LoggerInterface::class); + $this->loggerMock = $this->getMockBuilder(Logger::class) + ->disableOriginalConstructor() + ->getMock(); + $this->adapter = $this->getMockBuilder(StripeAdapter::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->model = new TransactionSale( + $criticalLoggerMock, + $this->loggerMock, + $this->adapter + ); + } + + /** + * @expectedException \Magento\Payment\Gateway\Http\ClientException + * @expectedExceptionMessage Test message + */ + public function testPlaceRequestException() + { + $this->loggerMock->expects($this->once()) + ->method('debug') + ->with( + [ + 'request' => $this->getTransferData(), + 'client' => TransactionSale::class, + 'response' => [] + ] + ); + + $this->adapter->expects($this->once()) + ->method('sale') + ->willThrowException(new \Exception('Test message')); + + $transferObjectMock = $this->getTransferObjectMock(); + + $this->model->placeRequest($transferObjectMock); + } + + public function testPlaceRequestSuccess() + { + $response = $this->getResponseObject(); + $this->adapter->expects($this->once()) + ->method('sale') + ->willReturn($response); + + $this->loggerMock->expects($this->once()) + ->method('debug') + ->with( + [ + 'request' => $this->getTransferData(), + 'client' => TransactionSale::class, + 'response' => ['success' => 1] + ] + ); + + $actualResult = $this->model->placeRequest($this->getTransferObjectMock()); + + $this->assertEquals(['object' => $response], $actualResult); + } + + private function getTransferData() + { + return ['test-data-key' => 'test-data-value']; + } + + private function getTransferObjectMock() + { + $transferObjectMock = $this->createMock(TransferInterface::class); + $transferObjectMock->expects($this->once()) + ->method('getBody') + ->willReturn($this->getTransferData()); + + return $transferObjectMock; + } + + private function getResponseObject() + { + return ['success' => true]; + } +} diff --git a/Test/Unit/Gateway/Http/Client/TransactionSubmitForSettlementTest.php b/Test/Unit/Gateway/Http/Client/TransactionSubmitForSettlementTest.php index 6262bf9..aa461db 100755 --- a/Test/Unit/Gateway/Http/Client/TransactionSubmitForSettlementTest.php +++ b/Test/Unit/Gateway/Http/Client/TransactionSubmitForSettlementTest.php @@ -13,6 +13,7 @@ * @copyright Copyright (c) 2017-2018 * @license Open Software License (OSL 3.0) */ + namespace Pmclain\Stripe\Test\Unit\Gateway\Http\Client; use Stripe\Charge; @@ -24,77 +25,81 @@ class TransactionSubmitForSettlementTest extends \PHPUnit\Framework\TestCase { - /** - * @var TransactionSubmitForSettlement - */ - private $client; + /** + * @var TransactionSubmitForSettlement + */ + private $client; + + /** + * @var Logger|\PHPUnit_Framework_MockObject_MockObject + */ + private $logger; - /** - * @var Logger|\PHPUnit_Framework_MockObject_MockObject - */ - private $logger; + /** + * @var StripeAdapter|\PHPUnit_Framework_MockObject_MockObject + */ + private $adapter; - /** - * @var StripeAdapter|\PHPUnit_Framework_MockObject_MockObject - */ - private $adapter; + protected function setUp() + { + $criticalLoggerMock = $this->getMockForAbstractClass(LoggerInterface::class); + $this->logger = $this->getMockBuilder(Logger::class) + ->disableOriginalConstructor() + ->setMethods(['debug']) + ->getMock(); + $this->adapter = $this->getMockBuilder(StripeAdapter::class) + ->disableOriginalConstructor() + ->setMethods(['submitForSettlement']) + ->getMock(); - protected function setUp() { - $criticalLoggerMock = $this->getMockForAbstractClass(LoggerInterface::class); - $this->logger = $this->getMockBuilder(Logger::class) - ->disableOriginalConstructor() - ->setMethods(['debug']) - ->getMock(); - $this->adapter = $this->getMockBuilder(StripeAdapter::class) - ->disableOriginalConstructor() - ->setMethods(['submitForSettlement']) - ->getMock(); + $this->client = new TransactionSubmitForSettlement( + $criticalLoggerMock, + $this->logger, + $this->adapter + ); + } - $this->client = new TransactionSubmitForSettlement( - $criticalLoggerMock, - $this->logger, - $this->adapter - ); - } + /** + * @expectedException \Magento\Payment\Gateway\Http\ClientException + * @expectedExceptionMessage Transaction has been declined + */ + public function testPlaceRequestWithException() + { + $exception = new \Exception('Transaction has been declined'); + $this->adapter->expects($this->once()) + ->method('submitForSettlement') + ->willThrowException($exception); - /** - * @expectedException \Magento\Payment\Gateway\Http\ClientException - * @expectedExceptionMessage Transaction has been declined - */ - public function testPlaceRequestWithException() { - $exception = new \Exception('Transaction has been declined'); - $this->adapter->expects($this->once()) - ->method('submitForSettlement') - ->willThrowException($exception); + $tranferObjectMock = $this->getTransferObjectMock(); + $this->client->placeRequest($tranferObjectMock); + } - $tranferObjectMock = $this->getTransferObjectMock(); - $this->client->placeRequest($tranferObjectMock); - } + public function testPlaceRequest() + { + $data = new Charge(); + $this->adapter->expects($this->once()) + ->method('submitForSettlement') + ->willReturn($data); - public function testPlaceRequest() { - $data = new Charge(); - $this->adapter->expects($this->once()) - ->method('submitForSettlement') - ->willReturn($data); + $transferObjectMock = $this->getTransferObjectMock(); + $response = $this->client->placeRequest($transferObjectMock); - $transferObjectMock = $this->getTransferObjectMock(); - $response = $this->client->placeRequest($transferObjectMock); + $this->assertTrue(is_object($response['object'])); + $this->assertEquals(['object' => $data], $response); + } - $this->assertTrue(is_object($response['object'])); - $this->assertEquals(['object' => $data], $response); - } - - private function getTransferObjectMock() { - $mock = $this->createMock(TransferInterface::class); - $mock->expects($this->once()) - ->method('getBody') - ->willReturn( - [ - 'transaction_id' => 'ch_19RXyy2eZvKYlo2CNU3GxOOe', - 'amount' => 1.00 - ] - ); + private function getTransferObjectMock() + { + $mock = $this->createMock(TransferInterface::class); + $mock->expects($this->once()) + ->method('getBody') + ->willReturn( + [ + 'transaction_id' => 'ch_19RXyy2eZvKYlo2CNU3GxOOe', + 'amount' => 1.00 + ] + ); - return $mock; - } -} \ No newline at end of file + return $mock; + } +} diff --git a/Test/Unit/Gateway/Http/TransferFactoryTest.php b/Test/Unit/Gateway/Http/TransferFactoryTest.php index e0f4cfb..cda56d6 100755 --- a/Test/Unit/Gateway/Http/TransferFactoryTest.php +++ b/Test/Unit/Gateway/Http/TransferFactoryTest.php @@ -13,6 +13,7 @@ * @copyright Copyright (c) 2017-2018 * @license Open Software License (OSL 3.0) */ + namespace Pmclain\Stripe\Test\Unit\Gateway\Http\Client; use Pmclain\Stripe\Gateway\Http\TransferFactory; @@ -21,40 +22,43 @@ class TransferFactoryTest extends \PHPUnit\Framework\TestCase { - /** - * @var TransferFactory - */ - private $transferFactory; - - /** - * @var TransferFactory - */ - private $transferMock; - - /** - * @var TransferBuilder|\PHPUnit_Framework_MockObject_MockObject - */ - private $transferBuilder; - - protected function setUp() { - $this->transferBuilder = $this->createMock(TransferBuilder::class); - $this->transferMock = $this->createMock(TransferInterface::class); - - $this->transferFactory = new TransferFactory($this->transferBuilder); - } - - public function testCreate() { - $request = ['data1', 'data1']; - - $this->transferBuilder->expects($this->once()) - ->method('setBody') - ->with($request) - ->willReturnSelf(); - - $this->transferBuilder->expects($this->once()) - ->method('build') - ->willReturn($this->transferMock); - - $this->assertEquals($this->transferMock, $this->transferFactory->create($request)); - } -} \ No newline at end of file + /** + * @var TransferFactory + */ + private $transferFactory; + + /** + * @var TransferFactory + */ + private $transferMock; + + /** + * @var TransferBuilder|\PHPUnit_Framework_MockObject_MockObject + */ + private $transferBuilder; + + protected function setUp() + { + $this->transferBuilder = $this->createMock(TransferBuilder::class); + $this->transferMock = $this->createMock(TransferInterface::class); + + $this->transferFactory = new TransferFactory($this->transferBuilder); + } + + public function testCreate() + { + $request = ['data1', 'data1']; + + $this->transferBuilder->expects($this->once()) + ->method('setBody') + ->with($request) + ->willReturnSelf(); + + $this->transferBuilder->expects($this->once()) + ->method('build') + ->willReturn($this->transferMock); + + $this->assertEquals($this->transferMock, + $this->transferFactory->create($request)); + } +} diff --git a/Test/Unit/Gateway/Request/AddressDataBuilderTest.php b/Test/Unit/Gateway/Request/AddressDataBuilderTest.php index 478c1bb..176d01b 100755 --- a/Test/Unit/Gateway/Request/AddressDataBuilderTest.php +++ b/Test/Unit/Gateway/Request/AddressDataBuilderTest.php @@ -13,6 +13,7 @@ * @copyright Copyright (c) 2017-2018 * @license Open Software License (OSL 3.0) */ + namespace Pmclain\Stripe\Test\Unit\Gateway\Request; use Pmclain\Stripe\Gateway\Request\AddressDataBuilder; @@ -23,177 +24,179 @@ class AddressDataBuilderTest extends \PHPUnit\Framework\TestCase { - /** - * @var PaymentDataObjectInterface|\PHPUnit_Framework_MockObject_MockObject - */ - private $paymentDataObjectMock; - - /** - * @var OrderAdapterInterface|\PHPUnit_Framework_MockObject_MockObject - */ - private $orderMock; - - /** - * @var AddressDataBuilder - */ - private $builder; - - /** - * @var SubjectReader|\PHPUnit_Framework_MockObject_MockObject - */ - private $subjectReaderMock; - - protected function setUp() { - $this->paymentDataObjectMock = $this->createMock(PaymentDataObjectInterface::class); - $this->orderMock = $this->createMock(OrderAdapterInterface::class); - $this->subjectReaderMock = $this->getMockBuilder(SubjectReader::class) - ->disableOriginalConstructor() - ->getMock(); - - $this->builder = new AddressDataBuilder($this->subjectReaderMock); - } - - /** - * @expectedException \InvalidArgumentException - */ - public function testBuildReadPaymentException() - { - $buildSubject = [ - 'payment' => null, - ]; - - $this->subjectReaderMock->expects(self::once()) - ->method('readPayment') - ->with($buildSubject) - ->willThrowException(new \InvalidArgumentException()); - - $this->builder->build($buildSubject); - } - - public function testBuildNoAddresses() - { - $this->paymentDataObjectMock->expects(static::once()) - ->method('getOrder') - ->willReturn($this->orderMock); - - $this->orderMock->expects(static::once()) - ->method('getShippingAddress') - ->willReturn(null); - - $buildSubject = [ - 'payment' => $this->paymentDataObjectMock, - ]; - - $this->subjectReaderMock->expects(self::once()) - ->method('readPayment') - ->with($buildSubject) - ->willReturn($this->paymentDataObjectMock); - - static::assertEquals([], $this->builder->build($buildSubject)); - } - - /** - * @param array $addressData - * @param array $expectedResult - * - * @dataProvider dataProviderBuild - */ - public function testBuild($addressData, $expectedResult) - { - $addressMock = $this->getAddressMock($addressData); - - $this->paymentDataObjectMock->expects(static::once()) - ->method('getOrder') - ->willReturn($this->orderMock); - - $this->orderMock->expects(static::once()) - ->method('getShippingAddress') - ->willReturn($addressMock); - - $buildSubject = [ - 'payment' => $this->paymentDataObjectMock, - ]; - - $this->subjectReaderMock->expects(self::once()) - ->method('readPayment') - ->with($buildSubject) - ->willReturn($this->paymentDataObjectMock); - - self::assertEquals($expectedResult, $this->builder->build($buildSubject)); - } - - /** - * @return array - */ - public function dataProviderBuild() - { - return [ - [ - [ - 'firstname' => 'john', - 'lastname' => 'doe', - 'phone' => '555-555-5555', - 'street_1' => 'street1', - 'street_2' => 'street2', - 'city' => 'Chicago', - 'region_code' => 'IL', - 'country_id' => 'US', - 'post_code' => '00000' - ], - [ - AddressDataBuilder::SHIPPING_ADDRESS => [ - 'address' => [ - AddressDataBuilder::STREET_ADDRESS => 'street1', - AddressDataBuilder::EXTENDED_ADDRESS => 'street2', - AddressDataBuilder::LOCALITY => 'Chicago', - AddressDataBuilder::REGION => 'IL', - AddressDataBuilder::POSTAL_CODE => '00000', - AddressDataBuilder::COUNTRY_CODE => 'US' - ], - AddressDataBuilder::NAME => 'john doe', - AddressDataBuilder::PHONE => '555-555-5555' - ] - ] - ] - ]; - } - - /** - * @param array $addressData - * @return AddressAdapterInterface|\PHPUnit_Framework_MockObject_MockObject - */ - private function getAddressMock($addressData) - { - $addressMock = $this->createMock(AddressAdapterInterface::class); - - $addressMock->expects($this->once()) - ->method('getFirstname') - ->willReturn($addressData['firstname']); - $addressMock->expects($this->once()) - ->method('getLastname') - ->willReturn($addressData['lastname']); - $addressMock->expects($this->once()) - ->method('getTelephone') - ->willReturn($addressData['phone']); - $addressMock->expects($this->once()) - ->method('getStreetLine1') - ->willReturn($addressData['street_1']); - $addressMock->expects($this->once()) - ->method('getStreetLine2') - ->willReturn($addressData['street_2']); - $addressMock->expects($this->once()) - ->method('getCity') - ->willReturn($addressData['city']); - $addressMock->expects($this->once()) - ->method('getRegionCode') - ->willReturn($addressData['region_code']); - $addressMock->expects($this->once()) - ->method('getPostcode') - ->willReturn($addressData['post_code']); - $addressMock->expects($this->once()) - ->method('getCountryId') - ->willReturn($addressData['country_id']); - - return $addressMock; - } -} \ No newline at end of file + /** + * @var PaymentDataObjectInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $paymentDataObjectMock; + + /** + * @var OrderAdapterInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $orderMock; + + /** + * @var AddressDataBuilder + */ + private $builder; + + /** + * @var SubjectReader|\PHPUnit_Framework_MockObject_MockObject + */ + private $subjectReaderMock; + + protected function setUp() + { + $this->paymentDataObjectMock = $this->createMock(PaymentDataObjectInterface::class); + $this->orderMock = $this->createMock(OrderAdapterInterface::class); + $this->subjectReaderMock = $this->getMockBuilder(SubjectReader::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->builder = new AddressDataBuilder($this->subjectReaderMock); + } + + /** + * @expectedException \InvalidArgumentException + */ + public function testBuildReadPaymentException() + { + $buildSubject = [ + 'payment' => null, + ]; + + $this->subjectReaderMock->expects(self::once()) + ->method('readPayment') + ->with($buildSubject) + ->willThrowException(new \InvalidArgumentException()); + + $this->builder->build($buildSubject); + } + + public function testBuildNoAddresses() + { + $this->paymentDataObjectMock->expects(static::once()) + ->method('getOrder') + ->willReturn($this->orderMock); + + $this->orderMock->expects(static::once()) + ->method('getShippingAddress') + ->willReturn(null); + + $buildSubject = [ + 'payment' => $this->paymentDataObjectMock, + ]; + + $this->subjectReaderMock->expects(self::once()) + ->method('readPayment') + ->with($buildSubject) + ->willReturn($this->paymentDataObjectMock); + + static::assertEquals([], $this->builder->build($buildSubject)); + } + + /** + * @param array $addressData + * @param array $expectedResult + * + * @dataProvider dataProviderBuild + */ + public function testBuild($addressData, $expectedResult) + { + $addressMock = $this->getAddressMock($addressData); + + $this->paymentDataObjectMock->expects(static::once()) + ->method('getOrder') + ->willReturn($this->orderMock); + + $this->orderMock->expects(static::once()) + ->method('getShippingAddress') + ->willReturn($addressMock); + + $buildSubject = [ + 'payment' => $this->paymentDataObjectMock, + ]; + + $this->subjectReaderMock->expects(self::once()) + ->method('readPayment') + ->with($buildSubject) + ->willReturn($this->paymentDataObjectMock); + + self::assertEquals($expectedResult, + $this->builder->build($buildSubject)); + } + + /** + * @return array + */ + public function dataProviderBuild() + { + return [ + [ + [ + 'firstname' => 'john', + 'lastname' => 'doe', + 'phone' => '555-555-5555', + 'street_1' => 'street1', + 'street_2' => 'street2', + 'city' => 'Chicago', + 'region_code' => 'IL', + 'country_id' => 'US', + 'post_code' => '00000' + ], + [ + AddressDataBuilder::SHIPPING_ADDRESS => [ + 'address' => [ + AddressDataBuilder::STREET_ADDRESS => 'street1', + AddressDataBuilder::EXTENDED_ADDRESS => 'street2', + AddressDataBuilder::LOCALITY => 'Chicago', + AddressDataBuilder::REGION => 'IL', + AddressDataBuilder::POSTAL_CODE => '00000', + AddressDataBuilder::COUNTRY_CODE => 'US' + ], + AddressDataBuilder::NAME => 'john doe', + AddressDataBuilder::PHONE => '555-555-5555' + ] + ] + ] + ]; + } + + /** + * @param array $addressData + * @return AddressAdapterInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private function getAddressMock($addressData) + { + $addressMock = $this->createMock(AddressAdapterInterface::class); + + $addressMock->expects($this->once()) + ->method('getFirstname') + ->willReturn($addressData['firstname']); + $addressMock->expects($this->once()) + ->method('getLastname') + ->willReturn($addressData['lastname']); + $addressMock->expects($this->once()) + ->method('getTelephone') + ->willReturn($addressData['phone']); + $addressMock->expects($this->once()) + ->method('getStreetLine1') + ->willReturn($addressData['street_1']); + $addressMock->expects($this->once()) + ->method('getStreetLine2') + ->willReturn($addressData['street_2']); + $addressMock->expects($this->once()) + ->method('getCity') + ->willReturn($addressData['city']); + $addressMock->expects($this->once()) + ->method('getRegionCode') + ->willReturn($addressData['region_code']); + $addressMock->expects($this->once()) + ->method('getPostcode') + ->willReturn($addressData['post_code']); + $addressMock->expects($this->once()) + ->method('getCountryId') + ->willReturn($addressData['country_id']); + + return $addressMock; + } +} diff --git a/Test/Unit/Gateway/Request/CaptureDataBuilderTest.php b/Test/Unit/Gateway/Request/CaptureDataBuilderTest.php index e09c103..b9e9374 100755 --- a/Test/Unit/Gateway/Request/CaptureDataBuilderTest.php +++ b/Test/Unit/Gateway/Request/CaptureDataBuilderTest.php @@ -13,6 +13,7 @@ * @copyright Copyright (c) 2017-2018 * @license Open Software License (OSL 3.0) */ + namespace Pmclain\Stripe\Test\Unit\Gateway\Request; use Pmclain\Stripe\Gateway\Request\CaptureDataBuilder; @@ -23,96 +24,99 @@ class CaptureDataBuilderTest extends \PHPUnit\Framework\TestCase { - use Formatter; - - /** - * @var \Pmclain\Stripe\Gateway\Request\CaptureDataBuilder - */ - private $builder; - - /** - * @var Payment|\PHPUnit_Framework_MockObject_MockObject - */ - private $payment; - - /** - * @var \Magento\Sales\Model\Order\Payment|\PHPUnit_Framework_MockObject_MockObject - */ - private $paymentDataObject; - - /** - * @var SubjectReader|\PHPUnit_Framework_MockObject_MockObject - */ - private $subjectReaderMock; - - protected function setUp() { - $this->paymentDataObject = $this->createMock(PaymentDataObjectInterface::class); - $this->payment = $this->getMockBuilder(Payment::class) - ->disableOriginalConstructor() - ->getMock(); - $this->subjectReaderMock = $this->getMockBuilder(SubjectReader::class) - ->disableOriginalConstructor() - ->getMock(); - - $this->builder = new CaptureDataBuilder($this->subjectReaderMock); - } - - /** - * @expectedException \Magento\Framework\Exception\LocalizedException - * @expectedExceptionMessage No Authorization Transaction to capture - */ - public function testBuildWithException() { - $amount = 10.00; - $buildSubject = [ - 'payment' => $this->paymentDataObject, - 'amount' => $amount - ]; - - $this->payment->expects($this->once()) - ->method('getCcTransId') - ->willReturn(''); - - $this->paymentDataObject->expects($this->once()) - ->method('getPayment') - ->willReturn($this->payment); - - $this->subjectReaderMock->expects($this->once()) - ->method('readPayment') - ->with($buildSubject) - ->willReturn($this->paymentDataObject); - - $this->builder->build($buildSubject); - } - - public function testBuild() { - $transactionId = 'ch_19RZmz2eZvKYlo2CktQObIT0'; - $amount = 10.00; - - $expected = [ - 'transaction_id' => $transactionId, - 'amount' => $this->formatPrice($amount) - ]; - - $buildSubject = [ - 'payment' => $this->paymentDataObject, - 'amount' => $amount - ]; - - $this->payment->expects($this->once()) - ->method('getCcTransId') - ->willReturn($transactionId); - $this->paymentDataObject->expects($this->once()) - ->method('getPayment') - ->willReturn($this->payment); - $this->subjectReaderMock->expects($this->once()) - ->method('readPayment') - ->with($buildSubject) - ->willReturn($this->paymentDataObject); - $this->subjectReaderMock->expects($this->once()) - ->method('readAmount') - ->with($buildSubject) - ->willReturn($amount); - - $this->assertEquals($expected, $this->builder->build($buildSubject)); - } -} \ No newline at end of file + use Formatter; + + /** + * @var \Pmclain\Stripe\Gateway\Request\CaptureDataBuilder + */ + private $builder; + + /** + * @var Payment|\PHPUnit_Framework_MockObject_MockObject + */ + private $payment; + + /** + * @var \Magento\Sales\Model\Order\Payment|\PHPUnit_Framework_MockObject_MockObject + */ + private $paymentDataObject; + + /** + * @var SubjectReader|\PHPUnit_Framework_MockObject_MockObject + */ + private $subjectReaderMock; + + protected function setUp() + { + $this->paymentDataObject = $this->createMock(PaymentDataObjectInterface::class); + $this->payment = $this->getMockBuilder(Payment::class) + ->disableOriginalConstructor() + ->getMock(); + $this->subjectReaderMock = $this->getMockBuilder(SubjectReader::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->builder = new CaptureDataBuilder($this->subjectReaderMock); + } + + /** + * @expectedException \Magento\Framework\Exception\LocalizedException + * @expectedExceptionMessage No Authorization Transaction to capture + */ + public function testBuildWithException() + { + $amount = 10.00; + $buildSubject = [ + 'payment' => $this->paymentDataObject, + 'amount' => $amount + ]; + + $this->payment->expects($this->once()) + ->method('getCcTransId') + ->willReturn(''); + + $this->paymentDataObject->expects($this->once()) + ->method('getPayment') + ->willReturn($this->payment); + + $this->subjectReaderMock->expects($this->once()) + ->method('readPayment') + ->with($buildSubject) + ->willReturn($this->paymentDataObject); + + $this->builder->build($buildSubject); + } + + public function testBuild() + { + $transactionId = 'ch_19RZmz2eZvKYlo2CktQObIT0'; + $amount = 10.00; + + $expected = [ + 'transaction_id' => $transactionId, + 'amount' => $this->formatPrice($amount) + ]; + + $buildSubject = [ + 'payment' => $this->paymentDataObject, + 'amount' => $amount + ]; + + $this->payment->expects($this->once()) + ->method('getCcTransId') + ->willReturn($transactionId); + $this->paymentDataObject->expects($this->once()) + ->method('getPayment') + ->willReturn($this->payment); + $this->subjectReaderMock->expects($this->once()) + ->method('readPayment') + ->with($buildSubject) + ->willReturn($this->paymentDataObject); + $this->subjectReaderMock->expects($this->once()) + ->method('readAmount') + ->with($buildSubject) + ->willReturn($amount); + + $this->assertEquals($expected, $this->builder->build($buildSubject)); + } +} diff --git a/Test/Unit/Gateway/Request/PaymentDataBuilder/VaultTest.php b/Test/Unit/Gateway/Request/PaymentDataBuilder/VaultTest.php index 03a161c..7dc2ed0 100644 --- a/Test/Unit/Gateway/Request/PaymentDataBuilder/VaultTest.php +++ b/Test/Unit/Gateway/Request/PaymentDataBuilder/VaultTest.php @@ -13,6 +13,7 @@ * @copyright Copyright (c) 2017-2018 * @license Open Software License (OSL 3.0) */ + namespace Pmclain\Stripe\Test\Unit\Gateway\PaymentDataBuilder; use Pmclain\Stripe\Gateway\Request\PaymentDataBuilder; @@ -33,169 +34,171 @@ class VaultTest extends \PHPUnit\Framework\TestCase { - /** @var SubjectReader|MockObject */ - private $subjectReaderMock; - - /** @var PaymentDataObjectInterface|MockObject */ - private $paymentDataObjectMock; - - /** @var InfoInterface|MockObject */ - private $paymentMock; - - /** @var OrderAdapterInterface|MockObject */ - private $orderMock; - - /** @var OrderPaymentExtension|MockObject */ - private $extensionAttributeMock; - - /** @var PaymentToken|MockObject */ - private $paymentTokenMock; + /** @var SubjectReader|MockObject */ + private $subjectReaderMock; - /** @var Session|MockObject */ - private $sessionMock; + /** @var PaymentDataObjectInterface|MockObject */ + private $paymentDataObjectMock; - /** @var CustomerRepositoryInterface|MockObject */ - private $customerRepositoryMock; + /** @var InfoInterface|MockObject */ + private $paymentMock; - /** @var CustomerInterface|MockObject */ - private $customerMock; + /** @var OrderAdapterInterface|MockObject */ + private $orderMock; - /** @var AttributeInterface|MockObject */ - private $customAttributeMock; + /** @var OrderPaymentExtension|MockObject */ + private $extensionAttributeMock; - /** @var Config|MockObject */ - private $configMock; + /** @var PaymentToken|MockObject */ + private $paymentTokenMock; - /** @var Vault */ - private $builder; + /** @var Session|MockObject */ + private $sessionMock; - protected function setUp() { - $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); + /** @var CustomerRepositoryInterface|MockObject */ + private $customerRepositoryMock; - $this->subjectReaderMock = $this->getMockBuilder(SubjectReader::class) - ->disableOriginalConstructor() - ->getMock(); + /** @var CustomerInterface|MockObject */ + private $customerMock; - $this->paymentDataObjectMock = $this->getMockBuilder(PaymentDataObjectInterface::class) - ->getMockForAbstractClass(); + /** @var AttributeInterface|MockObject */ + private $customAttributeMock; - $this->paymentMock = $this->getMockBuilder(InfoInterface::class) - ->setMethods(['getExtensionAttributes']) - ->getMockForAbstractClass(); + /** @var Config|MockObject */ + private $configMock; - $this->extensionAttributeMock = $this->getMockBuilder(OrderPaymentExtension::class) - ->disableOriginalConstructor() - ->setMethods(['getVaultPaymentToken']) - ->getMock(); + /** @var Vault */ + private $builder; - $this->paymentTokenMock = $this->getMockBuilder(PaymentToken::class) - ->disableOriginalConstructor() - ->setMethods(['getGatewayToken']) - ->getMock(); + protected function setUp() + { + $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); + + $this->subjectReaderMock = $this->getMockBuilder(SubjectReader::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->paymentDataObjectMock = $this->getMockBuilder(PaymentDataObjectInterface::class) + ->getMockForAbstractClass(); - $this->orderMock = $this->getMockBuilder(OrderAdapterInterface::class) - ->getMockForAbstractClass(); + $this->paymentMock = $this->getMockBuilder(InfoInterface::class) + ->setMethods(['getExtensionAttributes']) + ->getMockForAbstractClass(); - $this->sessionMock = $this->getMockBuilder(Session::class) - ->disableOriginalConstructor() - ->getMock(); - - $this->customerRepositoryMock = $this->getMockBuilder(CustomerRepositoryInterface::class) - ->getMockForAbstractClass(); - - $this->customerMock = $this->getMockBuilder(CustomerInterface::class) - ->getMockForAbstractClass(); - - $this->customAttributeMock = $this->getMockBuilder(AttributeInterface::class) - ->getMockForAbstractClass(); - - $this->configMock = $this->getMockBuilder(Config::class) - ->disableOriginalConstructor() - ->getMock(); - - $this->builder = $objectManager->getObject( - Vault::class, - [ - 'subjectReader' => $this->subjectReaderMock, - 'customerRepository' => $this->customerRepositoryMock, - 'customerSession' => $this->sessionMock, - 'config' => $this->configMock, - ] - ); - } - - public function testBuild() { - $buildSubject = [ - 'amount' => 10.00, - 'payment' => $this->paymentMock - ]; - - $expectedResult = [ - PaymentDataBuilder::AMOUNT => 1000, - PaymentDataBuilder::ORDER_ID => '100000001', - PaymentDataBuilder::CURRENCY => 'USD', - PaymentDataBuilder::SOURCE => 'card_token', - PaymentDataBuilder::CAPTURE => 'false', - PaymentDataBuilder::CUSTOMER => 'cus_token' - ]; - - $this->subjectReaderMock->expects($this->once()) - ->method('readPayment') - ->willReturn($this->paymentDataObjectMock); - - $this->paymentDataObjectMock->expects($this->once()) - ->method('getPayment') - ->willReturn($this->paymentMock); - - $this->paymentDataObjectMock->expects($this->once()) - ->method('getOrder') - ->willReturn($this->orderMock); - - $this->paymentMock->expects($this->once()) - ->method('getExtensionAttributes') - ->willReturn($this->extensionAttributeMock); - - $this->extensionAttributeMock->expects($this->once()) - ->method('getVaultPaymentToken') - ->willReturn($this->paymentTokenMock); - - $this->sessionMock->expects($this->once()) - ->method('getCustomerId') - ->willReturn(1); - - $this->customerRepositoryMock->expects($this->once()) - ->method('getById') - ->willReturn($this->customerMock); - - $this->customerMock->expects($this->once()) - ->method('getCustomAttribute') - ->with('stripe_customer_id') - ->willReturn($this->customAttributeMock); - - $this->customAttributeMock->expects($this->once()) - ->method('getValue') - ->willReturn('cus_token'); - - $this->subjectReaderMock->expects($this->once()) - ->method('readAmount') - ->with($buildSubject) - ->willReturn($buildSubject['amount']); - - $this->orderMock->expects($this->once()) - ->method('getOrderIncrementId') - ->willReturn('100000001'); - - $this->configMock->expects($this->once()) - ->method('getCurrency') - ->willReturn('USD'); - - $this->paymentTokenMock->expects($this->once()) - ->method('getGatewayToken') - ->willReturn('card_token'); - - $this->assertEquals( - $expectedResult, - $this->builder->build($buildSubject) - ); - } -} \ No newline at end of file + $this->extensionAttributeMock = $this->getMockBuilder(OrderPaymentExtension::class) + ->disableOriginalConstructor() + ->setMethods(['getVaultPaymentToken']) + ->getMock(); + + $this->paymentTokenMock = $this->getMockBuilder(PaymentToken::class) + ->disableOriginalConstructor() + ->setMethods(['getGatewayToken']) + ->getMock(); + + $this->orderMock = $this->getMockBuilder(OrderAdapterInterface::class) + ->getMockForAbstractClass(); + + $this->sessionMock = $this->getMockBuilder(Session::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->customerRepositoryMock = $this->getMockBuilder(CustomerRepositoryInterface::class) + ->getMockForAbstractClass(); + + $this->customerMock = $this->getMockBuilder(CustomerInterface::class) + ->getMockForAbstractClass(); + + $this->customAttributeMock = $this->getMockBuilder(AttributeInterface::class) + ->getMockForAbstractClass(); + + $this->configMock = $this->getMockBuilder(Config::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->builder = $objectManager->getObject( + Vault::class, + [ + 'subjectReader' => $this->subjectReaderMock, + 'customerRepository' => $this->customerRepositoryMock, + 'customerSession' => $this->sessionMock, + 'config' => $this->configMock, + ] + ); + } + + public function testBuild() + { + $buildSubject = [ + 'amount' => 10.00, + 'payment' => $this->paymentMock + ]; + + $expectedResult = [ + PaymentDataBuilder::AMOUNT => 1000, + PaymentDataBuilder::ORDER_ID => '100000001', + PaymentDataBuilder::CURRENCY => 'USD', + PaymentDataBuilder::SOURCE => 'card_token', + PaymentDataBuilder::CAPTURE => 'false', + PaymentDataBuilder::CUSTOMER => 'cus_token' + ]; + + $this->subjectReaderMock->expects($this->once()) + ->method('readPayment') + ->willReturn($this->paymentDataObjectMock); + + $this->paymentDataObjectMock->expects($this->once()) + ->method('getPayment') + ->willReturn($this->paymentMock); + + $this->paymentDataObjectMock->expects($this->once()) + ->method('getOrder') + ->willReturn($this->orderMock); + + $this->paymentMock->expects($this->once()) + ->method('getExtensionAttributes') + ->willReturn($this->extensionAttributeMock); + + $this->extensionAttributeMock->expects($this->once()) + ->method('getVaultPaymentToken') + ->willReturn($this->paymentTokenMock); + + $this->sessionMock->expects($this->once()) + ->method('getCustomerId') + ->willReturn(1); + + $this->customerRepositoryMock->expects($this->once()) + ->method('getById') + ->willReturn($this->customerMock); + + $this->customerMock->expects($this->once()) + ->method('getCustomAttribute') + ->with('stripe_customer_id') + ->willReturn($this->customAttributeMock); + + $this->customAttributeMock->expects($this->once()) + ->method('getValue') + ->willReturn('cus_token'); + + $this->subjectReaderMock->expects($this->once()) + ->method('readAmount') + ->with($buildSubject) + ->willReturn($buildSubject['amount']); + + $this->orderMock->expects($this->once()) + ->method('getOrderIncrementId') + ->willReturn('100000001'); + + $this->configMock->expects($this->once()) + ->method('getCurrency') + ->willReturn('USD'); + + $this->paymentTokenMock->expects($this->once()) + ->method('getGatewayToken') + ->willReturn('card_token'); + + $this->assertEquals( + $expectedResult, + $this->builder->build($buildSubject) + ); + } +} diff --git a/Test/Unit/Gateway/Request/PaymentDataBuilderTest.php b/Test/Unit/Gateway/Request/PaymentDataBuilderTest.php index b6c1466..f467c92 100755 --- a/Test/Unit/Gateway/Request/PaymentDataBuilderTest.php +++ b/Test/Unit/Gateway/Request/PaymentDataBuilderTest.php @@ -13,6 +13,7 @@ * @copyright Copyright (c) 2017-2018 * @license Open Software License (OSL 3.0) */ + namespace Pmclain\Stripe\Test\Unit\Gateway\Request; use Pmclain\Stripe\Gateway\Config\Config; @@ -30,334 +31,268 @@ class PaymentDataBuilderTest extends \PHPUnit\Framework\TestCase { - use Formatter; - - /** - * @var PaymentDataBuilder - */ - private $builder; - - /** - * @var Config|MockObject - */ - private $configMock; - - /** - * @var Payment|MockObject - */ - private $paymentMock; - - /** - * @var PaymentDataObjectInterface|MockObject - */ - private $paymentDataObjectMock; - - /** - * @var SubjectReader|MockObject - */ - private $subjectReaderMock; - - /** @var Session|MockObject */ - private $customerSessionMock; - - /** @var CustomerRepositoryInterface|MockObject */ - private $customerRespositoryMock; - - /** @var CustomerInterface|MockObject */ - private $customerInterfaceMock; - - /** - * @var OrderAdapterInterface|MockObject - */ - private $orderMock; - - /** @var AttributeInterface|MockObject */ - private $attributeInterfaceMock; - - protected function setUp() { - $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); - - $this->paymentDataObjectMock = $this->getMockBuilder(PaymentDataObjectInterface::class) - ->disableOriginalConstructor() - ->setMethods(['getPayment']) - ->getMockForAbstractClass(); - - $this->configMock = $this->getMockBuilder(Config::class) - ->disableOriginalConstructor() - ->setMethods(['getCurrency']) - ->getMock(); - - $this->paymentMock = $this->getMockBuilder(Payment::class) - ->disableOriginalConstructor() - ->setMethods([ - 'getAdditionalInformation', - 'getCcNumber', - 'getCcExpMonth', - 'getCcExpYear', - 'getCcCid' - ]) - ->getMock(); - - $this->subjectReaderMock = $this->getMockBuilder(SubjectReader::class) - ->disableOriginalConstructor() - ->getMock(); - - $this->customerSessionMock = $this->getMockBuilder(Session::class) - ->disableOriginalConstructor() - ->getMock(); - - $this->customerRespositoryMock = $this->getMockBuilder(CustomerRepositoryInterface::class) - ->getMockForAbstractClass(); - - $this->customerInterfaceMock = $this->getMockBuilder(CustomerInterface::class) - ->getMockForAbstractClass(); - - $this->attributeInterfaceMock = $this->getMockBuilder(AttributeInterface::class) - ->getMockForAbstractClass(); - - $this->orderMock = $this->createMock(OrderAdapterInterface::class); - - $this->builder = $objectManager->getObject( - PaymentDataBuilder::class, - [ - 'subjectReader' => $this->subjectReaderMock, - 'config' => $this->configMock, - 'customerRepository' => $this->customerRespositoryMock, - 'customerSession' => $this->customerSessionMock - ] - ); - } - - /** - * @expectedException \InvalidArgumentException - */ - public function testBuildReadPaymentException() { - $buildSubject = []; - - $this->subjectReaderMock->expects($this->once()) - ->method('readPayment') - ->with($buildSubject) - ->willThrowException(new \InvalidArgumentException()); - - $this->builder->build($buildSubject); - } - - /** - * @expectedException \InvalidArgumentException - */ - public function testBuildReadAmountException() { - $buildSubject = [ - 'payment' => $this->paymentDataObjectMock, - 'amount' => null - ]; - - $this->subjectReaderMock->expects($this->once()) - ->method('readPayment') - ->with($buildSubject) - ->willReturn($this->paymentDataObjectMock); - $this->subjectReaderMock->expects($this->once()) - ->method('readAmount') - ->willReturn($buildSubject) - ->willThrowException(new \InvalidArgumentException()); - - $this->builder->build($buildSubject); - } - - public function testBuildWithToken() { - $expectedResult = [ - PaymentDataBuilder::AMOUNT => $this->formatPrice(10.00), - PaymentDataBuilder::ORDER_ID => '000000101', - PaymentDataBuilder::CURRENCY => 'USD', - PaymentDataBuilder::SOURCE => 'token_number', - PaymentDataBuilder::CAPTURE => 'false' - ]; - - $buildSubject = [ - 'payment' => $this->paymentDataObjectMock, - 'amount' => 10.00 - ]; - - $this->subjectReaderMock->expects($this->once()) - ->method('readPayment') - ->willReturn($this->paymentDataObjectMock); - - $this->subjectReaderMock->expects($this->once()) - ->method('readAmount') - ->willReturn(10.00); - - $this->paymentMock->expects($this->at(0)) - ->method('getAdditionalInformation') - ->with('cc_token') - ->willReturn('token_number'); - - $this->paymentMock->expects($this->at(1)) - ->method('getAdditionalInformation') - ->with('is_active_payment_token_enabler') - ->willReturn(false); - - $this->paymentDataObjectMock->expects($this->any()) - ->method('getPayment') - ->willReturn($this->paymentMock); - - $this->paymentDataObjectMock->expects($this->once()) - ->method('getOrder') - ->willReturn($this->orderMock); - - $this->orderMock->expects($this->once()) - ->method('getOrderIncrementId') - ->willReturn('000000101'); - - $this->configMock->expects($this->once()) - ->method('getCurrency') - ->willReturn('USD'); - - $this->assertEquals( - $expectedResult, - $this->builder->build($buildSubject) - ); - } - - public function testBuildWithCardData() { - $expectedResult = [ - PaymentDataBuilder::AMOUNT => $this->formatPrice(10.00), - PaymentDataBuilder::ORDER_ID => '000000101', - PaymentDataBuilder::CURRENCY => 'USD', - PaymentDataBuilder::SOURCE => [ - 'exp_month' => '01', - 'exp_year' => '18', - 'number' => '4111111111111111', - 'object' => 'card', - 'cvc' => '123' - ], - PaymentDataBuilder::CAPTURE => 'false' - ]; - - $buildSubject = [ - 'payment' => $this->paymentDataObjectMock, - 'amount' => 10.00 - ]; - - $this->subjectReaderMock->expects($this->once()) - ->method('readPayment') - ->willReturn($this->paymentDataObjectMock); - - $this->subjectReaderMock->expects($this->once()) - ->method('readAmount') - ->willReturn(10.00); - - $this->paymentMock->expects($this->once()) - ->method('getCcNumber') - ->willReturn('4111111111111111'); - - $this->paymentMock->expects($this->once()) - ->method('getCcExpMonth') - ->willReturn('01'); - - $this->paymentMock->expects($this->once()) - ->method('getCcExpYear') - ->willReturn('18'); - - $this->paymentMock->expects($this->once()) - ->method('getCcCid') - ->willReturn('123'); - - $this->paymentMock->expects($this->at(0)) - ->method('getAdditionalInformation') - ->with('cc_token') - ->willReturn(null); - - $this->paymentDataObjectMock->expects($this->any()) - ->method('getPayment') - ->willReturn($this->paymentMock); - - $this->paymentDataObjectMock->expects($this->once()) - ->method('getOrder') - ->willReturn($this->orderMock); - - $this->orderMock->expects($this->once()) - ->method('getOrderIncrementId') - ->willReturn('000000101'); - - $this->configMock->expects($this->once()) - ->method('getCurrency') - ->willReturn('USD'); - - $this->assertEquals( - $expectedResult, - $this->builder->build($buildSubject) - ); - } - - public function testBuildWithSavePayment() { - $expectedResult = [ - PaymentDataBuilder::AMOUNT => $this->formatPrice(10.00), - PaymentDataBuilder::ORDER_ID => '000000101', - PaymentDataBuilder::CURRENCY => 'USD', - PaymentDataBuilder::SOURCE => 'token_number', - PaymentDataBuilder::CAPTURE => 'false', - PaymentDataBuilder::CUSTOMER => 'cus_token', - PaymentDataBuilder::SAVE_IN_VAULT => true - ]; - - $buildSubject = [ - 'payment' => $this->paymentDataObjectMock, - 'amount' => 10.00 - ]; - - $this->subjectReaderMock->expects($this->once()) - ->method('readPayment') - ->with($buildSubject) - ->willReturn($this->paymentDataObjectMock); - - $this->paymentDataObjectMock->expects($this->once()) - ->method('getPayment') - ->willReturn($this->paymentMock); - - $this->paymentDataObjectMock->expects($this->once()) - ->method('getOrder') - ->willReturn($this->orderMock); - - $this->subjectReaderMock->expects($this->once()) - ->method('readAmount') - ->willReturn(10.00); - - $this->orderMock->expects($this->once()) - ->method('getOrderIncrementId') - ->willReturn('000000101'); - - $this->configMock->expects($this->once()) - ->method('getCurrency') - ->willReturn('USD'); - - $this->paymentMock->expects($this->at(0)) - ->method('getAdditionalInformation') - ->with('cc_token') - ->willReturn('token_number'); - - $this->paymentMock->expects($this->at(1)) - ->method('getAdditionalInformation') - ->with('is_active_payment_token_enabler') - ->willReturn(true); - - $this->customerRespositoryMock->expects($this->once()) - ->method('getById') - ->willReturn($this->customerInterfaceMock); - - $this->customerSessionMock->expects($this->once()) - ->method('getCustomerId') - ->willReturn(1); - - $this->customerInterfaceMock->expects($this->once()) - ->method('getCustomAttribute') - ->willReturn($this->attributeInterfaceMock); - - $this->attributeInterfaceMock->expects($this->once()) - ->method('getValue') - ->willReturn('cus_token'); - - $this->assertEquals( - $expectedResult, - $this->builder->build($buildSubject) - ); - } -} \ No newline at end of file + use Formatter; + + /** + * @var PaymentDataBuilder + */ + private $builder; + + /** + * @var Config|MockObject + */ + private $configMock; + + /** + * @var Payment|MockObject + */ + private $paymentMock; + + /** + * @var PaymentDataObjectInterface|MockObject + */ + private $paymentDataObjectMock; + + /** + * @var SubjectReader|MockObject + */ + private $subjectReaderMock; + + /** @var Session|MockObject */ + private $customerSessionMock; + + /** @var CustomerRepositoryInterface|MockObject */ + private $customerRespositoryMock; + + /** @var CustomerInterface|MockObject */ + private $customerInterfaceMock; + + /** + * @var OrderAdapterInterface|MockObject + */ + private $orderMock; + + /** @var AttributeInterface|MockObject */ + private $attributeInterfaceMock; + + protected function setUp() + { + $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); + + $this->paymentDataObjectMock = $this->getMockBuilder(PaymentDataObjectInterface::class) + ->disableOriginalConstructor() + ->setMethods(['getPayment']) + ->getMockForAbstractClass(); + + $this->configMock = $this->getMockBuilder(Config::class) + ->disableOriginalConstructor() + ->setMethods(['getCurrency']) + ->getMock(); + + $this->paymentMock = $this->getMockBuilder(Payment::class) + ->disableOriginalConstructor() + ->setMethods([ + 'getAdditionalInformation', + 'getCcNumber', + 'getCcExpMonth', + 'getCcExpYear', + 'getCcCid' + ]) + ->getMock(); + + $this->subjectReaderMock = $this->getMockBuilder(SubjectReader::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->customerSessionMock = $this->getMockBuilder(Session::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->customerRespositoryMock = $this->getMockBuilder(CustomerRepositoryInterface::class) + ->getMockForAbstractClass(); + + $this->customerInterfaceMock = $this->getMockBuilder(CustomerInterface::class) + ->getMockForAbstractClass(); + + $this->attributeInterfaceMock = $this->getMockBuilder(AttributeInterface::class) + ->getMockForAbstractClass(); + + $this->orderMock = $this->createMock(OrderAdapterInterface::class); + + $this->builder = $objectManager->getObject( + PaymentDataBuilder::class, + [ + 'subjectReader' => $this->subjectReaderMock, + 'config' => $this->configMock, + 'customerRepository' => $this->customerRespositoryMock, + 'customerSession' => $this->customerSessionMock + ] + ); + } + + /** + * @expectedException \InvalidArgumentException + */ + public function testBuildReadPaymentException() + { + $buildSubject = []; + + $this->subjectReaderMock->expects($this->once()) + ->method('readPayment') + ->with($buildSubject) + ->willThrowException(new \InvalidArgumentException()); + + $this->builder->build($buildSubject); + } + + /** + * @expectedException \InvalidArgumentException + */ + public function testBuildReadAmountException() + { + $buildSubject = [ + 'payment' => $this->paymentDataObjectMock, + 'amount' => null + ]; + + $this->subjectReaderMock->expects($this->once()) + ->method('readPayment') + ->with($buildSubject) + ->willReturn($this->paymentDataObjectMock); + $this->subjectReaderMock->expects($this->once()) + ->method('readAmount') + ->willReturn($buildSubject) + ->willThrowException(new \InvalidArgumentException()); + + $this->builder->build($buildSubject); + } + + public function testBuildWithToken() + { + $expectedResult = [ + PaymentDataBuilder::AMOUNT => $this->formatPrice(10.00), + PaymentDataBuilder::ORDER_ID => '000000101', + PaymentDataBuilder::CURRENCY => 'USD', + PaymentDataBuilder::SOURCE => 'token_number', + PaymentDataBuilder::CAPTURE => 'false' + ]; + + $buildSubject = [ + 'payment' => $this->paymentDataObjectMock, + 'amount' => 10.00 + ]; + + $this->subjectReaderMock->expects($this->once()) + ->method('readPayment') + ->willReturn($this->paymentDataObjectMock); + + $this->subjectReaderMock->expects($this->once()) + ->method('readAmount') + ->willReturn(10.00); + + $this->paymentMock->expects($this->at(0)) + ->method('getAdditionalInformation') + ->with('cc_token') + ->willReturn('token_number'); + + $this->paymentMock->expects($this->at(1)) + ->method('getAdditionalInformation') + ->with('is_active_payment_token_enabler') + ->willReturn(false); + + $this->paymentDataObjectMock->expects($this->any()) + ->method('getPayment') + ->willReturn($this->paymentMock); + + $this->paymentDataObjectMock->expects($this->once()) + ->method('getOrder') + ->willReturn($this->orderMock); + + $this->orderMock->expects($this->once()) + ->method('getOrderIncrementId') + ->willReturn('000000101'); + + $this->configMock->expects($this->once()) + ->method('getCurrency') + ->willReturn('USD'); + + $this->assertEquals( + $expectedResult, + $this->builder->build($buildSubject) + ); + } + + public function testBuildWithSavePayment() + { + $expectedResult = [ + PaymentDataBuilder::AMOUNT => $this->formatPrice(10.00), + PaymentDataBuilder::ORDER_ID => '000000101', + PaymentDataBuilder::CURRENCY => 'USD', + PaymentDataBuilder::SOURCE => 'token_number', + PaymentDataBuilder::CAPTURE => 'false', + PaymentDataBuilder::CUSTOMER => 'cus_token', + PaymentDataBuilder::SAVE_IN_VAULT => true + ]; + + $buildSubject = [ + 'payment' => $this->paymentDataObjectMock, + 'amount' => 10.00 + ]; + + $this->subjectReaderMock->expects($this->once()) + ->method('readPayment') + ->with($buildSubject) + ->willReturn($this->paymentDataObjectMock); + + $this->paymentDataObjectMock->expects($this->once()) + ->method('getPayment') + ->willReturn($this->paymentMock); + + $this->paymentDataObjectMock->expects($this->once()) + ->method('getOrder') + ->willReturn($this->orderMock); + + $this->subjectReaderMock->expects($this->once()) + ->method('readAmount') + ->willReturn(10.00); + + $this->orderMock->expects($this->once()) + ->method('getOrderIncrementId') + ->willReturn('000000101'); + + $this->configMock->expects($this->once()) + ->method('getCurrency') + ->willReturn('USD'); + + $this->paymentMock->expects($this->at(0)) + ->method('getAdditionalInformation') + ->with('cc_token') + ->willReturn('token_number'); + + $this->paymentMock->expects($this->at(1)) + ->method('getAdditionalInformation') + ->with('is_active_payment_token_enabler') + ->willReturn(true); + + $this->customerRespositoryMock->expects($this->once()) + ->method('getById') + ->willReturn($this->customerInterfaceMock); + + $this->customerSessionMock->expects($this->once()) + ->method('getCustomerId') + ->willReturn(1); + + $this->customerInterfaceMock->expects($this->once()) + ->method('getCustomAttribute') + ->willReturn($this->attributeInterfaceMock); + + $this->attributeInterfaceMock->expects($this->once()) + ->method('getValue') + ->willReturn('cus_token'); + + $this->assertEquals( + $expectedResult, + $this->builder->build($buildSubject) + ); + } +} diff --git a/Test/Unit/Gateway/Request/RefundDataBuilderTest.php b/Test/Unit/Gateway/Request/RefundDataBuilderTest.php index 07fb9a4..2dfd620 100755 --- a/Test/Unit/Gateway/Request/RefundDataBuilderTest.php +++ b/Test/Unit/Gateway/Request/RefundDataBuilderTest.php @@ -13,6 +13,7 @@ * @copyright Copyright (c) 2017-2018 * @license Open Software License (OSL 3.0) */ + namespace Pmclain\Stripe\Test\Unit\Gateway\Request; use Pmclain\Stripe\Gateway\Helper\SubjectReader; @@ -25,86 +26,95 @@ class RefundDataBuilderTest extends \PHPUnit\Framework\TestCase { - use Formatter; + use Formatter; - /** - * @var SubjectReader|\PHPUnit_Framework_MockObject_MockObject - */ - private $subjectReader; + /** + * @var SubjectReader|\PHPUnit_Framework_MockObject_MockObject + */ + private $subjectReader; - /** - * @var RefundDataBuilder - */ - private $dataBuilder; + /** + * @var RefundDataBuilder + */ + private $dataBuilder; - public function setUp() { - $this->subjectReader = $this->getMockBuilder(SubjectReader::class) - ->disableOriginalConstructor() - ->getMock(); + public function setUp() + { + $this->subjectReader = $this->getMockBuilder(SubjectReader::class) + ->disableOriginalConstructor() + ->getMock(); - $this->dataBuilder = new RefundDataBuilder($this->subjectReader); - } + $this->dataBuilder = new RefundDataBuilder($this->subjectReader); + } - public function testBuild() { - $paymentDataObject = $this->createMock(PaymentDataObjectInterface::class); - $paymentMock = $this->getMockBuilder(Payment::class) - ->disableOriginalConstructor() - ->getMock(); + public function testBuild() + { + $paymentDataObject = $this->createMock(PaymentDataObjectInterface::class); + $paymentMock = $this->getMockBuilder(Payment::class) + ->disableOriginalConstructor() + ->getMock(); - $buildSubject = [ - 'payment' => $paymentDataObject, - 'amount' => 10.00, - ]; - $transactionId = 'ch_19RZmz2eZvKYlo2CktQObIT0'; + $buildSubject = [ + 'payment' => $paymentDataObject, + 'amount' => 10.00, + ]; + $transactionId = 'ch_19RZmz2eZvKYlo2CktQObIT0'; - $this->subjectReader->expects($this->once()) - ->method('readPayment') - ->with($buildSubject) - ->willReturn($paymentDataObject); - $paymentDataObject->expects($this->once()) - ->method('getPayment') - ->willReturn($paymentMock); - $paymentMock->expects($this->once()) - ->method('getParentTransactionId') - ->willReturn($transactionId); - $this->subjectReader->expects($this->once()) - ->method('readAmount') - ->willReturn($buildSubject) - ->willReturn($buildSubject['amount']); + $this->subjectReader->expects($this->once()) + ->method('readPayment') + ->with($buildSubject) + ->willReturn($paymentDataObject); + $paymentDataObject->expects($this->once()) + ->method('getPayment') + ->willReturn($paymentMock); + $paymentMock->expects($this->once()) + ->method('getParentTransactionId') + ->willReturn($transactionId); + $this->subjectReader->expects($this->once()) + ->method('readAmount') + ->willReturn($buildSubject) + ->willReturn($buildSubject['amount']); - $this->assertEquals( - ['transaction_id' => $transactionId, PaymentDataBuilder::AMOUNT => $this->formatPrice(10.00)], - $this->dataBuilder->build($buildSubject) - ); - } + $this->assertEquals( + [ + 'transaction_id' => $transactionId, + PaymentDataBuilder::AMOUNT => $this->formatPrice(10.00) + ], + $this->dataBuilder->build($buildSubject) + ); + } - public function testBuildNullAmount() { - $paymentDataObject = $this->createMock(PaymentDataObjectInterface::class); - $paymentMock = $this->getMockBuilder(Payment::class) - ->disableOriginalConstructor() - ->getMock(); + public function testBuildNullAmount() + { + $paymentDataObject = $this->createMock(PaymentDataObjectInterface::class); + $paymentMock = $this->getMockBuilder(Payment::class) + ->disableOriginalConstructor() + ->getMock(); - $buildSubject = ['payment' => $paymentDataObject]; - $transactionId = 'ch_19RZmz2eZvKYlo2CktQObIT0'; + $buildSubject = ['payment' => $paymentDataObject]; + $transactionId = 'ch_19RZmz2eZvKYlo2CktQObIT0'; - $this->subjectReader->expects($this->once()) - ->method('readPayment') - ->with($buildSubject) - ->willReturn($paymentDataObject); - $paymentDataObject->expects($this->once()) - ->method('getPayment') - ->willReturn($paymentMock); - $paymentMock->expects($this->once()) - ->method('getParentTransactionId') - ->willReturn($transactionId); - $this->subjectReader->expects($this->once()) - ->method('readAmount') - ->with($buildSubject) - ->willThrowException(new \InvalidArgumentException()); + $this->subjectReader->expects($this->once()) + ->method('readPayment') + ->with($buildSubject) + ->willReturn($paymentDataObject); + $paymentDataObject->expects($this->once()) + ->method('getPayment') + ->willReturn($paymentMock); + $paymentMock->expects($this->once()) + ->method('getParentTransactionId') + ->willReturn($transactionId); + $this->subjectReader->expects($this->once()) + ->method('readAmount') + ->with($buildSubject) + ->willThrowException(new \InvalidArgumentException()); - $this->assertEquals( - ['transaction_id' => $transactionId, PaymentDataBuilder::AMOUNT => null], - $this->dataBuilder->build($buildSubject) - ); - } -} \ No newline at end of file + $this->assertEquals( + [ + 'transaction_id' => $transactionId, + PaymentDataBuilder::AMOUNT => null + ], + $this->dataBuilder->build($buildSubject) + ); + } +} diff --git a/Test/Unit/Gateway/Request/SettlementDataBuilderTest.php b/Test/Unit/Gateway/Request/SettlementDataBuilderTest.php index 9efe642..3d0e81f 100755 --- a/Test/Unit/Gateway/Request/SettlementDataBuilderTest.php +++ b/Test/Unit/Gateway/Request/SettlementDataBuilderTest.php @@ -13,17 +13,19 @@ * @copyright Copyright (c) 2017-2018 * @license Open Software License (OSL 3.0) */ + namespace Pmclain\Stripe\Test\Unit\Gateway\Request; use Pmclain\Stripe\Gateway\Request\SettlementDataBuilder; class SettlementDataBuilderTest extends \PHPUnit\Framework\TestCase { - public function testBuild() { - $builder = new SettlementDataBuilder(); - $this->assertEquals( - [SettlementDataBuilder::SUBMIT_FOR_SETTLEMENT => true], - $builder->build([]) - ); - } -} \ No newline at end of file + public function testBuild() + { + $builder = new SettlementDataBuilder(); + $this->assertEquals( + [SettlementDataBuilder::SUBMIT_FOR_SETTLEMENT => true], + $builder->build([]) + ); + } +} diff --git a/Test/Unit/Gateway/Request/VoidDataBuilderTest.php b/Test/Unit/Gateway/Request/VoidDataBuilderTest.php index 0461590..2239bbc 100755 --- a/Test/Unit/Gateway/Request/VoidDataBuilderTest.php +++ b/Test/Unit/Gateway/Request/VoidDataBuilderTest.php @@ -13,6 +13,7 @@ * @copyright Copyright (c) 2017-2018 * @license Open Software License (OSL 3.0) */ + namespace Pmclain\Stripe\Test\Unit\Gateway\Request; use Pmclain\Stripe\Gateway\Request\VoidDataBuilder; @@ -22,61 +23,64 @@ class VoidDataBuilderTest extends \PHPUnit\Framework\TestCase { - /** - * @var VoidDataBuilder - */ - private $builder; + /** + * @var VoidDataBuilder + */ + private $builder; - /** - * @var SubjectReader|\PHPUnit_Framework_MockObject_MockObject - */ - private $subjectReader; + /** + * @var SubjectReader|\PHPUnit_Framework_MockObject_MockObject + */ + private $subjectReader; - protected function setUp() { - $this->subjectReader = $this->getMockBuilder(SubjectReader::class) - ->disableOriginalConstructor() - ->getMock(); + protected function setUp() + { + $this->subjectReader = $this->getMockBuilder(SubjectReader::class) + ->disableOriginalConstructor() + ->getMock(); - $this->builder = new VoidDataBuilder($this->subjectReader); - } + $this->builder = new VoidDataBuilder($this->subjectReader); + } - /** - * - * @dataProvider testBuildDataProvider - */ - public function testBuild($parentTransId, $lastTransId) { - $paymentDataObject = $this->createMock(PaymentDataObjectInterface::class); - $buildSubject = ['payment' => $paymentDataObject]; - $paymentMock = $this->getMockBuilder(Payment::class) - ->disableOriginalConstructor() - ->getMock(); + /** + * + * @dataProvider testBuildDataProvider + */ + public function testBuild($parentTransId, $lastTransId) + { + $paymentDataObject = $this->createMock(PaymentDataObjectInterface::class); + $buildSubject = ['payment' => $paymentDataObject]; + $paymentMock = $this->getMockBuilder(Payment::class) + ->disableOriginalConstructor() + ->getMock(); - $this->subjectReader->expects($this->once()) - ->method('readPayment') - ->with($buildSubject) - ->willReturn($paymentDataObject); - $paymentDataObject->expects($this->once()) - ->method('getPayment') - ->willReturn($paymentMock); - $paymentMock->expects($this->once()) - ->method('getParentTransactionId') - ->willReturn($parentTransId); - if(!$parentTransId) { - $paymentMock->expects($this->once()) - ->method('getLastTransId') - ->willReturn($lastTransId); - } + $this->subjectReader->expects($this->once()) + ->method('readPayment') + ->with($buildSubject) + ->willReturn($paymentDataObject); + $paymentDataObject->expects($this->once()) + ->method('getPayment') + ->willReturn($paymentMock); + $paymentMock->expects($this->once()) + ->method('getParentTransactionId') + ->willReturn($parentTransId); + if (!$parentTransId) { + $paymentMock->expects($this->once()) + ->method('getLastTransId') + ->willReturn($lastTransId); + } - $this->assertEquals( - ['transaction_id' => $parentTransId?:$lastTransId], - $this->builder->build($buildSubject) - ); - } + $this->assertEquals( + ['transaction_id' => $parentTransId ?: $lastTransId], + $this->builder->build($buildSubject) + ); + } - public function testBuildDataProvider() { - return [ - ['ch_19RZmz2eZvKYlo2CktQObIT0', null], - [false, 'ch_19RZmz2eZvKYlo2CktQObIT0'] - ]; - } -} \ No newline at end of file + public function testBuildDataProvider() + { + return [ + ['ch_19RZmz2eZvKYlo2CktQObIT0', null], + [false, 'ch_19RZmz2eZvKYlo2CktQObIT0'] + ]; + } +} diff --git a/Test/Unit/Gateway/Response/CardDetailsHandlerTest.php b/Test/Unit/Gateway/Response/CardDetailsHandlerTest.php index dd90684..364218c 100755 --- a/Test/Unit/Gateway/Response/CardDetailsHandlerTest.php +++ b/Test/Unit/Gateway/Response/CardDetailsHandlerTest.php @@ -13,6 +13,7 @@ * @copyright Copyright (c) 2017-2018 * @license Open Software License (OSL 3.0) */ + namespace Pmclain\Stripe\Test\Unit\Gateway\Response; use Pmclain\Stripe\Gateway\Response\CardDetailsHandler; @@ -23,90 +24,96 @@ class CardDetailsHandlerTest extends \PHPUnit\Framework\TestCase { - /** @var CardDetailsHandler */ - private $cardHandler; - - /** @var Payment|\PHPUnit_Framework_MockObject_MockObject */ - private $payment; - - /** @var Config|\PHPUnit_Framework_MockObject_MockObject */ - private $config; - - /** @var SubjectReader|\PHPUnit_Framework_MockObject_MockObject */ - private $subjectReader; - - protected function setUp() { - $this->initConfigMock(); - $this->subjectReader = $this->getMockBuilder(SubjectReader::class) - ->disableOriginalConstructor() - ->getMock(); - - $this->cardHandler = new CardDetailsHandler($this->config, $this->subjectReader); - } - - public function testHandle() { - $paymentData = $this->getPaymentDataObjectMock(); - $transaction = $this->getStripeTransaction(); - - $subject = ['payment' => $paymentData]; - $response = ['object' => $transaction]; - - $this->subjectReader->expects($this->once()) - ->method('readPayment') - ->with($subject) - ->willReturn($paymentData); - $this->subjectReader->expects($this->once()) - ->method('readTransaction') - ->with($response) - ->willReturn($transaction); - - $this->cardHandler->handle($subject, $response); - } - - private function initConfigMock() { - $this->config = $this->getMockBuilder(Config::class) - ->disableOriginalConstructor() - ->getMock(); - } - - private function getPaymentDataObjectMock() { - $this->payment = $this->getMockBuilder(Payment::class) - ->disableOriginalConstructor() - ->setMethods([ - 'setCcLast4', - 'setCcExpMonth', - 'setCcExpYear', - 'setCcType', - 'setAdditionalInformation' - ]) - ->getMock(); - $paymentDataObject = $this->getMockBuilder(PaymentDataObject::class) - ->disableOriginalConstructor() - ->setMethods(['getPayment']) - ->getMock(); - - $paymentDataObject->expects($this->once()) - ->method('getPayment') - ->willReturn($this->payment); - - return $paymentDataObject; - } - - private function getStripeTransaction() { - $source = $this->getMockBuilder(\stdClass::class) - ->setMethods(['__toArray']) - ->getMock(); - $source->expects($this->once()) - ->method('__toArray') - ->willReturn([ - 'brand' => 'Visa', - 'last4' => '1234', - 'exp_month' => '01', - 'exp_year' => '18' - ]); - - $transaction = ['source' => $source]; - - return $transaction; - } -} \ No newline at end of file + /** @var CardDetailsHandler */ + private $cardHandler; + + /** @var Payment|\PHPUnit_Framework_MockObject_MockObject */ + private $payment; + + /** @var Config|\PHPUnit_Framework_MockObject_MockObject */ + private $config; + + /** @var SubjectReader|\PHPUnit_Framework_MockObject_MockObject */ + private $subjectReader; + + protected function setUp() + { + $this->initConfigMock(); + $this->subjectReader = $this->getMockBuilder(SubjectReader::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->cardHandler = new CardDetailsHandler($this->config, + $this->subjectReader); + } + + public function testHandle() + { + $paymentData = $this->getPaymentDataObjectMock(); + $transaction = $this->getStripeTransaction(); + + $subject = ['payment' => $paymentData]; + $response = ['object' => $transaction]; + + $this->subjectReader->expects($this->once()) + ->method('readPayment') + ->with($subject) + ->willReturn($paymentData); + $this->subjectReader->expects($this->once()) + ->method('readTransaction') + ->with($response) + ->willReturn($transaction); + + $this->cardHandler->handle($subject, $response); + } + + private function initConfigMock() + { + $this->config = $this->getMockBuilder(Config::class) + ->disableOriginalConstructor() + ->getMock(); + } + + private function getPaymentDataObjectMock() + { + $this->payment = $this->getMockBuilder(Payment::class) + ->disableOriginalConstructor() + ->setMethods([ + 'setCcLast4', + 'setCcExpMonth', + 'setCcExpYear', + 'setCcType', + 'setAdditionalInformation' + ]) + ->getMock(); + $paymentDataObject = $this->getMockBuilder(PaymentDataObject::class) + ->disableOriginalConstructor() + ->setMethods(['getPayment']) + ->getMock(); + + $paymentDataObject->expects($this->once()) + ->method('getPayment') + ->willReturn($this->payment); + + return $paymentDataObject; + } + + private function getStripeTransaction() + { + $source = $this->getMockBuilder(\stdClass::class) + ->setMethods(['__toArray']) + ->getMock(); + $source->expects($this->once()) + ->method('__toArray') + ->willReturn([ + 'brand' => 'Visa', + 'last4' => '1234', + 'exp_month' => '01', + 'exp_year' => '18' + ]); + + $transaction = ['source' => $source]; + + return $transaction; + } +} diff --git a/Test/Unit/Gateway/Response/PaymentDetailsHandlerTest.php b/Test/Unit/Gateway/Response/PaymentDetailsHandlerTest.php index 5edb9e1..e9494a9 100755 --- a/Test/Unit/Gateway/Response/PaymentDetailsHandlerTest.php +++ b/Test/Unit/Gateway/Response/PaymentDetailsHandlerTest.php @@ -13,6 +13,7 @@ * @copyright Copyright (c) 2017-2018 * @license Open Software License (OSL 3.0) */ + namespace Pmclain\Stripe\Test\Unit\Gateway\Response; use Pmclain\Stripe\Gateway\Response\PaymentDetailsHandler; @@ -23,90 +24,94 @@ class PaymentDetailsHandlerTest extends \PHPUnit\Framework\TestCase { - const TRANSACTION_ID = 'txn_19PbvF2eZvKYlo2C0HCaOJw2'; - - /** @var PaymentDetailsHandler */ - private $paymentHandler; - - /** @var Payment|\PHPUnit_Framework_MockObject_MockObject */ - private $payment; - - /** @var SubjectReader|\PHPUnit_Framework_MockObject_MockObject */ - private $subjectReader; - - protected function setUp() { - $this->payment = $this->getMockBuilder(Payment::class) - ->disableOriginalConstructor() - ->setMethods([ - 'setCcTransId', - 'setLastTransId', - 'setAdditionalInformation' - ]) - ->getMock(); - $this->subjectReader = $this->getMockBuilder(SubjectReader::class) - ->disableOriginalConstructor() - ->getMock(); - - $this->payment->expects($this->once()) - ->method('setCcTransId'); - $this->payment->expects($this->once()) - ->method('setLastTransId'); - $this->payment->expects($this->any()) - ->method('setAdditionalInformation'); - - $this->paymentHandler = new PaymentDetailsHandler($this->subjectReader); - } - - public function testHandle() { - $paymentData = $this->getPaymentDataObject(); - $transaction = $this->getStripeTransaction(); - - $subject = ['payment' => $paymentData]; - $response = ['object' => $transaction]; - - $this->subjectReader->expects($this->once()) - ->method('readPayment') - ->with($subject) - ->willReturn($paymentData); - $this->subjectReader->expects($this->once()) - ->method('readTransaction') - ->with($response) - ->willReturn($transaction); - - $this->paymentHandler->handle($subject, $response); - } - - private function getPaymentDataObject() { - $paymentDataObject = $this->getMockBuilder(PaymentDataObject::class) - ->disableOriginalConstructor() - ->setMethods(['getPayment']) - ->getMock(); - - $paymentDataObject->expects($this->once()) - ->method('getPayment') - ->willReturn($this->payment); - - return $paymentDataObject; - } - - private function getStripeTransaction() { - $outcome = $this->getMockBuilder(\stdClass::class) - ->setMethods(['__toArray']) - ->getMock(); - $outcome->expects($this->once()) - ->method('__toArray') - ->willReturn([ - PaymentDetailsHandler::RISK_LEVEL => 'normal', - PaymentDetailsHandler::SELLER_MESSAGE => '', - PaymentDetailsHandler::CAPTURE => '', - PaymentDetailsHandler::TYPE => 'authorized' - ]); - - $transaction = [ - 'id' => 'ch_19RiLp2eZvKYlo2CjlqQlezC', - 'outcome' => $outcome - ]; - - return $transaction; - } -} \ No newline at end of file + const TRANSACTION_ID = 'txn_19PbvF2eZvKYlo2C0HCaOJw2'; + + /** @var PaymentDetailsHandler */ + private $paymentHandler; + + /** @var Payment|\PHPUnit_Framework_MockObject_MockObject */ + private $payment; + + /** @var SubjectReader|\PHPUnit_Framework_MockObject_MockObject */ + private $subjectReader; + + protected function setUp() + { + $this->payment = $this->getMockBuilder(Payment::class) + ->disableOriginalConstructor() + ->setMethods([ + 'setCcTransId', + 'setLastTransId', + 'setAdditionalInformation' + ]) + ->getMock(); + $this->subjectReader = $this->getMockBuilder(SubjectReader::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->payment->expects($this->once()) + ->method('setCcTransId'); + $this->payment->expects($this->once()) + ->method('setLastTransId'); + $this->payment->expects($this->any()) + ->method('setAdditionalInformation'); + + $this->paymentHandler = new PaymentDetailsHandler($this->subjectReader); + } + + public function testHandle() + { + $paymentData = $this->getPaymentDataObject(); + $transaction = $this->getStripeTransaction(); + + $subject = ['payment' => $paymentData]; + $response = ['object' => $transaction]; + + $this->subjectReader->expects($this->once()) + ->method('readPayment') + ->with($subject) + ->willReturn($paymentData); + $this->subjectReader->expects($this->once()) + ->method('readTransaction') + ->with($response) + ->willReturn($transaction); + + $this->paymentHandler->handle($subject, $response); + } + + private function getPaymentDataObject() + { + $paymentDataObject = $this->getMockBuilder(PaymentDataObject::class) + ->disableOriginalConstructor() + ->setMethods(['getPayment']) + ->getMock(); + + $paymentDataObject->expects($this->once()) + ->method('getPayment') + ->willReturn($this->payment); + + return $paymentDataObject; + } + + private function getStripeTransaction() + { + $outcome = $this->getMockBuilder(\stdClass::class) + ->setMethods(['__toArray']) + ->getMock(); + $outcome->expects($this->once()) + ->method('__toArray') + ->willReturn([ + PaymentDetailsHandler::RISK_LEVEL => 'normal', + PaymentDetailsHandler::SELLER_MESSAGE => '', + PaymentDetailsHandler::CAPTURE => '', + PaymentDetailsHandler::TYPE => 'authorized' + ]); + + $transaction = [ + 'id' => 'ch_19RiLp2eZvKYlo2CjlqQlezC', + 'outcome' => $outcome + ]; + + return $transaction; + } +} diff --git a/Test/Unit/Gateway/Response/RefundHandlerTest.php b/Test/Unit/Gateway/Response/RefundHandlerTest.php index 885d0aa..d1c9376 100755 --- a/Test/Unit/Gateway/Response/RefundHandlerTest.php +++ b/Test/Unit/Gateway/Response/RefundHandlerTest.php @@ -13,6 +13,7 @@ * @copyright Copyright (c) 2017-2018 * @license Open Software License (OSL 3.0) */ + namespace Pmclain\Stripe\Test\Unit\Gateway\Response; use Pmclain\Stripe\Gateway\Response\RefundHandler; @@ -23,38 +24,39 @@ class RefundHandlerTest extends \PHPUnit\Framework\TestCase { - public function testShouldCloseParentTransaction() { - $subjectReader = $this->getMockBuilder(SubjectReader::class) - ->disableOriginalConstructor() - ->getMock(); - $payment = $this->getMockBuilder(Payment::class) - ->disableOriginalConstructor() - ->setMethods(['getCreditmemo']) - ->getMock(); - $creditmemo = $this->getMockBuilder(Creditmemo::class) - ->disableOriginalConstructor() - ->setMethods(['getInvoice']) - ->getMock(); - $invoice = $this->getMockBuilder(Invoice::class) - ->disableOriginalConstructor() - ->setMethods(['canRefund']) - ->getMock(); + public function testShouldCloseParentTransaction() + { + $subjectReader = $this->getMockBuilder(SubjectReader::class) + ->disableOriginalConstructor() + ->getMock(); + $payment = $this->getMockBuilder(Payment::class) + ->disableOriginalConstructor() + ->setMethods(['getCreditmemo']) + ->getMock(); + $creditmemo = $this->getMockBuilder(Creditmemo::class) + ->disableOriginalConstructor() + ->setMethods(['getInvoice']) + ->getMock(); + $invoice = $this->getMockBuilder(Invoice::class) + ->disableOriginalConstructor() + ->setMethods(['canRefund']) + ->getMock(); - $invoice->expects($this->once()) - ->method('canRefund') - ->willReturn(true); - $creditmemo->expects($this->once()) - ->method('getInvoice') - ->willReturn($invoice); - $payment->expects($this->once()) - ->method('getCreditmemo') - ->willReturn($creditmemo); + $invoice->expects($this->once()) + ->method('canRefund') + ->willReturn(true); + $creditmemo->expects($this->once()) + ->method('getInvoice') + ->willReturn($invoice); + $payment->expects($this->once()) + ->method('getCreditmemo') + ->willReturn($creditmemo); - $handler = new RefundHandler($subjectReader); - $reflection = new \ReflectionClass(get_class($handler)); - $method = $reflection->getMethod('shouldCloseParentTransaction'); - $method->setAccessible(true); + $handler = new RefundHandler($subjectReader); + $reflection = new \ReflectionClass(get_class($handler)); + $method = $reflection->getMethod('shouldCloseParentTransaction'); + $method->setAccessible(true); - $this->assertFalse($method->invokeArgs($handler, [$payment])); - } -} \ No newline at end of file + $this->assertFalse($method->invokeArgs($handler, [$payment])); + } +} diff --git a/Test/Unit/Gateway/Response/TransactionHandlerTest.php b/Test/Unit/Gateway/Response/TransactionHandlerTest.php index 843bdc4..fb02835 100755 --- a/Test/Unit/Gateway/Response/TransactionHandlerTest.php +++ b/Test/Unit/Gateway/Response/TransactionHandlerTest.php @@ -13,6 +13,7 @@ * @copyright Copyright (c) 2017-2018 * @license Open Software License (OSL 3.0) */ + namespace Pmclain\Stripe\Test\Unit\Gateway\Response; use Pmclain\Stripe\Gateway\Response\TransactionIdHandler; @@ -22,42 +23,43 @@ class TransactionHandlerTest extends \PHPUnit\Framework\TestCase { - public function testHandle() { - $transactionId = 'ch_19Rjix2eZvKYlo2C5VFbcuXf'; - $paymentDataObject = $this->createMock(PaymentDataObjectInterface::class); - $paymentInfo = $this->getMockBuilder(Payment::class) - ->disableOriginalConstructor() - ->getMock(); + public function testHandle() + { + $transactionId = 'ch_19Rjix2eZvKYlo2C5VFbcuXf'; + $paymentDataObject = $this->createMock(PaymentDataObjectInterface::class); + $paymentInfo = $this->getMockBuilder(Payment::class) + ->disableOriginalConstructor() + ->getMock(); - $subject = ['payment' => $paymentDataObject]; - $response = ['object' => ['id' => $transactionId]]; + $subject = ['payment' => $paymentDataObject]; + $response = ['object' => ['id' => $transactionId]]; - $subjectReader = $this->getMockBuilder(SubjectReader::class) - ->disableOriginalConstructor() - ->getMock(); + $subjectReader = $this->getMockBuilder(SubjectReader::class) + ->disableOriginalConstructor() + ->getMock(); - $subjectReader->expects($this->once()) - ->method('readPayment') - ->with($subject) - ->willReturn($paymentDataObject); - $paymentDataObject->expects($this->atLeastOnce()) - ->method('getPayment') - ->willReturn($paymentInfo); - $subjectReader->expects($this->once()) - ->method('readTransaction') - ->with($response) - ->willReturn($response['object']); - $paymentInfo->expects($this->once()) - ->method('setTransactionId') - ->with($transactionId); - $paymentInfo->expects($this->once()) - ->method('setIsTransactionClosed') - ->with(false); - $paymentInfo->expects($this->once()) - ->method('setShouldCloseParentTransaction') - ->with(false); + $subjectReader->expects($this->once()) + ->method('readPayment') + ->with($subject) + ->willReturn($paymentDataObject); + $paymentDataObject->expects($this->atLeastOnce()) + ->method('getPayment') + ->willReturn($paymentInfo); + $subjectReader->expects($this->once()) + ->method('readTransaction') + ->with($response) + ->willReturn($response['object']); + $paymentInfo->expects($this->once()) + ->method('setTransactionId') + ->with($transactionId); + $paymentInfo->expects($this->once()) + ->method('setIsTransactionClosed') + ->with(false); + $paymentInfo->expects($this->once()) + ->method('setShouldCloseParentTransaction') + ->with(false); - $handler = new TransactionIdHandler($subjectReader); - $handler->handle($subject, $response); - } -} \ No newline at end of file + $handler = new TransactionIdHandler($subjectReader); + $handler->handle($subject, $response); + } +} diff --git a/Test/Unit/Gateway/Response/VaultDetailsHandlerTest.php b/Test/Unit/Gateway/Response/VaultDetailsHandlerTest.php index df49e6a..6408fcc 100644 --- a/Test/Unit/Gateway/Response/VaultDetailsHandlerTest.php +++ b/Test/Unit/Gateway/Response/VaultDetailsHandlerTest.php @@ -13,6 +13,7 @@ * @copyright Copyright (c) 2017-2018 * @license Open Software License (OSL 3.0) */ + namespace Pmclain\Stripe\Test\Unit\Gateway\Response; use Pmclain\Stripe\Gateway\Response\VaultDetailsHandler; @@ -30,149 +31,158 @@ class VaultDetailsHandlerTest extends \PHPUnit\Framework\TestCase { - /** @var PaymentDataObject|MockObject */ - private $paymentDataObjectMock; + /** @var PaymentDataObject|MockObject */ + private $paymentDataObjectMock; + + /** @var Charge|MockObject */ + private $chargeMock; + + /** @var SubjectReader|MockObject */ + private $subjectReaderMock; + + /** @var Card|MockObject */ + private $cardMock; + + /** @var Payment|MockObject */ + private $paymentMock; + + /** @var CreditCardTokenFactory|MockObject */ + private $paymentTokenFactoryMock; + + /** @var PaymentToken|MockObject */ + private $paymentTokenMock; + + /** @var Config|MockObject */ + private $configMock; + + /** @var OrderPaymentExtension|MockObject */ + private $extensionAttributeMock; + + /** @var OrderPaymentExtensionInterfaceFactory|MockObject */ + private $extensionAttributeFactoryMock; + + /** @var VaultDetailsHandler */ + private $handler; + + protected function setUp() + { + $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); + + $this->paymentDataObjectMock = $this->getMockBuilder(PaymentDataObject::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->chargeMock = $this->getMockBuilder(Charge::class) + ->getMock(); + + $this->subjectReaderMock = $this->getMockBuilder(SubjectReader::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->cardMock = $this->getMockBuilder(Card::class) + ->setMethods(['__toArray']) + ->getMock(); + + $this->paymentMock = $this->getMockBuilder(Payment::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->paymentTokenFactoryMock = $this->getMockBuilder(CreditCardTokenFactory::class) + ->disableOriginalConstructor() + ->setMethods(['create']) + ->getMock(); + + $this->paymentTokenMock = $this->getMockBuilder(PaymentToken::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->configMock = $this->getMockBuilder(Config::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->extensionAttributeMock = $this->getMockBuilder(OrderPaymentExtension::class) + ->disableOriginalConstructor() + ->setMethods(['setVaultPaymentToken']) + ->getmock(); - /** @var Charge|MockObject */ - private $chargeMock; + $this->extensionAttributeFactoryMock = $this->getMockBuilder(OrderPaymentExtensionInterfaceFactory::class) + ->disableOriginalConstructor() + ->getMock(); - /** @var SubjectReader|MockObject */ - private $subjectReaderMock; + $this->handler = $objectManager->getObject( + VaultDetailsHandler::class, + [ + 'subjectReader' => $this->subjectReaderMock, + 'paymentTokenFactory' => $this->paymentTokenFactoryMock, + 'config' => $this->configMock, + 'paymentExtensionFactory' => $this->extensionAttributeFactoryMock, + ] + ); + } - /** @var Card|MockObject */ - private $cardMock; + public function testHandle() + { + $handlingSubject = [ + 'payment' => $this->paymentDataObjectMock, + 'amount' => 10.00 + ]; - /** @var Payment|MockObject */ - private $paymentMock; + $response = [ + [$this->chargeMock] + ]; - /** @var CreditCardTokenFactory|MockObject */ - private $paymentTokenFactoryMock; + $this->subjectReaderMock->expects($this->once()) + ->method('readPayment') + ->with($handlingSubject) + ->willReturn($this->paymentDataObjectMock); - /** @var PaymentToken|MockObject */ - private $paymentTokenMock; - - /** @var Config|MockObject */ - private $configMock; - - /** @var OrderPaymentExtension|MockObject */ - private $extensionAttributeMock; - - /** @var OrderPaymentExtensionInterfaceFactory|MockObject */ - private $extensionAttributeFactoryMock; - - /** @var VaultDetailsHandler */ - private $handler; - - protected function setUp() { - $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); - - $this->paymentDataObjectMock = $this->getMockBuilder(PaymentDataObject::class) - ->disableOriginalConstructor() - ->getMock(); - - $this->chargeMock = $this->getMockBuilder(Charge::class) - ->getMock(); - - $this->subjectReaderMock = $this->getMockBuilder(SubjectReader::class) - ->disableOriginalConstructor() - ->getMock(); - - $this->cardMock = $this->getMockBuilder(Card::class) - ->setMethods(['__toArray']) - ->getMock(); - - $this->paymentMock = $this->getMockBuilder(Payment::class) - ->disableOriginalConstructor() - ->getMock(); - - $this->paymentTokenFactoryMock = $this->getMockBuilder(CreditCardTokenFactory::class) - ->disableOriginalConstructor() - ->setMethods(['create']) - ->getMock(); - - $this->paymentTokenMock = $this->getMockBuilder(PaymentToken::class) - ->disableOriginalConstructor() - ->getMock(); - - $this->configMock = $this->getMockBuilder(Config::class) - ->disableOriginalConstructor() - ->getMock(); - - $this->extensionAttributeMock = $this->getMockBuilder(OrderPaymentExtension::class) - ->disableOriginalConstructor() - ->setMethods(['setVaultPaymentToken']) - ->getmock(); - - $this->extensionAttributeFactoryMock = $this->getMockBuilder(OrderPaymentExtensionInterfaceFactory::class) - ->disableOriginalConstructor() - ->getMock(); - - $this->handler = $objectManager->getObject( - VaultDetailsHandler::class, - [ - 'subjectReader' => $this->subjectReaderMock, - 'paymentTokenFactory' => $this->paymentTokenFactoryMock, - 'config' => $this->configMock, - 'paymentExtensionFactory' => $this->extensionAttributeFactoryMock, - ] - ); - } - - public function testHandle() { - $handlingSubject = [ - 'payment' => $this->paymentDataObjectMock, - 'amount' => 10.00 - ]; - - $response = [ - [$this->chargeMock] - ]; - - $this->subjectReaderMock->expects($this->once()) - ->method('readPayment') - ->with($handlingSubject) - ->willReturn($this->paymentDataObjectMock); - - $this->subjectReaderMock->expects($this->once()) - ->method('readTransaction') - ->with($response) - ->willReturn(['source' => $this->cardMock]); - - $this->paymentDataObjectMock->expects($this->once()) - ->method('getPayment') - ->willReturn($this->paymentMock); - - $this->paymentMock->expects($this->once()) - ->method('getAdditionalInformation') - ->with('is_active_payment_token_enabler') - ->willReturn(true); - - $this->cardMock->expects($this->once()) - ->method('__toArray') - ->willReturn([ - 'id' => 'card_token', - 'brand' => 'Visa', - 'last4' => '4444', - 'exp_month' => '01', - 'exp_year' => '2018' - ]); - - $this->paymentTokenFactoryMock->expects($this->once()) - ->method('create') - ->willReturn($this->paymentTokenMock); - - $this->configMock->expects($this->once()) - ->method('getCcTypesMapper') - ->willReturn(['visa' => 'VI']); - - $this->paymentMock->expects($this->once()) - ->method('getExtensionAttributes') - ->willReturn($this->extensionAttributeMock); - - $this->extensionAttributeMock->expects($this->once()) - ->method('setVaultPaymentToken') - ->with($this->paymentTokenMock); - - $this->handler->handle($handlingSubject, $response); - } -} \ No newline at end of file + $this->subjectReaderMock->expects($this->once()) + ->method('readTransaction') + ->with($response) + ->willReturn(['source' => $this->cardMock]); + + $this->paymentDataObjectMock->expects($this->once()) + ->method('getPayment') + ->willReturn($this->paymentMock); + + $additionalInfo = [ + 'is_active_token_enabler' => true, + 'cc_src' => 'src_12323kjhlkh138', + ]; + + $this->paymentMock->method('getAdditionalInformation') + ->willReturn($this->returnCallback(function ($arg) use ($additionalInfo) { + return $additionalInfo[$arg]; + })); + + $this->paymentMock->method('getCcExpMonth') + ->willReturn('01'); + + $this->paymentMock->method('getCcExpYear') + ->willReturn(date('Y', strtotime('+2 years'))); + + $this->paymentMock->method('getCcType') + ->willReturn('Visa'); + + $this->paymentMock->method('getCcLast4') + ->willReturn('4444'); + + $this->paymentTokenFactoryMock->expects($this->once()) + ->method('create') + ->willReturn($this->paymentTokenMock); + + $this->configMock->expects($this->once()) + ->method('getCcTypesMapper') + ->willReturn(['visa' => 'VI']); + + $this->paymentMock->expects($this->once()) + ->method('getExtensionAttributes') + ->willReturn($this->extensionAttributeMock); + + $this->extensionAttributeMock->expects($this->once()) + ->method('setVaultPaymentToken') + ->with($this->paymentTokenMock); + + $this->handler->handle($handlingSubject, $response); + } +} diff --git a/Test/Unit/Gateway/Response/VoidHandlerTest.php b/Test/Unit/Gateway/Response/VoidHandlerTest.php index ef39af8..8bcd1e3 100755 --- a/Test/Unit/Gateway/Response/VoidHandlerTest.php +++ b/Test/Unit/Gateway/Response/VoidHandlerTest.php @@ -13,6 +13,7 @@ * @copyright Copyright (c) 2017-2018 * @license Open Software License (OSL 3.0) */ + namespace Pmclain\Stripe\Test\Unit\Gateway\Response; use Pmclain\Stripe\Gateway\Helper\SubjectReader; @@ -22,40 +23,41 @@ class VoidHandlerTest extends \PHPUnit\Framework\TestCase { - public function testHandle() { - $transactionId = 'ch_19Rjix2eZvKYlo2C5VFbcuXf'; - $paymentDataObject = $this->createMock(PaymentDataObjectInterface::class); - $payment = $this->getMockBuilder(Payment::class) - ->disableOriginalConstructor() - ->getMock(); - $subject = ['payment' => $paymentDataObject]; - $response = ['object' => ['id' => $transactionId]]; + public function testHandle() + { + $transactionId = 'ch_19Rjix2eZvKYlo2C5VFbcuXf'; + $paymentDataObject = $this->createMock(PaymentDataObjectInterface::class); + $payment = $this->getMockBuilder(Payment::class) + ->disableOriginalConstructor() + ->getMock(); + $subject = ['payment' => $paymentDataObject]; + $response = ['object' => ['id' => $transactionId]]; - $subjectReader = $this->getMockBuilder(SubjectReader::class) - ->disableOriginalConstructor() - ->getMock(); + $subjectReader = $this->getMockBuilder(SubjectReader::class) + ->disableOriginalConstructor() + ->getMock(); - $subjectReader->expects($this->once()) - ->method('readPayment') - ->with($subject) - ->willReturn($paymentDataObject); - $paymentDataObject->expects($this->atLeastOnce()) - ->method('getPayment') - ->willReturn($payment); - $subjectReader->expects($this->once()) - ->method('readTransaction') - ->with($response) - ->willReturn($response['object']); - $payment->expects($this->never()) - ->method('setTransactionId'); - $payment->expects($this->once()) - ->method('setIsTransactionClosed') - ->with(true); - $payment->expects($this->once()) - ->method('setShouldCloseParentTransaction') - ->with(true); + $subjectReader->expects($this->once()) + ->method('readPayment') + ->with($subject) + ->willReturn($paymentDataObject); + $paymentDataObject->expects($this->atLeastOnce()) + ->method('getPayment') + ->willReturn($payment); + $subjectReader->expects($this->once()) + ->method('readTransaction') + ->with($response) + ->willReturn($response['object']); + $payment->expects($this->never()) + ->method('setTransactionId'); + $payment->expects($this->once()) + ->method('setIsTransactionClosed') + ->with(true); + $payment->expects($this->once()) + ->method('setShouldCloseParentTransaction') + ->with(true); - $handler = new VoidHandler($subjectReader); - $handler->handle($subject, $response); - } -} \ No newline at end of file + $handler = new VoidHandler($subjectReader); + $handler->handle($subject, $response); + } +} diff --git a/Test/Unit/Gateway/Validator/GeneralResponseValidatorTest.php b/Test/Unit/Gateway/Validator/GeneralResponseValidatorTest.php index 8fce83f..337b016 100755 --- a/Test/Unit/Gateway/Validator/GeneralResponseValidatorTest.php +++ b/Test/Unit/Gateway/Validator/GeneralResponseValidatorTest.php @@ -13,6 +13,7 @@ * @copyright Copyright (c) 2017-2018 * @license Open Software License (OSL 3.0) */ + namespace Pmclain\Stripe\Test\Unit\Gateway\Validator; use Magento\Framework\Phrase; @@ -24,93 +25,94 @@ class GeneralResponseValidatorTest extends \PHPUnit\Framework\TestCase { - /** @var GeneralResponseValidator */ - private $responseValidator; + /** @var GeneralResponseValidator */ + private $responseValidator; - /** @var ResultInterfaceFactory|MockObject */ - private $resultInterfaceFactoryMock; + /** @var ResultInterfaceFactory|MockObject */ + private $resultInterfaceFactoryMock; - /** @var SubjectReader|MockObject */ - private $subjectReaderMock; + /** @var SubjectReader|MockObject */ + private $subjectReaderMock; - protected function setUp() { - $this->resultInterfaceFactoryMock = $this->getMockBuilder(ResultInterfaceFactory::class) - ->disableOriginalConstructor() - ->setMethods(['create']) - ->getMock(); - $this->subjectReaderMock = $this->getMockBuilder(SubjectReader::class) - ->disableOriginalConstructor() - ->getMock(); + protected function setUp() + { + $this->resultInterfaceFactoryMock = $this->getMockBuilder(ResultInterfaceFactory::class) + ->disableOriginalConstructor() + ->setMethods(['create']) + ->getMock(); + $this->subjectReaderMock = $this->getMockBuilder(SubjectReader::class) + ->disableOriginalConstructor() + ->getMock(); - $this->responseValidator = new GeneralResponseValidator( - $this->resultInterfaceFactoryMock, - $this->subjectReaderMock - ); - } + $this->responseValidator = new GeneralResponseValidator( + $this->resultInterfaceFactoryMock, + $this->subjectReaderMock + ); + } - /** - * Run test for validate method - * - * @param array $validationSubject - * @param bool $isValid - * @param Phrase[] $messages - * @return void - * - * @dataProvider dataProviderTestValidate - */ - public function testValidate(array $validationSubject, $isValid, $messages) - { - /** @var ResultInterface|MockObject $resultMock */ - $resultMock = $this->createMock(ResultInterface::class); + /** + * Run test for validate method + * + * @param array $validationSubject + * @param bool $isValid + * @param Phrase[] $messages + * @return void + * + * @dataProvider dataProviderTestValidate + */ + public function testValidate(array $validationSubject, $isValid, $messages) + { + /** @var ResultInterface|MockObject $resultMock */ + $resultMock = $this->createMock(ResultInterface::class); - $this->subjectReaderMock->expects($this->once()) - ->method('readResponseObject') - ->with($validationSubject) - ->willReturn($validationSubject['response']['object']); + $this->subjectReaderMock->expects($this->once()) + ->method('readResponseObject') + ->with($validationSubject) + ->willReturn($validationSubject['response']['object']); - $this->resultInterfaceFactoryMock->expects($this->once()) - ->method('create') - ->with([ - 'isValid' => $isValid, - 'failsDescription' => $messages - ]) - ->willReturn($resultMock); + $this->resultInterfaceFactoryMock->expects($this->once()) + ->method('create') + ->with([ + 'isValid' => $isValid, + 'failsDescription' => $messages + ]) + ->willReturn($resultMock); - $actualMock = $this->responseValidator->validate($validationSubject); + $actualMock = $this->responseValidator->validate($validationSubject); - $this->assertEquals($resultMock, $actualMock); - } + $this->assertEquals($resultMock, $actualMock); + } - /** - * @return array - */ - public function dataProviderTestValidate() - { - return [ - [ - 'validationSubject' => [ - 'response' => [ - 'object' => [ - 'status' => 'succeeded' - ] - ], - ], - 'isValid' => true, - [] - ], - [ - 'validationSubject' => [ - 'response' => [ - 'object' => [ - 'status' => 'failed' + /** + * @return array + */ + public function dataProviderTestValidate() + { + return [ + [ + 'validationSubject' => [ + 'response' => [ + 'object' => [ + 'status' => 'succeeded' + ] + ], + ], + 'isValid' => true, + [] + ], + [ + 'validationSubject' => [ + 'response' => [ + 'object' => [ + 'status' => 'failed' + ] + ] + ], + 'isValid' => false, + [ + __('Stripe error response.') + ] ] - ] - ], - 'isValid' => false, - [ - __('Stripe error response.') - ] - ] - ]; - } -} \ No newline at end of file + ]; + } +} diff --git a/Test/Unit/Gateway/Validator/ResponseValidator/AuthorizeTest.php b/Test/Unit/Gateway/Validator/ResponseValidator/AuthorizeTest.php index e827943..22cf7ab 100755 --- a/Test/Unit/Gateway/Validator/ResponseValidator/AuthorizeTest.php +++ b/Test/Unit/Gateway/Validator/ResponseValidator/AuthorizeTest.php @@ -13,6 +13,7 @@ * @copyright Copyright (c) 2017-2018 * @license Open Software License (OSL 3.0) */ + namespace Pmclain\Stripe\Test\Unit\Gateway\Validator\ResponseValidator; use Magento\Framework\Phrase; @@ -24,90 +25,91 @@ class AuthorizeTest extends \PHPUnit\Framework\TestCase { - /** @var Authorize */ - private $responseValidator; + /** @var Authorize */ + private $responseValidator; - /** @var ResultInterfaceFactory|MockObject */ - private $resultInterfaceFactoryMock; + /** @var ResultInterfaceFactory|MockObject */ + private $resultInterfaceFactoryMock; - /** @var SubjectReader|MockObject */ - private $subjectReaderMock; + /** @var SubjectReader|MockObject */ + private $subjectReaderMock; - protected function setUp() { - $this->resultInterfaceFactoryMock = $this->getMockBuilder(ResultInterfaceFactory::class) - ->disableOriginalConstructor() - ->setMethods(['create']) - ->getMock(); - $this->subjectReaderMock = $this->getMockBuilder(SubjectReader::class) - ->disableOriginalConstructor() - ->getMock(); + protected function setUp() + { + $this->resultInterfaceFactoryMock = $this->getMockBuilder(ResultInterfaceFactory::class) + ->disableOriginalConstructor() + ->setMethods(['create']) + ->getMock(); + $this->subjectReaderMock = $this->getMockBuilder(SubjectReader::class) + ->disableOriginalConstructor() + ->getMock(); - $this->responseValidator = new Authorize( - $this->resultInterfaceFactoryMock, - $this->subjectReaderMock - ); - } + $this->responseValidator = new Authorize( + $this->resultInterfaceFactoryMock, + $this->subjectReaderMock + ); + } - /** - * Run test for validate method - * - * @param array $validationSubject - * @param bool $isValid - * @param Phrase[] $messages - * @return void - * - * @dataProvider dataProviderTestValidate - */ - public function testValidate(array $response, $isValid, $messages) - { - /** @var ResultInterface|MockObject $resultMock */ - $resultMock = $this->createMock(ResultInterface::class); - $outcome = $this->getMockBuilder(\stdClass::class) - ->setMethods(['__toArray']) - ->getMock(); - $outcome->expects($this->once()) - ->method('__toArray') - ->willReturn($response); + /** + * Run test for validate method + * + * @param array $validationSubject + * @param bool $isValid + * @param Phrase[] $messages + * @return void + * + * @dataProvider dataProviderTestValidate + */ + public function testValidate(array $response, $isValid, $messages) + { + /** @var ResultInterface|MockObject $resultMock */ + $resultMock = $this->createMock(ResultInterface::class); + $outcome = $this->getMockBuilder(\stdClass::class) + ->setMethods(['__toArray']) + ->getMock(); + $outcome->expects($this->once()) + ->method('__toArray') + ->willReturn($response); - $validationSubject = [ - 'status' => 'succeeded', - 'outcome' => $outcome - ]; + $validationSubject = [ + 'status' => 'succeeded', + 'outcome' => $outcome + ]; - $this->subjectReaderMock->expects($this->once()) - ->method('readResponseObject') - ->with($validationSubject) - ->willReturn($validationSubject); + $this->subjectReaderMock->expects($this->once()) + ->method('readResponseObject') + ->with($validationSubject) + ->willReturn($validationSubject); - $this->resultInterfaceFactoryMock->expects($this->once()) - ->method('create') - ->with([ - 'isValid' => $isValid, - 'failsDescription' => $messages - ]) - ->willReturn($resultMock); + $this->resultInterfaceFactoryMock->expects($this->once()) + ->method('create') + ->with([ + 'isValid' => $isValid, + 'failsDescription' => $messages + ]) + ->willReturn($resultMock); - $actualMock = $this->responseValidator->validate($validationSubject); + $actualMock = $this->responseValidator->validate($validationSubject); - $this->assertEquals($resultMock, $actualMock); - } + $this->assertEquals($resultMock, $actualMock); + } - /** - * @return array - */ - public function dataProviderTestValidate() - { - return [ - [ - ['network_status' => 'approved_by_network'], - 'isValid' => true, - [] - ], - [ - ['network_status' => 'declined_by_network'], - 'isValid' => false, - [__('Transaction has been declined')] - ] - ]; - } -} \ No newline at end of file + /** + * @return array + */ + public function dataProviderTestValidate() + { + return [ + [ + ['network_status' => 'approved_by_network'], + 'isValid' => true, + [] + ], + [ + ['network_status' => 'declined_by_network'], + 'isValid' => false, + [__('Transaction has been declined')] + ] + ]; + } +} diff --git a/Test/Unit/Gateway/Validator/ResponseValidatorTest.php b/Test/Unit/Gateway/Validator/ResponseValidatorTest.php index c320582..30aa14f 100755 --- a/Test/Unit/Gateway/Validator/ResponseValidatorTest.php +++ b/Test/Unit/Gateway/Validator/ResponseValidatorTest.php @@ -13,6 +13,7 @@ * @copyright Copyright (c) 2017-2018 * @license Open Software License (OSL 3.0) */ + namespace Pmclain\Stripe\Test\Unit\Gateway\Validator; use Magento\Payment\Gateway\Validator\ResultInterface; @@ -23,116 +24,120 @@ class ResponseValidatorTest extends \PHPUnit\Framework\TestCase { - /** @var ResponseValidator */ - private $responseValidator; - - /** @var ResultInterfaceFactory|MockObject */ - private $resultInterFaceFactory; - - /** @var SubjectReader|MockObject */ - private $subjectReader; - - protected function setUp() { - $this->resultInterfaceFactory = $this->getMockBuilder(ResultInterfaceFactory::class) - ->disableOriginalConstructor() - ->setMethods(['create']) - ->getMock(); - $this->subjectReader = $this->getMockBuilder(SubjectReader::class) - ->disableOriginalConstructor() - ->getMock(); - - $this->responseValidator = new ResponseValidator( - $this->resultInterfaceFactory, - $this->subjectReader - ); - } - - /** @expectedException \InvalidArgumentException */ - public function testValidateReadResponseException() { - $subject = ['response' => null]; - - $this->subjectReader->expects($this->once()) - ->method('readResponseObject') - ->with($subject) - ->willThrowException(new \InvalidArgumentException()); - - $this->responseValidator->validate($subject); - } - - /** @expectedException \InvalidArgumentException */ - public function testValidateReadResponseObjectException() { - $subject = ['reponse' => ['object' => null]]; - - $this->subjectReader->expects($this->once()) - ->method('readResponseObject') - ->with($subject) - ->willThrowException(new \InvalidArgumentException()); - - $this->responseValidator->validate($subject); - } - - /** - * Run test for validate method - * - * @param array $validationSubject - * @param bool $isValid - * @param Phrase[] $messages - * @return void - * - * @dataProvider dataProviderTestValidate - */ - public function testValidate(array $validationSubject, $isValid, $messages) - { - /** @var ResultInterface|MockObject $result */ - $result = $this->createMock(ResultInterface::class); - - $this->subjectReader->expects($this->once()) - ->method('readResponseObject') - ->with($validationSubject) - ->willReturn($validationSubject['response']['object']); - - $this->resultInterfaceFactory->expects($this->once()) - ->method('create') - ->with([ - 'isValid' => $isValid, - 'failsDescription' => $messages - ]) - ->willReturn($result); - - $actual = $this->responseValidator->validate($validationSubject); - - $this->assertEquals($result, $actual); - } - - public function dataProviderTestValidate() { - $succeed = ['object' => ['status' => 'succeeded']]; - $pending = ['object' => ['status' => 'pending']]; - $failed = ['object' => ['status' => 'failed']]; - $invalid = ['object' => ['status' => null]]; - - return [ - [ - ['response' => $succeed], - 'isValid' => true, - [] - ], - [ - ['response' => $pending], - 'isValid' => false, - [__('Stripe error response.')] - ], - [ - ['response' => $failed], - 'isValid' => false, - [__('Stripe error response.')], - ], - [ - ['response' => $invalid], - 'isValid' => false, - [ - __('Stripe error response.') - ] - ] - ]; - } + /** @var ResponseValidator */ + private $responseValidator; + + /** @var ResultInterfaceFactory|MockObject */ + private $resultInterFaceFactory; + + /** @var SubjectReader|MockObject */ + private $subjectReader; + + protected function setUp() + { + $this->resultInterfaceFactory = $this->getMockBuilder(ResultInterfaceFactory::class) + ->disableOriginalConstructor() + ->setMethods(['create']) + ->getMock(); + $this->subjectReader = $this->getMockBuilder(SubjectReader::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->responseValidator = new ResponseValidator( + $this->resultInterfaceFactory, + $this->subjectReader + ); + } + + /** @expectedException \InvalidArgumentException */ + public function testValidateReadResponseException() + { + $subject = ['response' => null]; + + $this->subjectReader->expects($this->once()) + ->method('readResponseObject') + ->with($subject) + ->willThrowException(new \InvalidArgumentException()); + + $this->responseValidator->validate($subject); + } + + /** @expectedException \InvalidArgumentException */ + public function testValidateReadResponseObjectException() + { + $subject = ['reponse' => ['object' => null]]; + + $this->subjectReader->expects($this->once()) + ->method('readResponseObject') + ->with($subject) + ->willThrowException(new \InvalidArgumentException()); + + $this->responseValidator->validate($subject); + } + + /** + * Run test for validate method + * + * @param array $validationSubject + * @param bool $isValid + * @param Phrase[] $messages + * @return void + * + * @dataProvider dataProviderTestValidate + */ + public function testValidate(array $validationSubject, $isValid, $messages) + { + /** @var ResultInterface|MockObject $result */ + $result = $this->createMock(ResultInterface::class); + + $this->subjectReader->expects($this->once()) + ->method('readResponseObject') + ->with($validationSubject) + ->willReturn($validationSubject['response']['object']); + + $this->resultInterfaceFactory->expects($this->once()) + ->method('create') + ->with([ + 'isValid' => $isValid, + 'failsDescription' => $messages + ]) + ->willReturn($result); + + $actual = $this->responseValidator->validate($validationSubject); + + $this->assertEquals($result, $actual); + } + + public function dataProviderTestValidate() + { + $succeed = ['object' => ['status' => 'succeeded']]; + $pending = ['object' => ['status' => 'pending']]; + $failed = ['object' => ['status' => 'failed']]; + $invalid = ['object' => ['status' => null]]; + + return [ + [ + ['response' => $succeed], + 'isValid' => true, + [] + ], + [ + ['response' => $pending], + 'isValid' => false, + [__('Stripe error response.')] + ], + [ + ['response' => $failed], + 'isValid' => false, + [__('Stripe error response.')], + ], + [ + ['response' => $invalid], + 'isValid' => false, + [ + __('Stripe error response.') + ] + ] + ]; + } } diff --git a/Test/Unit/Helper/CcTypeTest.php b/Test/Unit/Helper/CcTypeTest.php index 82cc2bc..211df67 100755 --- a/Test/Unit/Helper/CcTypeTest.php +++ b/Test/Unit/Helper/CcTypeTest.php @@ -13,6 +13,7 @@ * @copyright Copyright (c) 2017-2018 * @license Open Software License (OSL 3.0) */ + namespace Pmclain\Stripe\Test\Unit\Helper; use Pmclain\Stripe\Model\Adminhtml\Source\Cctype as CcTypeSource; @@ -21,38 +22,41 @@ class CcTypeTest extends \PHPUnit\Framework\TestCase { - /** @var ObjectManager */ - private $objectManager; - - /** @var CcType */ - private $helper; - - /** @var CcTypeSource|\PHPUnit_Framework_MockObject_MockObject */ - private $ccTypeSource; - - protected function setUp() { - $this->objectManager = new ObjectManager($this); - - $this->ccTypeSource = $this->getMockBuilder(CcTypeSource::class) - ->disableOriginalConstructor() - ->setMethods(['toOptionArray']) - ->getMock(); - - $this->helper = $this->objectManager->getObject( - CcType::class, - ['ccTypeSource' => $this->ccTypeSource] - ); - } - - public function testGetCcTypes() { - $this->ccTypeSource->expects($this->once()) - ->method('toOptionArray') - ->willReturn([ - 'label' => 'Visa', 'value' => 'VI' - ]); - $this->helper->getCcTypes(); - $this->ccTypeSource->expects($this->never()) - ->method('toOptionArray'); - $this->helper->getCcTypes(); - } + /** @var ObjectManager */ + private $objectManager; + + /** @var CcType */ + private $helper; + + /** @var CcTypeSource|\PHPUnit_Framework_MockObject_MockObject */ + private $ccTypeSource; + + protected function setUp() + { + $this->objectManager = new ObjectManager($this); + + $this->ccTypeSource = $this->getMockBuilder(CcTypeSource::class) + ->disableOriginalConstructor() + ->setMethods(['toOptionArray']) + ->getMock(); + + $this->helper = $this->objectManager->getObject( + CcType::class, + ['ccTypeSource' => $this->ccTypeSource] + ); + } + + public function testGetCcTypes() + { + $this->ccTypeSource->expects($this->once()) + ->method('toOptionArray') + ->willReturn([ + 'label' => 'Visa', + 'value' => 'VI' + ]); + $this->helper->getCcTypes(); + $this->ccTypeSource->expects($this->never()) + ->method('toOptionArray'); + $this->helper->getCcTypes(); + } } diff --git a/Test/Unit/Helper/Payment/FormatterTest.php b/Test/Unit/Helper/Payment/FormatterTest.php index 8acdd16..38804ea 100755 --- a/Test/Unit/Helper/Payment/FormatterTest.php +++ b/Test/Unit/Helper/Payment/FormatterTest.php @@ -13,29 +13,32 @@ * @copyright Copyright (c) 2017-2018 * @license Open Software License (OSL 3.0) */ + namespace Pmclain\Stripe\Test\Unit\Helper\Payment; use Pmclain\Stripe\Helper\Payment\Formatter; class FormatterTest extends \PHPUnit\Framework\TestCase { - use Formatter; + use Formatter; - /** - * @param $subject int|float - * @param $expectedResult int - * @dataProvider testFormatPriceDataProvider - */ - public function testFormatPrice($subject, $expectedResult) { - $this->assertEquals($this->formatPrice($subject), $expectedResult); - } + /** + * @param $subject int|float + * @param $expectedResult int + * @dataProvider testFormatPriceDataProvider + */ + public function testFormatPrice($subject, $expectedResult) + { + $this->assertEquals($this->formatPrice($subject), $expectedResult); + } - public function testFormatPriceDataProvider() { - return [ - [1, 100], - [.1, 10], - [25.73, 2573], - [10, 1000], - ]; - } -} \ No newline at end of file + public function testFormatPriceDataProvider() + { + return [ + [1, 100], + [.1, 10], + [25.73, 2573], + [10, 1000], + ]; + } +} diff --git a/composer.json b/composer.json index d776783..1d025b9 100755 --- a/composer.json +++ b/composer.json @@ -4,9 +4,9 @@ "type": "magento2-module", "license": "OSL-3.0", "require": { - "php": "~5.5.0|~5.6.0|~7.0.0|~7.1.0", - "magento/framework": "~100.1.0|~101.0.0", - "stripe/stripe-php": "~5.8.0" + "php": "~7.0.0||~7.1.0", + "magento/framework": "~100.1.0||~101.0.0||~100.3.0-dev", + "stripe/stripe-php": "~6.3.0" }, "autoload": { "files": [ diff --git a/etc/adminhtml/system.xml b/etc/adminhtml/system.xml index ef19aad..8f3a28d 100755 --- a/etc/adminhtml/system.xml +++ b/etc/adminhtml/system.xml @@ -42,18 +42,30 @@ <field id="test_secret_key" translate="label" type="obscure" sortOrder="50" showInDefault="1" showInWebsite="1" showInStore="0"> <label>Test Secret Key</label> <backend_model>Magento\Config\Model\Config\Backend\Encrypted</backend_model> + <depends> + <field id="test_mode">1</field> + </depends> </field> <field id="test_publishable_key" translate="label" type="obscure" sortOrder="60" showInDefault="1" showInWebsite="1" showInStore="0"> <label>Test Publishable Key</label> <backend_model>Magento\Config\Model\Config\Backend\Encrypted</backend_model> + <depends> + <field id="test_mode">1</field> + </depends> </field> <field id="live_secret_key" translate="label" type="obscure" sortOrder="70" showInDefault="1" showInWebsite="1" showInStore="0"> <label>Live Secret Key</label> <backend_model>Magento\Config\Model\Config\Backend\Encrypted</backend_model> + <depends> + <field id="test_mode">0</field> + </depends> </field> <field id="live_publishable_key" translate="label" type="obscure" sortOrder="80" showInDefault="1" showInWebsite="1" showInStore="0"> <label>Live Publishable Key</label> <backend_model>Magento\Config\Model\Config\Backend\Encrypted</backend_model> + <depends> + <field id="test_mode">0</field> + </depends> </field> <field id="currency" translate="label" type="select" sortOrder="90" showInDefault="1" showInWebsite="1" showInStore="0"> <label>Accepted Currency</label> @@ -84,13 +96,21 @@ <label>Payment from Specific Countries</label> <source_model>Magento\Directory\Model\Config\Source\Country</source_model> </field> - <field id="min_order_total" translate="label" type="text" sortOrder="140" showInDefault="1" showInWebsite="1" showInStore="0"> + <field id="verify_3dsecure" translate="label" type="select" sortOrder="140" showInDefault="1" showInWebsite="1" showInStore="0"> + <label>3D Secure Verification</label> + <source_model>Magento\Config\Model\Config\Source\Yesno</source_model> + </field> + <field id="threshold_amount" translate="label comment" type="text" sortOrder="150" showInDefault="1" showInWebsite="1" showInStore="0"> + <label>Threshold Amount</label> + <comment>Minimum amount to require 3D secure verification.</comment> + </field> + <field id="min_order_total" translate="label" type="text" sortOrder="160" showInDefault="1" showInWebsite="1" showInStore="0"> <label>Minimum Order Total</label> </field> - <field id="max_order_total" translate="label" type="text" sortOrder="150" showInDefault="1" showInWebsite="1" showInStore="0"> + <field id="max_order_total" translate="label" type="text" sortOrder="170" showInDefault="1" showInWebsite="1" showInStore="0"> <label>Maximum Order Total</label> </field> - <field id="sort_order" translate="label" type="text" sortOrder="160" showInDefault="1" showInWebsite="1" showInStore="0"> + <field id="sort_order" translate="label" type="text" sortOrder="180" showInDefault="1" showInWebsite="1" showInStore="0"> <label>Sort Order</label> <frontend_class>validate-number</frontend_class> </field> diff --git a/etc/config.xml b/etc/config.xml index 83c1899..aba4958 100755 --- a/etc/config.xml +++ b/etc/config.xml @@ -22,6 +22,7 @@ <model>StripeFacade</model> <payment_action>authorize</payment_action> <active>0</active> + <title>Stripe Credit Card 1 1 1 @@ -42,10 +43,19 @@ processing 0 + USD + 1 + + + + + 0 + 0.00 StripeCreditCardVaultFacade Stored Cards (Stripe) + 1 1 diff --git a/etc/di.xml b/etc/di.xml index 16354c5..5b45466 100755 --- a/etc/di.xml +++ b/etc/di.xml @@ -139,6 +139,7 @@ Pmclain\Stripe\Gateway\Request\PaymentDataBuilder + Pmclain\Stripe\Gateway\Request\ThreeDSecureBuilder Pmclain\Stripe\Gateway\Request\AddressDataBuilder @@ -192,6 +193,7 @@ Pmclain\Stripe\Gateway\Request\PaymentDataBuilder\Vault + Pmclain\Stripe\Gateway\Request\ThreeDSecureBuilder Pmclain\Stripe\Gateway\Request\AddressDataBuilder @@ -250,7 +252,6 @@ Pmclain\Stripe\Gateway\Response\PaymentDetailsHandler Pmclain\Stripe\Gateway\Response\TransactionIdHandler - Pmclain\Stripe\Gateway\Response\CardDetailsHandler Pmclain\Stripe\Gateway\Response\VaultDetailsHandler @@ -260,8 +261,6 @@ Pmclain\Stripe\Gateway\Response\PaymentDetailsHandler Pmclain\Stripe\Gateway\Response\TransactionIdHandler - Pmclain\Stripe\Gateway\Response\CardDetailsHandler - diff --git a/etc/events.xml b/etc/events.xml index db8556e..d396b44 100755 --- a/etc/events.xml +++ b/etc/events.xml @@ -16,7 +16,10 @@ */ --> - + + + + diff --git a/etc/frontend/events.xml b/etc/frontend/events.xml new file mode 100755 index 0000000..712a145 --- /dev/null +++ b/etc/frontend/events.xml @@ -0,0 +1,22 @@ + + + + + + + \ No newline at end of file diff --git a/etc/frontend/routes.xml b/etc/frontend/routes.xml new file mode 100644 index 0000000..c40d069 --- /dev/null +++ b/etc/frontend/routes.xml @@ -0,0 +1,24 @@ + + + + + + + + + diff --git a/view/frontend/web/js/action/save-payment-information.js b/view/frontend/web/js/action/save-payment-information.js new file mode 100644 index 0000000..2ba43c5 --- /dev/null +++ b/view/frontend/web/js/action/save-payment-information.js @@ -0,0 +1,32 @@ +/** + * @api + */ +define([ + 'Magento_Checkout/js/model/quote', + 'Magento_Checkout/js/model/url-builder', + 'Magento_Customer/js/model/customer', + 'Pmclain_Stripe/js/model/save-payment-information' +], function (quote, urlBuilder, customer, savePaymentService) { + 'use strict'; + + return function (paymentData, messageContainer) { + var serviceUrl, payload; + + payload = { + cartId: quote.getQuoteId(), + billingAddress: quote.billingAddress(), + paymentMethod: paymentData + }; + + if (customer.isLoggedIn()) { + serviceUrl = urlBuilder.createUrl('/carts/mine/set-payment-information', {}); + } else { + serviceUrl = urlBuilder.createUrl('/guest-carts/:quoteId/set-payment-information', { + quoteId: quote.getQuoteId() + }); + payload.email = quote.guestEmail; + } + + return savePaymentService(serviceUrl, payload, messageContainer); + }; +}); diff --git a/view/frontend/web/js/model/save-payment-information.js b/view/frontend/web/js/model/save-payment-information.js new file mode 100644 index 0000000..84c6a45 --- /dev/null +++ b/view/frontend/web/js/model/save-payment-information.js @@ -0,0 +1,29 @@ +/** + * @api + */ +define( + [ + 'mage/storage', + 'Magento_Checkout/js/model/error-processor', + 'Magento_Checkout/js/model/full-screen-loader' + ], + function (storage, errorProcessor, fullScreenLoader) { + 'use strict'; + + return function (serviceUrl, payload, messageContainer) { + fullScreenLoader.startLoader(); + + return storage.post( + serviceUrl, JSON.stringify(payload) + ).fail( + function (response) { + errorProcessor.process(response, messageContainer); + } + ).always( + function () { + fullScreenLoader.stopLoader(); + } + ); + }; + } +); diff --git a/view/frontend/web/js/view/payment/method-renderer/pmclain_stripe.js b/view/frontend/web/js/view/payment/method-renderer/pmclain_stripe.js index 0004fc6..ed343bf 100755 --- a/view/frontend/web/js/view/payment/method-renderer/pmclain_stripe.js +++ b/view/frontend/web/js/view/payment/method-renderer/pmclain_stripe.js @@ -3,24 +3,30 @@ define( 'jquery', 'Magento_Payment/js/view/payment/cc-form', 'Magento_Checkout/js/action/place-order', + 'Pmclain_Stripe/js/action/save-payment-information', 'Magento_Checkout/js/model/full-screen-loader', 'Magento_Checkout/js/model/payment/additional-validators', 'Magento_Payment/js/model/credit-card-validation/validator', 'Magento_Checkout/js/action/redirect-on-success', 'Magento_Vault/js/view/payment/vault-enabler', 'Magento_Checkout/js/model/quote', + 'Magento_Ui/js/modal/alert', + 'Magento_Customer/js/customer-data', 'https://js.stripe.com/v3/' ], function ( $, Component, placeOrderAction, + savePaymentAction, fullScreenLoader, additionalValidators, validator, redirectOnSuccessAction, VaultEnabler, - quote + quote, + alert, + customerData ) { 'use strict'; @@ -30,7 +36,9 @@ define( stripe: null, stripeCardElement: null, stripeCard: null, - token: null + token: null, + source: null, + threeDSource: null }, initialize: function() { @@ -56,7 +64,7 @@ define( placeOrder: function(data, event) { var self = this, - placeOrder; + deferred; if (event) { event.preventDefault(); @@ -66,16 +74,18 @@ define( this.isPlaceOrderActionAllowed(false); fullScreenLoader.startLoader(); - $.when(this.createToken()).done(function() { - placeOrder = placeOrderAction(self.getData(), self.messageContainer); - $.when(placeOrder).done(function() { - if (self.redirectAfterPlaceOrder) { - redirectOnSuccessAction.execute(); - } - }).fail(function() { - fullScreenLoader.stopLoader(); - self.isPlaceOrderActionAllowed(true); - }); + if (this.requireThreeDSecure()) { + deferred = this.createSource(); + } else { + deferred = this.createToken(); + } + + $.when(deferred).done(function(result) { + if (result.hasOwnProperty('redirect')) { + return true; + } + + self._placeOrder(); }).fail(function(result) { fullScreenLoader.stopLoader(); self.isPlaceOrderActionAllowed(true); @@ -90,21 +100,104 @@ define( return false; }, - createToken: function() { - var self = this; + _placeOrder: function() { + var self = this, + placeOrder = placeOrderAction(self.getData(), self.messageContainer); - var deffer = $.Deferred(); + $.when(placeOrder).done(function() { + if (self.redirectAfterPlaceOrder) { + redirectOnSuccessAction.execute(); + } + }).fail(function() { + fullScreenLoader.stopLoader(); + self.isPlaceOrderActionAllowed(true); + }); + }, + + createToken: function() { + var self = this, + defer = $.Deferred(); self.stripe.createToken(self.stripeCard, this.getAddressData()).then(function(response) { if (response.error) { - deffer.reject(response.error.message); + defer.reject(response.error.message); }else { self.token = response.token; - deffer.resolve(); + defer.resolve({}); } }); - return deffer.promise(); + return defer.promise(); + }, + + createSource: function () { + var self = this, + savePayment, + defer = $.Deferred(); + + self.stripe.createSource(self.stripeCard, this.getOwnerData()).then(function(response) { + if (response.error) { + defer.reject(response.error.message); + return; + } + + self.source = response.source; + + $.when(self.createThreeDSource(self.source)).done(function (response) { + if (response.error) { + defer.reject(response.error.message); + return; + } + + self.threeDSource = response.source; + if (self.threeDSource.status !== 'pending') { + defer.resolve({}); + return; + } + + savePayment = savePaymentAction(self.getData(), self.messageContainer); + + $.when(savePayment).done(function () { + defer.resolve({redirect: true}); + fullScreenLoader.stopLoader(); + alert({ + title: $.mage.__('Additional Payment Verification Required'), + content: $.mage.__('Your card issue has requested additional verification before completing your order. You will be redirected to the issuer\'s website after closing this notification.'), + actions: { + always: function() { + customerData.invalidate(['cart']); + window.location = response.source.redirect.url; + } + } + }); + }).fail(function () { + defer.reject($.mage.__('An error occurred on the server. Please try again.')); + }); + }); + }); + + return defer.promise(); + }, + + createThreeDSource: function(source) { + var self = this, + defer = $.Deferred(); + + self.stripe.createSource({ + type: 'three_d_secure', + amount: quote.totals().base_grand_total * 100, + currency: quote.totals().base_currency_code, + three_d_secure: { + card: source.id + }, + redirect: { + return_url: this.getThreeDRedirectUrl() + } + }).then(function(response) { + defer.resolve(response); + }); + + return defer.promise(); }, getCode: function() { @@ -119,13 +212,9 @@ define( var data = this._super(); if (this.token) { - var card = this.token.card; - - data.additional_data.cc_exp_month = card.exp_month; - data.additional_data.cc_exp_year = card.exp_year; - data.additional_data.cc_last4 = card.last4; - data.additional_data.cc_type = card.brand; - data.additional_data.cc_token = this.token.id; + data = this.getTokenData(data); + } else if (this.source) { + data = this.getSourceData(data); } this.vaultEnabler.visitAdditionalData(data); @@ -133,6 +222,35 @@ define( return data; }, + getSourceData: function (data) { + var card = this.source.card; + + data.additional_data.cc_exp_month = card.exp_month; + data.additional_data.cc_exp_year = card.exp_year; + data.additional_data.cc_last4 = card.last4; + data.additional_data.cc_type = card.brand; + data.additional_data.cc_src = this.source.id; + + if (this.threeDSource) { + data.additional_data.three_d_src = this.threeDSource.id; + data.additional_data.three_d_client_secret = this.threeDSource.client_secret; + } + + return data; + }, + + getTokenData: function (data) { + var card = this.token.card; + + data.additional_data.cc_exp_month = card.exp_month; + data.additional_data.cc_exp_year = card.exp_year; + data.additional_data.cc_last4 = card.last4; + data.additional_data.cc_type = card.brand; + data.additional_data.cc_token = this.token.id; + + return data; + }, + getPublishableKey: function () { return window.checkoutConfig.payment[this.getCode()].publishableKey; }, @@ -146,10 +264,53 @@ define( return this.vaultEnabler.isVaultEnabled(); }, + requireThreeDSecure: function () { + return window.checkoutConfig.payment[this.getCode()].threeDSecure && this.threeDThresholdMet(); + }, + + threeDSecureThreshold: function () { + return window.checkoutConfig.payment[this.getCode()].threeDThreshold; + }, + + threeDThresholdMet: function () { + return quote.totals().base_grand_total >= this.threeDSecureThreshold(); + }, + + getThreeDRedirectUrl: function() { + return window.checkoutConfig.payment[this.getCode()].threeDRedirectUrl; + }, + getVaultCode: function () { return window.checkoutConfig.payment[this.getCode()].vaultCode; }, + getOwnerData: function () { + var billingAddress = quote.billingAddress(), + ownerData = { + owner: { + name: billingAddress.firstname + ' ' + billingAddress.lastname, + address: { + line1: billingAddress.street[0], + country: billingAddress.countryId + } + } + }; + + if (billingAddress.street.length === 2) { + ownerData.owner.address.line2 = billingAddress.street[1]; + } + + if (billingAddress.hasOwnProperty('postcode')) { + ownerData.owner.address.postal_code = billingAddress.postcode; + } + + if (billingAddress.hasOwnProperty('regionCode')) { + ownerData.owner.address.state = billingAddress.regionCode; + } + + return ownerData; + }, + getAddressData: function () { var billingAddress = quote.billingAddress(); diff --git a/view/frontend/web/js/view/payment/method-renderer/vault.js b/view/frontend/web/js/view/payment/method-renderer/vault.js index b97ff42..7828d39 100644 --- a/view/frontend/web/js/view/payment/method-renderer/vault.js +++ b/view/frontend/web/js/view/payment/method-renderer/vault.js @@ -1,13 +1,133 @@ /*browser:true*/ /*global define*/ define([ - 'Magento_Vault/js/view/payment/method-renderer/vault' -], function (VaultComponent) { + 'jquery', + 'Magento_Vault/js/view/payment/method-renderer/vault', + 'Magento_Checkout/js/action/place-order', + 'Pmclain_Stripe/js/action/save-payment-information', + 'Magento_Checkout/js/model/full-screen-loader', + 'Magento_Checkout/js/action/redirect-on-success', + 'Magento_Checkout/js/model/quote', + 'Magento_Ui/js/modal/alert', + 'Magento_Customer/js/customer-data', + 'https://js.stripe.com/v3/' +], function ( + $, + VaultComponent, + placeOrderAction, + savePaymentAction, + fullScreenLoader, + redirectOnSuccessAction, + quote, + alert, + customerData +) { 'use strict'; return VaultComponent.extend({ defaults: { - template: 'Magento_Vault/payment/form' + template: 'Magento_Vault/payment/form', + stripe: null, + threeDSource: null + }, + + initialize: function() { + this._super(); + this.stripe = Stripe(this.getPublishableKey()); + }, + + placeOrder: function (data, event) { + var self = this, + savePayment; + + if (event) { + event.preventDefault(); + } + + this.isPlaceOrderActionAllowed(false); + fullScreenLoader.startLoader(); + + if (!this.requireThreeDSecure()) { + this._super(data, event); + return true; + } + + $.when(self.createThreeDSource()).done(function(response) { + if (self.threeDSource.status !== 'pending') { + self._placeOrder(); + return true; + } + + savePayment = savePaymentAction(self.getData(), self.messageContainer); + + $.when(savePayment).done(function () { + fullScreenLoader.stopLoader(); + alert({ + title: $.mage.__('Additional Payment Verification Required'), + content: $.mage.__('Your card issue has requested additional verification before completing your order. You will be redirected to the issuer\'s website after closing this notification.'), + actions: { + always: function() { + customerData.invalidate(['cart']); + window.location = response.source.redirect.url; + } + } + }); + }).fail(function () { + fullScreenLoader.stopLoader(); + self.isPlaceOrderActionAllowed(true); + self.messageContainer.addErrorMessage({ + 'message': $.mage.__('An error occurred on the server. Please try again.') + }); + }); + }).fail(function(result) { + fullScreenLoader.stopLoader(); + self.isPlaceOrderActionAllowed(true); + + self.messageContainer.addErrorMessage({ + 'message': result + }); + }); + }, + + _placeOrder: function () { + var self = this, + placeOrder = placeOrderAction(self.getData(), self.messageContainer); + + $.when(placeOrder).done(function() { + if (self.redirectAfterPlaceOrder) { + redirectOnSuccessAction.execute(); + } + }).fail(function() { + fullScreenLoader.stopLoader(); + self.isPlaceOrderActionAllowed(true); + }); + }, + + createThreeDSource: function () { + var self = this, + defer = $.Deferred(); + + self.stripe.createSource({ + type: 'three_d_secure', + amount: quote.totals().base_grand_total * 100, + currency: quote.totals().base_currency_code, + three_d_secure: { + card: self.details.source + }, + redirect: { + return_url: this.getThreeDRedirectUrl() + } + }).then(function (response) { + if (response.error) { + defer.reject(response.error.message); + return; + } + + self.threeDSource = response.source; + defer.resolve(response); + }); + + return defer.promise(); }, getMaskedCard: function () { @@ -24,6 +144,39 @@ define([ getToken: function() { return this.publicHash; + }, + + getPublishableKey: function () { + return window.checkoutConfig.payment.pmclain_stripe.publishableKey; + }, + + getData: function () { + var data = this._super(); + + if (this.threeDSource) { + data.additional_data.three_d_src = this.threeDSource.id; + data.additional_data.three_d_client_secret = this.threeDSource.client_secret; + } + + return data; + }, + + requireThreeDSecure: function () { + return window.checkoutConfig.payment.pmclain_stripe.threeDSecure + && this.threeDThresholdMet() + && this.details.threeDSecure; + }, + + threeDSecureThreshold: function () { + return window.checkoutConfig.payment.pmclain_stripe.threeDThreshold; + }, + + threeDThresholdMet: function () { + return quote.totals().base_grand_total >= this.threeDSecureThreshold(); + }, + + getThreeDRedirectUrl: function() { + return window.checkoutConfig.payment.pmclain_stripe.threeDRedirectUrl; } }); }); \ No newline at end of file