From 1a4c5abb41b6233a76ca9ad7e3c09696defd9a12 Mon Sep 17 00:00:00 2001 From: Julius Zukauskas Date: Tue, 11 Jun 2024 13:18:14 +0300 Subject: [PATCH 1/9] upgrade api to 1.37->1.40, init wechatpay and upgrade module to 1.2.3 --- composer.json | 2 +- saferpayofficial.php | 2 +- src/Config/SaferPayConfig.php | 10 ++++++--- src/Service/LegacyTranslator.php | 1 + upgrade/install-1.2.3.php | 36 ++++++++++++++++++++++++++++++++ 5 files changed, 46 insertions(+), 5 deletions(-) create mode 100644 upgrade/install-1.2.3.php diff --git a/composer.json b/composer.json index e5851363..cd10dd9a 100755 --- a/composer.json +++ b/composer.json @@ -52,4 +52,4 @@ }, "author": "PrestaShop", "license": "AFL-3.0" -} \ No newline at end of file +} diff --git a/saferpayofficial.php b/saferpayofficial.php index c94e6f0b..88910a53 100755 --- a/saferpayofficial.php +++ b/saferpayofficial.php @@ -42,7 +42,7 @@ public function __construct($name = null) { $this->name = 'saferpayofficial'; $this->author = 'Invertus'; - $this->version = '1.2.2'; + $this->version = '1.2.3'; $this->module_key = '3d3506c3e184a1fe63b936b82bda1bdf'; $this->displayName = 'SaferpayOfficial'; $this->description = 'Saferpay Payment module'; diff --git a/src/Config/SaferPayConfig.php b/src/Config/SaferPayConfig.php index f04b7112..f311596f 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.37; + const API_VERSION = '1.40'; const PAYMENT_METHODS = [ self::PAYMENT_ALIPAY, self::PAYMENT_AMEX, @@ -77,6 +77,7 @@ class SaferPayConfig self::PAYMENT_APPLEPAY, self::PAYMENT_KLARNA, self::PAYMENT_WLCRYPTOPAYMENTS, + self::PAYMENT_WE_CHAT_PAY, ]; const PAYMENT_ALIPAY = 'ALIPAY'; @@ -111,6 +112,7 @@ class SaferPayConfig const PAYMENT_PAYCONIQ = 'PAYCONIQ'; const PAYMENT_CARD = 'CARD'; const PAYMENT_POSTFINANCE_PAY = 'POSTFINANCEPAY'; + const PAYMENT_WE_CHAT_PAY = 'WECHATPAY'; const WALLET_PAYMENT_METHODS = [ self::PAYMENT_APPLEPAY, @@ -141,6 +143,7 @@ class SaferPayConfig 'Payconiq' => self::PAYMENT_PAYCONIQ, 'Card' => self::PAYMENT_CARD, 'PostFinancePay' => self::PAYMENT_POSTFINANCE_PAY, + 'WeChatPay' => self::PAYMENT_WE_CHAT_PAY, ]; const FIELD_SUPPORTED_PAYMENT_METHODS = [ @@ -152,6 +155,7 @@ class SaferPayConfig self::PAYMENT_DINERS, self::PAYMENT_JCB, self::PAYMENT_MYONE, + self::PAYMENT_WE_CHAT_PAY, ]; const WLCRYPTOPAYMENTS_SUPPORTED_CURRENCIES = [ @@ -333,8 +337,8 @@ public static function getBaseUrl() public static function getDefaultConfiguration() { return [ - RequestHeader::SPEC_VERSION => '1.37', - RequestHeader::SPEC_REFUND_VERSION => '1.37', + RequestHeader::SPEC_VERSION => SaferPayConfig::API_VERSION, + RequestHeader::SPEC_REFUND_VERSION => SaferPayConfig::API_VERSION, RequestHeader::RETRY_INDICATOR => 0, SaferPayConfig::PAYMENT_BEHAVIOR => 1, SaferPayConfig::PAYMENT_BEHAVIOR_WITHOUT_3D => 1, diff --git a/src/Service/LegacyTranslator.php b/src/Service/LegacyTranslator.php index 96a0e1b8..b055f4d8 100755 --- a/src/Service/LegacyTranslator.php +++ b/src/Service/LegacyTranslator.php @@ -81,6 +81,7 @@ private function getTranslations() 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), + SaferPayConfig::PAYMENT_WE_CHAT_PAY => $this->module->l('WeChatPay', self::FILE_NAME), ]; } } diff --git a/upgrade/install-1.2.3.php b/upgrade/install-1.2.3.php new file mode 100644 index 00000000..b8af0277 --- /dev/null +++ b/upgrade/install-1.2.3.php @@ -0,0 +1,36 @@ + + *@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_2_3(SaferPayOfficial $module) +{ + Configuration::updateValue(RequestHeader::SPEC_VERSION, SaferPayConfig::API_VERSION); + Configuration::updateValue(RequestHeader::SPEC_REFUND_VERSION, SaferPayConfig::API_VERSION); + + return true; +} From 4271164c67e70a156706cbbb6d697f3dc0271c69 Mon Sep 17 00:00:00 2001 From: Julius Zukauskas Date: Wed, 12 Jun 2024 12:48:08 +0300 Subject: [PATCH 2/9] wechatpay handle unsupported capture/cancel --- controllers/front/notify.php | 3 +- controllers/front/return.php | 3 +- src/Config/SaferPayConfig.php | 29 ++++++++++++++++--- src/Presenter/AssertPresenter.php | 7 ++++- src/Service/LegacyTranslator.php | 2 +- views/templates/hook/admin/saferpay_order.tpl | 12 +++++--- 6 files changed, 44 insertions(+), 12 deletions(-) diff --git a/controllers/front/notify.php b/controllers/front/notify.php index 584dc479..f4a24aae 100755 --- a/controllers/front/notify.php +++ b/controllers/front/notify.php @@ -153,8 +153,9 @@ public function postProcess() //NOTE to get latest information possible and not override new information. $order = new Order($orderId); + $paymentMethod = $assertResponseBody->getPaymentMeans()->getBrand()->getPaymentMethod(); - if ((int) Configuration::get(SaferPayConfig::PAYMENT_BEHAVIOR) === SaferPayConfig::DEFAULT_PAYMENT_BEHAVIOR_CAPTURE && + if (SaferPayConfig::supportsOrderCapture($paymentMethod) && (int) Configuration::get(SaferPayConfig::PAYMENT_BEHAVIOR) === SaferPayConfig::DEFAULT_PAYMENT_BEHAVIOR_CAPTURE && $assertResponseBody->getTransaction()->getStatus() !== TransactionStatus::CAPTURED ) { /** @var SaferPayOrderStatusService $orderStatusService */ diff --git a/controllers/front/return.php b/controllers/front/return.php index f8e34029..f90c9855 100755 --- a/controllers/front/return.php +++ b/controllers/front/return.php @@ -172,8 +172,9 @@ public function postProcess() true )); } + $paymentMethod = $response->getPaymentMeans()->getBrand()->getPaymentMethod(); - if ((int) Configuration::get(SaferPayConfig::PAYMENT_BEHAVIOR) === SaferPayConfig::DEFAULT_PAYMENT_BEHAVIOR_CAPTURE && + if (SaferPayConfig::supportsOrderCapture($paymentMethod) && (int) Configuration::get(SaferPayConfig::PAYMENT_BEHAVIOR) === SaferPayConfig::DEFAULT_PAYMENT_BEHAVIOR_CAPTURE && $response->getTransaction()->getStatus() !== TransactionStatus::CAPTURED ) { $orderStatusService->capture(new Order($orderId)); diff --git a/src/Config/SaferPayConfig.php b/src/Config/SaferPayConfig.php index f311596f..b057cb5b 100755 --- a/src/Config/SaferPayConfig.php +++ b/src/Config/SaferPayConfig.php @@ -77,7 +77,7 @@ class SaferPayConfig self::PAYMENT_APPLEPAY, self::PAYMENT_KLARNA, self::PAYMENT_WLCRYPTOPAYMENTS, - self::PAYMENT_WE_CHAT_PAY, + self::PAYMENT_WECHATPAY, ]; const PAYMENT_ALIPAY = 'ALIPAY'; @@ -112,7 +112,7 @@ class SaferPayConfig const PAYMENT_PAYCONIQ = 'PAYCONIQ'; const PAYMENT_CARD = 'CARD'; const PAYMENT_POSTFINANCE_PAY = 'POSTFINANCEPAY'; - const PAYMENT_WE_CHAT_PAY = 'WECHATPAY'; + const PAYMENT_WECHATPAY = 'WECHATPAY'; const WALLET_PAYMENT_METHODS = [ self::PAYMENT_APPLEPAY, @@ -143,7 +143,7 @@ class SaferPayConfig 'Payconiq' => self::PAYMENT_PAYCONIQ, 'Card' => self::PAYMENT_CARD, 'PostFinancePay' => self::PAYMENT_POSTFINANCE_PAY, - 'WeChatPay' => self::PAYMENT_WE_CHAT_PAY, + 'WeChatPay' => self::PAYMENT_WECHATPAY, ]; const FIELD_SUPPORTED_PAYMENT_METHODS = [ @@ -155,7 +155,7 @@ class SaferPayConfig self::PAYMENT_DINERS, self::PAYMENT_JCB, self::PAYMENT_MYONE, - self::PAYMENT_WE_CHAT_PAY, + self::PAYMENT_WECHATPAY, ]; const WLCRYPTOPAYMENTS_SUPPORTED_CURRENCIES = [ @@ -266,6 +266,27 @@ class SaferPayConfig const PAYMENT_BEHAVIOR_WITHOUT_3D_CANCEL = 0; const PAYMENT_BEHAVIOR_WITHOUT_3D_AUTHORIZE = 1; + public static function supportsOrderCapture(string $paymentMethod): bool + { + //payments that DOES NOT SUPPORT capture + $unsupportedCapturePayments = [ + self::PAYMENT_WECHATPAY, + ]; + + return !in_array($paymentMethod, $unsupportedCapturePayments); + } + + public static function supportsOrderCancel(string $paymentMethod): bool + { + //payments that DOES NOT SUPPORT order cancel + $unsupportedCancelPayments = [ + self::PAYMENT_WECHATPAY, + ]; + + return !in_array($paymentMethod, $unsupportedCancelPayments); + } + + public static function getConfigSuffix() { if (Configuration::get(self::TEST_MODE)) { diff --git a/src/Presenter/AssertPresenter.php b/src/Presenter/AssertPresenter.php index f10ebabd..2e46e42a 100755 --- a/src/Presenter/AssertPresenter.php +++ b/src/Presenter/AssertPresenter.php @@ -23,6 +23,7 @@ namespace Invertus\SaferPay\Presenter; +use Invertus\SaferPay\Config\SaferPayConfig; use SaferPayAssert; use SaferPayOfficial; @@ -46,6 +47,8 @@ public function __construct(SaferPayOfficial $saferPay) public function present(SaferPayAssert $assert) { + $paymentMethod = $assert->payment_method; + return [ 'authAmount' => $assert->amount, 'transactionAuth' => $assert->authorized ? @@ -58,10 +61,12 @@ public function present(SaferPayAssert $assert) 'currency' => $assert->currency_code, 'transactionUncertain' => $assert->uncertain, 'brand' => $assert->brand, - 'paymentMethod' => $assert->payment_method, + 'paymentMethod' => $paymentMethod, 'transactionPaid' => $assert->status, 'merchantReference' => $assert->merchant_reference, 'paymentId' => $assert->payment_id, + 'supportsOrderCapture' => SaferPayConfig::supportsOrderCapture($paymentMethod), + 'supportsOrderCancel' => SaferPayConfig::supportsOrderCancel($paymentMethod), 'acceptance' => '????', 'liability_entity' => $assert->liability_entity, 'cardNumber' => $assert->card_number, diff --git a/src/Service/LegacyTranslator.php b/src/Service/LegacyTranslator.php index b055f4d8..5c53b5d2 100755 --- a/src/Service/LegacyTranslator.php +++ b/src/Service/LegacyTranslator.php @@ -81,7 +81,7 @@ private function getTranslations() 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), - SaferPayConfig::PAYMENT_WE_CHAT_PAY => $this->module->l('WeChatPay', self::FILE_NAME), + SaferPayConfig::PAYMENT_WECHATPAY => $this->module->l('WeChatPay', self::FILE_NAME), ]; } } diff --git a/views/templates/hook/admin/saferpay_order.tpl b/views/templates/hook/admin/saferpay_order.tpl index a8b8251d..fff4f2b2 100755 --- a/views/templates/hook/admin/saferpay_order.tpl +++ b/views/templates/hook/admin/saferpay_order.tpl @@ -54,10 +54,14 @@ {/if} {elseif $transactionPaid == 'AUTHORIZED'} - - + {if $supportsOrderCapture} + + {/if} + {if $supportsOrderCancel} + + {/if} {/if}
From f4aaea2ff99d24355a9ada990e8292b8287a567a Mon Sep 17 00:00:00 2001 From: Julius Zukauskas Date: Wed, 12 Jun 2024 18:20:25 +0300 Subject: [PATCH 3/9] wip --- saferpayofficial.php | 12 ++++++++++++ src/Config/SaferPayConfig.php | 3 +++ src/DTO/Request/Initialize/InitializeRequest.php | 4 +++- src/Entity/SaferPayOrder.php | 6 ++++++ src/EntityBuilder/SaferPayOrderBuilder.php | 3 ++- src/Install/Installer.php | 1 + src/Processor/CheckoutProcessor.php | 4 ++++ upgrade/install-1.2.3.php | 9 +++++---- 8 files changed, 36 insertions(+), 6 deletions(-) diff --git a/saferpayofficial.php b/saferpayofficial.php index 88910a53..c37f9f52 100755 --- a/saferpayofficial.php +++ b/saferpayofficial.php @@ -116,6 +116,18 @@ public function getService($service) return $containerProvider->getService($service); } + public function hookDisplayOrderConfirmation($params) + { + if (empty($params['order'])) { + return ''; + } + + //@todo: get saferpay order, check if pending and only then show custom message + //@todo: translate and move to template when requirements are clear + return 'Your payment is still being processed by your bank. This can take up to 5 days (120 hours). Once we receive the final status, we will notify you immediately. +Thank you for your patience!'; + } + public function hookActionObjectOrderPaymentAddAfter($params) { if (!isset($params['object'])) { diff --git a/src/Config/SaferPayConfig.php b/src/Config/SaferPayConfig.php index b057cb5b..c6649a1a 100755 --- a/src/Config/SaferPayConfig.php +++ b/src/Config/SaferPayConfig.php @@ -78,6 +78,7 @@ class SaferPayConfig self::PAYMENT_KLARNA, self::PAYMENT_WLCRYPTOPAYMENTS, self::PAYMENT_WECHATPAY, + self::PAYMENT_ACCOUNTTOACCOUNT, ]; const PAYMENT_ALIPAY = 'ALIPAY'; @@ -271,6 +272,7 @@ public static function supportsOrderCapture(string $paymentMethod): bool //payments that DOES NOT SUPPORT capture $unsupportedCapturePayments = [ self::PAYMENT_WECHATPAY, + self::PAYMENT_ACCOUNTTOACCOUNT, ]; return !in_array($paymentMethod, $unsupportedCapturePayments); @@ -281,6 +283,7 @@ public static function supportsOrderCancel(string $paymentMethod): bool //payments that DOES NOT SUPPORT order cancel $unsupportedCancelPayments = [ self::PAYMENT_WECHATPAY, + self::PAYMENT_ACCOUNTTOACCOUNT, ]; return !in_array($paymentMethod, $unsupportedCancelPayments); diff --git a/src/DTO/Request/Initialize/InitializeRequest.php b/src/DTO/Request/Initialize/InitializeRequest.php index 90d9d05f..07269cd0 100755 --- a/src/DTO/Request/Initialize/InitializeRequest.php +++ b/src/DTO/Request/Initialize/InitializeRequest.php @@ -177,7 +177,9 @@ public function getAsArray() ], 'Payment' => [ 'Amount' => [ - 'Value' => $this->payment->getValue(), + //@todo: don't forget this. Its for testing/debugging. https://docs.saferpay.com/home/integration-guide/testing-and-go-live#account-to-account-payments +// 'Value' => $this->payment->getValue(), + 'Value' => 4030030, 'CurrencyCode' => $this->payment->getCurrencyCode(), ], 'OrderId' => $this->payment->getOrderReference(), diff --git a/src/Entity/SaferPayOrder.php b/src/Entity/SaferPayOrder.php index 2bac92c9..81bd09e0 100755 --- a/src/Entity/SaferPayOrder.php +++ b/src/Entity/SaferPayOrder.php @@ -90,6 +90,11 @@ class SaferPayOrder extends ObjectModel */ public $authorized; + /** + * @var bool + */ + public $pending; + /** * @var array */ @@ -109,6 +114,7 @@ class SaferPayOrder extends ObjectModel 'canceled' => ['type' => self::TYPE_BOOL, 'validate' => 'isBool'], 'refunded' => ['type' => self::TYPE_BOOL, 'validate' => 'isBool'], 'authorized' => ['type' => self::TYPE_BOOL, 'validate' => 'isBool'], + 'pending' => ['type' => self::TYPE_BOOL, 'validate' => 'isBool'], ], ]; } diff --git a/src/EntityBuilder/SaferPayOrderBuilder.php b/src/EntityBuilder/SaferPayOrderBuilder.php index 4018db98..7da44046 100755 --- a/src/EntityBuilder/SaferPayOrderBuilder.php +++ b/src/EntityBuilder/SaferPayOrderBuilder.php @@ -35,7 +35,7 @@ class SaferPayOrderBuilder { //TODO to pass $body as InitializeBody. - public function create($body, $cartId, $customerId, $isTransaction) + public function create($body, $cartId, $customerId, $isTransaction, $status = null) { if (method_exists('Order', 'getIdByCartId')) { $orderId = Order::getIdByCartId($cartId); @@ -51,6 +51,7 @@ public function create($body, $cartId, $customerId, $isTransaction) $saferPayOrder->id_customer = $customerId; $saferPayOrder->redirect_url = $this->getRedirectionUrl($body); $saferPayOrder->is_transaction = $isTransaction; + $saferPayOrder->add(); return $saferPayOrder; diff --git a/src/Install/Installer.php b/src/Install/Installer.php index 8e5c9534..00974406 100755 --- a/src/Install/Installer.php +++ b/src/Install/Installer.php @@ -96,6 +96,7 @@ private function registerHooks() $this->module->registerHook('actionAdminControllerSetMedia'); $this->module->registerHook('actionOrderHistoryAddAfter'); $this->module->registerHook('actionObjectOrderPaymentAddAfter'); + $this->module->registerHook('displayOrderConfirmation'); } private function installConfiguration() diff --git a/src/Processor/CheckoutProcessor.php b/src/Processor/CheckoutProcessor.php index eac6cc4a..061f66bb 100644 --- a/src/Processor/CheckoutProcessor.php +++ b/src/Processor/CheckoutProcessor.php @@ -210,6 +210,10 @@ private function processAuthorizedOrder(CheckoutData $data, Cart $cart) } elseif ($data->getOrderStatus() === 'CAPTURED') { $order->setCurrentState(_SAFERPAY_PAYMENT_COMPLETED_); $saferPayOrder->captured = 1; + } elseif ($data->getOrderStatus() === 'PENDING') { + $order->setCurrentState(_SAFERPAY_PAYMENT_AUTHORIZED_); + $saferPayOrder->authorized = 1; + $saferPayOrder->pending = 1; } $saferPayOrder->update(); diff --git a/upgrade/install-1.2.3.php b/upgrade/install-1.2.3.php index b8af0277..bac6152c 100644 --- a/upgrade/install-1.2.3.php +++ b/upgrade/install-1.2.3.php @@ -27,10 +27,11 @@ if (!defined('_PS_VERSION_')) { exit; } + function upgrade_module_1_2_3(SaferPayOfficial $module) { - Configuration::updateValue(RequestHeader::SPEC_VERSION, SaferPayConfig::API_VERSION); - Configuration::updateValue(RequestHeader::SPEC_REFUND_VERSION, SaferPayConfig::API_VERSION); - - return true; + return Db::getInstance()->execute('ALTER TABLE ' . _DB_PREFIX_ . 'saferpay_order ADD COLUMN `pending` TINYINT(1) DEFAULT 0') && + $module->registerHook('displayOrderConfirmation') && + Configuration::updateValue(RequestHeader::SPEC_VERSION, SaferPayConfig::API_VERSION) && + Configuration::updateValue(RequestHeader::SPEC_REFUND_VERSION, SaferPayConfig::API_VERSION); } From f35ac76f4d2923ecc34ada6ea54fe34ca68065ac Mon Sep 17 00:00:00 2001 From: Julius Zukauskas Date: Wed, 26 Jun 2024 15:25:06 +0300 Subject: [PATCH 4/9] force create order before checkout for a2a. add upgrade and new pending status --- saferpay.config.php | 4 ++++ saferpayofficial.php | 13 +++++++++++- src/Config/SaferPayConfig.php | 1 + src/Core/Payment/DTO/CheckoutData.php | 24 ++++++++++++++++++++-- src/Install/Installer.php | 15 ++++++++++++++ src/Processor/CheckoutProcessor.php | 2 +- src/Repository/SaferPayOrderRepository.php | 12 +++++++++++ upgrade/install-1.2.3.php | 6 +++++- 8 files changed, 72 insertions(+), 5 deletions(-) diff --git a/saferpay.config.php b/saferpay.config.php index 94c75db3..b3c3553e 100755 --- a/saferpay.config.php +++ b/saferpay.config.php @@ -35,6 +35,10 @@ /** @var URL to module IMG files directory */ define('_SAFERPAY_PAYMENT_AUTHORIZED_', Configuration::get(SaferPayConfig::SAFERPAY_PAYMENT_AUTHORIZED)); } +if (!defined('_SAFERPAY_PAYMENT_PENDING_')) { + /** @var URL to module IMG files directory */ + define('_SAFERPAY_PAYMENT_PENDING_', Configuration::get(SaferPayConfig::SAFERPAY_PAYMENT_PENDING)); +} if (!defined('_SAFERPAY_PAYMENT_REJECTED_')) { /** @var URL to module IMG files directory */ define('_SAFERPAY_PAYMENT_REJECTED_', Configuration::get(SaferPayConfig::SAFERPAY_PAYMENT_REJECTED)); diff --git a/saferpayofficial.php b/saferpayofficial.php index c37f9f52..c8f1a8ad 100755 --- a/saferpayofficial.php +++ b/saferpayofficial.php @@ -122,8 +122,19 @@ public function hookDisplayOrderConfirmation($params) return ''; } - //@todo: get saferpay order, check if pending and only then show custom message + /** @var Order $psOrder */ + $psOrder = $params['order']; + + /** @var \Invertus\SaferPay\Repository\SaferPayOrderRepository $repository */ + $repository = $this->getService(\Invertus\SaferPay\Repository\SaferPayOrderRepository::class); + + $sfOrder = $repository->getByOrderId((int) $psOrder->id); + if (!$sfOrder->pending) { + return ''; + } + //@todo: translate and move to template when requirements are clear + //@todo: order confirmation is already shown and confirmation email is already sent (altough the payment is pending), is that ok? return 'Your payment is still being processed by your bank. This can take up to 5 days (120 hours). Once we receive the final status, we will notify you immediately. Thank you for your patience!'; } diff --git a/src/Config/SaferPayConfig.php b/src/Config/SaferPayConfig.php index c6649a1a..37f6393d 100755 --- a/src/Config/SaferPayConfig.php +++ b/src/Config/SaferPayConfig.php @@ -219,6 +219,7 @@ class SaferPayConfig const SAFERPAY_PAYMENT_COMPLETED = 'SAFERPAY_PAYMENT_COMPLETED'; const SAFERPAY_PAYMENT_AUTHORIZED = 'SAFERPAY_PAYMENT_AUTHORIZED'; + const SAFERPAY_PAYMENT_PENDING = 'SAFERPAY_PAYMENT_PENDING'; const SAFERPAY_PAYMENT_REJECTED = 'SAFERPAY_PAYMENT_REJECTED'; const SAFERPAY_PAYMENT_AWAITING = 'SAFERPAY_PAYMENT_AWAITING'; const SAFERPAY_PAYMENT_REFUNDED = 'SAFERPAY_PAYMENT_REFUNDED'; diff --git a/src/Core/Payment/DTO/CheckoutData.php b/src/Core/Payment/DTO/CheckoutData.php index 7281cfe9..7a48165d 100644 --- a/src/Core/Payment/DTO/CheckoutData.php +++ b/src/Core/Payment/DTO/CheckoutData.php @@ -60,8 +60,8 @@ public function __construct( $this->fieldToken = $fieldToken; $this->successController = $successController; $this->isTransaction = $isTransaction; - $this->createAfterAuthorization = Configuration::get(SaferPayConfig::SAFERPAY_ORDER_CREATION_AFTER_AUTHORIZATION); $this->isAuthorizedOrder = false; + $this->setCreateAfterAuthorization($paymentMethod); } public static function create( @@ -184,4 +184,24 @@ public function setOrderStatus($status) { $this->status = $status; } -} \ No newline at end of file + + /** + * @param string $paymentMethod + * + * @return void + */ + private function setCreateAfterAuthorization($paymentMethod) + { + $methodsToForceBeforeAuthorization = [ + SaferPayConfig::PAYMENT_ACCOUNTTOACCOUNT, + ]; + + if (in_array($paymentMethod, $methodsToForceBeforeAuthorization, true)) { + $this->createAfterAuthorization = false; + + return; + } + + $this->createAfterAuthorization = Configuration::get(SaferPayConfig::SAFERPAY_ORDER_CREATION_AFTER_AUTHORIZATION); + } +} diff --git a/src/Install/Installer.php b/src/Install/Installer.php index 00974406..81e21ca8 100755 --- a/src/Install/Installer.php +++ b/src/Install/Installer.php @@ -322,6 +322,20 @@ private function installOrderRefundTable() ); } + public function createPendingOrderStatus() + { + return $this->createOrderStatus( + SaferPayConfig::SAFERPAY_PAYMENT_PENDING, + 'Payment pending by Saferpay', + '#ec730a', + false, + true, + false, + false, + true + ); + } + public function createAllOrderStatus() { $success = true; @@ -344,6 +358,7 @@ public function createAllOrderStatus() true, true ); + $success &= $this->createPendingOrderStatus(); $success &= $this->createOrderStatus( SaferPayConfig::SAFERPAY_PAYMENT_REJECTED, 'Payment rejected by Saferpay', diff --git a/src/Processor/CheckoutProcessor.php b/src/Processor/CheckoutProcessor.php index 061f66bb..478520eb 100644 --- a/src/Processor/CheckoutProcessor.php +++ b/src/Processor/CheckoutProcessor.php @@ -211,7 +211,7 @@ private function processAuthorizedOrder(CheckoutData $data, Cart $cart) $order->setCurrentState(_SAFERPAY_PAYMENT_COMPLETED_); $saferPayOrder->captured = 1; } elseif ($data->getOrderStatus() === 'PENDING') { - $order->setCurrentState(_SAFERPAY_PAYMENT_AUTHORIZED_); + $order->setCurrentState(_SAFERPAY_PAYMENT_PENDING_); $saferPayOrder->authorized = 1; $saferPayOrder->pending = 1; } diff --git a/src/Repository/SaferPayOrderRepository.php b/src/Repository/SaferPayOrderRepository.php index ae51aa3f..b9d262e8 100755 --- a/src/Repository/SaferPayOrderRepository.php +++ b/src/Repository/SaferPayOrderRepository.php @@ -25,6 +25,7 @@ use Db; use DbQuery; +use SaferPayOrder; if (!defined('_PS_VERSION_')) { exit; @@ -32,6 +33,17 @@ class SaferPayOrderRepository { + + /** + * @param int $orderId + * + * @return SaferPayOrder + */ + public function getByOrderId($orderId) + { + return new SaferPayOrder($this->getIdByOrderId($orderId)); + } + public function getIdByOrderId($orderId) { $query = new DbQuery(); diff --git a/upgrade/install-1.2.3.php b/upgrade/install-1.2.3.php index bac6152c..b5ce3a0b 100644 --- a/upgrade/install-1.2.3.php +++ b/upgrade/install-1.2.3.php @@ -30,7 +30,11 @@ function upgrade_module_1_2_3(SaferPayOfficial $module) { - return Db::getInstance()->execute('ALTER TABLE ' . _DB_PREFIX_ . 'saferpay_order ADD COLUMN `pending` TINYINT(1) DEFAULT 0') && + $installer = new \Invertus\SaferPay\Install\Installer($module); + + return + $installer->createPendingOrderStatus() && + Db::getInstance()->execute('ALTER TABLE ' . _DB_PREFIX_ . 'saferpay_order ADD COLUMN `pending` TINYINT(1) DEFAULT 0') && $module->registerHook('displayOrderConfirmation') && Configuration::updateValue(RequestHeader::SPEC_VERSION, SaferPayConfig::API_VERSION) && Configuration::updateValue(RequestHeader::SPEC_REFUND_VERSION, SaferPayConfig::API_VERSION); From 68fb81f6f88bdb0ac52e292cf41eab7451f1ca0e Mon Sep 17 00:00:00 2001 From: Julius Zukauskas Date: Wed, 26 Jun 2024 15:26:14 +0300 Subject: [PATCH 5/9] remove testing todo --- saferpayofficial.php | 3 +-- src/DTO/Request/Initialize/InitializeRequest.php | 4 +--- src/EntityBuilder/SaferPayOrderBuilder.php | 3 +-- 3 files changed, 3 insertions(+), 7 deletions(-) diff --git a/saferpayofficial.php b/saferpayofficial.php index c8f1a8ad..a89a33e1 100755 --- a/saferpayofficial.php +++ b/saferpayofficial.php @@ -133,8 +133,7 @@ public function hookDisplayOrderConfirmation($params) return ''; } - //@todo: translate and move to template when requirements are clear - //@todo: order confirmation is already shown and confirmation email is already sent (altough the payment is pending), is that ok? + //@todo: translate and move to template if needed when requirements are clear return 'Your payment is still being processed by your bank. This can take up to 5 days (120 hours). Once we receive the final status, we will notify you immediately. Thank you for your patience!'; } diff --git a/src/DTO/Request/Initialize/InitializeRequest.php b/src/DTO/Request/Initialize/InitializeRequest.php index 07269cd0..90d9d05f 100755 --- a/src/DTO/Request/Initialize/InitializeRequest.php +++ b/src/DTO/Request/Initialize/InitializeRequest.php @@ -177,9 +177,7 @@ public function getAsArray() ], 'Payment' => [ 'Amount' => [ - //@todo: don't forget this. Its for testing/debugging. https://docs.saferpay.com/home/integration-guide/testing-and-go-live#account-to-account-payments -// 'Value' => $this->payment->getValue(), - 'Value' => 4030030, + 'Value' => $this->payment->getValue(), 'CurrencyCode' => $this->payment->getCurrencyCode(), ], 'OrderId' => $this->payment->getOrderReference(), diff --git a/src/EntityBuilder/SaferPayOrderBuilder.php b/src/EntityBuilder/SaferPayOrderBuilder.php index 7da44046..cca57f36 100755 --- a/src/EntityBuilder/SaferPayOrderBuilder.php +++ b/src/EntityBuilder/SaferPayOrderBuilder.php @@ -34,8 +34,7 @@ class SaferPayOrderBuilder { - //TODO to pass $body as InitializeBody. - public function create($body, $cartId, $customerId, $isTransaction, $status = null) + public function create($body, $cartId, $customerId, $isTransaction) { if (method_exists('Order', 'getIdByCartId')) { $orderId = Order::getIdByCartId($cartId); From 18a7df4f8cfca682dd658818391775f457ba1a24 Mon Sep 17 00:00:00 2001 From: Julius Zukauskas Date: Thu, 27 Jun 2024 12:53:03 +0300 Subject: [PATCH 6/9] handle pending decline --- controllers/front/notify.php | 54 ++++++++++++++++++++--------- src/Api/Request/AssertService.php | 1 + src/Processor/CheckoutProcessor.php | 3 +- 3 files changed, 40 insertions(+), 18 deletions(-) diff --git a/controllers/front/notify.php b/controllers/front/notify.php index f4a24aae..5bfd644d 100755 --- a/controllers/front/notify.php +++ b/controllers/front/notify.php @@ -75,13 +75,7 @@ public function postProcess() } if ($cart->orderExists()) { - if (method_exists('Order', 'getIdByCartId')) { - $orderId = Order::getIdByCartId($cartId); - } else { - // For PrestaShop 1.6 use the alternative method - $orderId = Order::getOrderByCartId($cartId); - } - + $orderId = $this->getOrderId($cartId); $order = new Order($orderId); $saferPayAuthorizedStatus = (int) Configuration::get(\Invertus\SaferPay\Config\SaferPayConfig::SAFERPAY_PAYMENT_AUTHORIZED); @@ -92,11 +86,11 @@ public function postProcess() } } + /** @var SaferPayOrderRepository $saferPayOrderRepository */ + $saferPayOrderRepository = $this->module->getService(SaferPayOrderRepository::class); + try { $assertResponseBody = $this->assertTransaction($cartId); - - /** @var SaferPayOrderRepository $saferPayOrderRepository */ - $saferPayOrderRepository = $this->module->getService(SaferPayOrderRepository::class); $saferPayOrderId = $saferPayOrderRepository->getIdByCartId($cartId); /** @var UpdateSaferPayOrderAction $updateSaferPayOrderAction */ @@ -104,12 +98,7 @@ public function postProcess() $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. - if (method_exists('Order', 'getIdByCartId')) { - $orderId = Order::getIdByCartId($cartId); - } else { - // For PrestaShop 1.6 use the alternative method - $orderId = Order::getOrderByCartId($cartId); - } + $orderId = $this->getOrderId($cartId); if (!$orderId) { /** @var CheckoutProcessor $checkoutProcessor **/ $checkoutProcessor = $this->module->getService(CheckoutProcessor::class); @@ -163,6 +152,24 @@ public function postProcess() $orderStatusService->capture($order); } } catch (Exception $e) { + // this might be executed after pending transaction is declined (e.g. with accountToAccount payment) + if (!isset($order)) { + $orderId = $this->getOrderId($cartId); + $order = new Order($orderId); + } + + $saferPayOrderId = $saferPayOrderRepository->getIdByOrderId($order->id); + $saferPayOrder = new SaferPayOrder($saferPayOrderId); + + if ($order->id && $saferPayOrder->id) { + // assuming order transaction was declined + $order->setCurrentState(_SAFERPAY_PAYMENT_AUTHORIZATION_FAILED_); + $order->update(); + $saferPayOrder->authorized = false; + $saferPayOrder->pending = false; + $saferPayOrder->update(); + } + PrestaShopLogger::addLog( sprintf( '%s has caught an error: %s', @@ -188,6 +195,21 @@ private function assertTransaction($cartId) { return $transactionAssert->assert($cartId); } + /** + * @param int $cartId + * + * @return bool|int + */ + private function getOrderId($cartId) + { + if (method_exists('Order', 'getIdByCartId')) { + return Order::getIdByCartId($cartId); + } else { + // For PrestaShop 1.6 use the alternative method + return Order::getOrderByCartId($cartId); + } + } + protected function displayMaintenancePage() { return true; diff --git a/src/Api/Request/AssertService.php b/src/Api/Request/AssertService.php index c430dbce..d1297a41 100755 --- a/src/Api/Request/AssertService.php +++ b/src/Api/Request/AssertService.php @@ -29,6 +29,7 @@ use Invertus\SaferPay\DTO\Response\Assert\AssertBody; use Invertus\SaferPay\EntityBuilder\SaferPayAssertBuilder; use Invertus\SaferPay\Exception\Api\SaferPayApiException; +use Invertus\SaferPay\Exception\Api\TransactionDeclinedException; use Invertus\SaferPay\Service\Response\AssertResponseObjectCreator; use SaferPayOrder; diff --git a/src/Processor/CheckoutProcessor.php b/src/Processor/CheckoutProcessor.php index 478520eb..5b6912f1 100644 --- a/src/Processor/CheckoutProcessor.php +++ b/src/Processor/CheckoutProcessor.php @@ -37,6 +37,7 @@ use Invertus\SaferPay\Repository\SaferPayOrderRepository; use Invertus\SaferPay\Service\SaferPayInitialize; use Order; +use PrestaShop\PrestaShop\Adapter\Entity\PrestaShopLogger; use PrestaShopException; use SaferPayOrder; @@ -203,7 +204,6 @@ private function processAuthorizedOrder(CheckoutData $data, Cart $cart) } $saferPayOrder->id_order = $order->id; - if ($data->getOrderStatus() === 'AUTHORIZED') { $order->setCurrentState(_SAFERPAY_PAYMENT_AUTHORIZED_); $saferPayOrder->authorized = 1; @@ -212,7 +212,6 @@ private function processAuthorizedOrder(CheckoutData $data, Cart $cart) $saferPayOrder->captured = 1; } elseif ($data->getOrderStatus() === 'PENDING') { $order->setCurrentState(_SAFERPAY_PAYMENT_PENDING_); - $saferPayOrder->authorized = 1; $saferPayOrder->pending = 1; } From 389e39e120baa018a3113f8cc07c7b3bacc850fa Mon Sep 17 00:00:00 2001 From: Julius Zukauskas Date: Thu, 27 Jun 2024 17:07:00 +0300 Subject: [PATCH 7/9] add wait tpl and remove order creation from return --- controllers/front/return.php | 193 ++++++------------------ views/templates/front/saferpay_wait.tpl | 118 +++++++++++++++ 2 files changed, 167 insertions(+), 144 deletions(-) create mode 100644 views/templates/front/saferpay_wait.tpl diff --git a/controllers/front/return.php b/controllers/front/return.php index f90c9855..70a4bdbd 100755 --- a/controllers/front/return.php +++ b/controllers/front/return.php @@ -21,15 +21,10 @@ *@license SIX Payment Services */ -use Invertus\SaferPay\Api\Enum\TransactionStatus; use Invertus\SaferPay\Config\SaferPayConfig; use Invertus\SaferPay\Controller\AbstractSaferPayController; -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; +use Invertus\SaferPay\Repository\SaferPayOrderRepository; if (!defined('_PS_VERSION_')) { exit; @@ -50,7 +45,6 @@ public function postProcess() $fieldToken = Tools::getValue('fieldToken'); $moduleId = $this->module->id; $selectedCard = Tools::getValue('selectedCard'); - $orderId = Tools::getValue('orderId'); $cart = new Cart($cartId); @@ -61,26 +55,6 @@ public function postProcess() ])); } - $lockResult = $this->applyLock( - sprintf( - '%s-%s', - $cartId, - $secureKey - ) - ); - - if (!$lockResult->isSuccessful()) { - $this->redirectWithNotifications($this->context->link->getModuleLink( - $this->module->name, - ControllerName::FAIL, - [ - 'cartId' => $cartId, - 'secureKey' => $secureKey, - 'moduleId' => $moduleId, - ] - )); - } - if ($cart->secure_key !== $secureKey) { $this->ajaxDie(json_encode([ 'error_type' => 'unknown_error', @@ -114,104 +88,73 @@ public function postProcess() ] )); } - } - - try { - 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); - - if (method_exists('Order', 'getIdByCartId')) { - $orderId = Order::getIdByCartId($cartId); - } else { - // For PrestaShop 1.6 use the alternative method - $orderId = Order::getOrderByCartId($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( + } else { + $this->context->smarty->assign( + 'checkStatusEndpoint', + $this->context->link->getModuleLink( $this->module->name, - ControllerName::FAIL, + 'return', [ - 'cartId' => $cartId, + 'ajax' => 1, + 'action' => 'getStatus', 'secureKey' => $secureKey, - 'orderId' => $orderId, - 'moduleId' => $moduleId, + 'cartId' => $cartId, ], true - )); - } - $paymentMethod = $response->getPaymentMeans()->getBrand()->getPaymentMethod(); + )); + parent::setTemplate('saferpay_wait.tpl'); + } + } - if (SaferPayConfig::supportsOrderCapture($paymentMethod) && (int) Configuration::get(SaferPayConfig::PAYMENT_BEHAVIOR) === SaferPayConfig::DEFAULT_PAYMENT_BEHAVIOR_CAPTURE && - $response->getTransaction()->getStatus() !== TransactionStatus::CAPTURED - ) { - $orderStatusService->capture(new Order($orderId)); - } + /** + * @throws PrestaShopDatabaseException + * @throws PrestaShopException + */ + protected function processGetStatus() + { + header('Content-Type: application/json;charset=UTF-8'); + /** @var SaferPayOrderRepository $saferPayOrderRepository */ + $saferPayOrderRepository = $this->module->getService(SaferPayOrderRepository::class); - Tools::redirect($this->context->link->getModuleLink( + $cartId = Tools::getValue('cartId'); + $secureKey = Tools::getValue('secureKey'); + $isBusinessLicence = (int) Tools::getValue(SaferPayConfig::IS_BUSINESS_LICENCE); + $fieldToken = Tools::getValue('fieldToken'); + $moduleId = $this->module->id; + $selectedCard = Tools::getValue('selectedCard'); + $saferPayOrderId = $saferPayOrderRepository->getIdByCartId($cartId); + $saferPayOrder = new SaferPayOrder($saferPayOrderId); + + if ($saferPayOrder->canceled || !$saferPayOrder->id_order) { + $href = $this->context->link->getModuleLink( $this->module->name, - $this->getSuccessControllerName($isBusinessLicence, $fieldToken), + ControllerName::FAIL, [ 'cartId' => $cartId, - 'orderId' => $orderId, - 'moduleId' => $moduleId, 'secureKey' => $secureKey, - 'selectedCard' => $selectedCard, + 'moduleId' => $moduleId, ], true - )); - } catch (Exception $e) { - PrestaShopLogger::addLog( - sprintf( - 'Failed to assert transaction. Message: %s. File name: %s', - $e->getMessage(), - self::FILENAME - ) ); - - Tools::redirect($this->context->link->getModuleLink( + } else { + $href = $this->context->link->getModuleLink( $this->module->name, - 'failValidation', + $this->getSuccessControllerName($isBusinessLicence, $fieldToken), [ 'cartId' => $cartId, - 'orderId' => $orderId, + 'orderId' => $saferPayOrder->id_order, + 'moduleId' => $moduleId, 'secureKey' => $secureKey, - ], - true - )); + 'selectedCard' => $selectedCard, + ] + ); } + + // @todo: this place needs attention after a2a pr merged - need to check if pending status works well + $this->ajaxDie(json_encode([ + 'isFinished' => $saferPayOrder->authorized || $saferPayOrder->captured || $saferPayOrder->canceled || isset($saferPayOrder->pending), + 'href' => $href + ])); } private function getSuccessControllerName($isBusinessLicence, $fieldToken) @@ -228,42 +171,4 @@ private function getSuccessControllerName($isBusinessLicence, $fieldToken) return $successController; } - - /** - * @param int $orderId - * @param int $selectedCard - * - * @return \Invertus\SaferPay\DTO\Response\Assert\AssertBody - * @throws Exception - */ - private function executeTransaction($orderId, $selectedCard) - { - /** @var SaferPayTransactionAuthorization $saferPayTransactionAuthorization */ - $saferPayTransactionAuthorization = $this->module->getService(SaferPayTransactionAuthorization::class); - - $response = $saferPayTransactionAuthorization->authorize( - $orderId, - $selectedCard === SaferPayConfig::CREDIT_CARD_OPTION_SAVE, - $selectedCard - ); - - return $response; - } - - /** - * @param int $cartId - * @param int $isBusinessLicence - * - * @return \Invertus\SaferPay\DTO\Response\Assert\AssertBody|null - * @throws Exception - */ - private function executePaymentPageAssertion($cartId, $isBusinessLicence) - { - - /** @var SaferPayTransactionAssertion $transactionAssert */ - $transactionAssert = $this->module->getService(SaferPayTransactionAssertion::class); - $assertionResponse = $transactionAssert->assert($cartId); - - return $assertionResponse; - } } diff --git a/views/templates/front/saferpay_wait.tpl b/views/templates/front/saferpay_wait.tpl new file mode 100644 index 00000000..2981c63c --- /dev/null +++ b/views/templates/front/saferpay_wait.tpl @@ -0,0 +1,118 @@ +{** + *NOTICE OF LICENSE + * + *This source file is subject to the Open Software License (OSL 3.0) + *that is bundled with this package in the file LICENSE.txt. + *It is also available through the world-wide-web at this URL: + *http://opensource.org/licenses/osl-3.0.php + *If you did not receive a copy of the license and are unable to + *obtain it through the world-wide-web, please send an email + *to license@prestashop.com so we can send you a copy immediately. + * + *DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade PrestaShop to newer + *versions in the future. If you wish to customize PrestaShop for your + *needs please refer to http://www.prestashop.com for more information. + * + *@author INVERTUS UAB www.invertus.eu + *@copyright SIX Payment Services + *@license SIX Payment Services + *} +

{l s='Awaiting payment status' mod='saferpay'}

+
+
+
+
+
+
+
+ + + From b3bac09c25e1c06994624d44e6a0fb9751aabc1a Mon Sep 17 00:00:00 2001 From: Julius Zukauskas Date: Thu, 27 Jun 2024 17:09:56 +0300 Subject: [PATCH 8/9] remove todo --- controllers/front/return.php | 1 - 1 file changed, 1 deletion(-) diff --git a/controllers/front/return.php b/controllers/front/return.php index 70a4bdbd..652c8dc6 100755 --- a/controllers/front/return.php +++ b/controllers/front/return.php @@ -150,7 +150,6 @@ protected function processGetStatus() ); } - // @todo: this place needs attention after a2a pr merged - need to check if pending status works well $this->ajaxDie(json_encode([ 'isFinished' => $saferPayOrder->authorized || $saferPayOrder->captured || $saferPayOrder->canceled || isset($saferPayOrder->pending), 'href' => $href From c1d83af97779e3308f300445aaed31e6c693ac65 Mon Sep 17 00:00:00 2001 From: Julius Zukauskas Date: Fri, 28 Jun 2024 15:46:48 +0300 Subject: [PATCH 9/9] fix pending status --- controllers/front/notify.php | 8 +- controllers/front/return.php | 104 +++++++++++++++++---- src/Processor/CheckoutProcessor.php | 1 - src/Service/SaferPayOrderStatusService.php | 9 ++ views/templates/front/saferpay_wait.tpl | 4 +- 5 files changed, 97 insertions(+), 29 deletions(-) diff --git a/controllers/front/notify.php b/controllers/front/notify.php index 5bfd644d..e6031a71 100755 --- a/controllers/front/notify.php +++ b/controllers/front/notify.php @@ -112,13 +112,7 @@ public function postProcess() $checkoutData->setOrderStatus($assertResponseBody->getTransaction()->getStatus()); $checkoutProcessor->run($checkoutData); - - if (method_exists('Order', 'getIdByCartId')) { - $orderId = Order::getIdByCartId($cartId); - } else { - // For PrestaShop 1.6 or lower, use the alternative method - $orderId = Order::getOrderByCartId($cartId); - } + $orderId = $this->getOrderId($cartId); } //TODO look into pipeline design pattern to use when object is modified in multiple places to avoid this issue. diff --git a/controllers/front/return.php b/controllers/front/return.php index 652c8dc6..6d62e477 100755 --- a/controllers/front/return.php +++ b/controllers/front/return.php @@ -25,6 +25,8 @@ use Invertus\SaferPay\Controller\AbstractSaferPayController; use Invertus\SaferPay\Enum\ControllerName; use Invertus\SaferPay\Repository\SaferPayOrderRepository; +use Invertus\SaferPay\Service\SaferPayOrderStatusService; +use Invertus\SaferPay\Service\TransactionFlow\SaferPayTransactionAssertion; if (!defined('_PS_VERSION_')) { exit; @@ -34,18 +36,40 @@ class SaferPayOfficialReturnModuleFrontController extends AbstractSaferPayContro { const FILENAME = 'return'; + public function postProcess() + { + $cartId = Tools::getValue('cartId'); + + $transactionResponse = $this->assertTransaction($cartId); + if ($transactionResponse->getTransaction()->getStatus() === 'PENDING') { + $orderId = $this->getOrderId($cartId); + if (!$orderId) { + return; + } + + /** @var SaferPayOrderStatusService $orderStatusService */ + $orderStatusService = $this->module->getService(SaferPayOrderStatusService::class); + $orderStatusService->pending(new \Order($orderId)); + } + } /** * @throws PrestaShopException */ - public function postProcess() + public function initContent() { + if (Tools::getValue('ajax')) { + $this->processAjax(); + exit; + } + + parent::initContent(); + $cartId = Tools::getValue('cartId'); $secureKey = Tools::getValue('secureKey'); $isBusinessLicence = (int) Tools::getValue(SaferPayConfig::IS_BUSINESS_LICENCE); $fieldToken = Tools::getValue('fieldToken'); $moduleId = $this->module->id; $selectedCard = Tools::getValue('selectedCard'); - $cart = new Cart($cartId); if (!Validate::isLoadedObject($cart)) { @@ -88,22 +112,39 @@ public function postProcess() ] )); } - } else { - $this->context->smarty->assign( - 'checkStatusEndpoint', - $this->context->link->getModuleLink( - $this->module->name, - 'return', - [ - 'ajax' => 1, - 'action' => 'getStatus', - 'secureKey' => $secureKey, - 'cartId' => $cartId, - ], - true - )); - parent::setTemplate('saferpay_wait.tpl'); } + + $this->context->smarty->assign( + 'checkStatusEndpoint', + $this->context->link->getModuleLink( + $this->module->name, + 'return', + [ + 'ajax' => 1, + 'action' => 'getStatus', + 'secureKey' => $secureKey, + 'cartId' => $cartId, + ], + true + ) + ); + + $this->setTemplate(SaferPayConfig::SAFERPAY_TEMPLATE_LOCATION . '/front/saferpay_wait.tpl'); + } + + protected function processAjax() + { + if (empty($this->context->customer->id)) { + return; + } + + switch (Tools::getValue('action')) { + case 'getStatus': + $this->processGetStatus(); + break; + } + + exit; } /** @@ -115,7 +156,6 @@ protected function processGetStatus() header('Content-Type: application/json;charset=UTF-8'); /** @var SaferPayOrderRepository $saferPayOrderRepository */ $saferPayOrderRepository = $this->module->getService(SaferPayOrderRepository::class); - $cartId = Tools::getValue('cartId'); $secureKey = Tools::getValue('secureKey'); $isBusinessLicence = (int) Tools::getValue(SaferPayConfig::IS_BUSINESS_LICENCE); @@ -151,7 +191,11 @@ protected function processGetStatus() } $this->ajaxDie(json_encode([ - 'isFinished' => $saferPayOrder->authorized || $saferPayOrder->captured || $saferPayOrder->canceled || isset($saferPayOrder->pending), + 'authorized' => $saferPayOrder->authorized, + 'captured' => $saferPayOrder->captured, + 'canceled' => $saferPayOrder->canceled, + 'pending' => $saferPayOrder->pending, + 'isFinished' => $saferPayOrder->authorized || $saferPayOrder->captured || $saferPayOrder->canceled || $saferPayOrder->pending, 'href' => $href ])); } @@ -170,4 +214,26 @@ private function getSuccessControllerName($isBusinessLicence, $fieldToken) return $successController; } + + private function assertTransaction($cartId) { + /** @var SaferPayTransactionAssertion $transactionAssert */ + $transactionAssert = $this->module->getService(SaferPayTransactionAssertion::class); + + return $transactionAssert->assert($cartId); + } + + /** + * @param int $cartId + * + * @return bool|int + */ + private function getOrderId($cartId) + { + if (method_exists('Order', 'getIdByCartId')) { + return Order::getIdByCartId($cartId); + } else { + // For PrestaShop 1.6 use the alternative method + return Order::getOrderByCartId($cartId); + } + } } diff --git a/src/Processor/CheckoutProcessor.php b/src/Processor/CheckoutProcessor.php index 5b6912f1..24c31544 100644 --- a/src/Processor/CheckoutProcessor.php +++ b/src/Processor/CheckoutProcessor.php @@ -216,7 +216,6 @@ private function processAuthorizedOrder(CheckoutData $data, Cart $cart) } $saferPayOrder->update(); - $order->update(); return; } catch (\Exception $exception) { throw CouldNotProcessCheckout::failedToCreateOrder($data->getCartId()); diff --git a/src/Service/SaferPayOrderStatusService.php b/src/Service/SaferPayOrderStatusService.php index 0894beef..b1800f83 100755 --- a/src/Service/SaferPayOrderStatusService.php +++ b/src/Service/SaferPayOrderStatusService.php @@ -111,6 +111,15 @@ public function __construct( $this->module = $module->getModule(); } + public function pending(Order $order) + { + $saferPayOrder = $this->orderRepository->getByOrderId($order->id); + $saferPayOrder->pending = 1; + + $saferPayOrder->update(); + $order->setCurrentState(_SAFERPAY_PAYMENT_PENDING_); + } + /** * @param Order $order * diff --git a/views/templates/front/saferpay_wait.tpl b/views/templates/front/saferpay_wait.tpl index 2981c63c..28d37257 100644 --- a/views/templates/front/saferpay_wait.tpl +++ b/views/templates/front/saferpay_wait.tpl @@ -19,7 +19,7 @@ *@copyright SIX Payment Services *@license SIX Payment Services *} -

{l s='Awaiting payment status' mod='saferpay'}

+

{l s='Awaiting payment status' mod='saferpayofficial'}

@@ -97,7 +97,7 @@ if (request.status >= 200 && request.status < 400) { try { var data = JSON.parse(request.responseText); - if (data.success && data.isFinished) { + if (data.isFinished && data.href) { window.location.href = data.href; return; }