From c3040eb3475f304f095ae87115eff0e8f49779b5 Mon Sep 17 00:00:00 2001 From: Emili Castells Guasch Date: Mon, 3 Feb 2025 12:56:28 +0100 Subject: [PATCH 001/412] Add is new merchant flag option --- modules.php | 4 ++-- woocommerce-paypal-payments.php | 7 +++++++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/modules.php b/modules.php index 21a4e645e..c4886bbc3 100644 --- a/modules.php +++ b/modules.php @@ -93,8 +93,8 @@ return function ( string $root_dir ): iterable { if ( apply_filters( 'woocommerce.feature-flags.woocommerce_paypal_payments.settings_enabled', - getenv( 'PCP_SETTINGS_ENABLED' ) === '1' - ) ) { + getenv( 'PCP_SETTINGS_ENABLED' ) !== '0' + ) && get_option('woocommerce-ppcp-is-new-merchant') === '1') { $modules[] = ( require "$modules_dir/ppcp-settings/module.php" )(); } diff --git a/woocommerce-paypal-payments.php b/woocommerce-paypal-payments.php index d9e1a2277..9d29f92c6 100644 --- a/woocommerce-paypal-payments.php +++ b/woocommerce-paypal-payments.php @@ -229,4 +229,11 @@ define( 'PPCP_PAYPAL_BN_CODE', 'Woo_PPCP' ); return class_exists( 'woocommerce' ); } + // Set new merchant flag on plugin install. + add_action( 'woocommerce_paypal_payments_gateway_migrate', function() { + $legacy_settings = get_option(Settings::KEY); + if(! $legacy_settings) { + update_option('woocommerce-ppcp-is-new-merchant', true); + } + }); } )(); From 9037fa9b7dbb0af8f4ac27079bcfff1d2d68e73a Mon Sep 17 00:00:00 2001 From: Philipp Stracker Date: Mon, 10 Feb 2025 16:27:52 +0100 Subject: [PATCH 002/412] =?UTF-8?q?=F0=9F=A6=BA=20Losen=20the=20validation?= =?UTF-8?q?=20rules=20for=20Client=20ID?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Screens/Onboarding/Components/ManualConnectionForm.js | 2 +- .../ppcp-settings/src/Endpoint/AuthenticationRestEndpoint.php | 1 - modules/ppcp-settings/src/Service/AuthenticationManager.php | 2 +- 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/modules/ppcp-settings/resources/js/Components/Screens/Onboarding/Components/ManualConnectionForm.js b/modules/ppcp-settings/resources/js/Components/Screens/Onboarding/Components/ManualConnectionForm.js index 6602c335b..9524ed553 100644 --- a/modules/ppcp-settings/resources/js/Components/Screens/Onboarding/Components/ManualConnectionForm.js +++ b/modules/ppcp-settings/resources/js/Components/Screens/Onboarding/Components/ManualConnectionForm.js @@ -96,7 +96,7 @@ const ManualConnectionForm = () => { // On-the-fly form validation. useEffect( () => { setClientValid( - ! manualClientId || /^A[\w-]{79}$/.test( manualClientId ) + ! manualClientId || /^[\w-]{80,}$/.test( manualClientId ) ); setSecretValid( manualClientSecret && manualClientSecret.length > 0 ); }, [ manualClientId, manualClientSecret ] ); diff --git a/modules/ppcp-settings/src/Endpoint/AuthenticationRestEndpoint.php b/modules/ppcp-settings/src/Endpoint/AuthenticationRestEndpoint.php index 7ac964b2d..40c82ffab 100644 --- a/modules/ppcp-settings/src/Endpoint/AuthenticationRestEndpoint.php +++ b/modules/ppcp-settings/src/Endpoint/AuthenticationRestEndpoint.php @@ -88,7 +88,6 @@ class AuthenticationRestEndpoint extends RestEndpoint { 'type' => 'string', 'sanitize_callback' => 'sanitize_text_field', 'minLength' => 80, - 'maxLength' => 80, ), 'clientSecret' => array( 'required' => true, diff --git a/modules/ppcp-settings/src/Service/AuthenticationManager.php b/modules/ppcp-settings/src/Service/AuthenticationManager.php index 95acf068b..fc3d8da74 100644 --- a/modules/ppcp-settings/src/Service/AuthenticationManager.php +++ b/modules/ppcp-settings/src/Service/AuthenticationManager.php @@ -147,7 +147,7 @@ class AuthenticationManager { throw new RuntimeException( 'No client ID provided.' ); } - if ( false === preg_match( '/^A[\w-]{79}$/', $client_secret ) ) { + if ( false === preg_match( '/^[\w-]{80,}$/', $client_secret ) ) { throw new RuntimeException( 'Invalid client ID provided.' ); } From 5e6f73d30b64ae3103d95fcfc4eeb7b69e45fa22 Mon Sep 17 00:00:00 2001 From: Philipp Stracker Date: Mon, 10 Feb 2025 16:29:09 +0100 Subject: [PATCH 003/412] =?UTF-8?q?=F0=9F=94=A7=20Fix=20psalm=20errors=20w?= =?UTF-8?q?hen=20node=5Fmodules=20is=20missing?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Due to a modified Mutagen ignore-list, the node_modules folder might not sync with the container; this adjustment fixes psalm errors in those events. --- psalm.xml.dist | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/psalm.xml.dist b/psalm.xml.dist index 46f4e8a49..470d5ceb9 100644 --- a/psalm.xml.dist +++ b/psalm.xml.dist @@ -28,7 +28,7 @@ - + From 91454b64d01e71073d63b000efd1be8a078a03cf Mon Sep 17 00:00:00 2001 From: Emili Castells Guasch Date: Tue, 11 Feb 2025 10:11:01 +0100 Subject: [PATCH 004/412] Add online card payments conditionally --- .../Settings/Tabs/TabPaymentMethods.js | 34 +++++++++++-------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/modules/ppcp-settings/resources/js/Components/Screens/Settings/Tabs/TabPaymentMethods.js b/modules/ppcp-settings/resources/js/Components/Screens/Settings/Tabs/TabPaymentMethods.js index 48da574f0..6b8899ba9 100644 --- a/modules/ppcp-settings/resources/js/Components/Screens/Settings/Tabs/TabPaymentMethods.js +++ b/modules/ppcp-settings/resources/js/Components/Screens/Settings/Tabs/TabPaymentMethods.js @@ -3,7 +3,7 @@ import { useCallback } from '@wordpress/element'; import SettingsCard from '../../../ReusableComponents/SettingsCard'; import { PaymentMethodsBlock } from '../../../ReusableComponents/SettingsBlocks'; -import { PaymentHooks } from '../../../../data'; +import { CommonHooks, PaymentHooks } from '../../../../data'; import { useActiveModal } from '../../../../data/common/hooks'; import Modal from '../Components/Payment/Modal'; @@ -45,6 +45,8 @@ const TabPaymentMethods = () => { [ changePaymentSettings, setActiveModal, setPersistent ] ); + const merchant = CommonHooks.useMerchant(); + return (
{ methods={ methods.paypal } onTriggerModal={ setActiveModal } /> - + { merchant.isBusinessSeller && ( + + ) } Date: Tue, 11 Feb 2025 12:07:47 +0100 Subject: [PATCH 005/412] Overview: Add spinner when waiting for all components to be ready --- .../js/Components/Screens/Settings/Tabs/TabOverview.js | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/modules/ppcp-settings/resources/js/Components/Screens/Settings/Tabs/TabOverview.js b/modules/ppcp-settings/resources/js/Components/Screens/Settings/Tabs/TabOverview.js index 05ba880d5..a5a1014e6 100644 --- a/modules/ppcp-settings/resources/js/Components/Screens/Settings/Tabs/TabOverview.js +++ b/modules/ppcp-settings/resources/js/Components/Screens/Settings/Tabs/TabOverview.js @@ -16,6 +16,7 @@ import { useTodos } from '../../../../data/todos/hooks'; import { useMerchantInfo } from '../../../../data/common/hooks'; import { STORE_NAME as COMMON_STORE_NAME } from '../../../../data/common'; import { STORE_NAME as TODOS_STORE_NAME } from '../../../../data/todos'; +import { CommonHooks, TodosHooks } from '../../../../data'; import { getFeatures } from '../Components/Overview/features-config'; @@ -23,8 +24,16 @@ import { NOTIFICATION_ERROR, NOTIFICATION_SUCCESS, } from '../../../ReusableComponents/Icons'; +import SpinnerOverlay from '../../../ReusableComponents/SpinnerOverlay'; const TabOverview = () => { + const { isReady: areTodosReady } = TodosHooks.useTodos(); + const { isReady: merchantIsReady } = CommonHooks.useMerchantInfo(); + + if ( ! areTodosReady || ! merchantIsReady ) { + return ; + } + return (
From 9ba62a8ebfd242e154ca03408146ae3f74397dcd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20H=C3=BCsken?= Date: Tue, 11 Feb 2025 12:16:22 +0100 Subject: [PATCH 006/412] add SG and HK to some services --- modules/ppcp-applepay/services.php | 2 ++ modules/ppcp-card-fields/services.php | 2 ++ modules/ppcp-googlepay/services.php | 2 ++ 3 files changed, 6 insertions(+) diff --git a/modules/ppcp-applepay/services.php b/modules/ppcp-applepay/services.php index 586a300ae..7e15dfdd9 100644 --- a/modules/ppcp-applepay/services.php +++ b/modules/ppcp-applepay/services.php @@ -191,6 +191,7 @@ return array( 'FR', // France 'DE', // Germany 'GR', // Greece + 'HK', // Hong Kong 'HU', // Hungary 'IE', // Ireland 'IT', // Italy @@ -204,6 +205,7 @@ return array( 'PL', // Poland 'PT', // Portugal 'RO', // Romania + 'SG', // Singapore 'SK', // Slovakia 'SI', // Slovenia 'ES', // Spain diff --git a/modules/ppcp-card-fields/services.php b/modules/ppcp-card-fields/services.php index 1e32cc4f6..d1bf340b3 100644 --- a/modules/ppcp-card-fields/services.php +++ b/modules/ppcp-card-fields/services.php @@ -43,6 +43,7 @@ return array( 'FR', 'DE', 'GR', + 'HK', 'HU', 'IE', 'IT', @@ -56,6 +57,7 @@ return array( 'PT', 'RO', 'SK', + 'SG', 'SI', 'ES', 'SE', diff --git a/modules/ppcp-googlepay/services.php b/modules/ppcp-googlepay/services.php index f92aa0bd8..3a1df9671 100644 --- a/modules/ppcp-googlepay/services.php +++ b/modules/ppcp-googlepay/services.php @@ -106,6 +106,7 @@ return array( 'FR', // France 'DE', // Germany 'GR', // Greece + 'HK', // Hong Kong 'HU', // Hungary 'IE', // Ireland 'IT', // Italy @@ -119,6 +120,7 @@ return array( 'PL', // Poland 'PT', // Portugal 'RO', // Romania + 'SG', // Singapore 'SK', // Slovakia 'SI', // Slovenia 'ES', // Spain From afe05d46976ee190d993407bd604b8e2733da640 Mon Sep 17 00:00:00 2001 From: carmenmaymo Date: Tue, 11 Feb 2025 14:13:53 +0100 Subject: [PATCH 007/412] Add notice if subscription is active --- .../Screens/Onboarding/Steps/StepBusiness.js | 44 ++++++++++++------- 1 file changed, 27 insertions(+), 17 deletions(-) diff --git a/modules/ppcp-settings/resources/js/Components/Screens/Onboarding/Steps/StepBusiness.js b/modules/ppcp-settings/resources/js/Components/Screens/Onboarding/Steps/StepBusiness.js index e15db6088..580ff475c 100644 --- a/modules/ppcp-settings/resources/js/Components/Screens/Onboarding/Steps/StepBusiness.js +++ b/modules/ppcp-settings/resources/js/Components/Screens/Onboarding/Steps/StepBusiness.js @@ -24,6 +24,26 @@ const StepBusiness = ( {} ) => { useEffect( () => { setIsCasualSeller( BUSINESS_TYPES.CASUAL_SELLER === businessChoice ); }, [ businessChoice, setIsCasualSeller ] ); + const { canUseSubscriptions } = OnboardingHooks.useFlags(); + const businessChoices = [ + { + value: BUSINESS_TYPES.BUSINESS, + title: __( 'Business', 'woocommerce-paypal-payments' ), + description: __( + 'Recommended for individuals and organizations that primarily use PayPal to sell goods or services or receive donations, even if your business is not incorporated.', + 'woocommerce-paypal-payments' + ), + }, + { + value: BUSINESS_TYPES.CASUAL_SELLER, + title: __( 'Personal Account', 'woocommerce-paypal-payments' ), + description: __( + 'Ideal for those who primarily make purchases or send personal transactions to family and friends.', + 'woocommerce-paypal-payments' + ), + contents: canUseSubscriptions ? : null, + }, + ]; return (
@@ -45,23 +65,13 @@ const StepBusiness = ( {} ) => { ); }; -const businessChoices = [ - { - value: BUSINESS_TYPES.BUSINESS, - title: __( 'Business', 'woocommerce-paypal-payments' ), - description: __( - 'Recommended for individuals and organizations that primarily use PayPal to sell goods or services or receive donations, even if your business is not incorporated.', +const DetailsAccountType = () => ( +

+ { __( + '* Business account is required for subscriptions.', 'woocommerce-paypal-payments' - ), - }, - { - value: BUSINESS_TYPES.CASUAL_SELLER, - title: __( 'Personal Account', 'woocommerce-paypal-payments' ), - description: __( - 'Ideal for those who primarily make purchases or send personal transactions to family and friends.', - 'woocommerce-paypal-payments' - ), - }, -]; + ) } +

+); export default StepBusiness; From 1ef7141903febb489b5f1863d82b4f232614aa65 Mon Sep 17 00:00:00 2001 From: carmenmaymo Date: Tue, 11 Feb 2025 14:16:23 +0100 Subject: [PATCH 008/412] Disable subscriptions if personal account --- .../Fields/OptionSelector.js | 15 +++- .../Screens/Onboarding/Steps/StepProducts.js | 86 +++++++++++-------- 2 files changed, 60 insertions(+), 41 deletions(-) diff --git a/modules/ppcp-settings/resources/js/Components/ReusableComponents/Fields/OptionSelector.js b/modules/ppcp-settings/resources/js/Components/ReusableComponents/Fields/OptionSelector.js index ba369d0f3..6ecdbdc5d 100644 --- a/modules/ppcp-settings/resources/js/Components/ReusableComponents/Fields/OptionSelector.js +++ b/modules/ppcp-settings/resources/js/Components/ReusableComponents/Fields/OptionSelector.js @@ -9,7 +9,13 @@ const OptionSelector = ( { } ) => (
{ options.map( - ( { value: itemValue, title, description, contents } ) => { + ( { + value: itemValue, + title, + description, + contents, + isDisabled = false, + } ) => { let isSelected; if ( Array.isArray( value ) ) { @@ -27,6 +33,7 @@ const OptionSelector = ( { onChange={ onChange } isMulti={ multiSelect } isSelected={ isSelected } + isDisabled={ isDisabled } > { contents } @@ -46,13 +53,13 @@ const OptionItem = ( { isMulti, isSelected, children, + isDisabled = false, } ) => { const boxClassName = classNames( 'ppcp-r-select-box', { 'ppcp--selected': isSelected, 'ppcp--multiselect': isMulti, 'ppcp--no-title': ! itemTitle, } ); - return ( // eslint-disable-next-line jsx-a11y/label-has-associated-control -- label has a nested input control.