From 557fd8d749358ee28a67aa914ffd6fd0b0efe906 Mon Sep 17 00:00:00 2001 From: Matt75 <5262628+Matt75@users.noreply.github.com> Date: Tue, 22 Aug 2023 11:42:30 +0200 Subject: [PATCH 01/20] PAYSHIP-2455 clear cache after order patch --- controllers/front/check.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/controllers/front/check.php b/controllers/front/check.php index bb439d5d7..3a4cc0896 100644 --- a/controllers/front/check.php +++ b/controllers/front/check.php @@ -22,6 +22,7 @@ use PrestaShop\Module\PrestashopCheckout\Exception\PsCheckoutException; use PrestaShop\Module\PrestashopCheckout\Handler\CreatePaypalOrderHandler; use PrestaShop\Module\PrestashopCheckout\Repository\PsCheckoutCartRepository; +use Psr\SimpleCache\CacheInterface; /** * This controller receive ajax call on customer click on a payment button @@ -118,6 +119,10 @@ public function postProcess() throw new PsCheckoutException(sprintf('Unable to patch PayPal Order - Exception %s : %s', $response['exceptionCode'], $response['exceptionMessage']), PsCheckoutException::PSCHECKOUT_UPDATE_ORDER_HANDLE_ERROR); } + /** @var CacheInterface $orderPayPalCache */ + $orderPayPalCache = $this->module->getService('ps_checkout.cache.paypal.order'); + $orderPayPalCache->delete($psCheckoutCart->getPaypalOrderId()); + $this->module->getLogger()->info( 'PayPal Order patched', [ From ae91cf01bd1ab1d3d9de917c6202b84a5b2dfba4 Mon Sep 17 00:00:00 2001 From: Matt75 <5262628+Matt75@users.noreply.github.com> Date: Tue, 22 Aug 2023 13:23:20 +0200 Subject: [PATCH 02/20] Fix http exception management --- src/Api/GenericClient.php | 38 ++++++++++++++++---------------------- 1 file changed, 16 insertions(+), 22 deletions(-) diff --git a/src/Api/GenericClient.php b/src/Api/GenericClient.php index bfc17d677..f0ef52135 100755 --- a/src/Api/GenericClient.php +++ b/src/Api/GenericClient.php @@ -22,6 +22,7 @@ use Exception; use GuzzleHttp\Psr7\Request; +use Http\Client\Exception\NetworkException; use Http\Client\Exception\TransferException; use Link; use Module; @@ -29,7 +30,6 @@ use PrestaShop\Module\PrestashopCheckout\Handler\Response\ResponseApiHandler; use PrestaShop\Module\PrestashopCheckout\Repository\PsAccountRepository; use Ps_checkout; -use RuntimeException; /** * Construct the client used to make call to maasland @@ -101,26 +101,14 @@ public function __construct() */ protected function post(array $options = []) { + $request = new Request('POST', $this->getRoute(), [], json_encode($options)); + try { - $response = $this->client->sendRequest( - new Request('POST', $this->getRoute(), [], json_encode($options)) - ); - } catch (TransferException $exception) { - return $this->handleException( - new PsCheckoutException( - $exception->getMessage(), - PsCheckoutException::PSCHECKOUT_HTTP_EXCEPTION, - $exception - ) - ); - } catch (RuntimeException $exception) { - return $this->handleException( - new PsCheckoutException( - $exception->getMessage(), - PsCheckoutException::PSCHECKOUT_HTTP_EXCEPTION, - $exception - ) - ); + $response = $this->client->sendRequest($request); + } catch (\GuzzleHttp\Ring\Exception\ConnectException $exception) { + return $this->handleException(new NetworkException($exception->getMessage(), $request, $exception)); + } catch (\GuzzleHttp\Ring\Exception\RingException $exception) { + return $this->handleException(new TransferException($exception->getMessage(), 0, $exception)); } catch (Exception $exception) { return $this->handleException($exception); } @@ -232,6 +220,12 @@ private function handleException(Exception $exception) { $body = ''; $httpCode = 500; + $exceptionCode = $exception->getCode(); + $exceptionMessage = $exception->getMessage(); + + if ($exception instanceof NetworkException || $exception instanceof TransferException) { + $exceptionCode = PsCheckoutException::PSCHECKOUT_HTTP_EXCEPTION; + } if (method_exists($exception, 'getResponse')) { $response = $exception->getResponse(); @@ -243,8 +237,8 @@ private function handleException(Exception $exception) 'status' => false, 'httpCode' => $httpCode, 'body' => $body, - 'exceptionCode' => $exception->getCode(), - 'exceptionMessage' => $exception->getMessage(), + 'exceptionCode' => $exceptionCode, + 'exceptionMessage' => $exceptionMessage, ]; } From 50a8811e9702b1310382415c48cf3c49c7cc491b Mon Sep 17 00:00:00 2001 From: Bastien Tafforeau Date: Fri, 15 Sep 2023 16:48:48 +0200 Subject: [PATCH 03/20] Fixing wrong module configuration when multishop enabled --- ps_checkout.php | 39 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/ps_checkout.php b/ps_checkout.php index 744270c84..4a898a311 100755 --- a/ps_checkout.php +++ b/ps_checkout.php @@ -1272,6 +1272,7 @@ public function hookActionObjectShopAddAfter(array $params) { /** @var Shop $shop */ $shop = $params['object']; + $now = date('Y-m-d H:i:s'); $toggleShopConfigurationCommandHandler = new \PrestaShop\Module\PrestashopCheckout\Configuration\ToggleShopConfigurationCommandHandler(); $toggleShopConfigurationCommandHandler->handle( @@ -1281,9 +1282,45 @@ public function hookActionObjectShopAddAfter(array $params) ) ); - $this->installConfiguration(); + foreach ($this->configurationList as $name => $value) { + if (Configuration::hasKey($name, null, (int) $shop->id_shop_group, (int) $shop->id)) { + Db::getInstance()->update( + 'configuration', + [ + 'name' => pSQL($name), + 'value' => pSQL($value), + 'date_add' => pSQL($now), + 'date_upd' => pSQL($now), + 'id_shop' => (int) $shop->id, + 'id_shop_group' => (int) $shop->id_shop_group, + ], + 'name = \'' . pSQL($name) . '\', id_shop = ' . (int) $shop->id . ', id_shop_group = ' . (int) $shop->id_shop_group, + 1, + true, + false + ); + } else { + Db::getInstance()->insert( + 'configuration', + [ + 'name' => pSQL($name), + 'value' => pSQL($value), + 'date_add' => pSQL($now), + 'date_upd' => pSQL($now), + 'id_shop' => (int) $shop->id, + 'id_shop_group' => (int) $shop->id_shop_group, + ], + true, + false + ); + } + + Configuration::set($name, $value, (int) $shop->id_shop_group, (int) $shop->id); + } + $this->addCheckboxCarrierRestrictionsForModule([(int) $shop->id]); $this->addCheckboxCountryRestrictionsForModule([(int) $shop->id]); + if ($this->currencies_mode === 'checkbox') { $this->addCheckboxCurrencyRestrictionsForModule([(int) $shop->id]); } elseif ($this->currencies_mode === 'radio') { From 3ac8da240b468f3c802eefe6916bc8d62310eaa7 Mon Sep 17 00:00:00 2001 From: sgodard Date: Wed, 12 Jul 2023 17:29:22 +0200 Subject: [PATCH 04/20] Add PayPal env value --- classes/PsCheckoutCart.php | 18 ++++++++++++++++++ .../AdminAjaxPrestashopCheckoutController.php | 2 ++ controllers/front/create.php | 8 +++++++- src/Database/TableManager.php | 1 + src/PayPal/PayPalConfiguration.php | 2 +- views/css/adminOrderView.css | 14 ++++++++++++++ views/templates/admin/ajaxPayPalOrder.tpl | 10 ++++++++++ .../templates/admin/ajaxPayPalOrderLegacy.tpl | 10 ++++++++++ 8 files changed, 63 insertions(+), 2 deletions(-) mode change 100644 => 100755 classes/PsCheckoutCart.php mode change 100644 => 100755 controllers/front/create.php mode change 100644 => 100755 views/css/adminOrderView.css mode change 100644 => 100755 views/templates/admin/ajaxPayPalOrder.tpl mode change 100644 => 100755 views/templates/admin/ajaxPayPalOrderLegacy.tpl diff --git a/classes/PsCheckoutCart.php b/classes/PsCheckoutCart.php old mode 100644 new mode 100755 index 7c4bfd8ce..075bde1d2 --- a/classes/PsCheckoutCart.php +++ b/classes/PsCheckoutCart.php @@ -70,6 +70,11 @@ class PsCheckoutCart extends ObjectModel */ public $paypal_authorization_expire; + /** + * @var string PayPal environment information + */ + public $environment = 'LIVE'; + /** * @var bool */ @@ -147,6 +152,11 @@ class PsCheckoutCart extends ObjectModel 'allow_null' => true, 'required' => false, ], + 'environment' => [ + 'type' => self::TYPE_STRING, + 'allow_null' => true, + 'required' => false, + ], 'isExpressCheckout' => [ 'type' => self::TYPE_BOOL, 'validate' => 'isBool', @@ -246,6 +256,14 @@ public function getPaypalAuthorizationExpireDate() return $this->paypal_authorization_expire; } + /** + * @return string + */ + public function getEnvironment() + { + return $this->environment; + } + /** * @return bool */ diff --git a/controllers/admin/AdminAjaxPrestashopCheckoutController.php b/controllers/admin/AdminAjaxPrestashopCheckoutController.php index b5f61f205..c3621345c 100755 --- a/controllers/admin/AdminAjaxPrestashopCheckoutController.php +++ b/controllers/admin/AdminAjaxPrestashopCheckoutController.php @@ -32,6 +32,7 @@ use PrestaShop\Module\PrestashopCheckout\Order\State\Exception\OrderStateException; use PrestaShop\Module\PrestashopCheckout\Order\State\OrderStateInstaller; use PrestaShop\Module\PrestashopCheckout\Order\State\Service\OrderStateMapper; +use PrestaShop\Module\PrestashopCheckout\PayPal\Mode; use PrestaShop\Module\PrestashopCheckout\PayPal\PayPalConfiguration; use PrestaShop\Module\PrestashopCheckout\PayPal\PayPalOrderProvider; use PrestaShop\Module\PrestashopCheckout\PayPal\PayPalPayLaterConfiguration; @@ -398,6 +399,7 @@ public function ajaxProcessFetchOrder() 'orderPaymentDisplayName' => $fundingSourceTranslationProvider->getPaymentMethodName($psCheckoutCart->paypal_funding), 'orderPaymentLogoUri' => $this->module->getPathUri() . 'views/img/' . $psCheckoutCart->paypal_funding . '.svg', 'psCheckoutCart' => $psCheckoutCart, + 'isProductionEnv' => $psCheckoutCart->getEnvironment() === Mode::LIVE, ]); $this->ajaxDie(json_encode([ diff --git a/controllers/front/create.php b/controllers/front/create.php old mode 100644 new mode 100755 index 15b6639d6..217416853 --- a/controllers/front/create.php +++ b/controllers/front/create.php @@ -22,6 +22,7 @@ use PrestaShop\Module\PrestashopCheckout\Controller\AbstractFrontController; use PrestaShop\Module\PrestashopCheckout\Exception\PsCheckoutException; use PrestaShop\Module\PrestashopCheckout\Handler\CreatePaypalOrderHandler; +use PrestaShop\Module\PrestashopCheckout\PayPal\PayPalConfiguration; use PrestaShop\Module\PrestashopCheckout\Repository\PsCheckoutCartRepository; /** @@ -145,6 +146,8 @@ public function postProcess() $orderId = isset($bodyValues['orderID']) ? $bodyValues['orderID'] : null; $isExpressCheckout = isset($bodyValues['isExpressCheckout']) && $bodyValues['isExpressCheckout']; $isHostedFields = isset($bodyValues['isHostedFields']) && $bodyValues['isHostedFields']; + /** @var PayPalConfiguration $configuration */ + $configuration = $this->module->getService('ps_checkout.paypal.configuration'); $this->module->getLogger()->info( 'PayPal Order created', @@ -154,6 +157,8 @@ public function postProcess() 'isExpressCheckout' => $isExpressCheckout, 'isHostedFields' => $isHostedFields, 'id_cart' => (int) $this->context->cart->id, + 'environment' => $configuration->getPaymentMode(), + 'intent' => $configuration->getIntent(), ] ); @@ -165,9 +170,10 @@ public function postProcess() $psCheckoutCart->paypal_funding = $fundingSource; $psCheckoutCart->paypal_order = $response['body']['id']; $psCheckoutCart->paypal_status = $response['body']['status']; - $psCheckoutCart->paypal_intent = 'AUTHORIZE' === Configuration::get('PS_CHECKOUT_INTENT') ? 'AUTHORIZE' : 'CAPTURE'; + $psCheckoutCart->paypal_intent = $configuration->getIntent(); $psCheckoutCart->paypal_token = $response['body']['client_token']; $psCheckoutCart->paypal_token_expire = (new DateTime())->modify('+3550 seconds')->format('Y-m-d H:i:s'); + $psCheckoutCart->environment = $configuration->getPaymentMode(); $psCheckoutCart->isExpressCheckout = isset($bodyValues['isExpressCheckout']) && $bodyValues['isExpressCheckout']; $psCheckoutCart->isHostedFields = isset($bodyValues['isHostedFields']) && $bodyValues['isHostedFields']; $psCheckoutCartRepository->save($psCheckoutCart); diff --git a/src/Database/TableManager.php b/src/Database/TableManager.php index 006c3de10..0a4c9c06c 100644 --- a/src/Database/TableManager.php +++ b/src/Database/TableManager.php @@ -64,6 +64,7 @@ public function createTable() `paypal_token` text DEFAULT NULL, `paypal_token_expire` datetime NULL, `paypal_authorization_expire` datetime NULL, + `environment` varchar(20) NULL, `isExpressCheckout` tinyint(1) unsigned DEFAULT 0 NOT NULL, `isHostedFields` tinyint(1) unsigned DEFAULT 0 NOT NULL, `date_add` datetime NOT NULL, diff --git a/src/PayPal/PayPalConfiguration.php b/src/PayPal/PayPalConfiguration.php index 974b157aa..0b296c306 100644 --- a/src/PayPal/PayPalConfiguration.php +++ b/src/PayPal/PayPalConfiguration.php @@ -70,7 +70,7 @@ public function __construct(PrestaShopConfiguration $configuration, PayPalCodeRe */ public function getIntent() { - return Intent::CAPTURE === $this->configuration->get(self::INTENT) ? Intent::CAPTURE : Intent::AUTHORIZE; + return Intent::AUTHORIZE === $this->configuration->get(self::INTENT) ? Intent::AUTHORIZE : Intent::CAPTURE; } /** diff --git a/views/css/adminOrderView.css b/views/css/adminOrderView.css old mode 100644 new mode 100755 index 4d9bdbdf7..ce7e6e1d0 --- a/views/css/adminOrderView.css +++ b/views/css/adminOrderView.css @@ -8,6 +8,20 @@ color: #fff; } +#ps_checkout .badge.badge-paypal-environment-sandbox { + background-color: #5E5E5E; + color: #FFF; + font-size: 12px; + border-radius: 10px!important; +} + +#ps_checkout .badge.badge-paypal-environment-live { + background-color: #174EEF; + color: #FFF; + font-size: 12px; + border-radius: 10px!important; +} + #ps_checkout .panel-wrapper { flex-grow: 1; padding: 18px 14px; diff --git a/views/templates/admin/ajaxPayPalOrder.tpl b/views/templates/admin/ajaxPayPalOrder.tpl old mode 100644 new mode 100755 index 397ffd403..6c4e74737 --- a/views/templates/admin/ajaxPayPalOrder.tpl +++ b/views/templates/admin/ajaxPayPalOrder.tpl @@ -66,6 +66,16 @@
{$orderPayPal.balance}
{l s='Payment mode' mod='ps_checkout'}
{$orderPaymentDisplayName|escape:'html':'UTF-8'} {$orderPaymentDisplayName|escape:'html':'UTF-8'}
+
+ + {if $isProductionEnv} + {l s='Production Environment' mod='ps_checkout'} + {else} + {l s='Test Environment' mod='ps_checkout'} + {/if} + +
+
diff --git a/views/templates/admin/ajaxPayPalOrderLegacy.tpl b/views/templates/admin/ajaxPayPalOrderLegacy.tpl old mode 100644 new mode 100755 index e0388a11a..8752e8829 --- a/views/templates/admin/ajaxPayPalOrderLegacy.tpl +++ b/views/templates/admin/ajaxPayPalOrderLegacy.tpl @@ -66,6 +66,16 @@
{$orderPayPal.balance}
{l s='Payment mode' mod='ps_checkout'}
{$orderPaymentDisplayName|escape:'html':'UTF-8'} {$orderPaymentDisplayName|escape:'html':'UTF-8'}
+
+ + {if $isProductionEnv} + {l s='Production Environment' mod='ps_checkout'} + {else} + {l s='Test Environment' mod='ps_checkout'} + {/if} + +
+
From a0fe24e45126eb492084d5c57599a18c5d963bda Mon Sep 17 00:00:00 2001 From: sgodard Date: Wed, 20 Sep 2023 17:43:48 +0200 Subject: [PATCH 05/20] Return url on validate --- controllers/front/validate.php | 62 ++++++++++++++------- src/Builder/Payload/OrderPayloadBuilder.php | 17 ++---- src/Routing/Router.php | 8 +++ 3 files changed, 57 insertions(+), 30 deletions(-) diff --git a/controllers/front/validate.php b/controllers/front/validate.php index dc6cf76a9..be9c2ab95 100644 --- a/controllers/front/validate.php +++ b/controllers/front/validate.php @@ -50,22 +50,29 @@ class Ps_CheckoutValidateModuleFrontController extends AbstractFrontController public function postProcess() { try { - $bodyContent = file_get_contents('php://input'); - - if (empty($bodyContent)) { - $this->exitWithResponse([ - 'httpCode' => 400, - 'body' => 'Payload invalid', - ]); - } - - $bodyValues = json_decode($bodyContent, true); - - if (empty($bodyValues)) { - $this->exitWithResponse([ - 'httpCode' => 400, - 'body' => 'Payload invalid', - ]); + if ($_SERVER['REQUEST_METHOD'] === 'POST') { + $bodyContent = file_get_contents('php://input'); + + if (empty($bodyContent)) { + $this->exitWithResponse([ + 'httpCode' => 400, + 'body' => 'Payload invalid', + ]); + } + + $bodyValues = json_decode($bodyContent, true); + + if (empty($bodyValues)) { + $this->exitWithResponse([ + 'httpCode' => 400, + 'body' => 'Payload invalid', + ]); + } + } else { + $bodyValues = [ + 'orderID' => Tools::getValue('token'), + 'payerID' => Tools::getValue('PayerID'), + ]; } if (empty($bodyValues['orderID']) || false === Validate::isGenericName($bodyValues['orderID'])) { @@ -94,9 +101,9 @@ public function postProcess() $eventDispatcher->dispatch(new CheckoutCompletedEvent( $psCheckoutCart->getIdCart(), $this->paypalOrderId, - (isset($bodyValues['fundingSource']) && Validate::isGenericName($bodyValues['fundingSource'])) ? $bodyValues['fundingSource'] : null, - isset($bodyValues['isExpressCheckout']) && $bodyValues['isExpressCheckout'], - isset($bodyValues['isHostedFields']) && $bodyValues['isHostedFields'] + (isset($bodyValues['fundingSource']) && Validate::isGenericName($bodyValues['fundingSource'])) ? $bodyValues['fundingSource'] : $psCheckoutCart->getPaypalFundingSource(), + isset($bodyValues['isExpressCheckout']) && $bodyValues['isExpressCheckout'] || $psCheckoutCart->isExpressCheckout(), + isset($bodyValues['isHostedFields']) && $bodyValues['isHostedFields'] || $psCheckoutCart->isHostedFields() )); $this->sendOkResponse($this->generateResponse()); @@ -200,6 +207,23 @@ private function sendOkResponse($response) $cart = new Cart($psCheckoutCart->getIdCart()); + if ($_SERVER['REQUEST_METHOD'] === 'GET') { + Tools::redirect($this->context->link->getPageLink( + 'order-confirmation', + true, + (int) $order->id_lang, + [ + 'paypal_status' => $response['status'], + 'paypal_order' => $response['paypalOrderId'], + 'paypal_transaction' => $response['transactionIdentifier'], + 'id_cart' => $psCheckoutCart->getIdCart(), + 'id_module' => (int) $this->module->id, + 'id_order' => (int) $order->id, + 'key' => $cart->secure_key, + ] + )); + } + $this->exitWithResponse([ 'status' => true, 'httpCode' => 200, diff --git a/src/Builder/Payload/OrderPayloadBuilder.php b/src/Builder/Payload/OrderPayloadBuilder.php index c53b45e9e..65b2903f0 100644 --- a/src/Builder/Payload/OrderPayloadBuilder.php +++ b/src/Builder/Payload/OrderPayloadBuilder.php @@ -20,12 +20,14 @@ namespace PrestaShop\Module\PrestashopCheckout\Builder\Payload; +use Context; use libphonenumber\PhoneNumberType; use libphonenumber\PhoneNumberUtil; use PrestaShop\Module\PrestashopCheckout\Configuration\PrestaShopConfiguration; use PrestaShop\Module\PrestashopCheckout\Exception\PsCheckoutException; use PrestaShop\Module\PrestashopCheckout\PayPal\PayPalConfiguration; use PrestaShop\Module\PrestashopCheckout\PaypalCountryCodeMatrice; +use PrestaShop\Module\PrestashopCheckout\Routing\Router; /** * Build the payload for creating paypal order @@ -161,7 +163,7 @@ public function buildBaseNode() ]; $psCheckoutCartCollection = new \PrestaShopCollection('PsCheckoutCart'); - $psCheckoutCartCollection->where('id_cart', '=', (int) \Context::getContext()->cart->id); + $psCheckoutCartCollection->where('id_cart', '=', (int) Context::getContext()->cart->id); /** @var \PsCheckoutCart|false $psCheckoutCart */ $psCheckoutCart = $psCheckoutCartCollection->getFirst(); @@ -292,6 +294,8 @@ public function buildApplicationContextNode() $context = \Context::getContext(); /** @var \Ps_checkout $module */ $module = \Module::getInstanceByName('ps_checkout'); + /** @var Router $router */ + $router = $module->getService('ps_checkout.prestashop.router'); $node['application_context'] = [ 'brand_name' => \Configuration::get( 'PS_SHOP_NAME', @@ -300,16 +304,7 @@ public function buildApplicationContextNode() (int) $context->shop->id ), 'shipping_preference' => $this->expressCheckout ? 'GET_FROM_FILE' : 'SET_PROVIDED_ADDRESS', - 'return_url' => \Context::getContext()->link->getPageLink( - 'order-confirmation', - true, - (int) $context->cart->id_lang, - [ - 'id_cart' => (int) $context->cart->id, - 'key' => $context->cart->secure_key, - 'id_module' => (int) $module->id, - ] - ), + 'return_url' => $router->getCheckoutValidateLink(), ]; $this->getPayload()->addAndMergeItems($node); diff --git a/src/Routing/Router.php b/src/Routing/Router.php index c91652130..83dce9573 100644 --- a/src/Routing/Router.php +++ b/src/Routing/Router.php @@ -34,6 +34,14 @@ public function __construct() $this->context = Context::getContext(); } + /** + * @return string + */ + public function getCheckoutValidateLink() + { + return $this->context->link->getModuleLink('ps_checkout', 'validate', [], true, $this->context->language->id, $this->context->shop->id); + } + /** * @return string */ From 14cff8de2cfe5ad940ddc1d6bd675ea89cad98d0 Mon Sep 17 00:00:00 2001 From: sgodard Date: Wed, 20 Sep 2023 16:12:14 +0200 Subject: [PATCH 06/20] Change Webhook url generation --- src/Api/Payment/Client/PaymentClient.php | 14 ++++-------- src/Routing/Router.php | 29 ++++++++++++++++++++++++ 2 files changed, 34 insertions(+), 9 deletions(-) diff --git a/src/Api/Payment/Client/PaymentClient.php b/src/Api/Payment/Client/PaymentClient.php index ccb7781d2..820448360 100755 --- a/src/Api/Payment/Client/PaymentClient.php +++ b/src/Api/Payment/Client/PaymentClient.php @@ -20,7 +20,6 @@ namespace PrestaShop\Module\PrestashopCheckout\Api\Payment\Client; -use Configuration; use Context; use GuzzleHttp\Event\Emitter; use GuzzleHttp\HandlerStack; @@ -34,6 +33,7 @@ use PrestaShop\Module\PrestashopCheckout\Exception\HttpTimeoutException; use PrestaShop\Module\PrestashopCheckout\Exception\PsCheckoutException; use PrestaShop\Module\PrestashopCheckout\Logger\LoggerConfiguration; +use PrestaShop\Module\PrestashopCheckout\Routing\Router; use PrestaShop\Module\PrestashopCheckout\ShopContext; use PrestaShop\Module\PrestashopCheckout\Version\Version; use Prestashop\ModuleLibGuzzleAdapter\ClientFactory; @@ -69,6 +69,9 @@ public function __construct(Link $link, $client = null) /** @var LoggerInterface $logger */ $logger = $module->getService('ps_checkout.logger'); + /** @var Router $router */ + $router = $module->getService('ps_checkout.prestashop.router'); + $clientConfiguration = [ 'base_url' => (new PaymentEnv())->getPaymentApiUrl(), 'verify' => $this->getVerify(), @@ -79,14 +82,7 @@ public function __construct(Link $link, $client = null) 'Accept' => 'application/json', 'Authorization' => 'Bearer ' . $this->token, // Token we get from PsAccounts 'Shop-Id' => $this->shopUid, // Shop UUID we get from PsAccounts - 'Hook-Url' => $this->link->getModuleLink( - 'ps_checkout', - 'DispatchWebHook', - [], - true, - (int) Configuration::get('PS_LANG_DEFAULT'), - (int) Context::getContext()->shop->id - ), + 'Hook-Url' => $router->getDispatchWebhookLink((int) Context::getContext()->shop->id), 'Bn-Code' => (new ShopContext())->getBnCode(), 'Module-Version' => $version->getSemVersion(), // version of the module 'Prestashop-Version' => _PS_VERSION_, // prestashop version diff --git a/src/Routing/Router.php b/src/Routing/Router.php index c91652130..c6328521c 100644 --- a/src/Routing/Router.php +++ b/src/Routing/Router.php @@ -20,7 +20,9 @@ namespace PrestaShop\Module\PrestashopCheckout\Routing; +use Configuration; use Context; +use Shop; class Router { @@ -35,10 +37,37 @@ public function __construct() } /** + * @param int|null $orderId + * * @return string */ public function getContactLink($orderId = null) { return $this->context->link->getPageLink('contact', true, $this->context->language->id, ['id_order' => (int) $orderId]); } + + /** + * @param int $idShop + * + * @return string + */ + public function getDispatchWebhookLink($idShop) + { + $idLang = Configuration::get('PS_LANG_DEFAULT'); + + return $this->getBaseLink($idShop) . 'index.php?controller=DispatchWebHook&module=ps_checkout&fc=module&id_lang=' . (int) $idLang . '&id_shop=' . (int) $idShop; + } + + /** + * @param int $idShop + * + * @return string + */ + private function getBaseLink($idShop) + { + $shop = new Shop($idShop); + $base = Configuration::get('PS_SSL_ENABLED') ? 'https://' . $shop->domain_ssl : 'http://' . $shop->domain; + + return $base . $shop->physical_uri; + } } From 4a396e43f91f694de1b7bc2d984f0b8f4a0386f2 Mon Sep 17 00:00:00 2001 From: Matt75 <5262628+Matt75@users.noreply.github.com> Date: Mon, 25 Sep 2023 12:41:35 +0200 Subject: [PATCH 07/20] Bump module version to 7.3.5.0 --- config.xml | 2 +- ps_checkout.php | 4 ++-- upgrade/upgrade-7.3.5.0.php | 43 +++++++++++++++++++++++++++++++++++++ 3 files changed, 46 insertions(+), 3 deletions(-) create mode 100644 upgrade/upgrade-7.3.5.0.php diff --git a/config.xml b/config.xml index 1432451e7..ddcfeb781 100644 --- a/config.xml +++ b/config.xml @@ -2,7 +2,7 @@ ps_checkout - + diff --git a/ps_checkout.php b/ps_checkout.php index 744270c84..4b4b62b60 100755 --- a/ps_checkout.php +++ b/ps_checkout.php @@ -123,7 +123,7 @@ class Ps_checkout extends PaymentModule // Needed in order to retrieve the module version easier (in api call headers) than instanciate // the module each time to get the version - const VERSION = '7.3.4.0'; + const VERSION = '7.3.5.0'; const INTEGRATION_DATE = '2022-14-06'; @@ -142,7 +142,7 @@ public function __construct() // We cannot use the const VERSION because the const is not computed by addons marketplace // when the zip is uploaded - $this->version = '7.3.4.0'; + $this->version = '7.3.5.0'; $this->author = 'PrestaShop'; $this->currencies = true; $this->currencies_mode = 'checkbox'; diff --git a/upgrade/upgrade-7.3.5.0.php b/upgrade/upgrade-7.3.5.0.php new file mode 100644 index 000000000..7c71e0d96 --- /dev/null +++ b/upgrade/upgrade-7.3.5.0.php @@ -0,0 +1,43 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ +if (!defined('_PS_VERSION_')) { + exit; +} + +/** + * Update main function for module version 7.3.5.0 + * + * @param Ps_checkout $module + * + * @return bool + */ +function upgrade_module_7_3_5_0($module) +{ + try { + $db = Db::getInstance(); + $db->execute('ALTER TABLE `' . _DB_PREFIX_ . 'pscheckout_cart` ADD COLUMN `environment` varchar(20) DEFAULT NULL;'); + } catch (Exception $exception) { + PrestaShopLogger::addLog($exception->getMessage(), 4, 1, 'Module', $module->id); + + return false; + } + + return true; +} From 904698d5758ae499397823bb410187aa33aa439d Mon Sep 17 00:00:00 2001 From: Matt75 <5262628+Matt75@users.noreply.github.com> Date: Mon, 25 Sep 2023 16:33:05 +0200 Subject: [PATCH 08/20] PHPStan feedback --- src/Routing/Router.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Routing/Router.php b/src/Routing/Router.php index c8488be7f..e5665dd00 100644 --- a/src/Routing/Router.php +++ b/src/Routing/Router.php @@ -37,8 +37,6 @@ public function __construct() } /** - * @param int|null $orderId - * * @return string */ public function getCheckoutValidateLink() @@ -47,6 +45,8 @@ public function getCheckoutValidateLink() } /** + * @param int|null $orderId + * * @return string */ public function getContactLink($orderId = null) From a9028005306700d8c34357c77470c4707c140d0c Mon Sep 17 00:00:00 2001 From: Matt75 <5262628+Matt75@users.noreply.github.com> Date: Mon, 25 Sep 2023 17:18:02 +0200 Subject: [PATCH 09/20] Set default environment value --- classes/PsCheckoutCart.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/classes/PsCheckoutCart.php b/classes/PsCheckoutCart.php index 075bde1d2..8aa101127 100755 --- a/classes/PsCheckoutCart.php +++ b/classes/PsCheckoutCart.php @@ -71,7 +71,7 @@ class PsCheckoutCart extends ObjectModel public $paypal_authorization_expire; /** - * @var string PayPal environment information + * @var string|null PayPal environment information */ public $environment = 'LIVE'; @@ -261,7 +261,7 @@ public function getPaypalAuthorizationExpireDate() */ public function getEnvironment() { - return $this->environment; + return $this->environment === 'SANDBOX' ? $this->environment : 'LIVE'; } /** From 1c0f559d6678b28b06139476c4e7f00dc057aab6 Mon Sep 17 00:00:00 2001 From: Matt75 <5262628+Matt75@users.noreply.github.com> Date: Mon, 25 Sep 2023 17:21:58 +0200 Subject: [PATCH 10/20] Add amount data to logs --- controllers/front/create.php | 1 + 1 file changed, 1 insertion(+) diff --git a/controllers/front/create.php b/controllers/front/create.php index 217416853..066250cfd 100755 --- a/controllers/front/create.php +++ b/controllers/front/create.php @@ -157,6 +157,7 @@ public function postProcess() 'isExpressCheckout' => $isExpressCheckout, 'isHostedFields' => $isHostedFields, 'id_cart' => (int) $this->context->cart->id, + 'amount' => $this->context->cart->getOrderTotal(true, Cart::BOTH), 'environment' => $configuration->getPaymentMode(), 'intent' => $configuration->getIntent(), ] From 0cc13dee8f0ad5d48b5538757157eface944f9c2 Mon Sep 17 00:00:00 2001 From: sgodard Date: Wed, 27 Sep 2023 09:48:30 +0200 Subject: [PATCH 11/20] rollback webhook url generation --- src/Routing/Router.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/Routing/Router.php b/src/Routing/Router.php index e5665dd00..55ced542c 100644 --- a/src/Routing/Router.php +++ b/src/Routing/Router.php @@ -61,9 +61,7 @@ public function getContactLink($orderId = null) */ public function getDispatchWebhookLink($idShop) { - $idLang = Configuration::get('PS_LANG_DEFAULT'); - - return $this->getBaseLink($idShop) . 'index.php?controller=DispatchWebHook&module=ps_checkout&fc=module&id_lang=' . (int) $idLang . '&id_shop=' . (int) $idShop; + return $this->context->link->getModuleLink('ps_checkout', 'DispatchWebHook', [], true, (int) Configuration::get('PS_LANG_DEFAULT'), (int) $idShop); } /** From 7c181d68c1d8d2a2cf52e904dc82a3dba649e176 Mon Sep 17 00:00:00 2001 From: Matt75 <5262628+Matt75@users.noreply.github.com> Date: Thu, 28 Sep 2023 11:04:47 +0200 Subject: [PATCH 12/20] Avoid fetch PayPal Order on another environment --- .../AdminAjaxPrestashopCheckoutController.php | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/controllers/admin/AdminAjaxPrestashopCheckoutController.php b/controllers/admin/AdminAjaxPrestashopCheckoutController.php index c3621345c..8046c0e63 100755 --- a/controllers/admin/AdminAjaxPrestashopCheckoutController.php +++ b/controllers/admin/AdminAjaxPrestashopCheckoutController.php @@ -378,6 +378,24 @@ public function ajaxProcessFetchOrder() } } + /** @var PayPalConfiguration $configurationPayPal */ + $configurationPayPal = $this->module->getService('ps_checkout.paypal.configuration'); + + if ($configurationPayPal->getPaymentMode() !== $psCheckoutCart->getEnvironment()) { + http_response_code(422); + $this->ajaxDie(json_encode([ + 'status' => false, + 'errors' => [ + strtr( + $this->l('PayPal Order [PAYPAL_ORDER_ID] is not in the same environment as PrestaShop Checkout'), + [ + '[PAYPAL_ORDER_ID]' => $psCheckoutCart->paypal_order, + ] + ), + ], + ])); + } + /** @var PayPalOrderProvider $paypalOrderProvider */ $paypalOrderProvider = $this->module->getService('ps_checkout.paypal.provider.order'); From 34360a15393cb0c1926d5b4a4d39f0e604e4846c Mon Sep 17 00:00:00 2001 From: Matt75 <5262628+Matt75@users.noreply.github.com> Date: Mon, 9 Oct 2023 18:08:51 +0200 Subject: [PATCH 13/20] Check Db table at module install --- src/Database/TableManager.php | 37 +++++++++++++++++++++++++++++++++-- 1 file changed, 35 insertions(+), 2 deletions(-) diff --git a/src/Database/TableManager.php b/src/Database/TableManager.php index 0a4c9c06c..501385036 100644 --- a/src/Database/TableManager.php +++ b/src/Database/TableManager.php @@ -46,7 +46,7 @@ public function __construct(\Db $db = null) */ public function createTable() { - return $this->db->execute(' + $result = $this->db->execute(' CREATE TABLE IF NOT EXISTS `' . _DB_PREFIX_ . 'pscheckout_order_matrice` ( `id_order_matrice` int(10) unsigned NOT NULL AUTO_INCREMENT, `id_order_prestashop` int(10) unsigned NOT NULL, @@ -81,6 +81,10 @@ public function createTable() INDEX (`id_shop`) ) ENGINE=' . _MYSQL_ENGINE_ . ' DEFAULT CHARSET=UTF8; '); + + $this->checkTable(); + + return (bool) $result; } /** @@ -90,8 +94,8 @@ public function createTable() */ public function dropTable() { + // Avoid to loose PayPal data if module is reset or uninstall return true; - //return $this->db->execute('DROP TABLE IF EXISTS `' . _DB_PREFIX_ . 'pscheckout_cart`'); } /** @@ -109,4 +113,33 @@ public function populatePsCartFromOrderMatrice() INNER JOIN `' . _DB_PREFIX_ . 'orders` AS o ON (om.id_order_prestashop = o.id_order) '); } + + /** + * Check if existing database is up to date + * Due to `CREATE TABLE IF NOT EXISTS` we need to check if table is up to date + * + * @return void + */ + public function checkTable() + { + $databaseFields = []; + $fields = $this->db->executeS('SHOW COLUMNS FROM `' . _DB_PREFIX_ . 'pscheckout_cart`'); + + if (!empty($fields)) { + foreach ($fields as $field) { + $databaseFields[] = $field['Field']; + if ($field['Field'] === 'paypal_token' && $field['Type'] !== 'text') { + $this->db->execute('ALTER TABLE `' . _DB_PREFIX_ . 'pscheckout_cart` CHANGE `paypal_token` `paypal_token` text DEFAULT NULL;'); + } + } + } + + $objectDefinition = \PsCheckoutCart::$definition; + $objectFields = array_keys($objectDefinition['fields']); + $missingFields = array_diff($objectFields, $databaseFields); + + if (in_array('environment', $missingFields, true)) { + $this->db->execute('ALTER TABLE `' . _DB_PREFIX_ . 'pscheckout_cart` ADD COLUMN `environment` varchar(20) DEFAULT NULL;'); + } + } } From 5100ade4d824b69f541d4c57b6321bcada82e0bb Mon Sep 17 00:00:00 2001 From: Matt75 <5262628+Matt75@users.noreply.github.com> Date: Fri, 13 Oct 2023 14:37:08 +0200 Subject: [PATCH 14/20] Fix autoload with Opcache allows importing conflicting class name to namespace --- src/Event/Event.php | 12 +++++------ src/Event/SymfonyEventDispatcherFactory.php | 22 ++++++++++----------- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/src/Event/Event.php b/src/Event/Event.php index b1a087c2c..878dae3d7 100644 --- a/src/Event/Event.php +++ b/src/Event/Event.php @@ -20,17 +20,17 @@ namespace PrestaShop\Module\PrestashopCheckout\Event; -use Symfony\Component\EventDispatcher\Event as ComponentEvent; -use Symfony\Contracts\EventDispatcher\Event as ContractEvent; +use Symfony\Component\EventDispatcher\Event as SymfonyComponentEvent; +use Symfony\Contracts\EventDispatcher\Event as SymfonyContractEvent; -if (class_exists(ComponentEvent::class)) { +if (class_exists(SymfonyComponentEvent::class)) { // @phpstan-ignore-next-line - class Event extends ComponentEvent + class Event extends SymfonyComponentEvent { } -} elseif (class_exists(ContractEvent::class)) { +} elseif (class_exists(SymfonyContractEvent::class)) { // @phpstan-ignore-next-line - class Event extends ContractEvent /* @phpstan-ignore-line */ + class Event extends SymfonyContractEvent /* @phpstan-ignore-line */ { } } diff --git a/src/Event/SymfonyEventDispatcherFactory.php b/src/Event/SymfonyEventDispatcherFactory.php index a3df62e25..f6908f820 100644 --- a/src/Event/SymfonyEventDispatcherFactory.php +++ b/src/Event/SymfonyEventDispatcherFactory.php @@ -22,11 +22,11 @@ use PrestaShop\Module\PrestashopCheckout\Logger\LoggerConfiguration; use Psr\Log\LoggerInterface; -use Symfony\Component\EventDispatcher\Debug\TraceableEventDispatcher; -use Symfony\Component\EventDispatcher\EventDispatcher; -use Symfony\Component\EventDispatcher\EventDispatcherInterface; -use Symfony\Component\EventDispatcher\EventSubscriberInterface; -use Symfony\Component\Stopwatch\Stopwatch; +use Symfony\Component\EventDispatcher\Debug\TraceableEventDispatcher as SymfonyTraceableEventDispatcher; +use Symfony\Component\EventDispatcher\EventDispatcher as SymfonyEventDispatcher; +use Symfony\Component\EventDispatcher\EventDispatcherInterface as SymfonyEventDispatcherInterface; +use Symfony\Component\EventDispatcher\EventSubscriberInterface as SymfonyEventSubscriberInterface; +use Symfony\Component\Stopwatch\Stopwatch as SymfonyStopwatch; class SymfonyEventDispatcherFactory { @@ -51,19 +51,19 @@ public function __construct(LoggerInterface $logger, LoggerConfiguration $config } /** - * @param EventSubscriberInterface[] $eventSubscribers + * @param SymfonyEventSubscriberInterface[] $eventSubscribers * - * @return EventDispatcherInterface + * @return SymfonyEventDispatcherInterface */ public function create(array $eventSubscribers) { $eventDispatcher = LoggerConfiguration::LEVEL_DEBUG === $this->configuration->getLevel() - ? new TraceableEventDispatcher( - new EventDispatcher(), - new Stopwatch(), + ? new SymfonyTraceableEventDispatcher( + new SymfonyEventDispatcher(), + new SymfonyStopwatch(), $this->logger ) - : new EventDispatcher(); + : new SymfonyEventDispatcher(); foreach ($eventSubscribers as $eventSubscriber) { $eventDispatcher->addSubscriber($eventSubscriber); From 36d68667aff5aae5ece8454d3652ec42eec8c381 Mon Sep 17 00:00:00 2001 From: Matt75 <5262628+Matt75@users.noreply.github.com> Date: Fri, 13 Oct 2023 16:54:14 +0200 Subject: [PATCH 15/20] Fix performance issue --- ps_checkout.php | 77 +++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 74 insertions(+), 3 deletions(-) diff --git a/ps_checkout.php b/ps_checkout.php index ab92772b6..497d316af 100755 --- a/ps_checkout.php +++ b/ps_checkout.php @@ -134,6 +134,8 @@ class Ps_checkout extends PaymentModule * @var \PrestaShop\ModuleLibServiceContainer\DependencyInjection\ServiceContainer */ private $serviceContainer; + private static $merchantIsValid; + private static $currencyIsAllowed; public function __construct() { @@ -393,6 +395,10 @@ public function uninstallTabs() */ public function hookDisplayPersonalInformationTop() { + if (!$this->merchantIsValid()) { + return ''; + } + return $this->display(__FILE__, 'views/templates/hook/displayPersonalInformationTop.tpl'); } @@ -503,6 +509,10 @@ public function hookDisplayProductAdditionalInfo() */ public function hookDisplayFooterProduct() { + if (!$this->merchantIsValid()) { + return ''; + } + return $this->display(__FILE__, 'views/templates/hook/displayFooterProduct.tpl'); } @@ -552,6 +562,10 @@ public function hookActionObjectProductInCartDeleteAfter() */ public function hookActionAfterDeleteProductInCart() { + if (!$this->merchantIsValid()) { + return; + } + /** @var \PrestaShop\Module\PrestashopCheckout\ShopContext $shopContext */ $shopContext = $this->getService('ps_checkout.context.shop'); @@ -567,6 +581,10 @@ public function hookActionAfterDeleteProductInCart() */ public function hookActionCartUpdateQuantityBefore() { + if (!$this->merchantIsValid()) { + return; + } + if (false === Validate::isLoadedObject($this->context->cart)) { return; } @@ -592,6 +610,10 @@ public function hookActionCartUpdateQuantityBefore() */ public function hookActionBeforeCartUpdateQty() { + if (!$this->merchantIsValid()) { + return; + } + /** @var \PrestaShop\Module\PrestashopCheckout\ShopContext $shopContext */ $shopContext = $this->getService('ps_checkout.context.shop'); @@ -713,6 +735,10 @@ public function hookPaymentOptions(array $params) */ public function hookDisplayOrderConfirmation(array $params) { + if (!$this->merchantIsValid()) { + return ''; + } + /** @var Order $order */ $order = (isset($params['objOrder'])) ? $params['objOrder'] : $params['order']; @@ -740,20 +766,46 @@ public function hookDisplayOrderConfirmation(array $params) */ public function checkCurrency($cart) { + if (isset(static::$currencyIsAllowed[$cart->id_currency])) { + return static::$currencyIsAllowed[$cart->id_currency]; + } + + /** @var \PrestaShop\Module\PrestashopCheckout\Repository\PayPalCodeRepository $codeRepository */ + $codeRepository = $this->getService('ps_checkout.repository.paypal.code'); $currency_order = Currency::getCurrencyInstance($cart->id_currency); + $isCurrencySupported = false; + + foreach (array_keys($codeRepository->getCurrencyCodes()) as $supportedCurrencyCode) { + if (strcasecmp($supportedCurrencyCode, $currency_order->iso_code) === 0) { + $isCurrencySupported = true; + } + } + + if (!$isCurrencySupported) { + static::$currencyIsAllowed[$cart->id_currency] = false; + + return false; + } + /** @var array $currencies_module */ $currencies_module = $this->getCurrency($cart->id_currency); if (empty($currencies_module)) { + static::$currencyIsAllowed[$cart->id_currency] = false; + return false; } foreach ($currencies_module as $currency_module) { if ($currency_order->id == $currency_module['id_currency']) { + static::$currencyIsAllowed[$cart->id_currency] = true; + return true; } } + static::$currencyIsAllowed[$cart->id_currency] = false; + return false; } @@ -876,10 +928,13 @@ public function hookActionAdminControllerSetMedia() */ public function merchantIsValid() { - /** @var \PrestaShop\Module\PrestashopCheckout\Validator\MerchantValidator $merchantValidator */ - $merchantValidator = $this->getService('ps_checkout.validator.merchant'); + if (static::$merchantIsValid === null) { + /** @var \PrestaShop\Module\PrestashopCheckout\Validator\MerchantValidator $merchantValidator */ + $merchantValidator = $this->getService('ps_checkout.validator.merchant'); + static::$merchantIsValid = $merchantValidator->merchantIsValid(); + } - return $merchantValidator->merchantIsValid(); + return static::$merchantIsValid; } /** @@ -1205,6 +1260,10 @@ public function getLogger() */ public function hookDisplayInvoiceLegalFreeText(array $params) { + if (!$this->merchantIsValid()) { + return ''; + } + /** @var \Order $order */ $order = $params['order']; @@ -1515,6 +1574,10 @@ private function getCheckoutPageUrl() public function hookDisplayHeader() { + if (!$this->merchantIsValid()) { + return ''; + } + $controller = Tools::getValue('controller'); if (empty($controller) && isset($this->context->controller->php_self)) { @@ -1687,6 +1750,10 @@ public function hookActionObjectShopDeleteAfter(array $params) */ public function hookDisplayPaymentReturn(array $params) { + if (!$this->merchantIsValid()) { + return ''; + } + /** @var Order $order */ $order = (isset($params['objOrder'])) ? $params['objOrder'] : $params['order']; @@ -1713,6 +1780,10 @@ public function hookDisplayPaymentReturn(array $params) */ public function hookDisplayOrderDetail(array $params) { + if (!$this->merchantIsValid()) { + return ''; + } + /** @var Order $order */ $order = $params['order']; From 7299a47fc88439694d63bfbbe87689e55427de2c Mon Sep 17 00:00:00 2001 From: Matt75 <5262628+Matt75@users.noreply.github.com> Date: Fri, 13 Oct 2023 16:53:43 +0200 Subject: [PATCH 16/20] Fix onboarding check --- src/Repository/PsAccountRepository.php | 47 +++++++++++--------------- 1 file changed, 19 insertions(+), 28 deletions(-) diff --git a/src/Repository/PsAccountRepository.php b/src/Repository/PsAccountRepository.php index cee589403..1e45463d3 100644 --- a/src/Repository/PsAccountRepository.php +++ b/src/Repository/PsAccountRepository.php @@ -37,6 +37,7 @@ class PsAccountRepository /** * @param PrestaShopConfiguration $configuration + * @param PsAccounts $psAccountsFacade */ public function __construct(PrestaShopConfiguration $configuration, PsAccounts $psAccountsFacade) { @@ -58,42 +59,28 @@ public function getOnboardedAccount() return new PsAccount( $this->getIdToken(), $this->getRefreshToken(), - $this->getEmail(), - $this->getLocalId() -// $this->getPsxForm() + $this->getEmail() ); } /** - * Retrieve the status of the psx form : return true if the form is completed, otherwise return false. - * If on ready, the merchant doesn't need to complete the form, so return true to act like if the - * user complete the form + * @deprecated 3.0.0 Moved to PS Accounts * * @return bool */ public function psxFormIsCompleted() { - // TODO: Remove all code related to PSX form. Since it's not used any more we return true to be sure to not make any breaking changes return true; -// -// if (getenv('PLATEFORM') === 'PSREADY') { // if on ready, the user is already onboarded -// return true; -// } -// -// return !empty($this->getPsxForm()); } /** - * Get the status of the firebase onboarding - * Only check idToken: is the only one truly mandatory + * Check if user and shop are linked with PS Accounts * * @return bool */ public function onBoardingIsCompleted() { - return !empty($this->getIdToken()); - // Commented out because psx form is no longer used - // && $this->psxFormIsCompleted(); + return $this->isAccountLinked(); } /** @@ -121,11 +108,15 @@ public function getIdToken() return false; } - return (string) $this->psAccountsService->getOrRefreshToken(); + try { + return (string) $this->psAccountsService->getOrRefreshToken(); + } catch (Exception $e) { + return false; + } } /** - * Get firebase localId from database + * @deprecated PS Accounts v5.1.1 * * @return string|bool */ @@ -157,13 +148,11 @@ public function getRefreshToken() * * @param bool $toArray * - * @return string|bool|array + * @return string|array */ public function getPsxForm($toArray = false) { - $form = $this->configuration->get(PsAccount::PS_CHECKOUT_PSX_FORM); - - return $toArray ? json_decode($form, true) : $form; + return $toArray ? '' : []; } /** @@ -196,15 +185,17 @@ public function isEmailValidated() /** * @return bool - * - * @throws Exception */ public function isAccountLinked() { - if (!$this->psAccountsService) { + if (!$this->psAccountsService || !method_exists($this->psAccountsService, 'isAccountLinked')) { return false; } - return $this->psAccountsService->isAccountLinked(); + try { + return $this->psAccountsService->isAccountLinked(); + } catch (Exception $e) { + return false; + } } } From f309556fcc4d8e18cbe5af442b2a486d3e93d86b Mon Sep 17 00:00:00 2001 From: Laurynas Date: Wed, 18 Oct 2023 10:39:31 +0300 Subject: [PATCH 17/20] Removed redirect to authentication page --- .../admin/AdminPaypalOnboardingPrestashopCheckoutController.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/controllers/admin/AdminPaypalOnboardingPrestashopCheckoutController.php b/controllers/admin/AdminPaypalOnboardingPrestashopCheckoutController.php index 53904dff8..464791fa4 100755 --- a/controllers/admin/AdminPaypalOnboardingPrestashopCheckoutController.php +++ b/controllers/admin/AdminPaypalOnboardingPrestashopCheckoutController.php @@ -54,7 +54,7 @@ public function postProcess() [ 'configure' => 'ps_checkout', ] - ) . '#/authentication' + ) ); } catch (Exception $e) { $this->errors[] = $e->getMessage(); From 757c10ebe11c30a7eedf27527869ea6f54772cdb Mon Sep 17 00:00:00 2001 From: Matt75 <5262628+Matt75@users.noreply.github.com> Date: Fri, 20 Oct 2023 15:13:02 +0200 Subject: [PATCH 18/20] Fix useless hosted-fields component if card disabled --- src/Builder/PayPalSdkLink/PayPalSdkLinkBuilder.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Builder/PayPalSdkLink/PayPalSdkLinkBuilder.php b/src/Builder/PayPalSdkLink/PayPalSdkLinkBuilder.php index fbfe4f038..80319694e 100644 --- a/src/Builder/PayPalSdkLink/PayPalSdkLinkBuilder.php +++ b/src/Builder/PayPalSdkLink/PayPalSdkLinkBuilder.php @@ -216,7 +216,7 @@ private function shouldIncludeButtonsComponent() */ private function shouldIncludeHostedFieldsComponent() { - if ('order' !== $this->getPageName()) { + if ('order' !== $this->getPageName() || in_array('card', $this->getFundingSourcesDisabled(), true)) { return false; } From bbd3bad5d65a844681a14212003c728d732e0bc5 Mon Sep 17 00:00:00 2001 From: Matt75 <5262628+Matt75@users.noreply.github.com> Date: Fri, 20 Oct 2023 16:38:12 +0200 Subject: [PATCH 19/20] Fix duplicate column name environment on upgrade --- upgrade/upgrade-7.3.5.0.php | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/upgrade/upgrade-7.3.5.0.php b/upgrade/upgrade-7.3.5.0.php index 7c71e0d96..6c62f8fd5 100644 --- a/upgrade/upgrade-7.3.5.0.php +++ b/upgrade/upgrade-7.3.5.0.php @@ -32,7 +32,20 @@ function upgrade_module_7_3_5_0($module) { try { $db = Db::getInstance(); - $db->execute('ALTER TABLE `' . _DB_PREFIX_ . 'pscheckout_cart` ADD COLUMN `environment` varchar(20) DEFAULT NULL;'); + $databaseFields = []; + $fields = $db->executeS('SHOW COLUMNS FROM `' . _DB_PREFIX_ . 'pscheckout_cart`'); + + if (!empty($fields)) { + foreach ($fields as $field) { + if (isset($field['Field'])) { + $databaseFields[] = $field['Field']; + } + } + } + + if (!empty($databaseFields) && !in_array('environment', $databaseFields, true)) { + $db->execute('ALTER TABLE `' . _DB_PREFIX_ . 'pscheckout_cart` ADD COLUMN `environment` varchar(20) DEFAULT NULL;'); + } } catch (Exception $exception) { PrestaShopLogger::addLog($exception->getMessage(), 4, 1, 'Module', $module->id); From ac6923f2d063d09c646780522abd1bfc760cf78d Mon Sep 17 00:00:00 2001 From: Matt75 <5262628+Matt75@users.noreply.github.com> Date: Tue, 24 Oct 2023 14:04:13 +0200 Subject: [PATCH 20/20] Remove duplicate PayPal logo displayed --- ps_checkout.php | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/ps_checkout.php b/ps_checkout.php index 497d316af..a3629ecb7 100755 --- a/ps_checkout.php +++ b/ps_checkout.php @@ -421,6 +421,10 @@ public function hookDisplayExpressCheckout() $paymentOptions = []; foreach ($fundingSourceProvider->getAll() as $fundingSource) { + if ($fundingSource->name === 'paylater') { + continue; + } + if ($count === 8) { break; } @@ -471,6 +475,10 @@ public function hookDisplayProductAdditionalInfo() $paymentOptions = []; foreach ($fundingSourceProvider->getAll() as $fundingSource) { + if ($fundingSource->name === 'paylater') { + continue; + } + if ($count === 8) { break; }