From 1a4c5abb41b6233a76ca9ad7e3c09696defd9a12 Mon Sep 17 00:00:00 2001 From: Julius Zukauskas Date: Tue, 11 Jun 2024 13:18:14 +0300 Subject: [PATCH 1/6] 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/6] 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/6] 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/6] 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/6] 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/6] 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; }