diff --git a/changelog.md b/changelog.md index 2f93b3c2..8760bdef 100755 --- a/changelog.md +++ b/changelog.md @@ -144,3 +144,13 @@ ## [1.1.7] - * - BO : Added PrestaShop module security validations - FO : Added PrestaShop module security validations + +## [1.1.8] - * +- BO : Added a toggle setting for Saferpay email sending option +- BO : Added a configuration field for the customization of the description parameter +- BO : Increased module's API version +- BO : Added a more descriptive payment method name in invoices +- BO : Additional improvements and fixes + +- ## [1.2.0] - * +- BO : Added order creation after authorization functionality \ No newline at end of file diff --git a/controllers/admin/AdminSaferPayOfficialSettingsController.php b/controllers/admin/AdminSaferPayOfficialSettingsController.php index 7eaad21a..dd83b297 100755 --- a/controllers/admin/AdminSaferPayOfficialSettingsController.php +++ b/controllers/admin/AdminSaferPayOfficialSettingsController.php @@ -30,6 +30,8 @@ class AdminSaferPayOfficialSettingsController extends ModuleAdminController { + const FILE_NAME = 'AdminSaferPayOfficialSettingsController'; + public function __construct() { parent::__construct(); @@ -267,6 +269,17 @@ public function initOptions() 'desc' => $this->l('If set to true, the refund will be rejected if the sum of authorized refunds exceeds the capture value.'), 'form_group_class' => 'thumbs_chose', ], + SaferPayConfig::SAFERPAY_ORDER_CREATION_AFTER_AUTHORIZATION => [ + 'type' => 'radio', + 'title' => $this->l('Order creation rule'), + 'validation' => 'isInt', + 'choices' => [ + 1 => $this->l('After authorization'), + 0 => $this->l('Before authorization'), + ], + 'desc' => $this->l('Select the option to determine whether the order should be created'), + 'form_group_class' => 'thumbs_chose', + ], ], 'buttons' => [ 'save_and_connect' => [ @@ -316,6 +329,13 @@ public function initOptions() 'cast' => 'intval', 'type' => 'bool', ], + SaferPayConfig::SAFERPAY_ALLOW_SAFERPAY_SEND_CUSTOMER_MAIL => [ + 'title' => $this->l('Send an email from Saferpay on payment completion'), + 'desc' => $this->l('With this setting enabled an email from the Saferpay system will be sent to the customer'), + 'validation' => 'isBool', + 'cast' => 'intval', + 'type' => 'bool', + ], SaferPayConfig::SAFERPAY_SEND_NEW_ORDER_MAIL => [ 'title' => $this->l('Send new order mail on authorization'), 'desc' => $this->l('Receive a notification when an order is authorized by Saferpay (Using the Mail alert module)'), @@ -341,6 +361,7 @@ public function initOptions() } $this->fields_options[] = $this->getFieldOptionsOrderState(); + $this->fields_options[] = $this->displayConfigurationSettings(); } private function getFieldOptionsOrderState() @@ -374,6 +395,32 @@ private function getFieldOptionsOrderState() ]; } + /** + * @return array + */ + private function displayConfigurationSettings() + { + return [ + 'title' => $this->module->l('Configuration', self::FILE_NAME), + 'fields' => [ + SaferPayConfig::SAFERPAY_PAYMENT_DESCRIPTION => [ + 'title' => $this->module->l('Description', self::FILE_NAME), + 'type' => 'text', + 'desc' => 'This description is visible in payment page also in payment confirmation email', + 'class' => 'fixed-width-xxl' + ], + ], + 'buttons' => [ + 'save_and_connect' => [ + 'title' => $this->module->l('Save', self::FILE_NAME), + 'icon' => 'process-icon-save', + 'class' => 'btn btn-default pull-right', + 'type' => 'submit', + ], + ], + ]; + } + public function setMedia($isNewTheme = false) { parent::setMedia($isNewTheme); diff --git a/controllers/front/ajax.php b/controllers/front/ajax.php index fc57d049..270c768c 100755 --- a/controllers/front/ajax.php +++ b/controllers/front/ajax.php @@ -22,9 +22,9 @@ */ use Invertus\SaferPay\Config\SaferPayConfig; -use Invertus\SaferPay\EntityBuilder\SaferPayOrderBuilder; -use Invertus\SaferPay\Repository\SaferPayCardAliasRepository; -use Invertus\SaferPay\Service\SaferPayInitialize; +use Invertus\SaferPay\Controller\Front\CheckoutController; +use Invertus\SaferPay\Core\Payment\DTO\CheckoutData; +use Invertus\SaferPay\Enum\ControllerName; if (!defined('_PS_VERSION_')) { exit; @@ -32,6 +32,11 @@ class SaferPayOfficialAjaxModuleFrontController extends ModuleFrontController { + const FILE_NAME = 'ajax'; + + /** @var SaferPayOfficial */ + public $module; + public function postProcess() { switch (Tools::getValue('action')) { @@ -44,28 +49,28 @@ public function postProcess() private function submitHostedFields() { try { - if (!Order::getOrderByCartId($this->context->cart->id)) { - $this->validateOrder(); + if (Order::getOrderByCartId($this->context->cart->id)) { + $this->ajaxDie(json_encode([ + 'error' => true, + 'message' => $this->module->l('Order already exists', self::FILE_NAME), + 'url' => $this->getRedirectionToControllerUrl('fail'), + ])); } - /** @var SaferPayCardAliasRepository $cardAliasRep */ - $cardAliasRep = $this->module->getService(SaferPayCardAliasRepository::class); - - $selectedCard = Tools::getValue('selectedCard'); - - $alias = $cardAliasRep->getSavedCardAliasFromId($selectedCard); - - /** @var SaferPayInitialize $initializeService */ - $initializeService = $this->module->getService(SaferPayInitialize::class); - $initializeBody = $initializeService->initialize( + // refactor it to create checkout data from validator request + $checkoutData = CheckoutData::create( + (int) $this->context->cart->id, Tools::getValue('paymentMethod'), (int) Tools::getValue(SaferPayConfig::IS_BUSINESS_LICENCE), - $selectedCard, - $alias, - Tools::getValue('fieldToken') + Tools::getValue('selectedCard'), + Tools::getValue('fieldToken'), + ControllerName::SUCCESS_HOSTED, + true ); - $this->createSaferPayOrder($initializeBody); - $redirectUrl = $this->getRedirectionUrl($initializeBody); + + /** @var CheckoutController $checkoutController */ + $checkoutController = $this->module->getService(CheckoutController::class); + $redirectUrl = $checkoutController->execute($checkoutData); if (empty($redirectUrl)) { $redirectUrl = $this->getRedirectionToControllerUrl('successHosted'); @@ -84,40 +89,6 @@ private function submitHostedFields() } } - /** - * @param object $initializeBody - * - * @return string - */ - private function getRedirectionUrl($initializeBody) - { - if (isset($initializeBody->RedirectUrl)) { - return $initializeBody->RedirectUrl; - } - - if (isset($initializeBody->Redirect->RedirectUrl)) { - return $initializeBody->Redirect->RedirectUrl; - } - - return ''; - } - - /** - * @param object $initializeBody - */ - private function createSaferPayOrder($initializeBody) - { - /** @var Invertus\SaferPay\EntityBuilder\SaferPayOrderBuilder $saferPayOrderBuilder */ - $saferPayOrderBuilder = $this->module->getService(SaferPayOrderBuilder::class); - $saferPayOrderBuilder->create( - $initializeBody, - $this->context->cart, - $this->context->customer, - true, - Tools::getValue(SaferPayConfig::IS_BUSINESS_LICENCE) - ); - } - /** * @param string $controllerName * @@ -137,24 +108,4 @@ private function getRedirectionToControllerUrl($controllerName) true ); } - - /** - * @throws Exception - */ - private function validateOrder() - { - $customer = new Customer($this->context->cart->id_customer); - - $this->module->validateOrder( - $this->context->cart->id, - Configuration::get(SaferPayConfig::SAFERPAY_ORDER_STATE_CHOICE_AWAITING_PAYMENT), - (float) $this->context->cart->getOrderTotal(), - Tools::getValue('paymentMethod'), - null, - [], - (int) $this->context->currency->id, - false, - $customer->secure_key - ); - } } diff --git a/controllers/front/fail.php b/controllers/front/fail.php index b771c012..19530f8b 100755 --- a/controllers/front/fail.php +++ b/controllers/front/fail.php @@ -34,13 +34,6 @@ class SaferPayOfficialFailModuleFrontController extends AbstractSaferPayControll { const FILENAME = 'fail'; - /** - * ID Order Variable Declaration. - * - * @var - */ - private $id_order; - /** * Security Key Variable Declaration. * @@ -67,31 +60,28 @@ public function init() if (!SaferPayConfig::isVersion17()) { return parent::init(); } + parent::init(); $this->id_cart = (int) Tools::getValue('cartId', 0); $redirectLink = 'index.php?controller=history'; - $this->id_order = Order::getOrderByCartId((int) $this->id_cart); $this->secure_key = Tools::getValue('secureKey'); - $order = new Order((int) $this->id_order); - if (!$this->id_order || !$this->module->id || !$this->secure_key || empty($this->secure_key)) { + $cart = new Cart($this->id_cart); + + if (!$this->module->id || empty($this->secure_key)) { Tools::redirect($redirectLink . (Tools::isSubmit('slowvalidation') ? '&slowvalidation' : '')); } - if ((string) $this->secure_key !== (string) $order->secure_key || - (int) $order->id_customer !== (int) $this->context->customer->id || - !Validate::isLoadedObject($order) + if ((string) $this->secure_key !== (string) $cart->secure_key || + (int) $cart->id_customer !== (int) $this->context->customer->id || + !Validate::isLoadedObject($cart) ) { Tools::redirect($redirectLink); } - if ($order->module !== $this->module->name) { - Tools::redirect($redirectLink); - } - /** @var CartDuplicationService $cartDuplicationService */ $cartDuplicationService = $this->module->getService(CartDuplicationService::class); $cartDuplicationService->restoreCart($this->id_cart); diff --git a/controllers/front/failIFrame.php b/controllers/front/failIFrame.php index 7752121a..c96b44a6 100755 --- a/controllers/front/failIFrame.php +++ b/controllers/front/failIFrame.php @@ -23,6 +23,7 @@ use Invertus\SaferPay\Config\SaferPayConfig; use Invertus\SaferPay\Controller\AbstractSaferPayController; +use Invertus\SaferPay\Enum\ControllerName; if (!defined('_PS_VERSION_')) { exit; @@ -76,7 +77,7 @@ public function setMedia() $failUrl = $this->context->link->getModuleLink( $this->module->name, - 'fail', + ControllerName::FAIL, [ 'cartId' => $cartId, 'secureKey' => $secureKey, diff --git a/controllers/front/failValidation.php b/controllers/front/failValidation.php index 991368c7..90951a60 100755 --- a/controllers/front/failValidation.php +++ b/controllers/front/failValidation.php @@ -52,14 +52,20 @@ public function postProcess() Tools::redirect($redirectLink); } + $order = new Order($orderId); - $order->setCurrentState(_SAFERPAY_PAYMENT_AUTHORIZATION_FAILED_); + + if (Validate::isLoadedObject($order)) { + $order->setCurrentState(_SAFERPAY_PAYMENT_AUTHORIZATION_FAILED_); + } + /** @var SaferPayOrderRepository $orderRepo */ $orderRepo = $this->module->getService(SaferPayOrderRepository::class); + /** @var CartDuplicationService $cartDuplicationService */ $cartDuplicationService = $this->module->getService(CartDuplicationService::class); - $saferPayOrderId = $orderRepo->getIdByOrderId($orderId); + $saferPayOrderId = $orderRepo->getIdByCartId($cartId); $saferPayOrder = new SaferPayOrder($saferPayOrderId); $saferPayOrder->canceled = 1; $saferPayOrder->update(); diff --git a/controllers/front/iframe.php b/controllers/front/iframe.php index 53a9659f..7fb34709 100755 --- a/controllers/front/iframe.php +++ b/controllers/front/iframe.php @@ -23,10 +23,9 @@ use Invertus\SaferPay\Config\SaferPayConfig; use Invertus\SaferPay\Controller\AbstractSaferPayController; -use Invertus\SaferPay\EntityBuilder\SaferPayOrderBuilder; +use Invertus\SaferPay\Controller\Front\CheckoutController; +use Invertus\SaferPay\Core\Payment\DTO\CheckoutData; use Invertus\SaferPay\Enum\ControllerName; -use Invertus\SaferPay\Repository\SaferPayCardAliasRepository; -use Invertus\SaferPay\Service\SaferPayInitialize; if (!defined('_PS_VERSION_')) { exit; @@ -73,48 +72,35 @@ public function postProcess() if (!Validate::isLoadedObject($customer)) { Tools::redirect($redirectLink); } - - $currency = $this->context->currency; - $total = (float) $cart->getOrderTotal(); - - $orderId = Order::getOrderByCartId($cart->id); - if (!$orderId) { - $paymentMethod = Tools::getValue('saved_card_method'); - $this->module->validateOrder( - $cart->id, - Configuration::get(SaferPayConfig::SAFERPAY_ORDER_STATE_CHOICE_AWAITING_PAYMENT), - $total, - $paymentMethod, - null, - [], - (int) $currency->id, - false, - $customer->secure_key - ); - } } public function initContent() { parent::initContent(); + $paymentMethod = Tools::getValue('saved_card_method'); $selectedCard = Tools::getValue("selectedCreditCard_{$paymentMethod}"); + if (!SaferPayConfig::isVersion17()) { $selectedCard = Tools::getValue("saved_card_{$paymentMethod}"); } - /** @var SaferPayOrderBuilder $saferPayOrderBuilder */ - $saferPayOrderBuilder = $this->module->getService(SaferPayOrderBuilder::class); - $isBusinessLicence = Tools::getValue(\Invertus\SaferPay\Config\SaferPayConfig::IS_BUSINESS_LICENCE); - /** @var SaferPayInitialize $initializeService */ - $initializeService = $this->module->getService(SaferPayInitialize::class); try { - /** @var SaferPayCardAliasRepository $cardAliasRep */ - $cardAliasRep = $this->module->getService(SaferPayCardAliasRepository::class); - $alias = $cardAliasRep->getSavedCardAliasFromId($selectedCard); - $response = $initializeService->initialize($paymentMethod, $isBusinessLicence, $selectedCard, $alias); - } catch (Exception $e) { - $redirectLink = $this->context->link->getModuleLink( + /** @var CheckoutController $checkoutController */ + $checkoutController = $this->module->getService(CheckoutController::class); + + // refactor it to create checkout data from validator request + $checkoutData = CheckoutData::create( + (int) $this->context->cart->id, + $paymentMethod, + (int) Tools::getValue(SaferPayConfig::IS_BUSINESS_LICENCE), + $selectedCard + ); + + $redirectUrl = $checkoutController->execute($checkoutData); + + } catch (\Exception $exception) { + $redirectUrl = $this->context->link->getModuleLink( $this->module->name, ControllerName::FAIL, [ @@ -125,22 +111,18 @@ public function initContent() ], true ); - $this->redirectWithNotifications($redirectLink); + $this->redirectWithNotifications($redirectUrl); } - $saferPayOrderBuilder->create( - $response, - $this->context->cart, - $this->context->customer, - true, - $isBusinessLicence - ); + $this->context->smarty->assign([ - 'redirect' => $response->Redirect->RedirectUrl, + 'redirect' => $redirectUrl, ]); + if (SaferPayConfig::isVersion17()) { $this->setTemplate(SaferPayConfig::SAFERPAY_TEMPLATE_LOCATION . '/front/saferpay_iframe.tpl'); return; } + $this->setTemplate('saferpay_iframe_16.tpl'); } diff --git a/controllers/front/notify.php b/controllers/front/notify.php index ce55cc26..8f2c09d1 100755 --- a/controllers/front/notify.php +++ b/controllers/front/notify.php @@ -24,7 +24,11 @@ use Invertus\SaferPay\Api\Enum\TransactionStatus; use Invertus\SaferPay\Config\SaferPayConfig; use Invertus\SaferPay\Controller\AbstractSaferPayController; -use Invertus\SaferPay\DTO\Response\Assert\AssertBody; +use Invertus\SaferPay\Core\Order\Action\UpdateOrderStatusAction; +use Invertus\SaferPay\Core\Order\Action\UpdateSaferPayOrderAction; +use Invertus\SaferPay\Core\Payment\DTO\CheckoutData; +use Invertus\SaferPay\Processor\CheckoutProcessor; +use Invertus\SaferPay\Repository\SaferPayOrderRepository; use Invertus\SaferPay\Service\SaferPayOrderStatusService; use Invertus\SaferPay\Service\TransactionFlow\SaferPayTransactionAssertion; @@ -35,6 +39,7 @@ class SaferPayOfficialNotifyModuleFrontController extends AbstractSaferPayController { const FILENAME = 'notify'; + const SAFERPAY_ORDER_AUTHORIZE_ACTION = 'AUTHORIZE'; /** * This code is being called by SaferPay by using NotifyUrl in InitializeRequest. @@ -44,7 +49,6 @@ class SaferPayOfficialNotifyModuleFrontController extends AbstractSaferPayContro public function postProcess() { $cartId = Tools::getValue('cartId'); - $orderId = Tools::getValue('orderId'); $secureKey = Tools::getValue('secureKey'); $cart = new Cart($cartId); @@ -63,20 +67,48 @@ public function postProcess() try { $assertResponseBody = $this->assertTransaction($cartId); + /** @var SaferPayOrderRepository $saferPayOrderRepository */ + $saferPayOrderRepository = $this->module->getService(SaferPayOrderRepository::class); + $saferPayOrderId = $saferPayOrderRepository->getIdByCartId($cartId); + + /** @var UpdateSaferPayOrderAction $updateSaferPayOrderAction */ + $updateSaferPayOrderAction = $this->module->getService(UpdateSaferPayOrderAction::class); + $updateSaferPayOrderAction->run(new SaferPayOrder($saferPayOrderId), self::SAFERPAY_ORDER_AUTHORIZE_ACTION); + + // If order does not exist but assertion is valid that means order authorized or captured. + $orderId = Order::getIdByCartId($cartId); + + if (!$orderId) { + /** @var CheckoutProcessor $checkoutProcessor **/ + $checkoutProcessor = $this->module->getService(CheckoutProcessor::class); + $checkoutData = CheckoutData::create( + (int) $cart->id, + $assertResponseBody->getPaymentMeans()->getBrand()->getPaymentMethod(), + (int) Configuration::get(SaferPayConfig::IS_BUSINESS_LICENCE) + ); + + $checkoutData->setIsAuthorizedOrder(true); + $checkoutData->setOrderStatus($assertResponseBody->getTransaction()->getStatus()); + + $checkoutProcessor->run($checkoutData); + + $orderId = Order::getIdByCartId($cart->id); + } + //TODO look into pipeline design pattern to use when object is modified in multiple places to avoid this issue. //NOTE must be left below assert action to get newest information. $order = new Order($orderId); - /** @var SaferPayOrderStatusService $orderStatusService */ - $orderStatusService = $this->module->getService(SaferPayOrderStatusService::class); - - $paymentBehaviourWithout3DS = (int) Configuration::get(SaferPayConfig::PAYMENT_BEHAVIOR_WITHOUT_3D); + /** @var UpdateOrderStatusAction $updateOrderStatusAction **/ + $updateOrderStatusAction = $this->module->getService(UpdateOrderStatusAction::class); + $updateOrderStatusAction->run((int) $orderId, (int) Configuration::get('SAFERPAY_PAYMENT_AUTHORIZED')); - if ( - !$assertResponseBody->getLiability()->getLiabilityShift() && + if (!$assertResponseBody->getLiability()->getLiabilityShift() && in_array($order->payment, SaferPayConfig::SUPPORTED_3DS_PAYMENT_METHODS) && - $paymentBehaviourWithout3DS === SaferPayConfig::PAYMENT_BEHAVIOR_WITHOUT_3D_CANCEL + (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); die($this->module->l('Liability shift is false', self::FILENAME)); @@ -85,12 +117,11 @@ public function postProcess() //NOTE to get latest information possible and not override new information. $order = new Order($orderId); - $paymentBehaviour = (int) Configuration::get(SaferPayConfig::PAYMENT_BEHAVIOR); - - if ( - $paymentBehaviour === SaferPayConfig::DEFAULT_PAYMENT_BEHAVIOR_CAPTURE && + if ((int) Configuration::get(SaferPayConfig::PAYMENT_BEHAVIOR) === SaferPayConfig::DEFAULT_PAYMENT_BEHAVIOR_CAPTURE && $assertResponseBody->getTransaction()->getStatus() !== TransactionStatus::CAPTURED ) { + /** @var SaferPayOrderStatusService $orderStatusService */ + $orderStatusService = $this->module->getService(SaferPayOrderStatusService::class); $orderStatusService->capture($order); } } catch (Exception $e) { @@ -112,19 +143,11 @@ public function postProcess() die($this->module->l('Success', self::FILENAME)); } - /** - * @param int $cartId - * - * @return AssertBody - * @throws Exception - */ - private function assertTransaction($cartId) - { + private function assertTransaction($cartId) { /** @var SaferPayTransactionAssertion $transactionAssert */ $transactionAssert = $this->module->getService(SaferPayTransactionAssertion::class); - $assertionResponse = $transactionAssert->assert(Order::getOrderByCartId($cartId), true); - return $assertionResponse; + return $transactionAssert->assert($cartId); } protected function displayMaintenancePage() diff --git a/controllers/front/pendingNotify.php b/controllers/front/pendingNotify.php index 208aa062..43c6639a 100755 --- a/controllers/front/pendingNotify.php +++ b/controllers/front/pendingNotify.php @@ -43,22 +43,24 @@ class SaferPayOfficialPendingNotifyModuleFrontController extends AbstractSaferPa public function postProcess() { $cartId = Tools::getValue('cartId'); - $orderId = Tools::getValue('orderId'); $secureKey = Tools::getValue('secureKey'); $cart = new Cart($cartId); + if ($cart->secure_key !== $secureKey) { die($this->module->l('Error. Insecure cart', self::FILENAME)); } + /** @var SaferPayOrderRepository $saferPayOrderRepository */ $saferPayOrderRepository = $this->module->getService(SaferPayOrderRepository::class); - $saferPayOrderId = $saferPayOrderRepository->getIdByOrderId($orderId); + $saferPayOrderId = $saferPayOrderRepository->getIdByCartId($cartId); $orderRefunds = $saferPayOrderRepository->getOrderRefunds($saferPayOrderId); foreach ($orderRefunds as $orderRefund) { if ($orderRefund['status'] === SaferPayConfig::TRANSACTION_STATUS_CAPTURED) { continue; } + $assertRefundResponse = $this->assertRefundTransaction($orderRefund['transaction_id']); if ($assertRefundResponse->getStatus() === SaferPayConfig::TRANSACTION_STATUS_CAPTURED) { $this->handleCapturedRefund($orderRefund['id_saferpay_order_refund']); diff --git a/controllers/front/return.php b/controllers/front/return.php index 80e18760..878c6ced 100755 --- a/controllers/front/return.php +++ b/controllers/front/return.php @@ -21,10 +21,15 @@ *@license SIX Payment Services */ +use Invertus\SaferPay\Api\Enum\TransactionStatus; use Invertus\SaferPay\Config\SaferPayConfig; use Invertus\SaferPay\Controller\AbstractSaferPayController; -use Invertus\SaferPay\DTO\Response\Assert\AssertBody; +use Invertus\SaferPay\Core\Payment\DTO\CheckoutData; +use Invertus\SaferPay\Enum\ControllerName; +use Invertus\SaferPay\Service\SaferPayOrderStatusService; use Invertus\SaferPay\Service\TransactionFlow\SaferPayTransactionAssertion; +use Invertus\SaferPay\Processor\CheckoutProcessor; +use Invertus\SaferPay\Service\TransactionFlow\SaferPayTransactionAuthorization; if (!defined('_PS_VERSION_')) { exit; @@ -45,8 +50,7 @@ public function postProcess() $fieldToken = Tools::getValue('fieldToken'); $moduleId = $this->module->id; $selectedCard = Tools::getValue('selectedCard'); - - $orderId = Order::getOrderByCartId($cartId); + $orderId = Tools::getValue('orderId'); $cart = new Cart($cartId); @@ -65,7 +69,62 @@ public function postProcess() } try { - $this->assertTransaction($orderId); + if ($isBusinessLicence) { + $response = $this->executeTransaction((int) $cartId, (int) $selectedCard); + } else { + $response = $this->executePaymentPageAssertion((int) $cartId, (int) $isBusinessLicence); + } + + $checkoutData = CheckoutData::create( + (int) $cartId, + $response->getPaymentMeans()->getBrand()->getPaymentMethod(), + (int) $isBusinessLicence + ); + + $checkoutData->setIsAuthorizedOrder(true); + $checkoutData->setOrderStatus($response->getTransaction()->getStatus()); + + /** @var CheckoutProcessor $checkoutProcessor **/ + $checkoutProcessor = $this->module->getService(CheckoutProcessor::class); + $checkoutProcessor->run($checkoutData); + + $orderId = \Order::getIdByCartId($cartId); + + $paymentBehaviourWithout3DS = (int) Configuration::get(SaferPayConfig::PAYMENT_BEHAVIOR_WITHOUT_3D); + + /** @var SaferPayOrderStatusService $orderStatusService */ + $orderStatusService = $this->module->getService(SaferPayOrderStatusService::class); + + $order = new Order($orderId); + + if ( + (!$response->getLiability()->getLiabilityShift() && + in_array($order->payment, SaferPayConfig::SUPPORTED_3DS_PAYMENT_METHODS) && + $paymentBehaviourWithout3DS === SaferPayConfig::PAYMENT_BEHAVIOR_WITHOUT_3D_CANCEL) || + $response->getTransaction()->getStatus() === SaferPayConfig::TRANSACTION_STATUS_CANCELED + ) { + $orderStatusService->cancel($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 + )); + } + + if ((int) Configuration::get(SaferPayConfig::PAYMENT_BEHAVIOR) === SaferPayConfig::DEFAULT_PAYMENT_BEHAVIOR_CAPTURE && + $response->getTransaction()->getStatus() !== TransactionStatus::CAPTURED + ) { + $orderStatusService->capture(new Order($orderId)); + } Tools::redirect($this->context->link->getModuleLink( $this->module->name, @@ -101,32 +160,43 @@ public function postProcess() } } - /** - * @param $cartId - * @return AssertBody - * @throws Exception - */ - private function assertTransaction($orderId) - { - /** @var SaferPayTransactionAssertion $transactionAssert */ - $transactionAssert = $this->module->getService(SaferPayTransactionAssertion::class); - $assertionResponse = $transactionAssert->assert($orderId, false); - - return $assertionResponse; - } - private function getSuccessControllerName($isBusinessLicence, $fieldToken) { - $successController = 'success'; + $successController = ControllerName::SUCCESS; if ($isBusinessLicence) { - $successController = 'successIFrame'; + $successController = ControllerName::SUCCESS_IFRAME; } if ($fieldToken) { - $successController = 'successHosted'; + $successController = ControllerName::SUCCESS_HOSTED; } return $successController; } + + private function executeTransaction(int $orderId, int $selectedCard) + { + /** @var SaferPayTransactionAuthorization $saferPayTransactionAuthorization */ + $saferPayTransactionAuthorization = $this->module->getService(SaferPayTransactionAuthorization::class); + + $response = $saferPayTransactionAuthorization->authorize( + $orderId, + $selectedCard === SaferPayConfig::CREDIT_CARD_OPTION_SAVE, + $selectedCard + ); + + return $response; + } + + private function executePaymentPageAssertion(int $cartId, int $isBusinessLicence) + { + + /** @var SaferPayTransactionAssertion $transactionAssert */ + $transactionAssert = $this->module->getService(SaferPayTransactionAssertion::class); + $assertionResponse = $transactionAssert->assert($cartId); + + + return $assertionResponse; + } } diff --git a/controllers/front/successHosted.php b/controllers/front/successHosted.php index ee91462b..9998633d 100755 --- a/controllers/front/successHosted.php +++ b/controllers/front/successHosted.php @@ -34,7 +34,7 @@ class SaferPayOfficialSuccessHostedModuleFrontController extends AbstractSaferPayController { - const FILENAME = 'successHosted'; + const FILE_NAME = 'successHosted'; protected $display_header = false; protected $display_footer = false; @@ -53,62 +53,15 @@ public function postProcess() $orderId = Tools::getValue('orderId'); $secureKey = Tools::getValue('secureKey'); $moduleId = Tools::getValue('moduleId'); - $selectedCard = Tools::getValue('selectedCard'); $cart = new Cart($cartId); if ($cart->secure_key !== $secureKey) { - Tools::redirect($this->getOrderLink()); + $this->errors[] = $this->module->l('Failed to validate cart.', self::FILE_NAME); + + $this->redirectWithNotifications($this->getOrderLink()); } try { - /** @var SaferPayOrderStatusService $orderStatusService */ - $orderStatusService = $this->module->getService(SaferPayOrderStatusService::class); - - $order = new Order($orderId); - - /** @var SaferPayTransactionAuthorization $saferPayTransactionAuthorization */ - $saferPayTransactionAuthorization = $this->module->getService(SaferPayTransactionAuthorization::class); - - $authResponseBody = $saferPayTransactionAuthorization->authorize( - $orderId, - (int) $selectedCard === SaferPayConfig::CREDIT_CARD_OPTION_SAVE, - $selectedCard - ); - - $paymentBehaviourWithout3DS = (int) Configuration::get(SaferPayConfig::PAYMENT_BEHAVIOR_WITHOUT_3D); - - if ( - (!$authResponseBody->getLiability()->getLiabilityShift() && - in_array($order->payment, SaferPayConfig::SUPPORTED_3DS_PAYMENT_METHODS) && - $paymentBehaviourWithout3DS === SaferPayConfig::PAYMENT_BEHAVIOR_WITHOUT_3D_CANCEL) || - $authResponseBody->getTransaction()->getStatus() === SaferPayConfig::TRANSACTION_STATUS_CANCELED - ) { - $orderStatusService->cancel($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 && $authResponseBody->getTransaction()->getStatus() !== TransactionStatus::CAPTURED) { - $orderStatusService->capture($order); - Tools::redirect($this->getOrderConfirmationLink($cartId, $moduleId, $orderId, $secureKey)); - } - Tools::redirect($this->getOrderConfirmationLink($cartId, $moduleId, $orderId, $secureKey)); } catch (Exception $e) { PrestaShopLogger::addLog( @@ -140,17 +93,6 @@ public function postProcess() } } - public function initContent() - { - parent::initContent(); - $cartId = Tools::getValue('cartId'); - $moduleId = Tools::getValue('moduleId'); - $orderId = Tools::getValue('orderId'); - $secureKey = Tools::getValue('secureKey'); - - Tools::redirect($this->getOrderConfirmationLink($cartId, $moduleId, $orderId, $secureKey)); - } - /** * @param int $cartId * @param int $moduleId diff --git a/controllers/front/successIFrame.php b/controllers/front/successIFrame.php index 8ede330d..a7ce3b5d 100755 --- a/controllers/front/successIFrame.php +++ b/controllers/front/successIFrame.php @@ -35,7 +35,7 @@ class SaferPayOfficialSuccessIFrameModuleFrontController extends AbstractSaferPayController { - const FILENAME = 'successIFrame'; + const FILE_NAME = 'successIFrame'; protected $display_header = false; protected $display_footer = false; @@ -48,83 +48,50 @@ public function init() parent::init(); } - public function postProcess() + public function postProcess() // todo refactor this by the logic provided { $cartId = Tools::getValue('cartId'); $orderId = Tools::getValue('orderId'); $secureKey = Tools::getValue('secureKey'); - $selectedCard = Tools::getValue('selectedCard'); $moduleId = Tools::getValue('moduleId'); $cart = new Cart($cartId); - if ($cart->secure_key !== $secureKey) { - Tools::redirect($this->getOrderLink()); - } - - /** @var SaferPayTransactionAuthorization $saferPayTransactionAuthorization */ - $saferPayTransactionAuthorization = $this->module->getService(SaferPayTransactionAuthorization::class); - - /** @var SaferPayOrderStatusService $orderStatusService */ - $orderStatusService = $this->module->getService(SaferPayOrderStatusService::class); - $order = new Order($orderId); + if ($cart->secure_key !== $secureKey) { + $this->errors[] = $this->module->l('Failed to validate cart.', self::FILE_NAME); - 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_IFRAME, - [ - 'cartId' => $cartId, - 'secureKey' => $secureKey, - 'orderId' => $orderId, - \Invertus\SaferPay\Config\SaferPayConfig::IS_BUSINESS_LICENCE => true, - ], - true - )); + $this->redirectWithNotifications($this->getOrderLink()); } - $paymentBehaviourWithout3DS = (int) Configuration::get(SaferPayConfig::PAYMENT_BEHAVIOR_WITHOUT_3D); - - if ( - (!$authResponseBody->getLiability()->getLiabilityShift() && - in_array($order->payment, SaferPayConfig::SUPPORTED_3DS_PAYMENT_METHODS) && - $paymentBehaviourWithout3DS === SaferPayConfig::PAYMENT_BEHAVIOR_WITHOUT_3D_CANCEL) || - $authResponseBody->getTransaction()->getStatus() === SaferPayConfig::TRANSACTION_STATUS_CANCELED - ) { - $orderStatusService->cancel($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_IFRAME, - [ - 'cartId' => $cartId, - 'secureKey' => $secureKey, - 'orderId' => $orderId, - 'moduleId' => $moduleId, - ], + try { + Tools::redirect($this->getOrderConfirmationLink($cartId, $moduleId, $orderId, $secureKey)); + } catch (Exception $e) { + PrestaShopLogger::addLog( + sprintf( + '%s has caught an error: %s', + __CLASS__, + $e->getMessage() + ), + 1, + null, + null, + null, true - )); - } - - $orderStatusService->authorize($order); - - $paymentBehaviour = (int) Configuration::get(SaferPayConfig::PAYMENT_BEHAVIOR); + ); - if ( - $paymentBehaviour === SaferPayConfig::DEFAULT_PAYMENT_BEHAVIOR_CAPTURE && - $authResponseBody->getLiability()->getThreeDs() && - $authResponseBody->getTransaction()->getStatus() !== TransactionStatus::CAPTURED - ) { - $orderStatusService->capture($order); + Tools::redirect( + $this->context->link->getModuleLink( + $this->module->name, + ControllerName::FAIL_IFRAME, + [ + 'cartId' => $cartId, + 'secureKey' => $secureKey, + 'orderId' => $orderId, + \Invertus\SaferPay\Config\SaferPayConfig::IS_BUSINESS_LICENCE => true, + ], + true + ) + ); } } diff --git a/controllers/front/validation.php b/controllers/front/validation.php index 7a11958b..7ee765ce 100755 --- a/controllers/front/validation.php +++ b/controllers/front/validation.php @@ -23,9 +23,9 @@ use Invertus\SaferPay\Config\SaferPayConfig; use Invertus\SaferPay\Controller\AbstractSaferPayController; -use Invertus\SaferPay\Exception\Api\SaferPayApiException; +use Invertus\SaferPay\Core\Payment\DTO\CheckoutData; use Invertus\SaferPay\Service\SaferPayExceptionService; -use Invertus\SaferPay\Service\SaferPayInitialize; +use Invertus\SaferPay\Controller\Front\CheckoutController; if (!defined('_PS_VERSION_')) { exit; @@ -35,6 +35,9 @@ class SaferPayOfficialValidationModuleFrontController extends AbstractSaferPayCo { const FILENAME = 'validation'; + /** @var SaferPayOfficial */ + public $module; + /** * @see FrontController::postProcess() */ @@ -66,49 +69,39 @@ public function postProcess() } } if (!$authorized) { - $this->errors[] = - $this->module->l('This payment method is not available.', self::FILENAME); + $this->errors[] = $this->module->l('This payment method is not available.', self::FILENAME); $this->redirectWithNotifications($redirectLink); } - $customer = new Customer($cart->id_customer); - if (!Validate::isLoadedObject($customer)) { - Tools::redirect($redirectLink); + if (Order::getOrderByCartId($this->context->cart->id)) { + $this->errors[] = $this->module->l('Order already exists.', self::FILENAME); + $this->redirectWithNotifications($redirectLink); } - $currency = $this->context->currency; - $total = (float) $cart->getOrderTotal(); - - $orderId = Order::getOrderByCartId($cart->id); - if (!$orderId) { - $this->module->validateOrder( - $cart->id, - Configuration::get(SaferPayConfig::SAFERPAY_ORDER_STATE_CHOICE_AWAITING_PAYMENT), - $total, + try { + /** @var CheckoutController $checkoutController */ + $checkoutController = $this->module->getService(CheckoutController::class); + // refactor it to create checkout data from validator request + $checkoutData = CheckoutData::create( + (int) $this->context->cart->id, $paymentMethod, - null, - [], - (int) $currency->id, - false, - $customer->secure_key + (int) Tools::getValue(SaferPayConfig::IS_BUSINESS_LICENCE) ); - } - /** @var SaferPayInitialize $initializeService */ - $initializeService = $this->module->getService(SaferPayInitialize::class); - try { - $isBusinessLicence = Tools::getValue(SaferPayConfig::IS_BUSINESS_LICENCE); - $initializeBody = $initializeService->initialize($paymentMethod, $isBusinessLicence); - } catch (SaferPayApiException $e) { + $redirectLink = $checkoutController->execute($checkoutData); + + Tools::redirect($redirectLink); + } catch (\Exception $exception) { /** @var SaferPayExceptionService $exceptionService */ $exceptionService = $this->module->getService(SaferPayExceptionService::class); - $this->errors[] = $exceptionService->getErrorMessageForException($e, $exceptionService->getErrorMessages()); + $this->errors[] = $exceptionService->getErrorMessageForException($exception, $exceptionService->getErrorMessages()); + $redirectLink = $this->context->link->getModuleLink( $this->module->name, 'fail', [ 'cartId' => $this->context->cart->id, - 'orderId' => Order::getOrderByCartId($this->context->cart->id), + 'orderId' => Order::getIdByCartId($this->context->cart->id), 'secureKey' => $this->context->cart->secure_key, 'moduleId' => $this->module->id, ], @@ -116,16 +109,5 @@ public function postProcess() ); $this->redirectWithNotifications($redirectLink); } - /** @var Invertus\SaferPay\EntityBuilder\SaferPayOrderBuilder $saferPayOrderBuilder */ - $saferPayOrderBuilder = $this->module->getService(\Invertus\SaferPay\EntityBuilder\SaferPayOrderBuilder::class); - $saferPayOrderBuilder->create( - $initializeBody, - $this->context->cart, - $this->context->customer, - false, - $isBusinessLicence - ); - - Tools::redirect($initializeBody->RedirectUrl); } } diff --git a/saferpayofficial.php b/saferpayofficial.php index a3d5fb1e..9904a91b 100755 --- a/saferpayofficial.php +++ b/saferpayofficial.php @@ -40,11 +40,15 @@ public function __construct($name = null) { $this->name = 'saferpayofficial'; $this->author = 'Invertus'; - $this->version = '1.1.7'; + $this->version = '1.2.0'; $this->module_key = '3d3506c3e184a1fe63b936b82bda1bdf'; $this->displayName = 'SaferpayOfficial'; $this->description = 'Saferpay Payment module'; $this->tab = 'payments_gateways'; + $this->ps_versions_compliancy = [ + 'min' => '1.6.1.0', + 'max' => '8.0.4', + ]; parent::__construct($name); @@ -111,6 +115,47 @@ public function getService($service) return $containerProvider->getService($service); } + public function hookActionObjectOrderPaymentAddAfter($params) + { + if (!isset($params['object'])) { + return; + } + + /** @var OrderPayment $orderPayment */ + $orderPayment = $params['object']; + + if (!Validate::isLoadedObject($orderPayment)) { + return; + } + + /** @var \Invertus\SaferPay\Repository\SaferPayOrderRepository $saferPayOrderRepository */ + $saferPayOrderRepository = $this->getService(\Invertus\SaferPay\Repository\SaferPayOrderRepository::class); + + $orders = Order::getByReference($orderPayment->order_reference); + + /** @var Order|bool $order */ + $order = $orders->getFirst(); + + if (!Validate::isLoadedObject($order) || !$order) { + return; + } + + $saferPayOrderId = (int) $saferPayOrderRepository->getIdByOrderId($order->id); + + if (!$saferPayOrderId) { + return; + } + + $brand = $saferPayOrderRepository->getPaymentBrandBySaferpayOrderId($saferPayOrderId); + + if (!$brand) { + return; + } + + $orderPayment->payment_method = 'Saferpay - ' . $brand; + $orderPayment->update(); + } + public function hookPaymentOptions($params) { /** @var Invertus\SaferPay\Service\SaferPayCartService $assertService */ diff --git a/src/Adapter/Configuration.php b/src/Adapter/Configuration.php new file mode 100644 index 00000000..0aad3b40 --- /dev/null +++ b/src/Adapter/Configuration.php @@ -0,0 +1,129 @@ + + *@copyright SIX Payment Services + *@license SIX Payment Services + */ + +namespace Invertus\SaferPay\Adapter; + +use Configuration as PrestaShopConfiguration; + +if (!defined('_PS_VERSION_')) { + exit; +} + +class Configuration +{ + + /** + * @var LegacyContext + */ + private $context; + + public function __construct(LegacyContext $context) + { + $this->context = $context; + } + + /** + * @param string $id + * @param $value + * @param int|null $shopId + * @return void + */ + public function set($id, $value, $shopId = null) + { + if (!$shopId) { + $shopId = $this->context->getShopId(); + } + + PrestaShopConfiguration::updateValue($id, $value, false, null, $shopId); + } + + /** + * @param string $id + * @param int|null $shopId + * @return false|string|null + */ + public function get($id, $shopId = null) + { + if (!$shopId) { + $shopId = $this->context->getShopId(); + } + + $result = PrestaShopConfiguration::get($id, null, null, $shopId); + + return $result ?: null; + } + + /** + * @param string $id + * @param int|null $shopId + * @return bool + */ + public function getAsBoolean($id, $shopId = null) + { + $result = $this->get($id, $shopId); + + if (in_array($result, ['null', 'false', '0', null, false, 0], true)) { + return false; + } + + return (bool) $result; + } + + /** + * @param string $id + * @param int|null $shopId + * @return int + */ + public function getAsInteger($id, $shopId = null) + { + $result = $this->get($id, $shopId); + + if (in_array($result, ['null', 'false', '0', null, false, 0], true)) { + return 0; + } + + return (int) $result; + } + + /** + * Removes by specific shop id + * + * @param string $id + * @param int|null $shopId + */ + public function remove($id, $shopId) + { + // making sure to set to null value only for single shop id + PrestaShopConfiguration::updateValue($id, null, false, null, $shopId); + } + + /** + * Drops configuration from all shops. + * + * @param string $id + */ + public function delete($id) + { + PrestaShopConfiguration::deleteByName($id); + } +} diff --git a/src/Adapter/LegacyContext.php b/src/Adapter/LegacyContext.php index 2a5c8e01..618d21cf 100755 --- a/src/Adapter/LegacyContext.php +++ b/src/Adapter/LegacyContext.php @@ -36,6 +36,11 @@ public function getContext() return Context::getContext(); } + public function getShopId() + { + return $this->getContext()->shop->id; + } + public function getCurrencyIsoCode() { return $this->getContext()->currency->iso_code; diff --git a/src/Api/ApiRequest.php b/src/Api/ApiRequest.php index 14e4fed5..a3526737 100755 --- a/src/Api/ApiRequest.php +++ b/src/Api/ApiRequest.php @@ -42,7 +42,7 @@ class ApiRequest * * @param string $url * @param array $params - * @return array |null + * @return object|null * @throws Exception */ public function post($url, $params = []) diff --git a/src/Api/Request/AssertService.php b/src/Api/Request/AssertService.php index 50563d3e..c430dbce 100755 --- a/src/Api/Request/AssertService.php +++ b/src/Api/Request/AssertService.php @@ -69,7 +69,7 @@ public function __construct( * @param AssertRequest $assertRequest * @param int $saferPayOrderId * - * @return array|null + * @return object|null * @throws \Exception */ public function assert(AssertRequest $assertRequest, $saferPayOrderId) @@ -78,8 +78,12 @@ public function assert(AssertRequest $assertRequest, $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) { - $assertApi = self::ASSERT_API_TRANSACTION; + $assertApi = self::ASSERT_API_TRANSACTION; } try { @@ -93,7 +97,7 @@ public function assert(AssertRequest $assertRequest, $saferPayOrderId) } /** - * @param object $responseBody + * @param object|null $responseBody * @param int $saferPayOrderId * * @return AssertBody diff --git a/src/Config/SaferPayConfig.php b/src/Config/SaferPayConfig.php index 3aef29da..6cf6f69e 100755 --- a/src/Config/SaferPayConfig.php +++ b/src/Config/SaferPayConfig.php @@ -50,7 +50,7 @@ class SaferPayConfig const CONFIGURATION_NAME = 'SAFERPAY_CONFIGURATION_NAME'; const CSS_FILE = 'SAFERPAY_CSS_FILE'; const TEST_SUFFIX = '_TEST'; - const API_VERSION = 1.32; + const API_VERSION = 1.37; const PAYMENT_METHODS = [ self::PAYMENT_ALIPAY, self::PAYMENT_AMEX, @@ -72,7 +72,6 @@ class SaferPayConfig self::PAYMENT_POSTFINANCE, self::PAYMENT_SOFORT, self::PAYMENT_TWINT, - self::PAYMENT_UNIONPAY, self::PAYMENT_VISA, self::PAYMENT_VPAY, self::PAYMENT_APPLEPAY, @@ -100,21 +99,22 @@ class SaferPayConfig const PAYMENT_POSTFINANCE = 'POSTFINANCE'; const PAYMENT_SOFORT = 'SOFORT'; const PAYMENT_TWINT = 'TWINT'; - const PAYMENT_UNIONPAY = 'UNIONPAY'; const PAYMENT_VISA = 'VISA'; const PAYMENT_VPAY = 'VPAY'; const PAYMENT_KLARNA = 'KLARNA'; const PAYMENT_APPLEPAY = 'APPLEPAY'; const PAYMENT_WLCRYPTOPAYMENTS = 'WLCRYPTOPAYMENTS'; const PAYMENT_GOOGLEPAY = 'GOOGLEPAY'; - const PAYMENT_MASTERPASS = 'MASTERPASS'; const PAYMENT_BONUS = 'BONUS'; const PAYMENT_LASTSCHRIFT = 'DIRECTDEBIT'; + const PAYMENT_ACCOUNTTOACCOUNT = 'ACCOUNTTOACCOUNT'; + const PAYMENT_PAYCONIQ = 'PAYCONIQ'; + const PAYMENT_CARD = 'CARD'; + const PAYMENT_POSTFINANCE_PAY = 'POSTFINANCEPAY'; const WALLET_PAYMENT_METHODS = [ self::PAYMENT_APPLEPAY, self::PAYMENT_GOOGLEPAY, - self::PAYMENT_MASTERPASS, ]; const PAYMENT_METHODS_KEYS = [ @@ -127,18 +127,20 @@ class SaferPayConfig 'KlarnaPayments' => self::PAYMENT_KLARNA, 'MaestroInternational' => self::PAYMENT_MAESTRO, 'Mastercard' => self::PAYMENT_MASTERCARD, - 'Masterpass' =>self::PAYMENT_MASTERPASS, 'myOne' => self::PAYMENT_MYONE, 'paydirekt' => self::PAYMENT_PAYDIREKT, 'PayPal' => self::PAYMENT_PAYPAL, 'Twint' => self::PAYMENT_TWINT, - 'UnionPay' => self::PAYMENT_UNIONPAY, 'Visa' => self::PAYMENT_VISA, 'WLCryptoPayments' => self::PAYMENT_WLCRYPTOPAYMENTS, 'Postcard' => self::PAYMENT_POSTCARD, 'BonusCard' => self::PAYMENT_BONUS, 'Lastschrift' => self::PAYMENT_LASTSCHRIFT, 'SOFORTUEBERWEISUNG' => self::PAYMENT_SOFORT, + 'AccountToAccount' => self::PAYMENT_ACCOUNTTOACCOUNT, + 'Payconiq' => self::PAYMENT_PAYCONIQ, + 'Card' => self::PAYMENT_CARD, + 'PostFinancePay' => self::PAYMENT_POSTFINANCE_PAY, ]; const FIELD_SUPPORTED_PAYMENT_METHODS = [ @@ -204,12 +206,12 @@ class SaferPayConfig self::PAYMENT_MASTERCARD, self::PAYMENT_VISA, self::PAYMENT_VPAY, - self::PAYMENT_UNIONPAY, self::PAYMENT_APPLEPAY, self::PAYMENT_AMEX, ]; const WEB_SERVICE_PASSWORD_PLACEHOLDER = '••••••'; + const SAFERPAY_PAYMENT_COMPLETED = 'SAFERPAY_PAYMENT_COMPLETED'; const SAFERPAY_PAYMENT_AUTHORIZED = 'SAFERPAY_PAYMENT_AUTHORIZED'; const SAFERPAY_PAYMENT_REJECTED = 'SAFERPAY_PAYMENT_REJECTED'; @@ -219,13 +221,19 @@ class SaferPayConfig const SAFERPAY_PAYMENT_PENDING_REFUND = 'SAFERPAY_PAYMENT_PENDING_REFUND'; const SAFERPAY_PAYMENT_CANCELED = 'SAFERPAY_PAYMENT_CANCELED'; const SAFERPAY_PAYMENT_AUTHORIZATION_FAILED = 'SAFERPAY_PAYMENT_AUTHORIZATION_FAILED'; + const SAFERPAY_SEND_ORDER_CONFIRMATION = 'SAFERPAY_SEND_ORDER_CONFIRMATION'; const SAFERPAY_SEND_NEW_ORDER_MAIL = 'SAFERPAY_SEND_NEW_ORDER_MAIL'; + const SAFERPAY_ALLOW_SAFERPAY_SEND_CUSTOMER_MAIL = 'SAFERPAY_ALLOW_SAFERPAY_SEND_CUSTOMER_MAIL'; + const SAFERPAY_ORDER_CREATION_AFTER_AUTHORIZATION = 'SAFERPAY_ORDER_CREATION_AFTER_AUTHORIZATION'; const STATUS_PS_OS_OUTOFSTOCK_PAID = 'PS_OS_OUTOFSTOCK_PAID'; const SAFERPAY_ORDER_STATE_CHOICE_AWAITING_PAYMENT = 'SAFERPAY_ORDER_STATE_CHOICE_AWAITING_PAYMENT'; + const SAFERPAY_PAYMENT_DESCRIPTION = 'SAFERPAY_PAYMENT_DESCRIPTION'; + const SAFERPAY_PAYMENT_DESCRIPTION_DEFAULT_VALUE = 'Prestashop Payment'; + const SAFERPAY_TEMPLATE_LOCATION = 'module:saferpayofficial/views/templates/'; const SAFERPAY_HOSTED_TEMPLATE_LOCATION = 'module:saferpayofficial/views/templates/front/hosted-templates/'; @@ -240,10 +248,6 @@ class SaferPayConfig const TRANSACTION_STATUS_PENDING = 'PENDING'; const TRANSACTION_STATUS_CANCELED = 'CANCELED'; - const LOG_TYPE_SUCCESS = 'SUCCESS'; - const LOG_TYPE_ERROR = 'ERROR'; - const LOG_TYPE_CRITICAL_ERROR = 'CRITICAL ERROR'; - const FIELDS_ACCESS_TOKEN = 'SAFERPAY_FIELDS_ACCESS_TOKEN'; const FIELDS_LIBRARY = 'SAFERPAY_FIELDS_JAVASCRIPT_LIBRARY'; const FIELDS_LIBRARY_DEFAULT_VALUE = 'https://www.saferpay.com/Fields/lib/1/saferpay-fields.js'; @@ -330,14 +334,17 @@ public static function getBaseUrl() public static function getDefaultConfiguration() { return [ - RequestHeader::SPEC_VERSION => '1.32', - RequestHeader::SPEC_REFUND_VERSION => '1.32', + RequestHeader::SPEC_VERSION => '1.37', + RequestHeader::SPEC_REFUND_VERSION => '1.37', RequestHeader::RETRY_INDICATOR => 0, SaferPayConfig::PAYMENT_BEHAVIOR => 1, SaferPayConfig::PAYMENT_BEHAVIOR_WITHOUT_3D => 1, SaferPayConfig::SAFERPAY_SEND_ORDER_CONFIRMATION => 1, + SaferPayConfig::SAFERPAY_ALLOW_SAFERPAY_SEND_CUSTOMER_MAIL => 1, + SaferPayConfig::SAFERPAY_PAYMENT_DESCRIPTION => self::SAFERPAY_PAYMENT_DESCRIPTION_DEFAULT_VALUE, SaferPayConfig::FIELDS_LIBRARY => self::FIELDS_LIBRARY_DEFAULT_VALUE, SaferPayConfig::FIELDS_LIBRARY . SaferPayConfig::TEST_SUFFIX => self::FIELDS_LIBRARY_TEST_DEFAULT_VALUE, + self::SAFERPAY_ORDER_CREATION_AFTER_AUTHORIZATION => 0, self::TEST_MODE => 1, self::HOSTED_FIELDS_TEMPLATE => self::HOSTED_FIELDS_TEMPLATE_DEFAULT, self::SAFERPAY_ORDER_STATE_CHOICE_AWAITING_PAYMENT => Configuration::get( @@ -352,6 +359,8 @@ public static function getUninstallConfiguration() RequestHeader::SPEC_VERSION, RequestHeader::RETRY_INDICATOR, RequestHeader::SPEC_REFUND_VERSION, + self::SAFERPAY_ALLOW_SAFERPAY_SEND_CUSTOMER_MAIL, + self::SAFERPAY_PAYMENT_DESCRIPTION, self::TEST_MODE, self::USERNAME, self::PASSWORD, @@ -374,6 +383,7 @@ public static function getUninstallConfiguration() self::FIELDS_ACCESS_TOKEN . self::TEST_SUFFIX, self::FIELDS_LIBRARY, self::FIELDS_LIBRARY . self::TEST_SUFFIX, + self::SAFERPAY_ORDER_CREATION_AFTER_AUTHORIZATION, ]; } diff --git a/src/Controller/Front/CheckoutController.php b/src/Controller/Front/CheckoutController.php new file mode 100644 index 00000000..979bba58 --- /dev/null +++ b/src/Controller/Front/CheckoutController.php @@ -0,0 +1,70 @@ + + *@copyright SIX Payment Services + *@license SIX Payment Services + */ + +namespace Invertus\SaferPay\Controller\Front; + +if (!defined('_PS_VERSION_')) { + exit; +} + +use Invertus\SaferPay\Core\Payment\DTO\CheckoutData; +use Invertus\SaferPay\Processor\CheckoutProcessor; + +class CheckoutController +{ + /** + * @var CheckoutProcessor + */ + private $checkoutProcessor; + + public function __construct( + CheckoutProcessor $checkoutProcessor + ) { + $this->checkoutProcessor = $checkoutProcessor; + } + + public function execute(CheckoutData $checkoutData) + { + $response = $this->checkoutProcessor->run($checkoutData); + + return $this->getRedirectionUrl($response); + } + + /** + * @param object $initializeBody + * + * @return string + */ + private function getRedirectionUrl($initializeBody) + { + if (isset($initializeBody->RedirectUrl)) { + return $initializeBody->RedirectUrl; + } + + if (isset($initializeBody->Redirect->RedirectUrl)) { + return $initializeBody->Redirect->RedirectUrl; + } + + return ''; + } +} diff --git a/src/Controller/Front/index.php b/src/Controller/Front/index.php new file mode 100644 index 00000000..7487f261 --- /dev/null +++ b/src/Controller/Front/index.php @@ -0,0 +1,31 @@ + + *@copyright SIX Payment Services + *@license SIX Payment Services + */ +header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); +header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT"); + +header("Cache-Control: no-store, no-cache, must-revalidate"); +header("Cache-Control: post-check=0, pre-check=0", false); +header("Pragma: no-cache"); + +header("Location: ../"); +exit; diff --git a/src/Core/Order/Action/UpdateOrderStatusAction.php b/src/Core/Order/Action/UpdateOrderStatusAction.php new file mode 100644 index 00000000..316bbd66 --- /dev/null +++ b/src/Core/Order/Action/UpdateOrderStatusAction.php @@ -0,0 +1,65 @@ + + *@copyright SIX Payment Services + *@license SIX Payment Services + */ + +namespace Invertus\SaferPay\Core\Order\Action; + +use Invertus\SaferPay\Exception\CouldNotChangeOrderStatus; +use Order; + +if (!defined('_PS_VERSION_')) { + exit; +} + +class UpdateOrderStatusAction +{ + /** + * @param int $orderId + * @param int $orderStatusId + * + * @return void + * @throws CouldNotChangeOrderStatus + */ + public function run($orderId, $orderStatusId) + { + try { + /** @var \Order|null $order */ + $order = new Order($orderId); + } catch (\Exception $exception) { + throw CouldNotChangeOrderStatus::unknownError($exception); + } + + if (!$order) { + throw CouldNotChangeOrderStatus::failedToFindOrder($orderId); + } + + try { + if ((int) $order->getCurrentState() !== (int) $orderStatusId) { + $order->setCurrentState($orderStatusId); + $order->update(); + } + } catch (\Exception $exception) { + throw CouldNotChangeOrderStatus::unknownError($exception); + } + + } +} diff --git a/src/Core/Order/Action/UpdateSaferPayOrderAction.php b/src/Core/Order/Action/UpdateSaferPayOrderAction.php new file mode 100644 index 00000000..dc48a47c --- /dev/null +++ b/src/Core/Order/Action/UpdateSaferPayOrderAction.php @@ -0,0 +1,65 @@ + + *@copyright SIX Payment Services + *@license SIX Payment Services + */ + +namespace Invertus\SaferPay\Core\Order\Action; + +use SaferPayOrder; + +if (!defined('_PS_VERSION_')) { + exit; +} + +class UpdateSaferPayOrderAction +{ + const ACTION_AUTHORIZE = 'AUTHORIZE'; + + /** + * @param SaferPayOrder $saferPayOrder + * @param string $action + * @return void + */ + public function run(SaferPayOrder $saferPayOrder, $action) + { + switch ($action) { + case self::ACTION_AUTHORIZE: + $this->authorizeSaferPayOrder($saferPayOrder); + break; + default: + throw new \InvalidArgumentException('Unsupported saferpay order action provided.'); + } + } + + /** + * @param SaferPayOrder $saferPayOrder + * @return void + */ + private function authorizeSaferPayOrder($saferPayOrder) + { + if ($saferPayOrder->authorized) { + return; + } + + $saferPayOrder->authorized = 1; + $saferPayOrder->update(); + } +} diff --git a/src/Core/Order/Action/index.php b/src/Core/Order/Action/index.php new file mode 100644 index 00000000..ee622726 --- /dev/null +++ b/src/Core/Order/Action/index.php @@ -0,0 +1,31 @@ + + *@copyright SIX Payment Services + *@license SIX Payment Services + */ +header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); +header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); + +header('Cache-Control: no-store, no-cache, must-revalidate'); +header('Cache-Control: post-check=0, pre-check=0', false); +header('Pragma: no-cache'); + +header('Location: ../'); +exit; diff --git a/src/Core/Payment/DTO/CheckoutData.php b/src/Core/Payment/DTO/CheckoutData.php new file mode 100644 index 00000000..7281cfe9 --- /dev/null +++ b/src/Core/Payment/DTO/CheckoutData.php @@ -0,0 +1,187 @@ + + *@copyright SIX Payment Services + *@license SIX Payment Services + */ + +namespace Invertus\SaferPay\Core\Payment\DTO; + +use Configuration; +use Invertus\SaferPay\Config\SaferPayConfig; + +if (!defined('_PS_VERSION_')) { + exit; +} + +class CheckoutData +{ + private $cartId; + private $paymentMethod; + private $isBusinessLicense; + private $selectedCard; + private $fieldToken; + private $successController; + private $isTransaction; + private $createAfterAuthorization; + private $isAuthorizedOrder; + private $status; + + public function __construct( + $cartId, + $paymentMethod, + $isBusinessLicense, + $selectedCard = -1, + $fieldToken = null, + $successController = null, + $isTransaction = false + ) + { + $this->cartId = $cartId; + $this->paymentMethod = $paymentMethod; + $this->isBusinessLicense = $isBusinessLicense; + $this->selectedCard = $selectedCard; + $this->fieldToken = $fieldToken; + $this->successController = $successController; + $this->isTransaction = $isTransaction; + $this->createAfterAuthorization = Configuration::get(SaferPayConfig::SAFERPAY_ORDER_CREATION_AFTER_AUTHORIZATION); + $this->isAuthorizedOrder = false; + } + + public static function create( + $cartId, + $paymentMethod, + $isBusinessLicense, + $selectedCard = -1, + $fieldToken = null, + $successController = null, + $isTransaction = false + ) + { + return new self( + $cartId, + $paymentMethod, + $isBusinessLicense, + $selectedCard, + $fieldToken, + $successController, + $isTransaction + ); + } + + /** + * @return int $cartId + */ + public function getCartId() + { + return $this->cartId; + } + + /** + * @return string + */ + public function getPaymentMethod() + { + return $this->paymentMethod; + } + + /** + * @return int + */ + public function getIsBusinessLicense() + { + return $this->isBusinessLicense; + } + + /** + * @return int|mixed + */ + public function getSelectedCard() + { + return $this->selectedCard; + } + + /** + * @return string|null + */ + public function getFieldToken() + { + return $this->fieldToken; + } + + /** + * @return string|null + */ + public function getSuccessController() + { + return $this->successController; + } + + /** + * @return bool + */ + public function getIsTransaction() + { + return $this->isTransaction; + } + + /** + * @return bool + */ + public function getCreateAfterAuthorization() + { + return (bool) $this->createAfterAuthorization; + } + + /** + * @return bool + */ + public function getIsAuthorizedOrder() + { + return $this->isAuthorizedOrder; + } + + /** + * @return string + */ + public function getOrderStatus() + { + return $this->status; + } + + /** + * @param bool $isAuthorized + * + * @return void + */ + public function setIsAuthorizedOrder($isAuthorized) + { + $this->isAuthorizedOrder = $isAuthorized; + } + + /** + * @param string $status + * + * @return void + */ + public function setOrderStatus($status) + { + $this->status = $status; + } +} \ No newline at end of file diff --git a/src/Core/Payment/DTO/index.php b/src/Core/Payment/DTO/index.php new file mode 100644 index 00000000..ee622726 --- /dev/null +++ b/src/Core/Payment/DTO/index.php @@ -0,0 +1,31 @@ + + *@copyright SIX Payment Services + *@license SIX Payment Services + */ +header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); +header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); + +header('Cache-Control: no-store, no-cache, must-revalidate'); +header('Cache-Control: post-check=0, pre-check=0', false); +header('Pragma: no-cache'); + +header('Location: ../'); +exit; diff --git a/src/Core/Payment/index.php b/src/Core/Payment/index.php new file mode 100644 index 00000000..ee622726 --- /dev/null +++ b/src/Core/Payment/index.php @@ -0,0 +1,31 @@ + + *@copyright SIX Payment Services + *@license SIX Payment Services + */ +header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); +header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); + +header('Cache-Control: no-store, no-cache, must-revalidate'); +header('Cache-Control: post-check=0, pre-check=0', false); +header('Pragma: no-cache'); + +header('Location: ../'); +exit; diff --git a/src/DTO/Request/Assert/AssertRequest.php b/src/DTO/Request/Assert/AssertRequest.php index 5b3b90c7..0ed01f54 100755 --- a/src/DTO/Request/Assert/AssertRequest.php +++ b/src/DTO/Request/Assert/AssertRequest.php @@ -29,6 +29,8 @@ exit; } +// TODO: A lot of these request are the same, we can at least put them under an interface + class AssertRequest { diff --git a/src/DTO/Request/Initialize/InitializeRequest.php b/src/DTO/Request/Initialize/InitializeRequest.php index 9b10f015..192dee0f 100755 --- a/src/DTO/Request/Initialize/InitializeRequest.php +++ b/src/DTO/Request/Initialize/InitializeRequest.php @@ -226,11 +226,14 @@ public function getAsArray() if ($this->notification !== null) { $return['Notification'] = [ - 'PayerEmail' => $this->notification->getPayerEmail(), 'MerchantEmails' => [$this->notification->getMerchantEmail()], 'SuccessNotifyUrl' => $this->notification->getNotifyUrl(), 'FailNotifyUrl' => $this->notification->getNotifyUrl(), ]; + + if (\Configuration::get(SaferPayConfig::SAFERPAY_ALLOW_SAFERPAY_SEND_CUSTOMER_MAIL)) { + $return['Notification'] = ['PayerEmail' => $this->notification->getPayerEmail()]; + } } if ($this->configSet) { diff --git a/src/DTO/Request/Payment.php b/src/DTO/Request/Payment.php index aeaa7247..5b3f910c 100755 --- a/src/DTO/Request/Payment.php +++ b/src/DTO/Request/Payment.php @@ -50,9 +50,9 @@ class Payment private $payerNote = null; /** - * @var null + * @var string */ - private $description = 'PrestaShop payment'; + private $description; /** * @return string @@ -119,7 +119,7 @@ public function setPayerNote($payerNote) } /** - * @return null + * @return string */ public function getDescription() { @@ -127,7 +127,7 @@ public function getDescription() } /** - * @param null $description + * @param string $description */ public function setDescription($description) { diff --git a/src/DTO/Response/ThreeDs.php b/src/DTO/Response/ThreeDs.php index e764ff03..cd69013a 100755 --- a/src/DTO/Response/ThreeDs.php +++ b/src/DTO/Response/ThreeDs.php @@ -34,11 +34,6 @@ class ThreeDs */ private $authenticated; - /** - * @var string|null - */ - private $liabilityShift; - /** * @var string|null */ @@ -52,14 +47,12 @@ class ThreeDs /** * ThreeDs constructor. * @param string $authenticated - * @param string $liabilityShift * @param string $xid * @param string $verificationValue */ - public function __construct($authenticated = null, $liabilityShift = null, $xid = null, $verificationValue = null) + public function __construct($authenticated = null, $xid = null, $verificationValue = null) { $this->authenticated = $authenticated; - $this->liabilityShift = $liabilityShift; $this->xid = $xid; $this->verificationValue = $verificationValue; } @@ -80,22 +73,6 @@ public function setAuthenticated($authenticated) $this->authenticated = $authenticated; } - /** - * @return mixed - */ - public function getLiabilityShift() - { - return $this->liabilityShift; - } - - /** - * @param mixed $liabilityShift - */ - public function setLiabilityShift($liabilityShift) - { - $this->liabilityShift = $liabilityShift; - } - /** * @return mixed */ diff --git a/src/Entity/SaferPayOrder.php b/src/Entity/SaferPayOrder.php index 3930f6f3..69240344 100755 --- a/src/Entity/SaferPayOrder.php +++ b/src/Entity/SaferPayOrder.php @@ -31,7 +31,7 @@ class SaferPayOrder extends ObjectModel { /** - * @var Int + * @var Int|null */ public $id_order; @@ -92,7 +92,8 @@ class SaferPayOrder extends ObjectModel 'table' => 'saferpay_order', 'primary' => 'id_saferpay_order', 'fields' => [ - 'id_order' => ['type' => self::TYPE_INT, 'validate' => 'isInt'], + 'id_order' => ['type' => self::TYPE_NOTHING, 'allow_null' => true], + 'id_cart' => ['type' => self::TYPE_INT, 'validate' => 'isInt'], 'id_customer' => ['type' => self::TYPE_INT, 'validate' => 'isInt'], 'transaction_id' => ['type' => self::TYPE_STRING, 'validate' => 'isString'], 'refund_id' => ['type' => self::TYPE_STRING, 'validate' => 'isString'], diff --git a/src/EntityBuilder/SaferPayOrderBuilder.php b/src/EntityBuilder/SaferPayOrderBuilder.php index d3418dcb..0ea782e4 100755 --- a/src/EntityBuilder/SaferPayOrderBuilder.php +++ b/src/EntityBuilder/SaferPayOrderBuilder.php @@ -35,13 +35,15 @@ class SaferPayOrderBuilder { //TODO to pass $body as InitializeBody. - public function create($body, Cart $cart, Customer $customer, $isTransaction, $isBusinessLicence) + public function create($body, $cartId, $customerId, $isTransaction) { - $orderId = Order::getOrderByCartId($cart->id); + $orderId = Order::getIdByCartId($cartId); + $saferPayOrder = new SaferPayOrder(); $saferPayOrder->token = $body->Token; - $saferPayOrder->id_order = $orderId; - $saferPayOrder->id_customer = $customer->id; + $saferPayOrder->id_order = $orderId ?: null; + $saferPayOrder->id_cart = $cartId; + $saferPayOrder->id_customer = $customerId; $saferPayOrder->redirect_url = $this->getRedirectionUrl($body); $saferPayOrder->is_transaction = $isTransaction; $saferPayOrder->add(); diff --git a/src/Enum/ControllerName.php b/src/Enum/ControllerName.php index faed5e1e..d1bfc5f2 100755 --- a/src/Enum/ControllerName.php +++ b/src/Enum/ControllerName.php @@ -41,7 +41,7 @@ class ControllerName const PENDING_NOTIFY = 'pendingNotify'; const SUCCESS = 'success'; const SUCCESS_HOSTED = 'successHosted'; - const SUCCESS_IFRAME = 'successIframe'; + const SUCCESS_IFRAME = 'successIFrame'; const VALIDATION = 'validation'; const RETURN_URL = 'return'; } diff --git a/src/Exception/CouldNotProcessCheckout.php b/src/Exception/CouldNotProcessCheckout.php new file mode 100644 index 00000000..e6d64667 --- /dev/null +++ b/src/Exception/CouldNotProcessCheckout.php @@ -0,0 +1,80 @@ + + *@copyright SIX Payment Services + *@license SIX Payment Services + */ + +namespace Invertus\SaferPay\Exception; + +use Invertus\SaferPay\Exception\Restriction\SaferPayException; + +if (!defined('_PS_VERSION_')) { + exit; +} + +class CouldNotProcessCheckout extends SaferPayException +{ + /** + * @param int $cartId + * @return static + */ + public static function failedToFindCart($cartId) + { + return new static( + sprintf('Failed to find cart by ID %s', $cartId), + ExceptionCode::PAYMENT_FAILED_TO_FIND_CART, + [ + 'cart_id' => $cartId, + ] + ); + } + + /** + * @param int $cartId + * + * @return static + */ + public static function failedToCreateOrder($cartId) + { + return new static( + sprintf('Failed to create order. Cart ID %s', $cartId), + ExceptionCode::PAYMENT_FAILED_TO_CREATE_ORDER, + [ + 'cart_id' => $cartId, + ] + ); + } + + /** + * @param int $cartId + * + * @return self + */ + public static function failedToCreateSaferPayOrder($cartId) + { + return new static( + sprintf('Failed to create order. Cart ID %s', $cartId), + ExceptionCode::PAYMENT_FAILED_TO_CREATE_ORDER, + [ + 'cart_id' => $cartId, + ] + ); + } +} \ No newline at end of file diff --git a/src/Exception/ExceptionCode.php b/src/Exception/ExceptionCode.php new file mode 100644 index 00000000..aabe86ec --- /dev/null +++ b/src/Exception/ExceptionCode.php @@ -0,0 +1,43 @@ + + *@copyright SIX Payment Services + *@license SIX Payment Services + */ + +namespace Invertus\SaferPay\Exception; + +if (!defined('_PS_VERSION_')) { + exit; +} + +// NOTE class to define most used exception codes for our development. +class ExceptionCode +{ + // Payment related codes starts from 5*** + const PAYMENT_FAILED_TO_FIND_CART = 5001; + const PAYMENT_FAILED_TO_CREATE_ORDER = 5002; + + // Order related codes starts from 7*** + const ORDER_FAILED_TO_FIND_ORDER = 7001; + const ORDER_UNHANDLED_TRANSACTION_STATUS = 7002; + + // Any other unhandled codes should start with 9*** + const UNKNOWN_ERROR = 9001; +} diff --git a/src/Exception/Order/CouldNotChangeOrderStatus.php b/src/Exception/Order/CouldNotChangeOrderStatus.php new file mode 100644 index 00000000..60ee5286 --- /dev/null +++ b/src/Exception/Order/CouldNotChangeOrderStatus.php @@ -0,0 +1,65 @@ + + *@copyright SIX Payment Services + *@license SIX Payment Services + */ + +namespace Invertus\SaferPay\Exception; + +use Invertus\SaferPay\Exception\Restriction\SaferPayException; + +if (!defined('_PS_VERSION_')) { + exit; +} + +class CouldNotChangeOrderStatus extends SaferPayException +{ + /** + * @param string $transactionStatus + * + * @return CouldNotChangeOrderStatus + */ + public static function unhandledOrderStatus($transactionStatus) + { + return new self( + sprintf('Unhandled transaction status (%s)', $transactionStatus), + ExceptionCode::ORDER_UNHANDLED_TRANSACTION_STATUS, + [ + 'transaction_status' => $transactionStatus, + ] + ); + } + + /** + * @param int $orderId + * + * @return CouldNotChangeOrderStatus + */ + public static function failedToFindOrder($orderId) + { + return new self( + sprintf('Failed to find order %s', $orderId), + ExceptionCode::ORDER_FAILED_TO_FIND_ORDER, + [ + 'order_id' => $orderId, + ] + ); + } +} diff --git a/src/Exception/Order/index.php b/src/Exception/Order/index.php new file mode 100644 index 00000000..ee622726 --- /dev/null +++ b/src/Exception/Order/index.php @@ -0,0 +1,31 @@ + + *@copyright SIX Payment Services + *@license SIX Payment Services + */ +header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); +header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); + +header('Cache-Control: no-store, no-cache, must-revalidate'); +header('Cache-Control: post-check=0, pre-check=0', false); +header('Pragma: no-cache'); + +header('Location: ../'); +exit; diff --git a/src/Exception/SaferPayException.php b/src/Exception/SaferPayException.php new file mode 100644 index 00000000..59b41e90 --- /dev/null +++ b/src/Exception/SaferPayException.php @@ -0,0 +1,63 @@ + + *@copyright SIX Payment Services + *@license SIX Payment Services + */ + +namespace Invertus\SaferPay\Exception\Restriction; + +use Invertus\SaferPay\Exception\ExceptionCode; + +if (!defined('_PS_VERSION_')) { + exit; +} + +class SaferPayException extends \Exception +{ + private $context; + + final public function __construct( + $internalMessage, + $code, + array $context = [] + ) + { + parent::__construct($internalMessage, $code); + $this->context = $context; + } + + public function getContext() + { + return $this->context; + } + + /** + * @param \Exception $exception + * + * @return static + */ + public static function unknownError($exception) + { + return new static( + 'An unknown error error occurred. Please check system logs or contact Click to Pay support.', + ExceptionCode::UNKNOWN_ERROR + ); + } +} \ No newline at end of file diff --git a/src/Install/Installer.php b/src/Install/Installer.php index a8f5a0d0..0e37ed4e 100755 --- a/src/Install/Installer.php +++ b/src/Install/Installer.php @@ -95,6 +95,7 @@ private function registerHooks() $this->module->registerHook('displayAdminOrderTabContent'); $this->module->registerHook('actionAdminControllerSetMedia'); $this->module->registerHook('actionOrderStatusUpdate'); + $this->module->registerHook('actionObjectOrderPaymentAddAfter'); } private function installConfiguration() @@ -228,7 +229,8 @@ private function installSaferPayOrderTable() return Db::getInstance()->execute( 'CREATE TABLE IF NOT EXISTS ' . _DB_PREFIX_ . 'saferpay_order' . '( `id_saferpay_order` INTEGER(10) UNSIGNED AUTO_INCREMENT PRIMARY KEY, - `id_order` INTEGER(10) DEFAULT 0, + `id_order` INTEGER(10) DEFAULT 0 NULL, + `id_cart` INTEGER(10) DEFAULT 0, `id_customer` INTEGER(10) DEFAULT 0, `transaction_id` VARCHAR(64) DEFAULT NULL, `refund_id` VARCHAR(64) DEFAULT NULL, diff --git a/src/Processor/CheckoutProcessor.php b/src/Processor/CheckoutProcessor.php new file mode 100644 index 00000000..57adc22c --- /dev/null +++ b/src/Processor/CheckoutProcessor.php @@ -0,0 +1,209 @@ + + *@copyright SIX Payment Services + *@license SIX Payment Services + */ + +namespace Invertus\SaferPay\Processor; + +if (!defined('_PS_VERSION_')) { + exit; +} + +use Cart; +use Invertus\SaferPay\Config\SaferPayConfig; +use Invertus\SaferPay\Core\Payment\DTO\CheckoutData; +use Invertus\SaferPay\EntityBuilder\SaferPayOrderBuilder; +use Invertus\SaferPay\Exception\Api\SaferPayApiException; +use Invertus\SaferPay\Exception\CouldNotProcessCheckout; +use Invertus\SaferPay\Factory\ModuleFactory; +use Invertus\SaferPay\Repository\SaferPayOrderRepository; +use Invertus\SaferPay\Service\SaferPayInitialize; +use Order; +use PrestaShopException; +use SaferPayOrder; + +class CheckoutProcessor +{ + /** @var \SaferPayOfficial */ + private $module; + + /** @var SaferPayOrderBuilder */ + private $saferPayOrderBuilder; + + /** @var SaferPayInitialize */ + private $saferPayInitialize; + + /** @var SaferPayOrderRepository */ + private $saferPayOrderRepository; + + public function __construct( + ModuleFactory $module, + SaferPayOrderBuilder $saferPayOrderBuilder, + SaferPayInitialize $saferPayInitialize, + SaferPayOrderRepository $saferPayOrderRepository + ) { + $this->module = $module->getModule(); + $this->saferPayOrderBuilder = $saferPayOrderBuilder; + $this->saferPayInitialize = $saferPayInitialize; + $this->saferPayOrderRepository = $saferPayOrderRepository; + } + + public function run(CheckoutData $data) { + + $cart = new Cart($data->getCartId()); + + if (!$cart) { + throw CouldNotProcessCheckout::failedToFindCart($data->getCartId()); + } + + if ($data->getIsAuthorizedOrder()) { + $this->processAuthorizedOrder($data, $cart); + return ''; + } + + try { + if (!$data->getCreateAfterAuthorization()) { + $this->processCreateOrder($cart, $data->getPaymentMethod()); + } + } catch (\Exception $exception) { + throw CouldNotProcessCheckout::failedToCreateOrder($data->getCartId()); + } + + try { + $response = $this->processInitializePayment( + $data->getPaymentMethod(), + $data->getIsBusinessLicense(), + $data->getSelectedCard(), + $data->getFieldToken(), + $data->getSuccessController() + ); + } catch (\Exception $exception) { + throw new SaferPayApiException('Failed to initialize payment API', SaferPayApiException::INITIALIZE); + } + + try { + $this->processCreateSaferPayOrder( + $response, + $cart->id, + $cart->id_customer, + $data->getIsTransaction() + ); + } catch (\Exception $exception) { + throw CouldNotProcessCheckout::failedToCreateSaferPayOrder($data->getCartId()); + } + + return $response; + } + + /** + * @param Cart $cart + * @param $paymentMethod + * @return void + * @throws PrestaShopException + */ + private function processCreateOrder(Cart $cart, $paymentMethod) + { + $customer = new \Customer($cart->id_customer); + + $this->module->validateOrder( + $cart->id, + \Configuration::get(SaferPayConfig::SAFERPAY_ORDER_STATE_CHOICE_AWAITING_PAYMENT), + (float) $cart->getOrderTotal(), + $paymentMethod, + null, + [], + null, + false, + $customer->secure_key + ); + } + + /** + * @param $paymentMethod + * @param $isBusinessLicense + * @param $selectedCard + * @param $fieldToken + * @param $successController + * @return array|null + */ + private function processInitializePayment( + $paymentMethod, + $isBusinessLicense, + $selectedCard, + $fieldToken, + $successController + ) { + $request = $this->saferPayInitialize->buildRequest( + $paymentMethod, + $isBusinessLicense, + $selectedCard, + $fieldToken, + $successController + ); + + return $this->saferPayInitialize->initialize($request, $isBusinessLicense); + } + + /** + * @param $initializeBody + * @param $cartId + * @param $customerId + * @param $isTransaction + * @return void + */ + private function processCreateSaferPayOrder($initializeBody, $cartId, $customerId, $isTransaction) + { + $this->saferPayOrderBuilder->create( + $initializeBody, + $cartId, + $customerId, + $isTransaction + ); + } + + private function processAuthorizedOrder(CheckoutData $data, Cart $cart): void + { + try { + $saferPayOrder = new SaferPayOrder($this->saferPayOrderRepository->getIdByCartId($cart->id)); + + if (!$saferPayOrder->id_order) { + $this->processCreateOrder($cart, $data->getPaymentMethod()); + } + + $order = new Order(Order::getIdByCartId($cart->id)); + $saferPayOrder->id_order = $order->id; + + if ($data->getOrderStatus() === 'AUTHORIZED') { + $order->setCurrentState(_SAFERPAY_PAYMENT_AUTHORIZED_); + $saferPayOrder->authorized = 1; + } elseif ($data->getOrderStatus() === 'CAPTURED') { + $order->setCurrentState(_SAFERPAY_PAYMENT_COMPLETED_); + $saferPayOrder->captured = 1; + } + + $saferPayOrder->update(); + $order->update(); + return; + } catch (\Exception $exception) { + throw CouldNotProcessCheckout::failedToCreateOrder($data->getCartId()); + } + } +} diff --git a/src/Processor/index.php b/src/Processor/index.php new file mode 100644 index 00000000..7487f261 --- /dev/null +++ b/src/Processor/index.php @@ -0,0 +1,31 @@ + + *@copyright SIX Payment Services + *@license SIX Payment Services + */ +header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); +header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT"); + +header("Cache-Control: no-store, no-cache, must-revalidate"); +header("Cache-Control: post-check=0, pre-check=0", false); +header("Pragma: no-cache"); + +header("Location: ../"); +exit; diff --git a/src/Repository/SaferPayOrderRepository.php b/src/Repository/SaferPayOrderRepository.php index 0d511c14..ae51aa3f 100755 --- a/src/Repository/SaferPayOrderRepository.php +++ b/src/Repository/SaferPayOrderRepository.php @@ -42,6 +42,15 @@ public function getIdByOrderId($orderId) return Db::getInstance()->getValue($query); } + public function getIdByCartId($cartId) + { + $query = new DbQuery(); + $query->select('`id_saferpay_order`'); + $query->from('saferpay_order'); + $query->where('id_cart = "' . (int) $cartId . '"'); + + return Db::getInstance()->getValue($query); + } public function getAssertIdBySaferPayOrderId($saferPayOrderId) { $query = new DbQuery(); @@ -66,4 +75,14 @@ public function getOrderRefunds($saferPayOrderId) return Db::getInstance()->executeS($query); } + + public function getPaymentBrandBySaferpayOrderId($saferpayOrderId) + { + $query = new DbQuery(); + $query->select('`brand`'); + $query->from('saferpay_assert'); + $query->where('id_saferpay_order = "' . (int) $saferpayOrderId . '"'); + + return Db::getInstance()->getValue($query); + } } diff --git a/src/Service/LegacyTranslator.php b/src/Service/LegacyTranslator.php index d6b31d2b..96a0e1b8 100755 --- a/src/Service/LegacyTranslator.php +++ b/src/Service/LegacyTranslator.php @@ -72,12 +72,15 @@ private function getTranslations() SaferPayConfig::PAYMENT_POSTFINANCE => $this->module->l('Postfinance', self::FILE_NAME), SaferPayConfig::PAYMENT_SOFORT => $this->module->l('Sofort', self::FILE_NAME), SaferPayConfig::PAYMENT_TWINT => $this->module->l('Twint', self::FILE_NAME), - SaferPayConfig::PAYMENT_UNIONPAY => $this->module->l('Unionpay', self::FILE_NAME), SaferPayConfig::PAYMENT_VISA => $this->module->l('Visa', self::FILE_NAME), SaferPayConfig::PAYMENT_VPAY => $this->module->l('Vpay', self::FILE_NAME), SaferPayConfig::PAYMENT_APPLEPAY => $this->module->l('Applepay', self::FILE_NAME), SaferPayConfig::PAYMENT_KLARNA => $this->module->l('Klarna', self::FILE_NAME), SaferPayConfig::PAYMENT_WLCRYPTOPAYMENTS => $this->module->l('Cryptocurrencies', self::FILE_NAME), + SaferPayConfig::PAYMENT_ACCOUNTTOACCOUNT => $this->module->l('AccountToAccount', self::FILE_NAME), + SaferPayConfig::PAYMENT_PAYCONIQ => $this->module->l('Payconiq', self::FILE_NAME), + SaferPayConfig::PAYMENT_CARD => $this->module->l('Card', self::FILE_NAME), + SaferPayConfig::PAYMENT_POSTFINANCE_PAY => $this->module->l('PostFinancePay', self::FILE_NAME), ]; } } diff --git a/src/Service/PaymentRestrictionValidation/ApplePayPaymentRestrictionValidation.php b/src/Service/PaymentRestrictionValidation/ApplePayPaymentRestrictionValidation.php index 035016ba..6dc84419 100755 --- a/src/Service/PaymentRestrictionValidation/ApplePayPaymentRestrictionValidation.php +++ b/src/Service/PaymentRestrictionValidation/ApplePayPaymentRestrictionValidation.php @@ -80,6 +80,6 @@ private function isMacDesktop() $device = $this->context->getDeviceDetect(); - return $device === \Context::DEVICE_COMPUTER && preg_match('/macintosh|mac os x|mac_powerpc/i', $_SERVER['HTTP_USER_AGENT']) !== false; + return $device === \Context::DEVICE_COMPUTER && (int) preg_match('/macintosh|mac os x|mac_powerpc/i', $_SERVER['HTTP_USER_AGENT']); } } diff --git a/src/Service/Request/AssertRequestObjectCreator.php b/src/Service/Request/AssertRequestObjectCreator.php index 5d8dde1f..34c1ef83 100755 --- a/src/Service/Request/AssertRequestObjectCreator.php +++ b/src/Service/Request/AssertRequestObjectCreator.php @@ -25,7 +25,6 @@ use Invertus\SaferPay\DTO\Request\Assert\AssertRequest; use Invertus\SaferPay\Repository\SaferPayOrderRepository; -use SaferPayOrder; if (!defined('_PS_VERSION_')) { exit; @@ -51,12 +50,15 @@ public function __construct( $this->saferPayOrderRepository = $saferPayOrderRepository; } - public function create($orderId) + /** + * @param string $token + * + * @return AssertRequest + */ + public function create($token) { $requestHeader = $this->requestObjectCreator->createRequestHeader(); - $saferPayOrderId = $this->saferPayOrderRepository->getIdByOrderId($orderId); - $saferPayOrder = new SaferPayOrder($saferPayOrderId); - return new AssertRequest($requestHeader, $saferPayOrder->token); + return new AssertRequest($requestHeader, $token); } } diff --git a/src/Service/Request/InitializeRequestObjectCreator.php b/src/Service/Request/InitializeRequestObjectCreator.php index 805da6b2..8ce62fd9 100755 --- a/src/Service/Request/InitializeRequestObjectCreator.php +++ b/src/Service/Request/InitializeRequestObjectCreator.php @@ -30,6 +30,7 @@ use Invertus\SaferPay\DTO\Request\RequestHeader; use Invertus\SaferPay\DTO\Request\Initialize\InitializeRequest; use Invertus\SaferPay\DTO\Request\Payer; +use PrestaShop\PrestaShop\Adapter\Shop\Context; if (!defined('_PS_VERSION_')) { exit; @@ -68,8 +69,14 @@ public function create( $totalPrice = (int) (round($totalPrice)); $payment = $this->requestObjectCreator->createPayment($cart, $totalPrice); $payer = new Payer(); + + $languageCode = !empty($cart->getAssociatedLanguage()->iso_code) + ? $cart->getAssociatedLanguage()->iso_code + : 'en'; + + $payer->setLanguageCode($languageCode); $returnUrl = $this->requestObjectCreator->createReturnUrl($returnUrl); - $notification = ($isBusinessLicence && version_compare(Configuration::get(RequestHeader::SPEC_VERSION), '1.35', '<')) ? null : $this->requestObjectCreator->createNotification($customerEmail, $notifyUrl); + $notification = $isBusinessLicence ? null : $this->requestObjectCreator->createNotification($customerEmail, $notifyUrl); $deliveryAddressForm = $this->requestObjectCreator->createDeliveryAddressForm(); $configSet = Configuration::get(SaferPayConfig::CONFIGURATION_NAME); $cssUrl = Configuration::get(SaferPayConfig::CSS_FILE); diff --git a/src/Service/Request/RequestObjectCreator.php b/src/Service/Request/RequestObjectCreator.php index 72cb3d70..6e961489 100755 --- a/src/Service/Request/RequestObjectCreator.php +++ b/src/Service/Request/RequestObjectCreator.php @@ -111,12 +111,20 @@ public function createPayment(Cart $cart, $totalPrice) /** @var \Order|null $order */ $order = $this->orderRepository->findOneByCartId($cart->id); - if (empty($order)) { + if (!(int) \Configuration::get(SaferPayConfig::SAFERPAY_ORDER_CREATION_AFTER_AUTHORIZATION) && empty($order)) { return null; } + $payment = new Payment(); $payment->setValue($totalPrice); $payment->setCurrencyCode($currency['iso_code']); + $payment->setDescription((string) Configuration::get(SaferPayConfig::SAFERPAY_PAYMENT_DESCRIPTION)); + + if ((int) \Configuration::get(SaferPayConfig::SAFERPAY_ORDER_CREATION_AFTER_AUTHORIZATION) && empty($order)) { + return $payment; + } + + /** This param is not mandatory, but recommended **/ $payment->setOrderReference($order->reference); return $payment; diff --git a/src/Service/Response/ResponseObjectCreator.php b/src/Service/Response/ResponseObjectCreator.php index 3b935dbd..6db2cd0e 100755 --- a/src/Service/Response/ResponseObjectCreator.php +++ b/src/Service/Response/ResponseObjectCreator.php @@ -154,7 +154,6 @@ protected function createThreeDs($threeDs) { $threeDsObj = new ThreeDs(); $threeDsObj->setAuthenticated($threeDs->Authenticated); - $threeDsObj->setLiabilityShift($threeDs->LiabilityShift); $threeDsObj->setXid($threeDs->Xid); $threeDsObj->setVerificationValue($threeDs->VerificationValue); @@ -168,7 +167,6 @@ protected function createLiability($liability) $threeDs = $liability->ThreeDs; $threeDsObj = new ThreeDs(); $threeDsObj->setAuthenticated($threeDs->Authenticated); - $threeDsObj->setLiabilityShift($threeDs->LiabilityShift); $threeDsObj->setXid($threeDs->Xid); if (isset($threeDs->VerificationValue)) { $threeDsObj->setVerificationValue($threeDs->VerificationValue); diff --git a/src/Service/SaferPayInitialize.php b/src/Service/SaferPayInitialize.php index bf6368d7..ddc6e217 100755 --- a/src/Service/SaferPayInitialize.php +++ b/src/Service/SaferPayInitialize.php @@ -25,12 +25,16 @@ use Context; use Exception; +use Invertus\SaferPay\Adapter\Configuration; use Invertus\SaferPay\Adapter\LegacyContext; use Invertus\SaferPay\Api\Request\InitializeService; +use Invertus\SaferPay\DTO\Request\Initialize\InitializeRequest; use Invertus\SaferPay\Enum\ControllerName; use Invertus\SaferPay\Exception\Api\SaferPayApiException; +use Invertus\SaferPay\Repository\SaferPayCardAliasRepository; use Invertus\SaferPay\Factory\ModuleFactory; use Invertus\SaferPay\Service\Request\InitializeRequestObjectCreator; +use Invertus\SaferPay\Config\SaferPayConfig; use Order; use SaferPayOfficial; @@ -60,35 +64,58 @@ class SaferPayInitialize */ private $requestObjectCreator; + /** @var SaferPayCardAliasRepository */ + private $saferPayCardAliasRepository; + + /** @var Configuration */ + private $configuration; + public function __construct( ModuleFactory $module, LegacyContext $context, InitializeService $initializeService, - InitializeRequestObjectCreator $requestObjectCreator + InitializeRequestObjectCreator $requestObjectCreator, + SaferPayCardAliasRepository $saferPayCardAliasRepository, + Configuration $configuration ) { $this->module = $module->getModule(); $this->context = $context->getContext(); $this->initializeService = $initializeService; $this->requestObjectCreator = $requestObjectCreator; + $this->saferPayCardAliasRepository = $saferPayCardAliasRepository; + $this->configuration = $configuration; + } + + public function initialize(InitializeRequest $initializeRequest, $isBusinessLicence) + { + try { + $initialize = $this->initializeService->initialize($initializeRequest, $isBusinessLicence); + } catch (Exception $e) { + throw new SaferPayApiException('Initialize API failed', SaferPayApiException::INITIALIZE); + } + + return $initialize; } - public function initialize( + public function buildRequest( $paymentMethod, $isBusinessLicence, $selectedCard = -1, - $alias = null, - $fieldToken = null + $fieldToken = null, + $successController = null ) { $customerEmail = $this->context->customer->email; $cartId = $this->context->cart->id; + $creationAfterInitialization = $this->configuration->getAsBoolean(SaferPayConfig::SAFERPAY_ORDER_CREATION_AFTER_AUTHORIZATION); + $alias = $this->saferPayCardAliasRepository->getSavedCardAliasFromId($selectedCard); - $returnUrl = $this->context->link->getModuleLink( + $successUrl = $this->context->link->getModuleLink( $this->module->name, ControllerName::RETURN_URL, [ 'cartId' => $cartId, 'secureKey' => $this->context->cart->secure_key, - 'orderId' => Order::getOrderByCartId($cartId), + 'orderId' => $creationAfterInitialization ? 0 : Order::getOrderByCartId($cartId), 'moduleId' => $this->module->id, 'selectedCard' => $selectedCard, 'isBusinessLicence' => $isBusinessLicence, @@ -103,31 +130,39 @@ public function initialize( [ 'success' => 1, 'cartId' => $this->context->cart->id, - 'orderId' => Order::getOrderByCartId($cartId), + 'orderId' => $creationAfterInitialization ? 0 : Order::getOrderByCartId($cartId), 'secureKey' => $this->context->cart->secure_key, ], true ); + $failUrl = $this->context->link->getModuleLink( + $this->module->name, + ControllerName::FAIL_VALIDATION, + [ + 'cartId' => $this->context->cart->id, + 'secureKey' => $this->context->cart->secure_key, + 'orderId' => $creationAfterInitialization ? 0 :Order::getOrderByCartId($cartId), + 'moduleId' => $this->module->id, + 'isBusinessLicence' => $isBusinessLicence, + ], + true + ); + $initializeRequest = $this->requestObjectCreator->create( $this->context->cart, $customerEmail, $paymentMethod, - $returnUrl, + $successUrl, $notifyUrl, + $failUrl, $this->context->cart->id_address_delivery, $this->context->cart->id_address_invoice, $this->context->cart->id_customer, - $isBusinessLicence, $alias, $fieldToken ); - try { - $initialize = $this->initializeService->initialize($initializeRequest, $isBusinessLicence); - } catch (Exception $e) { - throw new SaferPayApiException('Initialize API failed', SaferPayApiException::INITIALIZE); - } - return $initialize; + return $initializeRequest; } } diff --git a/src/Service/SaferPayOrderStatusService.php b/src/Service/SaferPayOrderStatusService.php index b3122096..0894beef 100755 --- a/src/Service/SaferPayOrderStatusService.php +++ b/src/Service/SaferPayOrderStatusService.php @@ -127,29 +127,6 @@ public function authorize(Order $order) $order->update(); } - /** - * @param Order $order - * - * @throws \Exception - */ - public function assert(Order $order, $status = 'AUTHORIZED') - { - $saferPayOrderId = $this->orderRepository->getIdByOrderId($order->id); - $saferPayOrder = new SaferPayOrder($saferPayOrderId); - if ($saferPayOrder->authorized) { - return; - } - $saferPayOrder->authorized = 1; - if ($status === 'AUTHORIZED') { - $order->setCurrentState(_SAFERPAY_PAYMENT_AUTHORIZED_); - } elseif ($status === 'CAPTURED') { - $order->setCurrentState(_SAFERPAY_PAYMENT_COMPLETED_); - } - - $saferPayOrder->update(); - $order->update(); - } - /** TODO extract capture api code to different service like Assert for readability */ public function capture(Order $order, $refundedAmount = 0, $isRefund = false) { diff --git a/src/Service/TransactionFlow/SaferPayTransactionAssertion.php b/src/Service/TransactionFlow/SaferPayTransactionAssertion.php index eab50579..05667d4c 100755 --- a/src/Service/TransactionFlow/SaferPayTransactionAssertion.php +++ b/src/Service/TransactionFlow/SaferPayTransactionAssertion.php @@ -27,8 +27,6 @@ use Invertus\SaferPay\DTO\Response\Assert\AssertBody; use Invertus\SaferPay\Repository\SaferPayOrderRepository; use Invertus\SaferPay\Service\Request\AssertRequestObjectCreator; -use Invertus\SaferPay\Service\SaferPayOrderStatusService; -use Order; use SaferPayOrder; if (!defined('_PS_VERSION_')) { @@ -52,37 +50,33 @@ class SaferPayTransactionAssertion */ private $assertionService; - /** - * @var SaferPayOrderStatusService - */ - private $orderStatusService; - public function __construct( AssertRequestObjectCreator $assertRequestCreator, SaferPayOrderRepository $orderRepository, - AssertService $assertionService, - SaferPayOrderStatusService $orderStatusService + AssertService $assertionService ) { $this->assertRequestCreator = $assertRequestCreator; $this->orderRepository = $orderRepository; $this->assertionService = $assertionService; - $this->orderStatusService = $orderStatusService; } /** - * @param int $orderId + * @param string $cartId * * @return AssertBody * @throws \Exception */ - public function assert($orderId, $changeOrderStatus) + public function assert($cartId) { - $saferPayOrder = $this->getSaferPayOrder($orderId); - $order = new Order($orderId); + $saferPayOrder = new SaferPayOrder($this->orderRepository->getIdByCartId($cartId)); - $assertRequest = $this->assertRequestCreator->create($orderId); + $assertRequest = $this->assertRequestCreator->create($saferPayOrder->token); $assertResponse = $this->assertionService->assert($assertRequest, $saferPayOrder->id); + if (empty($assertResponse)) { + return null; + } + $assertBody = $this->assertionService->createObjectsFromAssertResponse( $assertResponse, $saferPayOrder->id @@ -91,23 +85,6 @@ public function assert($orderId, $changeOrderStatus) $saferPayOrder->transaction_id = $assertBody->getTransaction()->getId(); $saferPayOrder->update(); - if ($changeOrderStatus) { - $this->orderStatusService->assert($order, $assertBody->getTransaction()->getStatus()); - } - return $assertBody; } - - /** - * @param $orderId - * - * @return false|SaferPayOrder - * @throws \Exception - */ - private function getSaferPayOrder($orderId) - { - $saferPayOrderId = $this->orderRepository->getIdByOrderId($orderId); - - return new SaferPayOrder($saferPayOrderId); - } } diff --git a/src/Service/TransactionFlow/SaferPayTransactionAuthorization.php b/src/Service/TransactionFlow/SaferPayTransactionAuthorization.php index 40179290..d1e95b99 100755 --- a/src/Service/TransactionFlow/SaferPayTransactionAuthorization.php +++ b/src/Service/TransactionFlow/SaferPayTransactionAuthorization.php @@ -23,6 +23,7 @@ namespace Invertus\SaferPay\Service\TransactionFlow; +use Cart; use Invertus\SaferPay\Adapter\LegacyContext; use Invertus\SaferPay\Api\Request\AuthorizationService; use Invertus\SaferPay\DTO\Response\Assert\AssertBody; @@ -85,11 +86,11 @@ public function __construct( * @return AssertBody * @throws \Exception */ - public function authorize($orderId, $saveCard, $selectedCard) + public function authorize($cartId, $saveCard, $selectedCard) { - $order = new Order($orderId); + $cart = new Cart($cartId); - $saferPayOrderId = $this->orderRepository->getIdByOrderId($orderId); + $saferPayOrderId = $this->orderRepository->getIdByCartId($cartId); $saferPayOrder = new SaferPayOrder($saferPayOrderId); $authRequest = $this->authRequestCreator->create($saferPayOrder->token, $saveCard); @@ -98,7 +99,7 @@ public function authorize($orderId, $saveCard, $selectedCard) $assertBody = $this->authorizationService->createObjectsFromAuthorizationResponse( $authResponse, $saferPayOrder->id, - $order->id_customer, + $cart->id_customer, $selectedCard ); diff --git a/upgrade/install-1.1.4.php b/upgrade/install-1.1.4.php index 8b710f13..daa84eb9 100644 --- a/upgrade/install-1.1.4.php +++ b/upgrade/install-1.1.4.php @@ -27,7 +27,7 @@ if (!defined('_PS_VERSION_')) { exit; } -function upgrade_module_1_1_4($module) +function upgrade_module_1_1_4() { Configuration::updateValue(RequestHeader::SPEC_VERSION, SaferPayConfig::API_VERSION); Configuration::updateValue(RequestHeader::SPEC_REFUND_VERSION, SaferPayConfig::API_VERSION); diff --git a/upgrade/install-1.1.8.php b/upgrade/install-1.1.8.php new file mode 100644 index 00000000..d52c8914 --- /dev/null +++ b/upgrade/install-1.1.8.php @@ -0,0 +1,44 @@ + + *@copyright SIX Payment Services + *@license SIX Payment Services + */ + +use Invertus\SaferPay\Config\SaferPayConfig; +use Invertus\SaferPay\DTO\Request\RequestHeader; + +if (!defined('_PS_VERSION_')) { + exit; +} +function upgrade_module_1_1_8(SaferPayOfficial $module) +{ + Configuration::updateValue(SaferPayConfig::SAFERPAY_ALLOW_SAFERPAY_SEND_CUSTOMER_MAIL, 1); + Configuration::updateValue( + SaferPayConfig::SAFERPAY_PAYMENT_DESCRIPTION, + SaferPayConfig::SAFERPAY_PAYMENT_DESCRIPTION_DEFAULT_VALUE + ); + + Configuration::updateValue(RequestHeader::SPEC_VERSION, SaferPayConfig::API_VERSION); + Configuration::updateValue(RequestHeader::SPEC_REFUND_VERSION, SaferPayConfig::API_VERSION); + + $module->registerHook('actionObjectOrderPaymentAddAfter'); + + return true; +} \ No newline at end of file diff --git a/upgrade/install-1.2.0.php b/upgrade/install-1.2.0.php new file mode 100644 index 00000000..d127a4e6 --- /dev/null +++ b/upgrade/install-1.2.0.php @@ -0,0 +1,49 @@ + + *@copyright SIX Payment Services + *@license SIX Payment Services + */ + +use Invertus\SaferPay\Config\SaferPayConfig; +use Configuration; + +if (!defined('_PS_VERSION_')) { + exit; +} + +function upgrade_module_1_2_0($module) +{ + // Make id_order nullable + $sql = 'ALTER TABLE `' . bqSQL(_DB_PREFIX_ . 'saferpay_order') . '` MODIFY `id_order` INT NULL;'; + + if (!Db::getInstance()->execute($sql)) { + return false; + } + + // Add the new column id_cart after id_order + $sql = 'ALTER TABLE `' . bqSQL(_DB_PREFIX_ . 'saferpay_order') . '` ADD COLUMN `id_cart` INT AFTER `id_order`;'; + if (!Db::getInstance()->execute($sql)) { + return false; + } + + Configuration::updateValue(SaferPayConfig::SAFERPAY_ORDER_CREATION_AFTER_AUTHORIZATION, 0); + + return true; +} diff --git a/views/templates/front/credit_cards.tpl b/views/templates/front/credit_cards.tpl index 331c111d..d042b193 100755 --- a/views/templates/front/credit_cards.tpl +++ b/views/templates/front/credit_cards.tpl @@ -51,7 +51,7 @@ {foreach $rows as $row} - {$row nofilter} + {$row nofilter|escape:'htmlall':'UTF-8'} {/foreach} diff --git a/views/templates/front/credit_cards_16.tpl b/views/templates/front/credit_cards_16.tpl index 4ff29402..ee8f2a0a 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 nofilter} + {$row nofilter|escape:'htmlall':'UTF-8'} {/foreach} diff --git a/views/templates/front/hosted-templates/template1.tpl b/views/templates/front/hosted-templates/template1.tpl index 88db7c7f..60d81917 100755 --- a/views/templates/front/hosted-templates/template1.tpl +++ b/views/templates/front/hosted-templates/template1.tpl @@ -58,5 +58,5 @@ - + {/block} \ No newline at end of file diff --git a/views/templates/front/hosted-templates/template1_16.tpl b/views/templates/front/hosted-templates/template1_16.tpl index 52088bf5..47bde7d4 100755 --- a/views/templates/front/hosted-templates/template1_16.tpl +++ b/views/templates/front/hosted-templates/template1_16.tpl @@ -46,5 +46,5 @@ - + diff --git a/views/templates/front/hosted-templates/template2.tpl b/views/templates/front/hosted-templates/template2.tpl index f90c72d4..41d864a2 100755 --- a/views/templates/front/hosted-templates/template2.tpl +++ b/views/templates/front/hosted-templates/template2.tpl @@ -66,7 +66,7 @@ - + {/block} \ No newline at end of file diff --git a/views/templates/front/hosted-templates/template2_16.tpl b/views/templates/front/hosted-templates/template2_16.tpl index 4b81b5bd..e1b4e7ec 100755 --- a/views/templates/front/hosted-templates/template2_16.tpl +++ b/views/templates/front/hosted-templates/template2_16.tpl @@ -62,5 +62,5 @@ - + diff --git a/views/templates/front/hosted-templates/template3.tpl b/views/templates/front/hosted-templates/template3.tpl index dd2ab5cd..492696d7 100755 --- a/views/templates/front/hosted-templates/template3.tpl +++ b/views/templates/front/hosted-templates/template3.tpl @@ -71,5 +71,5 @@ - + {/block} \ No newline at end of file diff --git a/views/templates/front/hosted-templates/template3_16.tpl b/views/templates/front/hosted-templates/template3_16.tpl index 27c68602..f785cde2 100755 --- a/views/templates/front/hosted-templates/template3_16.tpl +++ b/views/templates/front/hosted-templates/template3_16.tpl @@ -60,5 +60,5 @@ - + \ No newline at end of file diff --git a/views/templates/hook/front/payment_with_cards.tpl b/views/templates/hook/front/payment_with_cards.tpl index c4f05006..5ec47b52 100755 --- a/views/templates/hook/front/payment_with_cards.tpl +++ b/views/templates/hook/front/payment_with_cards.tpl @@ -32,9 +32,9 @@