diff --git a/core/src/FundingSource/Constraint/FundingSourceConstraint.php b/core/src/FundingSource/Constraint/FundingSourceConstraint.php index aee2afbcd..2d859c0f3 100644 --- a/core/src/FundingSource/Constraint/FundingSourceConstraint.php +++ b/core/src/FundingSource/Constraint/FundingSourceConstraint.php @@ -38,7 +38,7 @@ public static function getCountries(string $fundingSourceName): array 'ideal' => ['NL'], 'mybank' => ['IT'], 'p24' => ['PL'], - 'paylater' => ['FR', 'GB', 'US', 'ES', 'IT'], + 'paylater' => ['AU', 'DE', 'ES', 'FR', 'GB', 'IT', 'US'], 'google_pay' => ['AU', 'AT', 'BE', 'BG', 'CA', 'CN', 'CY', 'CZ', 'DK', 'EE', 'FI', 'FR', 'DE', 'GR', 'HK', 'HU', 'IE', 'IT', 'JP', 'LV', 'LI', 'LT', 'LU', 'MT', 'NL', 'NO', 'PL', 'PT', 'RO', 'SG', 'SK', 'SI', 'ES', 'SE', 'GB', 'US'], 'apple_pay' => ['AU', 'AT', 'BE', 'BG', 'CA', 'CN', 'CY', 'CZ', 'DK', 'EE', 'FI', 'FR', 'DE', 'GR', 'HK', 'HU', 'IE', 'IT', 'JP', 'LV', 'LI', 'LT', 'LU', 'MT', 'NL', 'NO', 'PL', 'PT', 'RO', 'SG', 'SK', 'SI', 'ES', 'SE', 'GB', 'US'], ]; @@ -58,6 +58,7 @@ public static function getCurrencies(string $fundingSourceName): array $currencies = [ 'google_pay' => ['AUD', 'BRL', 'CAD', 'CHF', 'CZK', 'DKK', 'EUR', 'GBP', 'HKD', 'HUF', 'ILS', 'JPY', 'MXN', 'NOK', 'NZD', 'PHP', 'PLN', 'SEK', 'SGD', 'THB', 'TWD', 'USD'], 'apple_pay' => ['AUD', 'BRL', 'CAD', 'CHF', 'CZK', 'DKK', 'EUR', 'GBP', 'HKD', 'HUF', 'ILS', 'JPY', 'MXN', 'NOK', 'NZD', 'PHP', 'PLN', 'SEK', 'SGD', 'THB', 'TWD', 'USD'], + 'paylater' => ['EUR', 'USD', 'AUD', 'GBP'], ]; return isset($currencies[$fundingSourceName]) ? $currencies[$fundingSourceName] : []; diff --git a/core/src/Settings/Configuration/DefaultConfiguration.php b/core/src/Settings/Configuration/DefaultConfiguration.php index 62fdeadda..4a9543950 100644 --- a/core/src/Settings/Configuration/DefaultConfiguration.php +++ b/core/src/Settings/Configuration/DefaultConfiguration.php @@ -47,5 +47,6 @@ class DefaultConfiguration 'PS_CHECKOUT_DISPLAY_LOGO_CART' => '1', 'PS_CHECKOUT_HOSTED_FIELDS_CONTINGENCIES' => 'SCA_WHEN_REQUIRED', 'PS_CHECKOUT_PAYPAL_BUTTON' => '{"shape":"pill","label":"pay","color":"gold"}', + 'PS_CHECKOUT_PAY_LATER_CONFIG' => '{"cart":{"placement":"cart","status":"enabled","layout":"text","logo-type":"inline","text-color":"black","text-size":"12"},"category":{"placement":"category","status":"disabled","color":"white","layout":"flex","ratio":"8x1"},"checkout":{"placement":"checkout","status":"enabled","layout":"text","logo-type":"inline","text-color":"black","text-size":"12"},"homepage":{"placement":"homepage","status":"disabled","color":"white","layout":"flex","ratio":"8x1"},"product":{"placement":"product","status":"enabled","layout":"text","logo-type":"inline","text-color":"black","text-size":"12"}}', ]; } diff --git a/core/src/Settings/Configuration/PayPalConfiguration.php b/core/src/Settings/Configuration/PayPalConfiguration.php index 9cdcc54c0..afd125199 100644 --- a/core/src/Settings/Configuration/PayPalConfiguration.php +++ b/core/src/Settings/Configuration/PayPalConfiguration.php @@ -74,6 +74,9 @@ class PayPalConfiguration const PS_CHECKOUT_DOMAIN_REGISTERED_LIVE = 'PS_CHECKOUT_DOMAIN_REGISTERED_LIVE'; + const PS_CHECKOUT_PAYPAL_COUNTRY_MERCHANT = 'PS_CHECKOUT_PAYPAL_COUNTRY_MERCHANT'; + + // NOT CONFIGURATION const PS_CHECKOUT_CUSTOMER_INTENT_VAULT = 'VAULT'; const PS_CHECKOUT_CUSTOMER_INTENT_FAVORITE = 'FAVORITE'; @@ -116,4 +119,12 @@ public function is3dSecureEnabled(): bool { return $this->getCardFieldsContingencies() !== 'NONE'; } + + /** + * @return string + */ + public function getMerchantCountry(): string + { + return $this->configuration->get(self::PS_CHECKOUT_PAYPAL_COUNTRY_MERCHANT); + } } diff --git a/core/src/Settings/Configuration/PayPalPayLaterConfiguration.php b/core/src/Settings/Configuration/PayPalPayLaterConfiguration.php index b750f9837..2aaeba99b 100644 --- a/core/src/Settings/Configuration/PayPalPayLaterConfiguration.php +++ b/core/src/Settings/Configuration/PayPalPayLaterConfiguration.php @@ -20,23 +20,94 @@ namespace PsCheckout\Core\Settings\Configuration; +use PsCheckout\Infrastructure\Adapter\ConfigurationInterface; + class PayPalPayLaterConfiguration { + /** @deprecated used only as fallback */ const PS_CHECKOUT_PAY_LATER_ORDER_PAGE = 'PS_CHECKOUT_PAY_IN_4X_ORDER_PAGE'; + /** @deprecated used only as fallback */ const PS_CHECKOUT_PAY_LATER_PRODUCT_PAGE = 'PS_CHECKOUT_PAY_IN_4X_PRODUCT_PAGE'; - const PS_CHECKOUT_PAY_LATER_ORDER_PAGE_BANNER = 'PS_CHECKOUT_PAY_LATER_ORDER_PAGE_BANNER'; - + /** @deprecated used only as fallback */ const PS_CHECKOUT_PAY_LATER_HOME_PAGE_BANNER = 'PS_CHECKOUT_PAY_LATER_HOME_PAGE_BANNER'; + /** @deprecated used only as fallback */ const PS_CHECKOUT_PAY_LATER_CATEGORY_PAGE_BANNER = 'PS_CHECKOUT_PAY_LATER_CATEGORY_PAGE_BANNER'; - const PS_CHECKOUT_PAY_LATER_PRODUCT_PAGE_BANNER = 'PS_CHECKOUT_PAY_LATER_PRODUCT_PAGE_BANNER'; - const PS_CHECKOUT_PAY_LATER_ORDER_PAGE_BUTTON = 'PS_CHECKOUT_PAY_IN_4X_ORDER_PAGE_BUTTON'; const PS_CHECKOUT_PAY_LATER_CART_PAGE_BUTTON = 'PS_CHECKOUT_PAY_IN_4X_CART_PAGE_BUTTON'; const PS_CHECKOUT_PAY_LATER_PRODUCT_PAGE_BUTTON = 'PS_CHECKOUT_PAY_IN_4X_PRODUCT_PAGE_BUTTON'; + + const PS_CHECKOUT_PAY_LATER_CONFIG = 'PS_CHECKOUT_PAY_LATER_CONFIG'; + + /** + * @var ConfigurationInterface + */ + private $configuration; + + /** + * @var array|null + */ + private $config; + + public function __construct(ConfigurationInterface $configuration) + { + $this->configuration = $configuration; + $this->config = $this->configuration->getDeserializedRaw(self::PS_CHECKOUT_PAY_LATER_CONFIG); + } + + /** + * Returns Pay Later customization, with fallback from old configuration values for banner and message statuses + * + * @return array[] + */ + public function getPayLaterMessagingConfiguration(): array + { + if (!$this->config) { + return $this->getPayLaterMessagingConfigurationLegacy(); + } + + return $this->config; + } + + /** + * Returns the default Pay Later configuration + * + * @return array[] + */ + public function getPayLaterMessagingConfigurationDefault(): array + { + return [ + 'product' => ['status' => 'disabled'], + 'homepage' => ['status' => 'disabled'], + 'category' => ['status' => 'disabled'], + 'checkout' => ['status' => 'disabled'], + 'cart' => ['status' => 'disabled'], + ]; + } + + public function isPayLaterMessagingEnabled($page): bool + { + return isset($this->config[$page]) && $this->config[$page]['status'] === 'enabled'; + } + + /** + * Returns Pay Later customization from legacy configuration values + * + * @return array[] + */ + private function getPayLaterMessagingConfigurationLegacy(): array + { + return [ + 'product' => ['status' => $this->configuration->getBoolean(self::PS_CHECKOUT_PAY_LATER_PRODUCT_PAGE) ? 'enabled': 'disabled'], + 'homepage' => ['status' => $this->configuration->getBoolean(self::PS_CHECKOUT_PAY_LATER_HOME_PAGE_BANNER) ? 'enabled': 'disabled'], + 'category' => ['status' => $this->configuration->getBoolean(self::PS_CHECKOUT_PAY_LATER_CATEGORY_PAGE_BANNER) ? 'enabled': 'disabled'], + 'checkout' => ['status' => $this->configuration->getBoolean(self::PS_CHECKOUT_PAY_LATER_ORDER_PAGE) ? 'enabled': 'disabled'], + 'cart' => ['status' => $this->configuration->getBoolean(self::PS_CHECKOUT_PAY_LATER_ORDER_PAGE) ? 'enabled': 'disabled'], + ]; + } } diff --git a/core/src/Settings/Configuration/PayPalSdkConfiguration.php b/core/src/Settings/Configuration/PayPalSdkConfiguration.php index 7fb8523e5..187b18d3c 100644 --- a/core/src/Settings/Configuration/PayPalSdkConfiguration.php +++ b/core/src/Settings/Configuration/PayPalSdkConfiguration.php @@ -82,6 +82,11 @@ class PayPalSdkConfiguration */ private $logger; + /** + * @var PayPalPayLaterConfiguration + */ + private $payPalPayLaterConfiguration; + /** * @param ContextInterface $context * @param ConfigurationInterface $configuration @@ -91,6 +96,7 @@ class PayPalSdkConfiguration * @param PayPalCustomerRepositoryInterface $payPalCustomerRepository * @param OAuthServiceInterface $oAuthService * @param LoggerInterface $logger + * @param PayPalPayLaterConfiguration $payPalPayLaterConfiguration */ public function __construct( ContextInterface $context, @@ -100,7 +106,8 @@ public function __construct( FundingSourcePresenterInterface $fundingSourcePresenter, PayPalCustomerRepositoryInterface $payPalCustomerRepository, OAuthServiceInterface $oAuthService, - LoggerInterface $logger + LoggerInterface $logger, + PayPalPayLaterConfiguration $payPalPayLaterConfiguration ) { $this->context = $context; $this->configuration = $configuration; @@ -110,6 +117,7 @@ public function __construct( $this->payPalCustomerRepository = $payPalCustomerRepository; $this->oAuthService = $oAuthService; $this->logger = $logger; + $this->payPalPayLaterConfiguration = $payPalPayLaterConfiguration; } /** @@ -261,35 +269,18 @@ private function shouldIncludeMessagesComponent(): bool { $pageName = $this->getPageName(); - if ('index' === $pageName && $this->configuration->getBoolean(PayPalPayLaterConfiguration::PS_CHECKOUT_PAY_LATER_HOME_PAGE_BANNER)) { - return true; - } - - if ('category' === $pageName && $this->configuration->getBoolean(PayPalPayLaterConfiguration::PS_CHECKOUT_PAY_LATER_CATEGORY_PAGE_BANNER)) { - return true; - } - - if ( - in_array($pageName, ['cart', 'order']) && - ( - $this->configuration->getBoolean(PayPalPayLaterConfiguration::PS_CHECKOUT_PAY_LATER_ORDER_PAGE) || - $this->configuration->getBoolean(PayPalPayLaterConfiguration::PS_CHECKOUT_PAY_LATER_ORDER_PAGE_BANNER) - ) - ) { - return true; - } - - if ( - 'product' === $pageName && - ( - $this->configuration->getBoolean(PayPalPayLaterConfiguration::PS_CHECKOUT_PAY_LATER_PRODUCT_PAGE) || - $this->configuration->getBoolean(PayPalPayLaterConfiguration::PS_CHECKOUT_PAY_LATER_PRODUCT_PAGE_BANNER) - ) - ) { - return true; + switch ($pageName) { + case 'cart': + case 'category': + case 'product': + return $this->payPalPayLaterConfiguration->isPayLaterMessagingEnabled($pageName); + case 'order': + return $this->payPalPayLaterConfiguration->isPayLaterMessagingEnabled('checkout'); + case 'index': + return $this->payPalPayLaterConfiguration->isPayLaterMessagingEnabled('homepage'); + default: + return false; } - - return false; } private function shouldIncludeGooglePayComponent(): bool diff --git a/infrastructure/src/Adapter/Configuration.php b/infrastructure/src/Adapter/Configuration.php index d2797c4fb..6d16e8ad2 100644 --- a/infrastructure/src/Adapter/Configuration.php +++ b/infrastructure/src/Adapter/Configuration.php @@ -67,10 +67,10 @@ public function getDeserializedRaw(string $key) $configuration = $this->get($key); if (!$configuration) { - return ''; + return []; } - return json_decode($configuration); + return json_decode($configuration, true); } /** diff --git a/infrastructure/src/Validator/FrontControllerValidator.php b/infrastructure/src/Validator/FrontControllerValidator.php index 66b72e1ef..225f87b41 100644 --- a/infrastructure/src/Validator/FrontControllerValidator.php +++ b/infrastructure/src/Validator/FrontControllerValidator.php @@ -32,10 +32,17 @@ class FrontControllerValidator implements FrontControllerValidatorInterface */ private $configuration; + /** + * @var PayPalPayLaterConfiguration + */ + private $payPalPayLaterConfiguration; + public function __construct( - ConfigurationInterface $configuration + ConfigurationInterface $configuration, + PayPalPayLaterConfiguration $payPalPayLaterConfiguration ) { $this->configuration = $configuration; + $this->payPalPayLaterConfiguration = $payPalPayLaterConfiguration; } /** @@ -46,10 +53,10 @@ public function shouldLoadFrontCss(string $controller): bool switch ($controller) { // Homepage case 'index': - return $this->configuration->getBoolean(PayPalPayLaterConfiguration::PS_CHECKOUT_PAY_LATER_HOME_PAGE_BANNER); + return $this->payPalPayLaterConfiguration->isPayLaterMessagingEnabled('homepage'); // Category case 'category': - return $this->configuration->getBoolean(PayPalPayLaterConfiguration::PS_CHECKOUT_PAY_LATER_CATEGORY_PAGE_BANNER); + return $this->payPalPayLaterConfiguration->isPayLaterMessagingEnabled('category'); // Payment step case 'orderopc': case 'order': @@ -74,22 +81,21 @@ public function shouldLoadFrontJS(string $controller): bool switch ($controller) { // Homepage case 'index': - return $this->configuration->getBoolean(PayPalPayLaterConfiguration::PS_CHECKOUT_PAY_LATER_HOME_PAGE_BANNER); + return $this->payPalPayLaterConfiguration->isPayLaterMessagingEnabled('homepage'); // Category case 'category': - return $this->configuration->getBoolean(PayPalPayLaterConfiguration::PS_CHECKOUT_PAY_LATER_CATEGORY_PAGE_BANNER); + return $this->payPalPayLaterConfiguration->isPayLaterMessagingEnabled('category'); case 'orderopc': case 'order': return true; case 'product': - return $this->configuration->getBoolean(PayPalPayLaterConfiguration::PS_CHECKOUT_PAY_LATER_PRODUCT_PAGE) - || $this->configuration->getBoolean(PayPalPayLaterConfiguration::PS_CHECKOUT_PAY_LATER_PRODUCT_PAGE_BANNER) + return + $this->payPalPayLaterConfiguration->isPayLaterMessagingEnabled('product') || $this->configuration->getBoolean(PayPalPayLaterConfiguration::PS_CHECKOUT_PAY_LATER_PRODUCT_PAGE_BUTTON) || $this->configuration->getBoolean(PayPalExpressCheckoutConfiguration::PS_CHECKOUT_EC_PRODUCT_PAGE) || $this->configuration->getBoolean(PayPalConfiguration::PS_CHECKOUT_DISPLAY_LOGO_PRODUCT); case 'cart': - return $this->configuration->getBoolean(PayPalPayLaterConfiguration::PS_CHECKOUT_PAY_LATER_ORDER_PAGE) - || $this->configuration->getBoolean(PayPalPayLaterConfiguration::PS_CHECKOUT_PAY_LATER_ORDER_PAGE_BANNER) + return $this->payPalPayLaterConfiguration->isPayLaterMessagingEnabled('cart') || $this->configuration->getBoolean(PayPalPayLaterConfiguration::PS_CHECKOUT_PAY_LATER_CART_PAGE_BUTTON) || $this->configuration->getBoolean(PayPalExpressCheckoutConfiguration::PS_CHECKOUT_EC_ORDER_PAGE) || $this->configuration->getBoolean(PayPalConfiguration::PS_CHECKOUT_DISPLAY_LOGO_CART); diff --git a/infrastructure/src/Validator/PayLaterValidator.php b/infrastructure/src/Validator/PayLaterValidator.php new file mode 100644 index 000000000..76d3ebab1 --- /dev/null +++ b/infrastructure/src/Validator/PayLaterValidator.php @@ -0,0 +1,64 @@ +context = $context; + $this->payPalConfiguration = $payPalConfiguration; + } + + public function isPayLaterAvailable(): bool + { + $merchantCountry = $this->payPalConfiguration->getMerchantCountry(); + $countries = FundingSourceConstraint::getCountries('paylater'); + $currency = $this->context->getCurrency()->iso_code; + $locale = $this->context->getLanguage()->locale; + $customerCountry = $this->context->getCountry()->iso_code; + + // Define supported country-currency combinations for Pay Later messaging + $supportedCountryCurrencyMap = [ + 'AU' => 'AUD', // Australia + 'FR' => 'EUR', // France + 'DE' => 'EUR', // Germany + 'IT' => 'EUR', // Italy + 'ES' => 'EUR', // Spain + 'GB' => 'GBP', // United Kingdom + 'US' => 'USD', // United States + ]; + + // Define locale to country mapping for website locale validation + $localeCountryMap = [ + 'en-AU' => 'AU', // Australia + 'fr-FR' => 'FR', // France + 'de-DE' => 'DE', // Germany + 'it-IT' => 'IT', // Italy + 'es-ES' => 'ES', // Spain + 'en-GB' => 'GB', // United Kingdom + 'en-US' => 'US', // United States + ]; + + return in_array($merchantCountry, $countries, true) + && $merchantCountry === $customerCountry + && isset($supportedCountryCurrencyMap[$customerCountry]) + && $supportedCountryCurrencyMap[$customerCountry] === $currency + && isset($localeCountryMap[$locale]) + && $localeCountryMap[$locale] === $merchantCountry; + } +} diff --git a/infrastructure/src/Validator/PayLaterValidatorInterface.php b/infrastructure/src/Validator/PayLaterValidatorInterface.php new file mode 100644 index 000000000..3db45dd16 --- /dev/null +++ b/infrastructure/src/Validator/PayLaterValidatorInterface.php @@ -0,0 +1,29 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ + +namespace PsCheckout\Infrastructure\Validator; + +interface PayLaterValidatorInterface +{ + /** + * @return bool + */ + public function isPayLaterAvailable(): bool; +} diff --git a/infrastructure/tests/Unit/Validator/PayLaterValidatorTest.php b/infrastructure/tests/Unit/Validator/PayLaterValidatorTest.php new file mode 100644 index 000000000..26c37a9e8 --- /dev/null +++ b/infrastructure/tests/Unit/Validator/PayLaterValidatorTest.php @@ -0,0 +1,272 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 + */ + +namespace Tests\Unit\PsCheckout\Infrastructure\Validator; + +use PHPUnit\Framework\TestCase; +use PsCheckout\Core\Settings\Configuration\PayPalConfiguration; +use PsCheckout\Infrastructure\Adapter\Context; +use PsCheckout\Infrastructure\Validator\PayLaterValidator; + +class PayLaterValidatorTest extends TestCase +{ + private $contextMock; + + private $payPalConfigurationMock; + + private $payLaterValidator; + + protected function setUp(): void + { + $this->contextMock = $this->createMock(Context::class); + $this->payPalConfigurationMock = $this->createMock(PayPalConfiguration::class); + $this->payLaterValidator = new PayLaterValidator($this->contextMock, $this->payPalConfigurationMock); + } + + /** + * @dataProvider validPayLaterScenariosProvider + */ + public function testIsPayLaterAvailableReturnsTrueForValidScenarios( + string $merchantCountry, + string $customerCountry, + string $currency, + string $locale + ): void { + $this->payPalConfigurationMock + ->method('getMerchantCountry') + ->willReturn($merchantCountry); + + $currencyMock = $this->createMock(\stdClass::class); + $currencyMock->iso_code = $currency; + + $languageMock = $this->createMock(\stdClass::class); + $languageMock->locale = $locale; + + $countryMock = $this->createMock(\stdClass::class); + $countryMock->iso_code = $customerCountry; + + $this->contextMock + ->method('getCurrency') + ->willReturn($currencyMock); + + $this->contextMock + ->method('getLanguage') + ->willReturn($languageMock); + + $this->contextMock + ->method('getCountry') + ->willReturn($countryMock); + + $this->assertTrue($this->payLaterValidator->isPayLaterAvailable()); + } + + /** + * @dataProvider invalidPayLaterScenariosProvider + */ + public function testIsPayLaterAvailableReturnsFalseForInvalidScenarios( + string $merchantCountry, + string $customerCountry, + string $currency, + string $locale + ): void { + $this->payPalConfigurationMock + ->method('getMerchantCountry') + ->willReturn($merchantCountry); + + $currencyMock = $this->createMock(\stdClass::class); + $currencyMock->iso_code = $currency; + + $languageMock = $this->createMock(\stdClass::class); + $languageMock->locale = $locale; + + $countryMock = $this->createMock(\stdClass::class); + $countryMock->iso_code = $customerCountry; + + $this->contextMock + ->method('getCurrency') + ->willReturn($currencyMock); + + $this->contextMock + ->method('getLanguage') + ->willReturn($languageMock); + + $this->contextMock + ->method('getCountry') + ->willReturn($countryMock); + + $this->assertFalse($this->payLaterValidator->isPayLaterAvailable()); + } + + public function testIsPayLaterAvailableReturnsFalseForUnsupportedMerchantCountry(): void + { + $this->payPalConfigurationMock + ->method('getMerchantCountry') + ->willReturn('CA'); // Canada is not supported + + $currencyMock = $this->createMock(\stdClass::class); + $currencyMock->iso_code = 'CAD'; + + $languageMock = $this->createMock(\stdClass::class); + $languageMock->locale = 'en-CA'; + + $countryMock = $this->createMock(\stdClass::class); + $countryMock->iso_code = 'CA'; + + $this->contextMock + ->method('getCurrency') + ->willReturn($currencyMock); + + $this->contextMock + ->method('getLanguage') + ->willReturn($languageMock); + + $this->contextMock + ->method('getCountry') + ->willReturn($countryMock); + + $this->assertFalse($this->payLaterValidator->isPayLaterAvailable()); + } + + public function testIsPayLaterAvailableReturnsFalseForMismatchedMerchantAndCustomerCountry(): void + { + $this->payPalConfigurationMock + ->method('getMerchantCountry') + ->willReturn('US'); // US merchant + + $currencyMock = $this->createMock(\stdClass::class); + $currencyMock->iso_code = 'USD'; + + $languageMock = $this->createMock(\stdClass::class); + $languageMock->locale = 'en-US'; + + $countryMock = $this->createMock(\stdClass::class); + $countryMock->iso_code = 'CA'; // Canadian customer + + $this->contextMock + ->method('getCurrency') + ->willReturn($currencyMock); + + $this->contextMock + ->method('getLanguage') + ->willReturn($languageMock); + + $this->contextMock + ->method('getCountry') + ->willReturn($countryMock); + + $this->assertFalse($this->payLaterValidator->isPayLaterAvailable()); + } + + public function testIsPayLaterAvailableReturnsFalseForWrongCurrency(): void + { + $this->payPalConfigurationMock + ->method('getMerchantCountry') + ->willReturn('US'); + + $currencyMock = $this->createMock(\stdClass::class); + $currencyMock->iso_code = 'EUR'; // Wrong currency for US + + $languageMock = $this->createMock(\stdClass::class); + $languageMock->locale = 'en-US'; + + $countryMock = $this->createMock(\stdClass::class); + $countryMock->iso_code = 'US'; + + $this->contextMock + ->method('getCurrency') + ->willReturn($currencyMock); + + $this->contextMock + ->method('getLanguage') + ->willReturn($languageMock); + + $this->contextMock + ->method('getCountry') + ->willReturn($countryMock); + + $this->assertFalse($this->payLaterValidator->isPayLaterAvailable()); + } + + public function testIsPayLaterAvailableReturnsFalseForUnsupportedLocale(): void + { + $this->payPalConfigurationMock + ->method('getMerchantCountry') + ->willReturn('US'); + + $currencyMock = $this->createMock(\stdClass::class); + $currencyMock->iso_code = 'USD'; + + $languageMock = $this->createMock(\stdClass::class); + $languageMock->locale = 'fr-FR'; // French locale for US merchant + + $countryMock = $this->createMock(\stdClass::class); + $countryMock->iso_code = 'US'; + + $this->contextMock + ->method('getCurrency') + ->willReturn($currencyMock); + + $this->contextMock + ->method('getLanguage') + ->willReturn($languageMock); + + $this->contextMock + ->method('getCountry') + ->willReturn($countryMock); + + $this->assertFalse($this->payLaterValidator->isPayLaterAvailable()); + } + + public function validPayLaterScenariosProvider(): array + { + return [ + 'Australia scenario' => ['AU', 'AU', 'AUD', 'en-AU'], + 'France scenario' => ['FR', 'FR', 'EUR', 'fr-FR'], + 'Germany scenario' => ['DE', 'DE', 'EUR', 'de-DE'], + 'Italy scenario' => ['IT', 'IT', 'EUR', 'it-IT'], + 'Spain scenario' => ['ES', 'ES', 'EUR', 'es-ES'], + 'United Kingdom scenario' => ['GB', 'GB', 'GBP', 'en-GB'], + 'United States scenario' => ['US', 'US', 'USD', 'en-US'], + ]; + } + + public function invalidPayLaterScenariosProvider(): array + { + return [ + 'Wrong currency for Australia' => ['AU', 'AU', 'USD', 'en-AU'], + 'Wrong currency for France' => ['FR', 'FR', 'USD', 'fr-FR'], + 'Wrong currency for Germany' => ['DE', 'DE', 'GBP', 'de-DE'], + 'Wrong currency for Italy' => ['IT', 'IT', 'AUD', 'it-IT'], + 'Wrong currency for Spain' => ['ES', 'ES', 'GBP', 'es-ES'], + 'Wrong currency for UK' => ['GB', 'GB', 'EUR', 'en-GB'], + 'Wrong currency for US' => ['US', 'US', 'EUR', 'en-US'], + 'Wrong locale for Australia' => ['AU', 'AU', 'AUD', 'fr-FR'], + 'Wrong locale for France' => ['FR', 'FR', 'EUR', 'en-US'], + 'Wrong locale for Germany' => ['DE', 'DE', 'EUR', 'it-IT'], + 'Wrong locale for Italy' => ['IT', 'IT', 'EUR', 'es-ES'], + 'Wrong locale for Spain' => ['ES', 'ES', 'EUR', 'de-DE'], + 'Wrong locale for UK' => ['GB', 'GB', 'GBP', 'fr-FR'], + 'Wrong locale for US' => ['US', 'US', 'USD', 'de-DE'], + 'Unsupported merchant country' => ['CA', 'CA', 'CAD', 'en-CA'], + 'Unsupported customer country' => ['US', 'CA', 'USD', 'en-US'], + ]; + } +} diff --git a/presentation/src/Presenter/Settings/Admin/Modules/ConfigurationModule.php b/presentation/src/Presenter/Settings/Admin/Modules/ConfigurationModule.php index 2665e685e..dfd76c5f7 100644 --- a/presentation/src/Presenter/Settings/Admin/Modules/ConfigurationModule.php +++ b/presentation/src/Presenter/Settings/Admin/Modules/ConfigurationModule.php @@ -92,24 +92,14 @@ public function present(): array ], 'payLater' => [ 'orderPage' => [ - 'message' => $this->configuration->getBoolean(PayPalPayLaterConfiguration::PS_CHECKOUT_PAY_LATER_ORDER_PAGE), - 'banner' => $this->configuration->getBoolean(PayPalPayLaterConfiguration::PS_CHECKOUT_PAY_LATER_ORDER_PAGE_BANNER), 'button' => $this->configuration->getBoolean(PayPalPayLaterConfiguration::PS_CHECKOUT_PAY_LATER_ORDER_PAGE_BUTTON), ], 'cartPage' => [ 'button' => $this->configuration->getBoolean(PayPalPayLaterConfiguration::PS_CHECKOUT_PAY_LATER_CART_PAGE_BUTTON), ], 'productPage' => [ - 'message' => $this->configuration->getBoolean(PayPalPayLaterConfiguration::PS_CHECKOUT_PAY_LATER_PRODUCT_PAGE), - 'banner' => $this->configuration->getBoolean(PayPalPayLaterConfiguration::PS_CHECKOUT_PAY_LATER_PRODUCT_PAGE_BANNER), 'button' => $this->configuration->getBoolean(PayPalPayLaterConfiguration::PS_CHECKOUT_PAY_LATER_PRODUCT_PAGE_BUTTON), ], - 'categoryPage' => [ - 'banner' => $this->configuration->getBoolean(PayPalPayLaterConfiguration::PS_CHECKOUT_PAY_LATER_CATEGORY_PAGE_BANNER), - ], - 'homePage' => [ - 'banner' => $this->configuration->getBoolean(PayPalPayLaterConfiguration::PS_CHECKOUT_PAY_LATER_HOME_PAGE_BANNER), - ], ], 'logger' => [ 'levels' => [ diff --git a/presentation/src/Presenter/Settings/Admin/Modules/ContextModule.php b/presentation/src/Presenter/Settings/Admin/Modules/ContextModule.php index 53533057f..7dc09491e 100644 --- a/presentation/src/Presenter/Settings/Admin/Modules/ContextModule.php +++ b/presentation/src/Presenter/Settings/Admin/Modules/ContextModule.php @@ -24,6 +24,7 @@ use PsCheckout\Infrastructure\Adapter\ConfigurationInterface; use PsCheckout\Infrastructure\Adapter\ContextInterface; use PsCheckout\Infrastructure\Adapter\LinkInterface; +use PsCheckout\Infrastructure\Environment\EnvInterface; use PsCheckout\Presentation\Presenter\PresenterInterface; /** @@ -56,6 +57,11 @@ class ContextModule implements PresenterInterface */ private $configuration; + /** + * @var EnvInterface + */ + private $env; + /** * @param string $moduleName * @param string $moduleVersion @@ -68,13 +74,15 @@ public function __construct( string $moduleVersion, ContextInterface $context, LinkInterface $link, - ConfigurationInterface $configuration + ConfigurationInterface $configuration, + EnvInterface $env ) { $this->moduleName = $moduleName; $this->moduleVersion = $moduleVersion; $this->context = $context; $this->link = $link; $this->configuration = $configuration; + $this->env = $env; } /** @@ -109,6 +117,8 @@ public function present(): array 'configure' => $this->moduleName, ] ), + 'clientId' => $this->env->getPaypalClientId(), + 'bnCode' => $this->env->getBnCode(), ], ]; } diff --git a/presentation/src/Presenter/Settings/Front/Modules/ConfigurationModule.php b/presentation/src/Presenter/Settings/Front/Modules/ConfigurationModule.php index e570642e7..d2affab7f 100644 --- a/presentation/src/Presenter/Settings/Front/Modules/ConfigurationModule.php +++ b/presentation/src/Presenter/Settings/Front/Modules/ConfigurationModule.php @@ -20,12 +20,14 @@ namespace PsCheckout\Presentation\Presenter\Settings\Front\Modules; +use PsCheckout\Core\FundingSource\Constraint\FundingSourceConstraint; use PsCheckout\Core\Settings\Configuration\PayPalConfiguration; use PsCheckout\Core\Settings\Configuration\PayPalExpressCheckoutConfiguration; use PsCheckout\Core\Settings\Configuration\PayPalPayLaterConfiguration; use PsCheckout\Core\Settings\Configuration\PayPalSdkConfiguration; use PsCheckout\Infrastructure\Adapter\ConfigurationInterface; use PsCheckout\Infrastructure\Adapter\ContextInterface; +use PsCheckout\Infrastructure\Validator\PayLaterValidatorInterface; use PsCheckout\Presentation\Presenter\FundingSource\FundingSourcePresenterInterface; use PsCheckout\Presentation\Presenter\PresenterInterface; @@ -61,12 +63,25 @@ class ConfigurationModule implements PresenterInterface */ private $payPalSdkConfiguration; + /** + * @var PayPalPayLaterConfiguration + */ + private $payLaterConfiguration; + + /** + * @var PayLaterValidatorInterface + */ + private $payLaterValidator; + /** * @param string $moduleName * @param ContextInterface $context * @param ConfigurationInterface $configuration * @param PayPalConfiguration $payPalConfiguration * @param FundingSourcePresenterInterface $fundingSourcePresenter + * @param PayPalSdkConfiguration $payPalSdkConfiguration + * @param PayPalPayLaterConfiguration $payLaterConfiguration + * @param PayLaterValidatorInterface $payLaterValidator */ public function __construct( string $moduleName, @@ -74,7 +89,9 @@ public function __construct( ConfigurationInterface $configuration, PayPalConfiguration $payPalConfiguration, FundingSourcePresenterInterface $fundingSourcePresenter, - PayPalSdkConfiguration $payPalSdkConfiguration + PayPalSdkConfiguration $payPalSdkConfiguration, + PayPalPayLaterConfiguration $payLaterConfiguration, + PayLaterValidatorInterface $payLaterValidator ) { $this->moduleName = $moduleName; $this->context = $context; @@ -82,6 +99,8 @@ public function __construct( $this->payPalConfiguration = $payPalConfiguration; $this->fundingSourcePresenter = $fundingSourcePresenter; $this->payPalSdkConfiguration = $payPalSdkConfiguration; + $this->payLaterConfiguration = $payLaterConfiguration; + $this->payLaterValidator = $payLaterValidator; } public function present(): array @@ -97,6 +116,7 @@ public function present(): array } $isPayPalPaymentsReceivable = $this->configuration->getBoolean(PayPalConfiguration::PS_CHECKOUT_PAYPAL_PAYMENT_STATUS); + $isPayLaterAvailable = $this->payLaterValidator->isPayLaterAvailable(); return [ $this->moduleName . 'PayPalSdkConfig' => $this->payPalSdkConfiguration->buildConfiguration(), @@ -108,15 +128,12 @@ public function present(): array $this->moduleName . 'ExpressCheckoutCartEnabled' => $this->configuration->getBoolean(PayPalExpressCheckoutConfiguration::PS_CHECKOUT_EC_ORDER_PAGE) && $isPayPalPaymentsReceivable, $this->moduleName . 'ExpressCheckoutOrderEnabled' => $this->configuration->getBoolean(PayPalExpressCheckoutConfiguration::PS_CHECKOUT_EC_CHECKOUT_PAGE) && $isPayPalPaymentsReceivable, $this->moduleName . 'ExpressCheckoutProductEnabled' => $this->configuration->getBoolean(PayPalExpressCheckoutConfiguration::PS_CHECKOUT_EC_PRODUCT_PAGE) && $isPayPalPaymentsReceivable, - $this->moduleName . 'PayLaterOrderPageMessageEnabled' => $this->configuration->getBoolean(PayPalPayLaterConfiguration::PS_CHECKOUT_PAY_LATER_ORDER_PAGE) && $isPayPalPaymentsReceivable, - $this->moduleName . 'PayLaterProductPageMessageEnabled' => $this->configuration->getBoolean(PayPalPayLaterConfiguration::PS_CHECKOUT_PAY_LATER_PRODUCT_PAGE) && $isPayPalPaymentsReceivable, - $this->moduleName . 'PayLaterOrderPageBannerEnabled' => $this->configuration->getBoolean(PayPalPayLaterConfiguration::PS_CHECKOUT_PAY_LATER_ORDER_PAGE_BANNER) && $isPayPalPaymentsReceivable, - $this->moduleName . 'PayLaterHomePageBannerEnabled' => $this->configuration->getBoolean(PayPalPayLaterConfiguration::PS_CHECKOUT_PAY_LATER_HOME_PAGE_BANNER) && $isPayPalPaymentsReceivable, - $this->moduleName . 'PayLaterCategoryPageBannerEnabled' => $this->configuration->getBoolean(PayPalPayLaterConfiguration::PS_CHECKOUT_PAY_LATER_CATEGORY_PAGE_BANNER) && $isPayPalPaymentsReceivable, - $this->moduleName . 'PayLaterProductPageBannerEnabled' => $this->configuration->getBoolean(PayPalPayLaterConfiguration::PS_CHECKOUT_PAY_LATER_PRODUCT_PAGE_BANNER) && $isPayPalPaymentsReceivable, $this->moduleName . 'PayLaterOrderPageButtonEnabled' => $this->configuration->getBoolean(PayPalPayLaterConfiguration::PS_CHECKOUT_PAY_LATER_ORDER_PAGE_BUTTON) && $isPayPalPaymentsReceivable, $this->moduleName . 'PayLaterCartPageButtonEnabled' => $this->configuration->getBoolean(PayPalPayLaterConfiguration::PS_CHECKOUT_PAY_LATER_CART_PAGE_BUTTON) && $isPayPalPaymentsReceivable, $this->moduleName . 'PayLaterProductPageButtonEnabled' => $this->configuration->getBoolean(PayPalPayLaterConfiguration::PS_CHECKOUT_PAY_LATER_PRODUCT_PAGE_BUTTON) && $isPayPalPaymentsReceivable, + $this->moduleName . 'PayLaterMessagingConfig' => $isPayPalPaymentsReceivable && $isPayLaterAvailable + ? $this->payLaterConfiguration->getPayLaterMessagingConfiguration() + : $this->payLaterConfiguration->getPayLaterMessagingConfigurationDefault(), ]; } } diff --git a/ps17/config.xml b/ps17/config.xml index 9b82c457e..55d13ec03 100644 --- a/ps17/config.xml +++ b/ps17/config.xml @@ -2,7 +2,7 @@ ps_checkout - + diff --git a/ps17/config/admin/presenter.yml b/ps17/config/admin/presenter.yml index e2636990b..c491cb70a 100644 --- a/ps17/config/admin/presenter.yml +++ b/ps17/config/admin/presenter.yml @@ -18,6 +18,7 @@ services: - '@PsCheckout\Infrastructure\Adapter\Context' - '@PsCheckout\Infrastructure\Adapter\Link' - '@PsCheckout\Infrastructure\Adapter\Configuration' + - '@PsCheckout\Infrastructure\Environment\Env' PsCheckout\Presentation\Presenter\Settings\Admin\Modules\ConfigurationModule: class: PsCheckout\Presentation\Presenter\Settings\Admin\Modules\ConfigurationModule diff --git a/ps17/config/front/configuration.yml b/ps17/config/front/configuration.yml index c93866af4..d9d09aef5 100644 --- a/ps17/config/front/configuration.yml +++ b/ps17/config/front/configuration.yml @@ -13,3 +13,4 @@ services: - '@PsCheckout\Infrastructure\Repository\PayPalCustomerRepository' - '@PsCheckout\Core\PayPal\OAuth\OAuthService' - '@Psr\Log\LoggerInterface' + - '@PsCheckout\Core\Settings\Configuration\PayPalPayLaterConfiguration' diff --git a/ps17/config/front/presenter.yml b/ps17/config/front/presenter.yml index 7d1d37a69..3c40a1d93 100644 --- a/ps17/config/front/presenter.yml +++ b/ps17/config/front/presenter.yml @@ -39,6 +39,8 @@ services: - '@PsCheckout\Core\Settings\Configuration\PayPalConfiguration' - '@PsCheckout\Presentation\Presenter\FundingSource\FundingSourcePresenter' - '@PsCheckout\Core\Settings\Configuration\PayPalSdkConfiguration' + - '@PsCheckout\Core\Settings\Configuration\PayPalPayLaterConfiguration' + - '@PsCheckout\Infrastructure\Validator\PayLaterValidator' PsCheckout\Presentation\Presenter\Settings\Front\Modules\MediaModule: class: PsCheckout\Presentation\Presenter\Settings\Front\Modules\MediaModule diff --git a/ps17/config/front/validator.yml b/ps17/config/front/validator.yml index 179456f47..381a9568f 100644 --- a/ps17/config/front/validator.yml +++ b/ps17/config/front/validator.yml @@ -6,6 +6,7 @@ services: class: PsCheckout\Infrastructure\Validator\FrontControllerValidator arguments: - '@PsCheckout\Infrastructure\Adapter\Configuration' + - '@PsCheckout\Core\Settings\Configuration\PayPalPayLaterConfiguration' PsCheckout\Core\Order\Validator\OrderAuthorizationValidator: class: PsCheckout\Core\Order\Validator\OrderAuthorizationValidator diff --git a/ps17/config/shared/configuration.yml b/ps17/config/shared/configuration.yml index 08625ca25..222b6438a 100644 --- a/ps17/config/shared/configuration.yml +++ b/ps17/config/shared/configuration.yml @@ -6,3 +6,8 @@ services: class: PsCheckout\Core\Settings\Configuration\PayPalConfiguration arguments: - '@PsCheckout\Infrastructure\Adapter\Configuration' + + PsCheckout\Core\Settings\Configuration\PayPalPayLaterConfiguration: + class: PsCheckout\Core\Settings\Configuration\PayPalPayLaterConfiguration + arguments: + - '@PsCheckout\Infrastructure\Adapter\Configuration' diff --git a/ps17/config/shared/validator.yml b/ps17/config/shared/validator.yml index b12ad128e..d7e5153bd 100644 --- a/ps17/config/shared/validator.yml +++ b/ps17/config/shared/validator.yml @@ -9,4 +9,10 @@ services: - '@PsCheckout\Infrastructure\Repository\PsAccountRepository' PsCheckout\Core\PayPal\Card3DSecure\Card3DSecureValidator: - class: PsCheckout\Core\PayPal\Card3DSecure\Card3DSecureValidator \ No newline at end of file + class: PsCheckout\Core\PayPal\Card3DSecure\Card3DSecureValidator + + PsCheckout\Infrastructure\Validator\PayLaterValidator: + class: PsCheckout\Infrastructure\Validator\PayLaterValidator + arguments: + - '@PsCheckout\Infrastructure\Adapter\Context' + - '@PsCheckout\Core\Settings\Configuration\PayPalConfiguration' \ No newline at end of file diff --git a/ps17/controllers/admin/AdminAjaxPrestashopCheckoutController.php b/ps17/controllers/admin/AdminAjaxPrestashopCheckoutController.php index 194d509e3..6209fd3e2 100644 --- a/ps17/controllers/admin/AdminAjaxPrestashopCheckoutController.php +++ b/ps17/controllers/admin/AdminAjaxPrestashopCheckoutController.php @@ -602,56 +602,6 @@ public function ajaxProcessToggleECProductPage() $this->ajaxRender(json_encode(true)); } - /** - * AJAX: Toggle pay later message on order page - */ - public function ajaxProcessTogglePayLaterOrderPageMessage() - { - $this->setConfiguration(PayPalPayLaterConfiguration::PS_CHECKOUT_PAY_LATER_ORDER_PAGE, (bool) Tools::getValue('status')); - - $this->ajaxRender(json_encode(true)); - } - - /** - * AJAX: Toggle pay later message on product page - */ - public function ajaxProcessTogglePayLaterProductPageMessage() - { - $this->setConfiguration(PayPalPayLaterConfiguration::PS_CHECKOUT_PAY_LATER_PRODUCT_PAGE, (bool) Tools::getValue('status')); - - $this->ajaxRender(json_encode(true)); - } - - /** - * AJAX: Toggle pay later banner on home page - */ - public function ajaxProcessTogglePayLaterHomePageBanner() - { - $this->setConfiguration(PayPalPayLaterConfiguration::PS_CHECKOUT_PAY_LATER_HOME_PAGE_BANNER, (bool) Tools::getValue('status')); - - $this->ajaxRender(json_encode(true)); - } - - /** - * AJAX: Toggle pay later banner on cart page - */ - public function ajaxProcessTogglePayLaterOrderPageBanner() - { - $this->setConfiguration(PayPalPayLaterConfiguration::PS_CHECKOUT_PAY_LATER_ORDER_PAGE_BANNER, (bool) Tools::getValue('status')); - - $this->ajaxRender(json_encode(true)); - } - - /** - * AJAX: Toggle pay later banner on product page - */ - public function ajaxProcessTogglePayLaterProductPageBanner() - { - $this->setConfiguration(PayPalPayLaterConfiguration::PS_CHECKOUT_PAY_LATER_PRODUCT_PAGE_BANNER, (bool) Tools::getValue('status')); - - $this->ajaxRender(json_encode(true)); - } - /** * AJAX: Toggle pay later button on cart page */ diff --git a/ps17/ps_checkout.php b/ps17/ps_checkout.php index 0d1692adc..9b091a00a 100644 --- a/ps17/ps_checkout.php +++ b/ps17/ps_checkout.php @@ -108,7 +108,7 @@ public function __construct() { $this->name = 'ps_checkout'; $this->tab = 'payments_gateways'; - $this->version = '7.5.0.6'; + $this->version = '7.5.1.0'; $this->author = 'PrestaShop'; parent::__construct(); diff --git a/ps17/upgrade/upgrade-7.5.1.0.php b/ps17/upgrade/upgrade-7.5.1.0.php new file mode 100644 index 000000000..d88e05a36 --- /dev/null +++ b/ps17/upgrade/upgrade-7.5.1.0.php @@ -0,0 +1,125 @@ + + * @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.5.1.0 + * + * @param Ps_checkout $module + * + * @return bool + */ +function upgrade_module_7_5_1_0(Ps_checkout $module) +{ + try { + $savedShopContext = Shop::getContext(); + $savedShopId = Shop::getContextShopID(); + $savedGroupShopId = Shop::getContextShopGroupID(); + Shop::setContext(Shop::CONTEXT_ALL); + $shopsList = \Shop::getShops(false, null, true); + + foreach ($shopsList as $shopId) { + $configuration = json_encode([ + 'cart' => [ + 'placement' => 'cart', + 'status' => (bool) \Configuration::get( + 'PS_CHECKOUT_PAY_LATER_ORDER_PAGE_BANNER', + null, + null, + $shopId + ) ? 'enabled' : 'disabled', + 'layout' => 'text', + 'logo-type' => 'inline', + 'text-color' => 'black', + 'text-size' => '12', + ], + 'category' => [ + 'placement' => 'category', + 'status' => (bool) \Configuration::get( + 'PS_CHECKOUT_PAY_LATER_CATEGORY_PAGE_BANNER', + null, + null, + $shopId + ) ? 'enabled' : 'disabled', + 'color' => 'white', + 'layout' => 'flex', + 'ratio' => '8x1', + ], + 'checkout' => [ + 'placement' => 'checkout', + 'status' => (bool) \Configuration::get( + 'PS_CHECKOUT_PAY_LATER_ORDER_PAGE_BANNER', + null, + null, + $shopId + ) ? 'enabled' : 'disabled', + 'layout' => 'text', + 'logo-type' => 'inline', + 'text-color' => 'black', + 'text-size' => '12', + ], + 'homepage' => [ + 'placement' => 'homepage', + 'status' => (bool) \Configuration::get( + 'PS_CHECKOUT_PAY_LATER_HOME_PAGE_BANNER', + null, + null, + $shopId + ) ? 'enabled' : 'disabled', + 'color' => 'white', + 'layout' => 'flex', + 'ratio' => '8x1', + ], + 'product' => [ + 'placement' => 'product', + 'status' => (bool) \Configuration::get( + 'PS_CHECKOUT_PAY_LATER_PRODUCT_PAGE', + null, + null, + $shopId + ) ? 'enabled' : 'disabled', + 'layout' => 'text', + 'logo-type' => 'inline', + 'text-color' => 'black', + 'text-size' => '12', + ], + ]); + + Configuration::updateValue('PS_CHECKOUT_PAY_LATER_CONFIG', $configuration, false, null, (int) $shopId); + } + + // Restore initial PrestaShop shop context + if (Shop::CONTEXT_SHOP === $savedShopContext) { + Shop::setContext($savedShopContext, $savedShopId); + } elseif (Shop::CONTEXT_GROUP === $savedShopContext) { + Shop::setContext($savedShopContext, $savedGroupShopId); + } else { + Shop::setContext($savedShopContext); + } + } catch (Exception $exception) { + PrestaShopLogger::addLog($exception->getMessage(), 4, 1, 'Module', $module->id); + + return false; + } + + return true; +} diff --git a/ps8/config.xml b/ps8/config.xml index acb4d479b..149f0dd05 100644 --- a/ps8/config.xml +++ b/ps8/config.xml @@ -2,7 +2,7 @@ ps_checkout - + diff --git a/ps8/config/admin/presenter.yml b/ps8/config/admin/presenter.yml index a5350210d..0444d2809 100644 --- a/ps8/config/admin/presenter.yml +++ b/ps8/config/admin/presenter.yml @@ -19,6 +19,7 @@ services: - '@PsCheckout\Infrastructure\Adapter\Context' - '@PsCheckout\Infrastructure\Adapter\Link' - '@PsCheckout\Infrastructure\Adapter\Configuration' + - '@PsCheckout\Infrastructure\Environment\Env' PsCheckout\Presentation\Presenter\Settings\Admin\Modules\ConfigurationModule: class: PsCheckout\Presentation\Presenter\Settings\Admin\Modules\ConfigurationModule diff --git a/ps8/config/front/configuration.yml b/ps8/config/front/configuration.yml index c93866af4..d9d09aef5 100644 --- a/ps8/config/front/configuration.yml +++ b/ps8/config/front/configuration.yml @@ -13,3 +13,4 @@ services: - '@PsCheckout\Infrastructure\Repository\PayPalCustomerRepository' - '@PsCheckout\Core\PayPal\OAuth\OAuthService' - '@Psr\Log\LoggerInterface' + - '@PsCheckout\Core\Settings\Configuration\PayPalPayLaterConfiguration' diff --git a/ps8/config/front/presenter.yml b/ps8/config/front/presenter.yml index 2a3120fb3..0b8e48765 100644 --- a/ps8/config/front/presenter.yml +++ b/ps8/config/front/presenter.yml @@ -40,6 +40,8 @@ services: - '@PsCheckout\Core\Settings\Configuration\PayPalConfiguration' - '@PsCheckout\Presentation\Presenter\FundingSource\FundingSourcePresenter' - '@PsCheckout\Core\Settings\Configuration\PayPalSdkConfiguration' + - '@PsCheckout\Core\Settings\Configuration\PayPalPayLaterConfiguration' + - '@PsCheckout\Infrastructure\Validator\PayLaterValidator' PsCheckout\Presentation\Presenter\Settings\Front\Modules\MediaModule: class: PsCheckout\Presentation\Presenter\Settings\Front\Modules\MediaModule diff --git a/ps8/config/front/validator.yml b/ps8/config/front/validator.yml index 179456f47..381a9568f 100644 --- a/ps8/config/front/validator.yml +++ b/ps8/config/front/validator.yml @@ -6,6 +6,7 @@ services: class: PsCheckout\Infrastructure\Validator\FrontControllerValidator arguments: - '@PsCheckout\Infrastructure\Adapter\Configuration' + - '@PsCheckout\Core\Settings\Configuration\PayPalPayLaterConfiguration' PsCheckout\Core\Order\Validator\OrderAuthorizationValidator: class: PsCheckout\Core\Order\Validator\OrderAuthorizationValidator diff --git a/ps8/config/shared/configuration.yml b/ps8/config/shared/configuration.yml index 08625ca25..222b6438a 100644 --- a/ps8/config/shared/configuration.yml +++ b/ps8/config/shared/configuration.yml @@ -6,3 +6,8 @@ services: class: PsCheckout\Core\Settings\Configuration\PayPalConfiguration arguments: - '@PsCheckout\Infrastructure\Adapter\Configuration' + + PsCheckout\Core\Settings\Configuration\PayPalPayLaterConfiguration: + class: PsCheckout\Core\Settings\Configuration\PayPalPayLaterConfiguration + arguments: + - '@PsCheckout\Infrastructure\Adapter\Configuration' diff --git a/ps8/config/shared/validator.yml b/ps8/config/shared/validator.yml index b12ad128e..d7e5153bd 100644 --- a/ps8/config/shared/validator.yml +++ b/ps8/config/shared/validator.yml @@ -9,4 +9,10 @@ services: - '@PsCheckout\Infrastructure\Repository\PsAccountRepository' PsCheckout\Core\PayPal\Card3DSecure\Card3DSecureValidator: - class: PsCheckout\Core\PayPal\Card3DSecure\Card3DSecureValidator \ No newline at end of file + class: PsCheckout\Core\PayPal\Card3DSecure\Card3DSecureValidator + + PsCheckout\Infrastructure\Validator\PayLaterValidator: + class: PsCheckout\Infrastructure\Validator\PayLaterValidator + arguments: + - '@PsCheckout\Infrastructure\Adapter\Context' + - '@PsCheckout\Core\Settings\Configuration\PayPalConfiguration' \ No newline at end of file diff --git a/ps8/controllers/admin/AdminAjaxPrestashopCheckoutController.php b/ps8/controllers/admin/AdminAjaxPrestashopCheckoutController.php index 906ea757c..049820a36 100644 --- a/ps8/controllers/admin/AdminAjaxPrestashopCheckoutController.php +++ b/ps8/controllers/admin/AdminAjaxPrestashopCheckoutController.php @@ -601,56 +601,6 @@ public function ajaxProcessToggleECProductPage() $this->ajaxRender(json_encode(true)); } - /** - * AJAX: Toggle pay later message on order page - */ - public function ajaxProcessTogglePayLaterOrderPageMessage() - { - $this->setConfiguration(PayPalPayLaterConfiguration::PS_CHECKOUT_PAY_LATER_ORDER_PAGE, (bool) Tools::getValue('status')); - - $this->ajaxRender(json_encode(true)); - } - - /** - * AJAX: Toggle pay later message on product page - */ - public function ajaxProcessTogglePayLaterProductPageMessage() - { - $this->setConfiguration(PayPalPayLaterConfiguration::PS_CHECKOUT_PAY_LATER_PRODUCT_PAGE, (bool) Tools::getValue('status')); - - $this->ajaxRender(json_encode(true)); - } - - /** - * AJAX: Toggle pay later banner on home page - */ - public function ajaxProcessTogglePayLaterHomePageBanner() - { - $this->setConfiguration(PayPalPayLaterConfiguration::PS_CHECKOUT_PAY_LATER_HOME_PAGE_BANNER, (bool) Tools::getValue('status')); - - $this->ajaxRender(json_encode(true)); - } - - /** - * AJAX: Toggle pay later banner on cart page - */ - public function ajaxProcessTogglePayLaterOrderPageBanner() - { - $this->setConfiguration(PayPalPayLaterConfiguration::PS_CHECKOUT_PAY_LATER_ORDER_PAGE_BANNER, (bool) Tools::getValue('status')); - - $this->ajaxRender(json_encode(true)); - } - - /** - * AJAX: Toggle pay later banner on product page - */ - public function ajaxProcessTogglePayLaterProductPageBanner() - { - $this->setConfiguration(PayPalPayLaterConfiguration::PS_CHECKOUT_PAY_LATER_PRODUCT_PAGE_BANNER, (bool) Tools::getValue('status')); - - $this->ajaxRender(json_encode(true)); - } - /** * AJAX: Toggle pay later button on cart page */ diff --git a/ps8/ps_checkout.php b/ps8/ps_checkout.php index 10b7ea705..85601822f 100644 --- a/ps8/ps_checkout.php +++ b/ps8/ps_checkout.php @@ -107,7 +107,7 @@ public function __construct() { $this->name = 'ps_checkout'; $this->tab = 'payments_gateways'; - $this->version = '8.5.0.6'; + $this->version = '8.5.1.0'; $this->author = 'PrestaShop'; parent::__construct(); diff --git a/ps8/upgrade/upgrade-8.5.1.0.php b/ps8/upgrade/upgrade-8.5.1.0.php new file mode 100644 index 000000000..15c30f031 --- /dev/null +++ b/ps8/upgrade/upgrade-8.5.1.0.php @@ -0,0 +1,125 @@ + + * @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 8.5.1.0 + * + * @param Ps_checkout $module + * + * @return bool + */ +function upgrade_module_8_5_1_0(Ps_checkout $module) +{ + try { + $savedShopContext = Shop::getContext(); + $savedShopId = Shop::getContextShopID(); + $savedGroupShopId = Shop::getContextShopGroupID(); + Shop::setContext(Shop::CONTEXT_ALL); + $shopsList = \Shop::getShops(false, null, true); + + foreach ($shopsList as $shopId) { + $configuration = json_encode([ + 'cart' => [ + 'placement' => 'cart', + 'status' => (bool) \Configuration::get( + 'PS_CHECKOUT_PAY_LATER_ORDER_PAGE_BANNER', + null, + null, + $shopId + ) ? 'enabled' : 'disabled', + 'layout' => 'text', + 'logo-type' => 'inline', + 'text-color' => 'black', + 'text-size' => '12', + ], + 'category' => [ + 'placement' => 'category', + 'status' => (bool) \Configuration::get( + 'PS_CHECKOUT_PAY_LATER_CATEGORY_PAGE_BANNER', + null, + null, + $shopId + ) ? 'enabled' : 'disabled', + 'color' => 'white', + 'layout' => 'flex', + 'ratio' => '8x1', + ], + 'checkout' => [ + 'placement' => 'checkout', + 'status' => (bool) \Configuration::get( + 'PS_CHECKOUT_PAY_LATER_ORDER_PAGE_BANNER', + null, + null, + $shopId + ) ? 'enabled' : 'disabled', + 'layout' => 'text', + 'logo-type' => 'inline', + 'text-color' => 'black', + 'text-size' => '12', + ], + 'homepage' => [ + 'placement' => 'homepage', + 'status' => (bool) \Configuration::get( + 'PS_CHECKOUT_PAY_LATER_HOME_PAGE_BANNER', + null, + null, + $shopId + ) ? 'enabled' : 'disabled', + 'color' => 'white', + 'layout' => 'flex', + 'ratio' => '8x1', + ], + 'product' => [ + 'placement' => 'product', + 'status' => (bool) \Configuration::get( + 'PS_CHECKOUT_PAY_LATER_PRODUCT_PAGE', + null, + null, + $shopId + ) ? 'enabled' : 'disabled', + 'layout' => 'text', + 'logo-type' => 'inline', + 'text-color' => 'black', + 'text-size' => '12', + ], + ]); + + Configuration::updateValue('PS_CHECKOUT_PAY_LATER_CONFIG', $configuration, false, null, (int) $shopId); + } + + // Restore initial PrestaShop shop context + if (Shop::CONTEXT_SHOP === $savedShopContext) { + Shop::setContext($savedShopContext, $savedShopId); + } elseif (Shop::CONTEXT_GROUP === $savedShopContext) { + Shop::setContext($savedShopContext, $savedGroupShopId); + } else { + Shop::setContext($savedShopContext); + } + } catch (Exception $exception) { + PrestaShopLogger::addLog($exception->getMessage(), 4, 1, 'Module', $module->id); + + return false; + } + + return true; +} diff --git a/ps9/config.xml b/ps9/config.xml index dda163f26..fde773e63 100644 --- a/ps9/config.xml +++ b/ps9/config.xml @@ -2,7 +2,7 @@ ps_checkout - + diff --git a/ps9/config/admin/presenter.yml b/ps9/config/admin/presenter.yml index a5350210d..0444d2809 100644 --- a/ps9/config/admin/presenter.yml +++ b/ps9/config/admin/presenter.yml @@ -19,6 +19,7 @@ services: - '@PsCheckout\Infrastructure\Adapter\Context' - '@PsCheckout\Infrastructure\Adapter\Link' - '@PsCheckout\Infrastructure\Adapter\Configuration' + - '@PsCheckout\Infrastructure\Environment\Env' PsCheckout\Presentation\Presenter\Settings\Admin\Modules\ConfigurationModule: class: PsCheckout\Presentation\Presenter\Settings\Admin\Modules\ConfigurationModule diff --git a/ps9/config/front/configuration.yml b/ps9/config/front/configuration.yml index c93866af4..523880ae7 100644 --- a/ps9/config/front/configuration.yml +++ b/ps9/config/front/configuration.yml @@ -13,3 +13,5 @@ services: - '@PsCheckout\Infrastructure\Repository\PayPalCustomerRepository' - '@PsCheckout\Core\PayPal\OAuth\OAuthService' - '@Psr\Log\LoggerInterface' + - '@PsCheckout\Core\Settings\Configuration\PayPalPayLaterConfiguration' + diff --git a/ps9/config/front/presenter.yml b/ps9/config/front/presenter.yml index 2a3120fb3..0b8e48765 100644 --- a/ps9/config/front/presenter.yml +++ b/ps9/config/front/presenter.yml @@ -40,6 +40,8 @@ services: - '@PsCheckout\Core\Settings\Configuration\PayPalConfiguration' - '@PsCheckout\Presentation\Presenter\FundingSource\FundingSourcePresenter' - '@PsCheckout\Core\Settings\Configuration\PayPalSdkConfiguration' + - '@PsCheckout\Core\Settings\Configuration\PayPalPayLaterConfiguration' + - '@PsCheckout\Infrastructure\Validator\PayLaterValidator' PsCheckout\Presentation\Presenter\Settings\Front\Modules\MediaModule: class: PsCheckout\Presentation\Presenter\Settings\Front\Modules\MediaModule diff --git a/ps9/config/front/validator.yml b/ps9/config/front/validator.yml index 179456f47..381a9568f 100644 --- a/ps9/config/front/validator.yml +++ b/ps9/config/front/validator.yml @@ -6,6 +6,7 @@ services: class: PsCheckout\Infrastructure\Validator\FrontControllerValidator arguments: - '@PsCheckout\Infrastructure\Adapter\Configuration' + - '@PsCheckout\Core\Settings\Configuration\PayPalPayLaterConfiguration' PsCheckout\Core\Order\Validator\OrderAuthorizationValidator: class: PsCheckout\Core\Order\Validator\OrderAuthorizationValidator diff --git a/ps9/config/shared/configuration.yml b/ps9/config/shared/configuration.yml index 08625ca25..222b6438a 100644 --- a/ps9/config/shared/configuration.yml +++ b/ps9/config/shared/configuration.yml @@ -6,3 +6,8 @@ services: class: PsCheckout\Core\Settings\Configuration\PayPalConfiguration arguments: - '@PsCheckout\Infrastructure\Adapter\Configuration' + + PsCheckout\Core\Settings\Configuration\PayPalPayLaterConfiguration: + class: PsCheckout\Core\Settings\Configuration\PayPalPayLaterConfiguration + arguments: + - '@PsCheckout\Infrastructure\Adapter\Configuration' diff --git a/ps9/config/shared/validator.yml b/ps9/config/shared/validator.yml index b12ad128e..d7e5153bd 100644 --- a/ps9/config/shared/validator.yml +++ b/ps9/config/shared/validator.yml @@ -9,4 +9,10 @@ services: - '@PsCheckout\Infrastructure\Repository\PsAccountRepository' PsCheckout\Core\PayPal\Card3DSecure\Card3DSecureValidator: - class: PsCheckout\Core\PayPal\Card3DSecure\Card3DSecureValidator \ No newline at end of file + class: PsCheckout\Core\PayPal\Card3DSecure\Card3DSecureValidator + + PsCheckout\Infrastructure\Validator\PayLaterValidator: + class: PsCheckout\Infrastructure\Validator\PayLaterValidator + arguments: + - '@PsCheckout\Infrastructure\Adapter\Context' + - '@PsCheckout\Core\Settings\Configuration\PayPalConfiguration' \ No newline at end of file diff --git a/ps9/controllers/admin/AdminAjaxPrestashopCheckoutController.php b/ps9/controllers/admin/AdminAjaxPrestashopCheckoutController.php index f64c6f14c..e915939d3 100644 --- a/ps9/controllers/admin/AdminAjaxPrestashopCheckoutController.php +++ b/ps9/controllers/admin/AdminAjaxPrestashopCheckoutController.php @@ -602,56 +602,6 @@ public function ajaxProcessToggleECProductPage() $this->ajaxRender(json_encode(true)); } - /** - * AJAX: Toggle pay later message on order page - */ - public function ajaxProcessTogglePayLaterOrderPageMessage() - { - $this->setConfiguration(PayPalPayLaterConfiguration::PS_CHECKOUT_PAY_LATER_ORDER_PAGE, (bool) Tools::getValue('status')); - - $this->ajaxRender(json_encode(true)); - } - - /** - * AJAX: Toggle pay later message on product page - */ - public function ajaxProcessTogglePayLaterProductPageMessage() - { - $this->setConfiguration(PayPalPayLaterConfiguration::PS_CHECKOUT_PAY_LATER_PRODUCT_PAGE, (bool) Tools::getValue('status')); - - $this->ajaxRender(json_encode(true)); - } - - /** - * AJAX: Toggle pay later banner on home page - */ - public function ajaxProcessTogglePayLaterHomePageBanner() - { - $this->setConfiguration(PayPalPayLaterConfiguration::PS_CHECKOUT_PAY_LATER_HOME_PAGE_BANNER, (bool) Tools::getValue('status')); - - $this->ajaxRender(json_encode(true)); - } - - /** - * AJAX: Toggle pay later banner on cart page - */ - public function ajaxProcessTogglePayLaterOrderPageBanner() - { - $this->setConfiguration(PayPalPayLaterConfiguration::PS_CHECKOUT_PAY_LATER_ORDER_PAGE_BANNER, (bool) Tools::getValue('status')); - - $this->ajaxRender(json_encode(true)); - } - - /** - * AJAX: Toggle pay later banner on product page - */ - public function ajaxProcessTogglePayLaterProductPageBanner() - { - $this->setConfiguration(PayPalPayLaterConfiguration::PS_CHECKOUT_PAY_LATER_PRODUCT_PAGE_BANNER, (bool) Tools::getValue('status')); - - $this->ajaxRender(json_encode(true)); - } - /** * AJAX: Toggle pay later button on cart page */ diff --git a/ps9/ps_checkout.php b/ps9/ps_checkout.php index 90fb079e0..e67e66a8d 100644 --- a/ps9/ps_checkout.php +++ b/ps9/ps_checkout.php @@ -107,7 +107,7 @@ public function __construct() { $this->name = 'ps_checkout'; $this->tab = 'payments_gateways'; - $this->version = '9.5.0.6'; + $this->version = '9.5.1.0'; $this->author = 'PrestaShop'; parent::__construct(); diff --git a/ps9/upgrade/upgrade-9.5.1.0.php b/ps9/upgrade/upgrade-9.5.1.0.php new file mode 100644 index 000000000..56485d4ab --- /dev/null +++ b/ps9/upgrade/upgrade-9.5.1.0.php @@ -0,0 +1,125 @@ + + * @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 9.5.1.0 + * + * @param Ps_checkout $module + * + * @return bool + */ +function upgrade_module_9_5_1_0(Ps_checkout $module) +{ + try { + $savedShopContext = Shop::getContext(); + $savedShopId = Shop::getContextShopID(); + $savedGroupShopId = Shop::getContextShopGroupID(); + Shop::setContext(Shop::CONTEXT_ALL); + $shopsList = \Shop::getShops(false, null, true); + + foreach ($shopsList as $shopId) { + $configuration = json_encode([ + 'cart' => [ + 'placement' => 'cart', + 'status' => (bool) \Configuration::get( + 'PS_CHECKOUT_PAY_LATER_ORDER_PAGE_BANNER', + null, + null, + $shopId + ) ? 'enabled' : 'disabled', + 'layout' => 'text', + 'logo-type' => 'inline', + 'text-color' => 'black', + 'text-size' => '12', + ], + 'category' => [ + 'placement' => 'category', + 'status' => (bool) \Configuration::get( + 'PS_CHECKOUT_PAY_LATER_CATEGORY_PAGE_BANNER', + null, + null, + $shopId + ) ? 'enabled' : 'disabled', + 'color' => 'white', + 'layout' => 'flex', + 'ratio' => '8x1', + ], + 'checkout' => [ + 'placement' => 'checkout', + 'status' => (bool) \Configuration::get( + 'PS_CHECKOUT_PAY_LATER_ORDER_PAGE_BANNER', + null, + null, + $shopId + ) ? 'enabled' : 'disabled', + 'layout' => 'text', + 'logo-type' => 'inline', + 'text-color' => 'black', + 'text-size' => '12', + ], + 'homepage' => [ + 'placement' => 'homepage', + 'status' => (bool) \Configuration::get( + 'PS_CHECKOUT_PAY_LATER_HOME_PAGE_BANNER', + null, + null, + $shopId + ) ? 'enabled' : 'disabled', + 'color' => 'white', + 'layout' => 'flex', + 'ratio' => '8x1', + ], + 'product' => [ + 'placement' => 'product', + 'status' => (bool) \Configuration::get( + 'PS_CHECKOUT_PAY_LATER_PRODUCT_PAGE', + null, + null, + $shopId + ) ? 'enabled' : 'disabled', + 'layout' => 'text', + 'logo-type' => 'inline', + 'text-color' => 'black', + 'text-size' => '12', + ], + ]); + + Configuration::updateValue('PS_CHECKOUT_PAY_LATER_CONFIG', $configuration, false, null, (int) $shopId); + } + + // Restore initial PrestaShop shop context + if (Shop::CONTEXT_SHOP === $savedShopContext) { + Shop::setContext($savedShopContext, $savedShopId); + } elseif (Shop::CONTEXT_GROUP === $savedShopContext) { + Shop::setContext($savedShopContext, $savedGroupShopId); + } else { + Shop::setContext($savedShopContext); + } + } catch (Exception $exception) { + PrestaShopLogger::addLog($exception->getMessage(), 4, 1, 'Module', $module->id); + + return false; + } + + return true; +}