diff --git a/changelog.md b/changelog.md index c2b1012f4..99ea7cc92 100755 --- a/changelog.md +++ b/changelog.md @@ -86,3 +86,8 @@ ## [1.0.19] - * - FO: added ability to save and use saved cards with hosted fields payment + +## [1.0.20] - * + +- FO: Fixed issue when payment was cancelled due to 3DS failure but Order confirmation was still shown +- FO: Fixed issue when 3DS failed, but it still captured/authorized payment diff --git a/controllers/admin/AdminSaferPayOfficialSettingsController.php b/controllers/admin/AdminSaferPayOfficialSettingsController.php index d1d571e8f..f1cc866dc 100755 --- a/controllers/admin/AdminSaferPayOfficialSettingsController.php +++ b/controllers/admin/AdminSaferPayOfficialSettingsController.php @@ -235,8 +235,8 @@ public function initOptions() 'title' => $this->l('Behaviour when 3D secure fails'), 'validation' => 'isInt', 'choices' => [ - 0 => $this->l('Cancel'), - 1 => $this->l('Authorize'), + SaferPayConfig::PAYMENT_BEHAVIOR_WITHOUT_3D_CANCEL => $this->l('Cancel'), + SaferPayConfig::PAYMENT_BEHAVIOR_WITHOUT_3D_AUTHORIZE => $this->l('Authorize'), ], 'desc' => $this->l('Default payment behavior for payment without 3-D Secure'), 'form_group_class' => 'thumbs_chose', diff --git a/controllers/front/iframe.php b/controllers/front/iframe.php index c9096840e..cb42c231e 100755 --- a/controllers/front/iframe.php +++ b/controllers/front/iframe.php @@ -24,6 +24,7 @@ use Invertus\SaferPay\Config\SaferPayConfig; use Invertus\SaferPay\Controller\AbstractSaferPayController; use Invertus\SaferPay\EntityBuilder\SaferPayOrderBuilder; +use Invertus\SaferPay\Enum\ControllerName; use Invertus\SaferPay\Repository\SaferPayCardAliasRepository; use Invertus\SaferPay\Service\SaferPayInitialize; @@ -111,7 +112,7 @@ public function initContent() } catch (Exception $e) { $redirectLink = $this->context->link->getModuleLink( $this->module->name, - 'fail', + ControllerName::FAIL, [ 'cartId' => $this->context->cart->id, 'orderId' => Order::getOrderByCartId($this->context->cart->id), diff --git a/controllers/front/notify.php b/controllers/front/notify.php index dc8467dd4..784003986 100755 --- a/controllers/front/notify.php +++ b/controllers/front/notify.php @@ -49,9 +49,6 @@ public function postProcess() if ($cart->secure_key !== $secureKey) { die($this->module->l('Error. Insecure cart', self::FILENAME)); } - /** @var SaferPayOrderRepository $saferPayOrderRepository */ - $saferPayOrderRepository = $this->module->getModuleContainer()->get(SaferPayOrderRepository::class); - $saferPayOrderId = $saferPayOrderRepository->getIdByOrderId($orderId); try { $assertResponseBody = $this->assertTransaction($cartId); @@ -60,20 +57,28 @@ public function postProcess() //NOTE must be left below assert action to get newest information. $order = new Order($orderId); - if (in_array($order->payment, SaferPayConfig::SUPPORTED_3DS_PAYMENT_METHODS) && - !$assertResponseBody->getLiability()->getLiabilityShift() + /** @var SaferPay3DSecureService $secureService */ + $secureService = $this->module->getModuleContainer()->get(SaferPay3DSecureService::class); + + $paymentBehaviourWithout3DS = (int) Configuration::get(SaferPayConfig::PAYMENT_BEHAVIOR_WITHOUT_3D); + + if ( + !$assertResponseBody->getLiability()->getLiabilityShift() && + in_array($order->payment, SaferPayConfig::SUPPORTED_3DS_PAYMENT_METHODS) && + $paymentBehaviourWithout3DS === SaferPayConfig::PAYMENT_BEHAVIOR_WITHOUT_3D_CANCEL ) { - /** @var SaferPay3DSecureService $secureService */ - $secureService = $this->module->getModuleContainer()->get(SaferPay3DSecureService::class); - $secureService->processNotSecuredPayment($order); + $secureService->cancelPayment($order); + die($this->module->l('Liability shift is false', self::FILENAME)); } //NOTE to get latest information possible and not override new information. $order = new Order($orderId); - $defaultBehavior = Configuration::get(SaferPayConfig::PAYMENT_BEHAVIOR); - if ((int) $defaultBehavior === SaferPayConfig::DEFAULT_PAYMENT_BEHAVIOR_CAPTURE && + $paymentBehaviour = (int) Configuration::get(SaferPayConfig::PAYMENT_BEHAVIOR); + + if ( + $paymentBehaviour === SaferPayConfig::DEFAULT_PAYMENT_BEHAVIOR_CAPTURE && $assertResponseBody->getTransaction()->getStatus() !== 'CAPTURED' ) { /** @var SaferPayOrderStatusService $orderStatusService */ diff --git a/controllers/front/successHosted.php b/controllers/front/successHosted.php index f63986263..51d70f673 100755 --- a/controllers/front/successHosted.php +++ b/controllers/front/successHosted.php @@ -24,6 +24,7 @@ use Invertus\SaferPay\Config\SaferPayConfig; use Invertus\SaferPay\Controller\AbstractSaferPayController; use Invertus\SaferPay\DTO\Response\Assert\AssertBody; +use Invertus\SaferPay\Enum\ControllerName; use Invertus\SaferPay\Repository\SaferPayOrderRepository; use Invertus\SaferPay\Service\SaferPay3DSecureService; use Invertus\SaferPay\Service\SaferPayOrderStatusService; @@ -54,23 +55,13 @@ public function postProcess() $cart = new Cart($cartId); if ($cart->secure_key !== $secureKey) { - $redirectLink = $this->context->link->getPageLink( - 'order', - true, - null, - [ - 'step' => 1, - ] - ); - Tools::redirect($redirectLink); + Tools::redirect($this->getOrderLink()); } try { - /** @var SaferPayOrderRepository $orderRepo */ - $orderRepo = $this->module->getModuleContainer()->get(SaferPayOrderRepository::class); - $saferPayOrderId = $orderRepo->getIdByOrderId($orderId); + /** @var SaferPayOrderStatusService $orderStatusService */ + $orderStatusService = $this->module->getModuleContainer()->get(SaferPayOrderStatusService::class); - $saferPayOrder = new SaferPayOrder($saferPayOrderId); $order = new Order($orderId); /** @var SaferPayTransactionAuthorization $saferPayTransactionAuthorization */ @@ -82,22 +73,43 @@ public function postProcess() $selectedCard ); - if (!$authResponseBody->getLiability()->getLiabilityShift()) { - /** @var SaferPay3DSecureService $secureService */ - $secureService = $this->module->getModuleContainer()->get(SaferPay3DSecureService::class); - $secureService->processNotSecuredPayment($order); - Tools::redirect($this->getOrderConfirmationLink($cartId, $moduleId, $orderId, $secureKey)); - } + /** @var SaferPay3DSecureService $secureService */ + $secureService = $this->module->getModuleContainer()->get(SaferPay3DSecureService::class); - $defaultBehavior = Configuration::get(SaferPayConfig::PAYMENT_BEHAVIOR); - if ((int) $defaultBehavior === SaferPayConfig::DEFAULT_PAYMENT_BEHAVIOR_CAPTURE && - !$saferPayOrder->captured + $paymentBehaviourWithout3DS = (int) Configuration::get(SaferPayConfig::PAYMENT_BEHAVIOR_WITHOUT_3D); + + if ( + !$authResponseBody->getLiability()->getLiabilityShift() && + $paymentBehaviourWithout3DS === SaferPayConfig::PAYMENT_BEHAVIOR_WITHOUT_3D_CANCEL ) { - /** @var SaferPayOrderStatusService $orderStatusService */ - $orderStatusService = $this->module->getModuleContainer()->get(SaferPayOrderStatusService::class); + $secureService->cancelPayment($order); + + $this->warning[] = $this->module->l('We couldn\'t authorize your payment. Please try again.', self::FILENAME); + + $this->redirectWithNotifications($this->context->link->getModuleLink( + $this->module->name, + ControllerName::FAIL, + [ + 'cartId' => $cartId, + 'secureKey' => $secureKey, + 'orderId' => $orderId, + 'moduleId' => $moduleId, + ], + true + )); + } + + $orderStatusService->authorize($order); + + $paymentBehaviour = (int) Configuration::get(SaferPayConfig::PAYMENT_BEHAVIOR); + + if ($paymentBehaviour === SaferPayConfig::DEFAULT_PAYMENT_BEHAVIOR_CAPTURE) { + $orderStatusService->capture($order); Tools::redirect($this->getOrderConfirmationLink($cartId, $moduleId, $orderId, $secureKey)); } + + Tools::redirect($this->getOrderConfirmationLink($cartId, $moduleId, $orderId, $secureKey)); } catch (Exception $e) { PrestaShopLogger::addLog( sprintf( @@ -115,7 +127,7 @@ public function postProcess() Tools::redirect( $this->context->link->getModuleLink( $this->module->name, - 'fail', + ControllerName::FAIL, [ 'cartId' => $cartId, 'secureKey' => $secureKey, @@ -161,4 +173,16 @@ private function getOrderConfirmationLink($cartId, $moduleId, $orderId, $secureK ] ); } + + private function getOrderLink() + { + return $this->context->link->getPageLink( + 'order', + true, + null, + [ + 'step' => 1, + ] + ); + } } diff --git a/controllers/front/successIFrame.php b/controllers/front/successIFrame.php index c40136d79..9c66a1d97 100755 --- a/controllers/front/successIFrame.php +++ b/controllers/front/successIFrame.php @@ -24,11 +24,13 @@ use Invertus\SaferPay\Api\Request\AuthorizationService; use Invertus\SaferPay\Config\SaferPayConfig; use Invertus\SaferPay\Controller\AbstractSaferPayController; +use Invertus\SaferPay\Enum\ControllerName; use Invertus\SaferPay\Exception\Api\SaferPayApiException; use Invertus\SaferPay\Repository\SaferPayOrderRepository; use Invertus\SaferPay\Service\Request\AuthorizationRequestObjectCreator; use Invertus\SaferPay\Service\SaferPay3DSecureService; use Invertus\SaferPay\Service\SaferPayOrderStatusService; +use Invertus\SaferPay\Service\TransactionFlow\SaferPayTransactionAuthorization; class SaferPayOfficialSuccessIFrameModuleFrontController extends AbstractSaferPayController { @@ -51,134 +53,82 @@ public function postProcess() $orderId = Tools::getValue('orderId'); $secureKey = Tools::getValue('secureKey'); $selectedCard = Tools::getValue('selectedCard'); - $isDirectPayment = Tools::getValue('directPayment'); $moduleId = Tools::getValue('moduleId'); $cart = new Cart($cartId); if ($cart->secure_key !== $secureKey) { - $redirectLink = $this->context->link->getPageLink( - 'order', - true, - null, - [ - 'step' => 1, - ] - ); - - Tools::redirect($redirectLink); + Tools::redirect($this->getOrderLink()); } - /** @var AuthorizationRequestObjectCreator $authRequestCreator */ - $authRequestCreator = $this->module->getModuleContainer()->get(AuthorizationRequestObjectCreator::class); + /** @var SaferPayTransactionAuthorization $saferPayTransactionAuthorization */ + $saferPayTransactionAuthorization = $this->module->getModuleContainer()->get(SaferPayTransactionAuthorization::class); - /** @var SaferPayOrderRepository $orderRepo */ - $orderRepo = $this->module->getModuleContainer()->get('saferpay.order.repository'); + /** @var SaferPayOrderStatusService $orderStatusService */ + $orderStatusService = $this->module->getModuleContainer()->get(SaferPayOrderStatusService::class); - $saferPayOrderId = $orderRepo->getIdByOrderId($orderId); - $saferPayOrder = new SaferPayOrder($saferPayOrderId); - $saveCard = (int) $selectedCard === SaferPayConfig::CREDIT_CARD_OPTION_SAVE; - $authRequest = $authRequestCreator->create($saferPayOrder->token, $saveCard); - - /** @var AuthorizationService $authorizeService */ - $authorizeService = $this->module->getModuleContainer()->get(AuthorizationService::class); $order = new Order($orderId); - if (!$isDirectPayment) { - try { - $response = $authorizeService->authorize( - $authRequest - ); - $authResponse = $authorizeService->createObjectsFromAuthorizationResponse( - $response, - $saferPayOrderId, - $order->id_customer, - $selectedCard - ); - } catch (SaferPayApiException $e) { - $this->warning[] = $this->module->l( - 'We couldn\'t authorize your payment. Please try again.', - self::FILENAME - ); - $failUrl = $this->context->link->getModuleLink( - $this->module->name, - 'failValidation', - [ - 'cartId' => $cartId, - 'secureKey' => $secureKey, - 'orderId' => $orderId, - \Invertus\SaferPay\Config\SaferPayConfig::IS_BUSINESS_LICENCE => true, - ], - true - ); - $this->redirectWithNotifications($failUrl); - } - $saferPayOrder->transaction_id = $authResponse->getTransaction()->getId(); - if ($authResponse->getTransaction()->getStatus() === 'AUTHORIZED') { - $saferPayOrder->authorized = 1; - } - if ($authResponse->getTransaction()->getStatus() === 'CAPTURED') { - $saferPayOrder->authorized = 1; - $saferPayOrder->captured = 1; - $order->setCurrentState(_SAFERPAY_PAYMENT_COMPLETED_); - } - $saferPayOrder->update(); - - $newOrderStatus = _SAFERPAY_PAYMENT_AUTHORIZED_; - $order->setCurrentState($newOrderStatus); - - if ($authResponse->getLiability()->getThreeDs() && !$authResponse->getLiability()->getLiabilityShift()) { - /** @var SaferPay3DSecureService $secureService */ - $secureService = $this->module->getModuleContainer()->get(SaferPay3DSecureService::class); - $secureService->processNotSecuredPayment($order); - $isOrderCanceled = $secureService->isSaferPayOrderCanceled($orderId); - if ($isOrderCanceled) { - $this->warning[] = $this->module->l( - 'We couldn\'t authorize your payment. Please try again.', - self::FILENAME - ); - $failUrl = $this->context->link->getModuleLink( - $this->module->name, - 'failIFrame', - [ - 'cartId' => $cartId, - 'secureKey' => $secureKey, - 'orderId' => $orderId, - 'moduleId' => $moduleId, - ], - true - ); - $this->redirectWithNotifications($failUrl); - } - - return; - } - } - if ($authResponse->getLiability()->getThreeDs()) { - $defaultBehavior = Configuration::get(SaferPayConfig::PAYMENT_BEHAVIOR); - if ((int) $defaultBehavior === SaferPayConfig::DEFAULT_PAYMENT_BEHAVIOR_CAPTURE) { - /** @var SaferPayOrderStatusService $orderStatusService */ - $orderStatusService = $this->module->getModuleContainer()->get(SaferPayOrderStatusService::class); - $orderStatusService->capture($order); - } + try { + $authResponseBody = $saferPayTransactionAuthorization->authorize( + $orderId, + (int) $selectedCard === SaferPayConfig::CREDIT_CARD_OPTION_SAVE, + $selectedCard + ); + } catch (SaferPayApiException $e) { + $this->warning[] = $this->module->l('We couldn\'t authorize your payment. Please try again.', self::FILENAME); + $this->redirectWithNotifications($this->context->link->getModuleLink( + $this->module->name, + ControllerName::FAIL_VALIDATION, + [ + 'cartId' => $cartId, + 'secureKey' => $secureKey, + 'orderId' => $orderId, + \Invertus\SaferPay\Config\SaferPayConfig::IS_BUSINESS_LICENCE => true, + ], + true + )); } - $isDirectPayment = Tools::getValue('directPayment'); - if ($isDirectPayment) { - $orderLink = $this->context->link->getPageLink( - 'order-confirmation', - true, - null, + /** @var SaferPay3DSecureService $secureService */ + $secureService = $this->module->getModuleContainer()->get(SaferPay3DSecureService::class); + + $paymentBehaviourWithout3DS = (int) Configuration::get(SaferPayConfig::PAYMENT_BEHAVIOR_WITHOUT_3D); + + if ( + $authResponseBody->getLiability()->getThreeDs() && + !$authResponseBody->getLiability()->getLiabilityShift() && + $paymentBehaviourWithout3DS === SaferPayConfig::PAYMENT_BEHAVIOR_WITHOUT_3D_CANCEL + ) { + $secureService->cancelPayment($order); + + $this->warning[] = $this->module->l('We couldn\'t authorize your payment. Please try again.', self::FILENAME); + + $this->redirectWithNotifications($this->context->link->getModuleLink( + $this->module->name, + ControllerName::FAIL, [ - 'id_cart' => $cartId, - 'id_module' => $moduleId, - 'id_order' => $orderId, - 'key' => $secureKey, - ] - ); - if ($isDirectPayment) { - Tools::redirect($orderLink); - } + 'cartId' => $cartId, + 'secureKey' => $secureKey, + 'orderId' => $orderId, + 'moduleId' => $moduleId, + ], + true + )); } + + $orderStatusService->authorize($order); + + $paymentBehaviour = (int) Configuration::get(SaferPayConfig::PAYMENT_BEHAVIOR); + + if ( + $paymentBehaviour === SaferPayConfig::DEFAULT_PAYMENT_BEHAVIOR_CAPTURE && + $authResponseBody->getLiability()->getThreeDs() + ) { + $orderStatusService->capture($order); + Tools::redirect($this->getOrderConfirmationLink($cartId, $moduleId, $orderId, $secureKey)); + } + + Tools::redirect($this->getOrderConfirmationLink($cartId, $moduleId, $orderId, $secureKey)); } public function initContent() @@ -252,4 +202,39 @@ public function setMedia() ); } } + + /** + * @param int $cartId + * @param int $moduleId + * @param int $orderId + * @param string $secureKey + * + * @return string + */ + private function getOrderConfirmationLink($cartId, $moduleId, $orderId, $secureKey) + { + return $this->context->link->getPageLink( + 'order-confirmation', + true, + null, + [ + 'id_cart' => $cartId, + 'id_module' => $moduleId, + 'id_order' => $orderId, + 'key' => $secureKey, + ] + ); + } + + private function getOrderLink() + { + return $this->context->link->getPageLink( + 'order', + true, + null, + [ + 'step' => 1, + ] + ); + } } diff --git a/saferpayofficial.php b/saferpayofficial.php index 1a84f31d6..9c7aa152c 100755 --- a/saferpayofficial.php +++ b/saferpayofficial.php @@ -41,7 +41,7 @@ public function __construct($name = null) { $this->name = 'saferpayofficial'; $this->author = 'Invertus'; - $this->version = '1.0.19'; + $this->version = '1.0.20'; $this->module_key = '3d3506c3e184a1fe63b936b82bda1bdf'; $this->displayName = 'SaferpayOfficial'; $this->description = 'Saferpay Payment module'; diff --git a/src/Config/SaferPayConfig.php b/src/Config/SaferPayConfig.php index b5c557389..9c0abcccd 100755 --- a/src/Config/SaferPayConfig.php +++ b/src/Config/SaferPayConfig.php @@ -248,6 +248,9 @@ class SaferPayConfig const EMAIL_ALERTS_MODULE_NAME = 'ps_emailalerts'; + const PAYMENT_BEHAVIOR_WITHOUT_3D_CANCEL = 0; + const PAYMENT_BEHAVIOR_WITHOUT_3D_AUTHORIZE = 1; + public static function getConfigSuffix() { if (Configuration::get(self::TEST_MODE)) { diff --git a/src/Service/SaferPay3DSecureService.php b/src/Service/SaferPay3DSecureService.php index d79d8dd7d..a3050b22f 100755 --- a/src/Service/SaferPay3DSecureService.php +++ b/src/Service/SaferPay3DSecureService.php @@ -58,27 +58,9 @@ public function __construct( /** * @param Order $order */ - public function processNotSecuredPayment(Order $order) + public function cancelPayment(Order $order) { - $defaultBehavior = Configuration::get(SaferPayConfig::PAYMENT_BEHAVIOR_WITHOUT_3D); - if ($defaultBehavior) { - return; - } $this->cartDuplicationService->restoreCart($order->id_cart); $this->orderStatusService->cancel($order); } - - /** - * @param $orderId - * @return bool - * @throws \PrestaShopDatabaseException - * @throws \PrestaShopException - */ - public function isSaferPayOrderCanceled($orderId) - { - $saferPayOrderId = $this->orderRepository->getIdByOrderId($orderId); - $saferPayOrder = new SaferPayOrder($saferPayOrderId); - - return $saferPayOrder->canceled; - } } diff --git a/src/Service/SaferPayInitialize.php b/src/Service/SaferPayInitialize.php index 3fa73713a..522087e44 100755 --- a/src/Service/SaferPayInitialize.php +++ b/src/Service/SaferPayInitialize.php @@ -26,6 +26,7 @@ use Context; use Exception; use Invertus\SaferPay\Api\Request\InitializeService; +use Invertus\SaferPay\Enum\ControllerName; use Invertus\SaferPay\Exception\Api\SaferPayApiException; use Invertus\SaferPay\Service\Request\InitializeRequestObjectCreator; use Order; @@ -90,7 +91,7 @@ public function initialize( ); $notifyUrl = $this->context->link->getModuleLink( $this->module->name, - 'notify', + ControllerName::NOTIFY, [ 'success' => 1, 'cartId' => $this->context->cart->id, @@ -101,7 +102,7 @@ public function initialize( ); $failUrl = $this->context->link->getModuleLink( $this->module->name, - 'failValidation', + ControllerName::FAIL_VALIDATION, [ 'cartId' => $this->context->cart->id, 'secureKey' => $this->context->cart->secure_key, diff --git a/src/Service/SaferPayOrderStatusService.php b/src/Service/SaferPayOrderStatusService.php index 169fa4b0b..3e035fc6d 100755 --- a/src/Service/SaferPayOrderStatusService.php +++ b/src/Service/SaferPayOrderStatusService.php @@ -33,6 +33,7 @@ use Invertus\SaferPay\Api\Request\RefundService; use Invertus\SaferPay\Config\SaferPayConfig; use Invertus\SaferPay\DTO\Request\PendingNotification; +use Invertus\SaferPay\Enum\ControllerName; use Invertus\SaferPay\Exception\Api\SaferPayApiException; use Invertus\SaferPay\Repository\SaferPayOrderRepository; use Invertus\SaferPay\Service\Request\CancelRequestObjectCreator; @@ -229,7 +230,7 @@ public function refund(Order $order, $refundedAmount) $saferPayAssert->payment_method === SaferPayConfig::PAYMENT_PAYDIREKT) { $pendingNotify = $this->context->getLink()->getModuleLink( $this->module->name, - 'pendingNotify', + ControllerName::PENDING_NOTIFY, [ 'success' => 1, 'cartId' => $cart->id, diff --git a/src/Service/TransactionFlow/SaferPayTransactionAuthorization.php b/src/Service/TransactionFlow/SaferPayTransactionAuthorization.php index bc2823e15..cbc31d86a 100755 --- a/src/Service/TransactionFlow/SaferPayTransactionAuthorization.php +++ b/src/Service/TransactionFlow/SaferPayTransactionAuthorization.php @@ -84,7 +84,6 @@ public function __construct( public function authorize($orderId, $saveCard, $selectedCard) { $saferPayOrder = $this->getSaferPayOrder($orderId); - $order = new Order($orderId); $authRequest = $this->authRequestCreator->create($saferPayOrder->token, $saveCard); $authResponse = $this->authorizationService->authorize($authRequest); @@ -99,8 +98,6 @@ public function authorize($orderId, $saveCard, $selectedCard) $saferPayOrder->transaction_id = $assertBody->getTransaction()->getId(); $saferPayOrder->update(); - $this->orderStatusService->authorize($order); - return $assertBody; }