diff --git a/controllers/front/return.php b/controllers/front/return.php index 48cb8db7..d377ed14 100755 --- a/controllers/front/return.php +++ b/controllers/front/return.php @@ -46,6 +46,8 @@ public function postProcess() $cartId = (int) Tools::getValue('cartId'); $order = new Order($this->getOrderId($cartId)); $secureKey = Tools::getValue('secureKey'); + $selectedCard = Tools::getValue('selectedCard'); + $cart = new Cart($cartId); if (!Validate::isLoadedObject($cart)) { @@ -62,7 +64,12 @@ public function postProcess() $transactionAssert = $this->module->getService(SaferPayTransactionAssertion::class); try { - $assertResponseBody = $transactionAssert->assert($cartId); + $assertResponseBody = $transactionAssert->assert( + $cartId, + (int) $selectedCard === SaferPayConfig::CREDIT_CARD_OPTION_SAVE, + $selectedCard, + (int) Tools::getValue(SaferPayConfig::IS_BUSINESS_LICENCE) + ); $transactionStatus = $assertResponseBody->getTransaction()->getStatus(); } catch (Exception $e) { \PrestaShopLogger::addLog($e->getMessage()); @@ -73,57 +80,12 @@ public function postProcess() /** * NOTE: This flow is for hosted iframe payment method */ - if (Tools::getValue('isBusinessLicence')) { + if ( + Configuration::get(SaferPayConfig::BUSINESS_LICENSE . SaferPayConfig::getConfigSuffix()) + || Configuration::get(SaferPayConfig::FIELDS_ACCESS_TOKEN . SaferPayConfig::getConfigSuffix()) + ) { try { - /** @var CheckoutProcessor $checkoutProcessor * */ - $checkoutProcessor = $this->module->getService(CheckoutProcessor::class); - - $checkoutData = CheckoutData::create( - (int) $cartId, - $assertResponseBody->getPaymentMeans()->getBrand()->getPaymentMethod(), - (int) Configuration::get(SaferPayConfig::IS_BUSINESS_LICENCE) - ); - $checkoutData->setOrderStatus($transactionStatus); - - $checkoutProcessor->run($checkoutData); - - $orderId = $this->getOrderId($cartId); - - $order = new Order($orderId); - if (!$assertResponseBody->getLiability()->getLiabilityShift() && - in_array($order->payment, SaferPayConfig::SUPPORTED_3DS_PAYMENT_METHODS) && - (int) Configuration::get(SaferPayConfig::PAYMENT_BEHAVIOR_WITHOUT_3D) === SaferPayConfig::PAYMENT_BEHAVIOR_WITHOUT_3D_CANCEL - ) { - /** @var SaferPayOrderStatusService $orderStatusService */ - $orderStatusService = $this->module->getService(SaferPayOrderStatusService::class); - $orderStatusService->cancel($order); - } - - //NOTE to get latest information possible and not override new information. - - $paymentMethod = $assertResponseBody->getPaymentMeans()->getBrand()->getPaymentMethod();// if payment does not support order capture, it means it always auto-captures it (at least with accountToAccount payment), - - // so in this case if status comes back "captured" we just update the order state accordingly - if (!SaferPayConfig::supportsOrderCapture($paymentMethod) && - $transactionStatus === TransactionStatus::CAPTURED - ) { - /** @var SaferPayOrderStatusService $orderStatusService */ - $orderStatusService = $this->module->getService(SaferPayOrderStatusService::class); - $orderStatusService->setComplete($order); - - return; - } - - if (SaferPayConfig::supportsOrderCapture($paymentMethod) && - (int) Configuration::get(SaferPayConfig::PAYMENT_BEHAVIOR) === SaferPayConfig::DEFAULT_PAYMENT_BEHAVIOR_CAPTURE && - $transactionStatus !== TransactionStatus::CAPTURED - ) { - /** @var SaferPayOrderStatusService $orderStatusService */ - $orderStatusService = $this->module->getService(SaferPayOrderStatusService::class); - $orderStatusService->capture($order); - - return; - } + $this->createAndValidateOrder($assertResponseBody, $transactionStatus, $cartId); } catch (Exception $e) { \PrestaShopLogger::addLog($e->getMessage()); $this->warning[] = $this->module->l('An error occurred. Please contact support', self::FILENAME); @@ -182,10 +144,12 @@ public function initContent() $saferPayAuthorizedStatus = (int) Configuration::get(SaferPayConfig::SAFERPAY_PAYMENT_AUTHORIZED); $saferPayCapturedStatus = (int) Configuration::get(SaferPayConfig::SAFERPAY_PAYMENT_COMPLETED); + $usingSavedCard = $selectedCard > 0; + if ((int) $order->current_state === $saferPayAuthorizedStatus || (int) $order->current_state === $saferPayCapturedStatus) { Tools::redirect($this->context->link->getModuleLink( $this->module->name, - $this->getSuccessControllerName($isBusinessLicence, $fieldToken), + $this->getSuccessControllerName($isBusinessLicence, $fieldToken, $usingSavedCard), [ 'cartId' => $cartId, 'orderId' => $orderId, @@ -220,7 +184,7 @@ public function initContent() $this->setTemplate('saferpay_wait_16.tpl'); } - private function getSuccessControllerName($isBusinessLicence, $fieldToken) + private function getSuccessControllerName($isBusinessLicence, $fieldToken, $usingSavedCard) { $successController = ControllerName::SUCCESS; @@ -228,7 +192,7 @@ private function getSuccessControllerName($isBusinessLicence, $fieldToken) $successController = ControllerName::SUCCESS_IFRAME; } - if ($fieldToken) { + if ($fieldToken || $usingSavedCard) { $successController = ControllerName::SUCCESS_HOSTED; } @@ -286,4 +250,57 @@ private function getRedirectionToControllerUrl($controllerName) ] ); } + + private function createAndValidateOrder($assertResponseBody, $transactionStatus, $cartId) + { + /** @var CheckoutProcessor $checkoutProcessor * */ + $checkoutProcessor = $this->module->getService(CheckoutProcessor::class); + + $checkoutData = CheckoutData::create( + (int) $cartId, + $assertResponseBody->getPaymentMeans()->getBrand()->getPaymentMethod(), + (int) Configuration::get(SaferPayConfig::IS_BUSINESS_LICENCE) + ); + $checkoutData->setOrderStatus($transactionStatus); + + $checkoutProcessor->run($checkoutData); + + $orderId = $this->getOrderId($cartId); + + $order = new Order($orderId); + if (!$assertResponseBody->getLiability()->getLiabilityShift() && + in_array($order->payment, SaferPayConfig::SUPPORTED_3DS_PAYMENT_METHODS) && + (int) Configuration::get(SaferPayConfig::PAYMENT_BEHAVIOR_WITHOUT_3D) === SaferPayConfig::PAYMENT_BEHAVIOR_WITHOUT_3D_CANCEL + ) { + /** @var SaferPayOrderStatusService $orderStatusService */ + $orderStatusService = $this->module->getService(SaferPayOrderStatusService::class); + $orderStatusService->cancel($order); + } + + //NOTE to get latest information possible and not override new information. + + $paymentMethod = $assertResponseBody->getPaymentMeans()->getBrand()->getPaymentMethod();// if payment does not support order capture, it means it always auto-captures it (at least with accountToAccount payment), + + // so in this case if status comes back "captured" we just update the order state accordingly + if (!SaferPayConfig::supportsOrderCapture($paymentMethod) && + $transactionStatus === TransactionStatus::CAPTURED + ) { + /** @var SaferPayOrderStatusService $orderStatusService */ + $orderStatusService = $this->module->getService(SaferPayOrderStatusService::class); + $orderStatusService->setComplete($order); + + return; + } + + if (SaferPayConfig::supportsOrderCapture($paymentMethod) && + (int) Configuration::get(SaferPayConfig::PAYMENT_BEHAVIOR) === SaferPayConfig::DEFAULT_PAYMENT_BEHAVIOR_CAPTURE && + $transactionStatus !== TransactionStatus::CAPTURED + ) { + /** @var SaferPayOrderStatusService $orderStatusService */ + $orderStatusService = $this->module->getService(SaferPayOrderStatusService::class); + $orderStatusService->capture($order); + + return; + } + } } diff --git a/controllers/front/successIFrame.php b/controllers/front/successIFrame.php index b7450363..84449d15 100755 --- a/controllers/front/successIFrame.php +++ b/controllers/front/successIFrame.php @@ -59,6 +59,11 @@ public function postProcess() // todo refactor this by the logic provided $this->redirectWithNotifications($this->getOrderLink()); } + /** Purchase is made with card that needs to be saved */ + if (Tools::getValue('selectedCard') <= 0) { + return; + } + try { Tools::redirect($this->getOrderConfirmationLink($cartId, $moduleId, $orderId, $secureKey)); } catch (Exception $e) { diff --git a/src/Api/Request/AssertService.php b/src/Api/Request/AssertService.php index fc0d2871..4ae3d511 100755 --- a/src/Api/Request/AssertService.php +++ b/src/Api/Request/AssertService.php @@ -24,10 +24,14 @@ namespace Invertus\SaferPay\Api\Request; use Exception; +use Invertus\SaferPay\Adapter\Configuration; use Invertus\SaferPay\Api\ApiRequest; +use Invertus\SaferPay\Config\SaferPayConfig; +use Invertus\SaferPay\Core\Payment\DTO\CheckoutData; use Invertus\SaferPay\DTO\Request\Assert\AssertRequest; use Invertus\SaferPay\DTO\Response\Assert\AssertBody; use Invertus\SaferPay\EntityBuilder\SaferPayAssertBuilder; +use Invertus\SaferPay\EntityBuilder\SaferPayCardAliasBuilder; use Invertus\SaferPay\Exception\Api\SaferPayApiException; use Invertus\SaferPay\Service\Response\AssertResponseObjectCreator; use SaferPayOrder; @@ -54,15 +58,18 @@ class AssertService * @var SaferPayAssertBuilder */ private $assertBuilder; + private $aliasBuilder; public function __construct( ApiRequest $apiRequest, AssertResponseObjectCreator $assertResponseObjectCreator, - SaferPayAssertBuilder $assertBuilder + SaferPayAssertBuilder $assertBuilder, + SaferPayCardAliasBuilder $aliasBuilder ) { $this->apiRequest = $apiRequest; $this->assertResponseObjectCreator = $assertResponseObjectCreator; $this->assertBuilder = $assertBuilder; + $this->aliasBuilder = $aliasBuilder; } /** @@ -72,17 +79,13 @@ public function __construct( * @return object|null * @throws \Exception */ - public function assert(AssertRequest $assertRequest, $saferPayOrderId) + public function assert(AssertRequest $assertRequest, $isBusiness) { - $saferPayOrder = new SaferPayOrder($saferPayOrderId); - $assertApi = self::ASSERT_API_PAYMENT; - //TODO: refactor this to use authorize request. - // naming is weird. With transaction, we do a request to an authorize endpoint but name it assert ? - // also we call authorize method in some of the success controllers, so if we leave the logic here, - // we get an error with TRANSACTION_IN_WRONG_STATE - if ($saferPayOrder->is_transaction) { + $isBusinessLicense = \Configuration::get(SaferPayConfig::BUSINESS_LICENSE . SaferPayConfig::getConfigSuffix()); + + if ($isBusiness) { $assertApi = self::ASSERT_API_TRANSACTION; } @@ -103,10 +106,15 @@ public function assert(AssertRequest $assertRequest, $saferPayOrderId) * @return AssertBody * @throws Exception */ - public function createObjectsFromAssertResponse($responseBody, $saferPayOrderId) + public function createObjectsFromAssertResponse($responseBody, $saferPayOrderId, $customerId, $selectedCardOption) { $assertBody = $this->assertResponseObjectCreator->createAssertObject($responseBody); $this->assertBuilder->createAssert($assertBody, $saferPayOrderId); + $isPaymentSafe = $assertBody->getLiability()->getLiabilityShift(); + + if ((int) $selectedCardOption === SaferPayConfig::CREDIT_CARD_OPTION_SAVE && $isPaymentSafe) { + $this->aliasBuilder->createCardAlias($assertBody, $customerId); + } return $assertBody; } diff --git a/src/DTO/Request/Assert/AssertRequest.php b/src/DTO/Request/Assert/AssertRequest.php index 0ed01f54..3caa6884 100755 --- a/src/DTO/Request/Assert/AssertRequest.php +++ b/src/DTO/Request/Assert/AssertRequest.php @@ -43,13 +43,16 @@ class AssertRequest * @var string */ private $token; + private $saveCard; public function __construct( RequestHeader $requestHeader, - $token + $token, + $saveCard ) { $this->requestHeader = $requestHeader; $this->token = $token; + $this->saveCard = $saveCard; } public function getAsArray() @@ -65,6 +68,10 @@ public function getAsArray() 'Token' => $this->token, ]; + if ($this->saveCard) { + $return['RegisterAlias'] = [ 'IdGenerator' => 'RANDOM_UNIQUE']; + } + return $return; } } diff --git a/src/Service/Request/AssertRequestObjectCreator.php b/src/Service/Request/AssertRequestObjectCreator.php index 34c1ef83..0689c19a 100755 --- a/src/Service/Request/AssertRequestObjectCreator.php +++ b/src/Service/Request/AssertRequestObjectCreator.php @@ -55,10 +55,10 @@ public function __construct( * * @return AssertRequest */ - public function create($token) + public function create($token, $saveCard) { $requestHeader = $this->requestObjectCreator->createRequestHeader(); - return new AssertRequest($requestHeader, $token); + return new AssertRequest($requestHeader, $token, $saveCard); } } diff --git a/src/Service/TransactionFlow/SaferPayTransactionAssertion.php b/src/Service/TransactionFlow/SaferPayTransactionAssertion.php index 5fcc3549..561fd2a1 100755 --- a/src/Service/TransactionFlow/SaferPayTransactionAssertion.php +++ b/src/Service/TransactionFlow/SaferPayTransactionAssertion.php @@ -24,6 +24,7 @@ namespace Invertus\SaferPay\Service\TransactionFlow; use Invertus\SaferPay\Api\Request\AssertService; +use Invertus\SaferPay\Config\SaferPayConfig; use Invertus\SaferPay\DTO\Response\Assert\AssertBody; use Invertus\SaferPay\Repository\SaferPayOrderRepository; use Invertus\SaferPay\Service\Request\AssertRequestObjectCreator; @@ -66,13 +67,15 @@ public function __construct( * @return AssertBody * @throws \Exception */ - public function assert($cartId, $update = true) + public function assert($cartId, $saveCard = null, $selectedCard = null, $isBusiness = 0, $update = true) { + $cart = new \Cart($cartId); + $saferPayOrder = new SaferPayOrder($this->orderRepository->getIdByCartId($cartId)); \PrestaShopLogger::addLog('saferpayOrderId:' . $saferPayOrder->id); - $assertRequest = $this->assertRequestCreator->create($saferPayOrder->token); - $assertResponse = $this->assertionService->assert($assertRequest, $saferPayOrder->id); + $assertRequest = $this->assertRequestCreator->create($saferPayOrder->token, $saveCard); + $assertResponse = $this->assertionService->assert($assertRequest, $isBusiness); if (empty($assertResponse)) { return null; @@ -80,7 +83,9 @@ public function assert($cartId, $update = true) $assertBody = $this->assertionService->createObjectsFromAssertResponse( $assertResponse, - $saferPayOrder->id + $saferPayOrder->id, + $cart->id_customer, + $selectedCard ); // assertion shouldn't update, this is quickfix for what seems to be a general flaw in structure diff --git a/src/ServiceProvider/BaseServiceProvider.php b/src/ServiceProvider/BaseServiceProvider.php index fb547e64..f31c61e3 100755 --- a/src/ServiceProvider/BaseServiceProvider.php +++ b/src/ServiceProvider/BaseServiceProvider.php @@ -24,6 +24,7 @@ namespace Invertus\SaferPay\ServiceProvider; use Invertus\SaferPay\Provider\BasicIdempotencyProvider; +use Invertus\SaferPay\Provider\CurrentPaymentTypeProvider; use Invertus\SaferPay\Provider\IdempotencyProviderInterface; use Invertus\SaferPay\Repository\OrderRepository; use Invertus\SaferPay\Repository\OrderRepositoryInterface; diff --git a/views/js/front/hosted-templates/hosted_fields.js b/views/js/front/hosted-templates/hosted_fields.js index 66324a49..96f254b8 100755 --- a/views/js/front/hosted-templates/hosted_fields.js +++ b/views/js/front/hosted-templates/hosted_fields.js @@ -30,15 +30,6 @@ $(document).ready(function () { $('[id="payment-form"]').on('submit', function (event) { event.preventDefault(); - var paymentType = $(this).find("[name=saferpayPaymentType]").val(); - - //NOTE: if it's not a hosted iframe then we don't need to submitHostedFields. - if (paymentType !== saferpay_payment_types.hosted_iframe) { - event.target.submit(); - - return; - } - var selectedCardMethod = $(this).find("[name=saved_card_method]").val(); var selectedCard = $(this).find("[name=selectedCreditCard_" + selectedCardMethod + "]").val(); diff --git a/views/templates/front/credit_cards.tpl b/views/templates/front/credit_cards.tpl index e2631bc9..16083a4b 100755 --- a/views/templates/front/credit_cards.tpl +++ b/views/templates/front/credit_cards.tpl @@ -51,7 +51,7 @@ {foreach $rows as $row} - {$row|escape:'htmlall':'UTF-8'|nofilter} + {$row|cleanHtml nofilter} {/foreach} diff --git a/views/templates/front/credit_cards_16.tpl b/views/templates/front/credit_cards_16.tpl index 8065bbfe..af1140bf 100755 --- a/views/templates/front/credit_cards_16.tpl +++ b/views/templates/front/credit_cards_16.tpl @@ -53,7 +53,7 @@ {foreach $rows as $row} - {$row|escape:'htmlall':'UTF-8'|nofilter} + {$row|cleanHtml nofilter} {/foreach}