From e4d567d44483226e842693b05ae94bcbc5d3cd1c Mon Sep 17 00:00:00 2001 From: Daniel Dudzic Date: Mon, 20 Jan 2025 16:33:30 +0100 Subject: [PATCH 01/62] Fastlane: Add a check to make sure that the Fastlane SDK token only gets requested for elegible stores --- modules/ppcp-axo-block/src/AxoBlockModule.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/modules/ppcp-axo-block/src/AxoBlockModule.php b/modules/ppcp-axo-block/src/AxoBlockModule.php index af94976a3..7a24c4494 100644 --- a/modules/ppcp-axo-block/src/AxoBlockModule.php +++ b/modules/ppcp-axo-block/src/AxoBlockModule.php @@ -74,6 +74,10 @@ class AxoBlockModule implements ServiceModule, ExtendingModule, ExecutableModule add_filter( 'woocommerce_paypal_payments_localized_script_data', function( array $localized_script_data ) use ( $c ) { + if ( ! $c->has( 'axo.available' ) || ! $c->get( 'axo.available' ) ) { + return $localized_script_data; + } + $module = $this; $api = $c->get( 'api.sdk-client-token' ); assert( $api instanceof SdkClientToken ); From 1938f6b6edc17b82307d5c7b0240e151b82bb93d Mon Sep 17 00:00:00 2001 From: Philipp Stracker Date: Wed, 12 Mar 2025 11:48:15 +0100 Subject: [PATCH 02/62] =?UTF-8?q?=F0=9F=8E=A8=20Make=20condition=20easier?= =?UTF-8?q?=20to=20read?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- modules/ppcp-button/src/Helper/DisabledFundingSources.php | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/modules/ppcp-button/src/Helper/DisabledFundingSources.php b/modules/ppcp-button/src/Helper/DisabledFundingSources.php index 1f5c87afc..63d644bff 100644 --- a/modules/ppcp-button/src/Helper/DisabledFundingSources.php +++ b/modules/ppcp-button/src/Helper/DisabledFundingSources.php @@ -58,11 +58,13 @@ class DisabledFundingSources { ? $this->settings->get( 'disable_funding' ) : array(); - $is_dcc_enabled = $this->settings->has( 'dcc_enabled' ) && $this->settings->get( 'dcc_enabled' ); + $is_dcc_enabled = $this->settings->has( 'dcc_enabled' ) && $this->settings->get( 'dcc_enabled' ); + $is_checkout = is_checkout(); + $is_block_context = in_array( $context, array( 'checkout-block', 'cart-block' ), true ); if ( - ! is_checkout() - || ( $is_dcc_enabled && in_array( $context, array( 'checkout-block', 'cart-block' ), true ) ) + ! $is_checkout + || ( $is_dcc_enabled && $is_block_context ) ) { $disable_funding[] = 'card'; } From 6da8988e0ab39c0e5c17490b728394eba9ab52b7 Mon Sep 17 00:00:00 2001 From: Philipp Stracker Date: Wed, 12 Mar 2025 11:59:10 +0100 Subject: [PATCH 03/62] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20Improve=20readabilit?= =?UTF-8?q?y=20and=20code=20structure?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/Helper/DisabledFundingSources.php | 81 +++++++++++-------- 1 file changed, 48 insertions(+), 33 deletions(-) diff --git a/modules/ppcp-button/src/Helper/DisabledFundingSources.php b/modules/ppcp-button/src/Helper/DisabledFundingSources.php index 63d644bff..54e35f718 100644 --- a/modules/ppcp-button/src/Helper/DisabledFundingSources.php +++ b/modules/ppcp-button/src/Helper/DisabledFundingSources.php @@ -58,52 +58,67 @@ class DisabledFundingSources { ? $this->settings->get( 'disable_funding' ) : array(); - $is_dcc_enabled = $this->settings->has( 'dcc_enabled' ) && $this->settings->get( 'dcc_enabled' ); - $is_checkout = is_checkout(); - $is_block_context = in_array( $context, array( 'checkout-block', 'cart-block' ), true ); + // Determine context flags. + $is_checkout_page = is_checkout(); + $is_block_context = in_array( $context, array( 'checkout-block', 'cart-block' ), true ); + $is_classic_checkout = $is_checkout_page && ! $is_block_context; - if ( - ! $is_checkout - || ( $is_dcc_enabled && $is_block_context ) - ) { - $disable_funding[] = 'card'; - } + // Determine payment method availability flags. + $is_dcc_enabled = $this->settings->has( 'dcc_enabled' ) && $this->settings->get( 'dcc_enabled' ); + $available_gateways = WC()->payment_gateways->get_available_payment_gateways(); + $is_card_gateway_enabled = isset( $available_gateways[ CardButtonGateway::ID ] ); + $is_using_cards = $is_dcc_enabled || $is_card_gateway_enabled; - $available_gateways = WC()->payment_gateways->get_available_payment_gateways(); - $is_separate_card_enabled = isset( $available_gateways[ CardButtonGateway::ID ] ); + // Check if card is already in disabled funding (from settings value). + $card_key = array_search( 'card', $disable_funding, true ); + $is_card_disabled = ( $card_key !== false ); - if ( - ( - is_checkout() - && ! in_array( $context, array( 'checkout-block', 'cart-block' ), true ) - ) - && ( - $is_dcc_enabled - || $is_separate_card_enabled - ) - ) { - $key = array_search( 'card', $disable_funding, true ); - if ( false !== $key ) { - unset( $disable_funding[ $key ] ); + if ( $is_block_context && $is_dcc_enabled ) { + // Rule 1: Block checkout with DCC - do not load ACDC. + if ( ! $is_card_disabled ) { + $disable_funding[] = 'card'; + } + } elseif ( ! $is_checkout_page ) { + // Rule 2: Non-checkout pages - do not load ACDC. + if ( ! $is_card_disabled ) { + $disable_funding[] = 'card'; + } + } elseif ( $is_classic_checkout && $is_using_cards ) { + // Rule 3: Standard checkout with card methods - load ACDC. + if ( $is_card_disabled ) { + unset( $disable_funding[ $card_key ] ); } } - if ( in_array( $context, array( 'checkout-block', 'cart-block' ), true ) ) { + /** + * Block checkout only supports the following funding methods: + * - PayPal + * - PayLater + * - Venmo + * - ACDC ("card", conditionally) + */ + if ( $is_block_context ) { + $allowed_in_blocks = array( 'venmo', 'paylater', 'paypal', 'card' ); + $disable_funding = array_merge( $disable_funding, - array_diff( - array_keys( $this->all_funding_sources ), - array( 'venmo', 'paylater', 'paypal', 'card' ) - ) + array_diff( array_keys( $this->all_funding_sources ), $allowed_in_blocks ) ); } + /** + * Free trials only support the funding method ACDC ("card"). + */ if ( $this->is_free_trial_cart() ) { - $all_sources = array_keys( $this->all_funding_sources ); - if ( $is_dcc_enabled || $is_separate_card_enabled ) { - $all_sources = array_diff( $all_sources, array( 'card' ) ); + $disable_funding = array_keys( $this->all_funding_sources ); + + if ( $is_using_cards ) { + $card_key = array_search( 'card', $disable_funding, true ); + + if ( false !== $card_key ) { + unset( $disable_funding[ $card_key ] ); + } } - $disable_funding = $all_sources; } return apply_filters( 'woocommerce_paypal_payments_disabled_funding_sources', $disable_funding ); From e2fbeffcdd298db7429defdd6aab1b0302705710 Mon Sep 17 00:00:00 2001 From: Philipp Stracker Date: Wed, 12 Mar 2025 13:42:24 +0100 Subject: [PATCH 04/62] =?UTF-8?q?=F0=9F=94=A5=20Remove=20incorrect=20filte?= =?UTF-8?q?r?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The filter solved a wrong problem: It only hides the BCDC button, while the solution would be to disable the entire BCDC gateway. --- modules/ppcp-settings/src/SettingsModule.php | 29 -------------------- 1 file changed, 29 deletions(-) diff --git a/modules/ppcp-settings/src/SettingsModule.php b/modules/ppcp-settings/src/SettingsModule.php index 9008facd8..e8c2b8641 100644 --- a/modules/ppcp-settings/src/SettingsModule.php +++ b/modules/ppcp-settings/src/SettingsModule.php @@ -552,35 +552,6 @@ class SettingsModule implements ServiceModule, ExecutableModule { ); } - /** - * Unsets the BCDC black button if merchant is eligible for ACDC. - */ - add_filter( - 'woocommerce_paypal_payments_disabled_funding_sources', - /** - * Unsets the BCDC black button if merchant is eligible for ACDC. - * - * @param int[]|string[]|mixed $disable_funding The disabled funding sources. - * @return int[]|string[]|mixed The disabled funding sources. - * - * @psalm-suppress MissingClosureParamType - */ - static function ( $disable_funding ) use ( $container ) { - if ( ! is_array( $disable_funding ) || in_array( 'card', $disable_funding, true ) ) { - return $disable_funding; - } - - $dcc_product_status = $container->get( 'wcgateway.helper.dcc-product-status' ); - assert( $dcc_product_status instanceof DCCProductStatus ); - - if ( $dcc_product_status->is_active() ) { - $disable_funding[] = 'card'; - } - - return $disable_funding; - } - ); - // Enable Fastlane after onboarding if the store is compatible. add_action( 'woocommerce_paypal_payments_apply_default_configuration', From f178636951097e7c38aa66ade5f2a22b02dd17b0 Mon Sep 17 00:00:00 2001 From: Philipp Stracker Date: Wed, 12 Mar 2025 14:21:29 +0100 Subject: [PATCH 05/62] =?UTF-8?q?=F0=9F=92=A1=20Fix=20typo=20in=20comment?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- modules/ppcp-settings/src/SettingsModule.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/ppcp-settings/src/SettingsModule.php b/modules/ppcp-settings/src/SettingsModule.php index e8c2b8641..9041a7c15 100644 --- a/modules/ppcp-settings/src/SettingsModule.php +++ b/modules/ppcp-settings/src/SettingsModule.php @@ -394,7 +394,7 @@ class SettingsModule implements ServiceModule, ExecutableModule { unset( $payment_methods[ OXXO::ID ] ); } - // Unset Pay Unon Invoice if merchant country is not Germany. + // Unset Pay Upon Invoice if merchant country is not Germany. if ( 'DE' !== $merchant_country ) { unset( $payment_methods[ PayUponInvoiceGateway::ID ] ); } From a5ee2e29d5f0d7428ee2fdc8f9eeb70f7ff2b2f4 Mon Sep 17 00:00:00 2001 From: Philipp Stracker Date: Wed, 12 Mar 2025 14:36:41 +0100 Subject: [PATCH 06/62] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20Never=20disable=20fu?= =?UTF-8?q?nding=20source=20=E2=80=9Cpaypal=E2=80=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Consolidate funding source logic into the responsible class --- .../ppcp-button/src/Assets/SmartButton.php | 14 ------- .../src/Helper/DisabledFundingSources.php | 39 +++++++++++-------- 2 files changed, 22 insertions(+), 31 deletions(-) diff --git a/modules/ppcp-button/src/Assets/SmartButton.php b/modules/ppcp-button/src/Assets/SmartButton.php index 81ced3a68..3375ecd31 100644 --- a/modules/ppcp-button/src/Assets/SmartButton.php +++ b/modules/ppcp-button/src/Assets/SmartButton.php @@ -1455,20 +1455,6 @@ document.querySelector("#payment").before(document.querySelector(".ppcp-messages $disabled_funding_sources[] = 'paylater'; } - $disabled_funding_sources = array_filter( - $disabled_funding_sources, - /** - * Make sure paypal is not sent in disable funding. - * - * @param string $funding_source The funding_source. - * - * @psalm-suppress MissingClosureParamType - */ - function( $funding_source ) { - return $funding_source !== 'paypal'; - } - ); - if ( count( $disabled_funding_sources ) > 0 ) { $params['disable-funding'] = implode( ',', array_unique( $disabled_funding_sources ) ); } diff --git a/modules/ppcp-button/src/Helper/DisabledFundingSources.php b/modules/ppcp-button/src/Helper/DisabledFundingSources.php index 54e35f718..9d4863838 100644 --- a/modules/ppcp-button/src/Helper/DisabledFundingSources.php +++ b/modules/ppcp-button/src/Helper/DisabledFundingSources.php @@ -5,7 +5,7 @@ * @package WooCommerce\PayPalCommerce\Button\Helper */ -declare(strict_types=1); +declare( strict_types = 1 ); namespace WooCommerce\PayPalCommerce\Button\Helper; @@ -38,7 +38,7 @@ class DisabledFundingSources { /** * DisabledFundingSources constructor. * - * @param Settings $settings The settings. + * @param Settings $settings The settings. * @param array $all_funding_sources All existing funding sources. */ public function __construct( Settings $settings, array $all_funding_sources ) { @@ -69,25 +69,22 @@ class DisabledFundingSources { $is_card_gateway_enabled = isset( $available_gateways[ CardButtonGateway::ID ] ); $is_using_cards = $is_dcc_enabled || $is_card_gateway_enabled; - // Check if card is already in disabled funding (from settings value). - $card_key = array_search( 'card', $disable_funding, true ); - $is_card_disabled = ( $card_key !== false ); - if ( $is_block_context && $is_dcc_enabled ) { // Rule 1: Block checkout with DCC - do not load ACDC. - if ( ! $is_card_disabled ) { + if ( ! in_array( 'card', $disable_funding, true ) ) { $disable_funding[] = 'card'; } } elseif ( ! $is_checkout_page ) { // Rule 2: Non-checkout pages - do not load ACDC. - if ( ! $is_card_disabled ) { + if ( ! in_array( 'card', $disable_funding, true ) ) { $disable_funding[] = 'card'; } } elseif ( $is_classic_checkout && $is_using_cards ) { // Rule 3: Standard checkout with card methods - load ACDC. - if ( $is_card_disabled ) { - unset( $disable_funding[ $card_key ] ); - } + $disable_funding = array_filter( + $disable_funding, + static fn( string $funding_source ) => $funding_source !== 'card' + ); } /** @@ -113,14 +110,22 @@ class DisabledFundingSources { $disable_funding = array_keys( $this->all_funding_sources ); if ( $is_using_cards ) { - $card_key = array_search( 'card', $disable_funding, true ); - - if ( false !== $card_key ) { - unset( $disable_funding[ $card_key ] ); - } + $disable_funding = array_filter( + $disable_funding, + static fn( string $funding_source ) => $funding_source !== 'card' + ); } } - return apply_filters( 'woocommerce_paypal_payments_disabled_funding_sources', $disable_funding ); + $disable_funding = apply_filters( + 'woocommerce_paypal_payments_disabled_funding_sources', + $disable_funding + ); + + // Make sure "paypal" is never disabled in the funding-sources. + return array_filter( + $disable_funding, + static fn( string $funding_source ) => $funding_source !== 'paypal' + ); } } From 3a652f30b579fa293f850bc92dba9dfae11085b4 Mon Sep 17 00:00:00 2001 From: Philipp Stracker Date: Wed, 12 Mar 2025 14:53:13 +0100 Subject: [PATCH 07/62] =?UTF-8?q?=F0=9F=8E=A8=20Fix=20phpcs=20suggestions?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- modules/ppcp-button/src/Helper/DisabledFundingSources.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/ppcp-button/src/Helper/DisabledFundingSources.php b/modules/ppcp-button/src/Helper/DisabledFundingSources.php index 9d4863838..7ec303151 100644 --- a/modules/ppcp-button/src/Helper/DisabledFundingSources.php +++ b/modules/ppcp-button/src/Helper/DisabledFundingSources.php @@ -26,14 +26,14 @@ class DisabledFundingSources { * * @var Settings */ - private $settings; + private Settings $settings; /** * All existing funding sources. * * @var array */ - private $all_funding_sources; + private array $all_funding_sources; /** * DisabledFundingSources constructor. From 11f91eed626fb0ea08cd90134aa8edd480bc3b47 Mon Sep 17 00:00:00 2001 From: Philipp Stracker Date: Wed, 12 Mar 2025 15:58:39 +0100 Subject: [PATCH 08/62] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20Refactor=20the=20Dis?= =?UTF-8?q?abledFundingSources=20class?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Split the code into small, documented functions to make the decision flow and data-relationship clearer --- .../src/Helper/DisabledFundingSources.php | 164 ++++++++++++++---- 1 file changed, 133 insertions(+), 31 deletions(-) diff --git a/modules/ppcp-button/src/Helper/DisabledFundingSources.php b/modules/ppcp-button/src/Helper/DisabledFundingSources.php index 7ec303151..3ef1a1826 100644 --- a/modules/ppcp-button/src/Helper/DisabledFundingSources.php +++ b/modules/ppcp-button/src/Helper/DisabledFundingSources.php @@ -50,36 +50,133 @@ class DisabledFundingSources { * Returns the list of funding sources to be disabled. * * @param string $context The context. - * @return array|int[]|mixed|string[] - * @throws NotFoundException When the setting is not found. + * @return string[] List of disabled sources */ - public function sources( string $context ) { - $disable_funding = $this->settings->has( 'disable_funding' ) - ? $this->settings->get( 'disable_funding' ) - : array(); + public function sources( string $context ) : array { + // Free trials have a shorter, special funding-source rule. + if ( $this->is_free_trial_cart() ) { + $disable_funding = $this->get_sources_for_free_trial(); - // Determine context flags. + return $this->sanitize_and_filter_sources( $disable_funding ); + } + + $disable_funding = $this->get_sources_from_settings(); + $payment_flags = $this->get_payment_method_flags(); + $context_flags = $this->get_context_flags( $context ); + + // Apply rules based on context and payment methods. + $disable_funding = $this->apply_context_rules( + $disable_funding, + $context_flags, + $payment_flags + ); + + // Apply special rules for block checkout. + if ( $context_flags['is_block_context'] ) { + $disable_funding = $this->apply_block_checkout_rules( $disable_funding ); + } + + return $this->sanitize_and_filter_sources( $disable_funding ); + } + + /** + * Gets disabled funding sources from settings. + * + * @return array + */ + private function get_sources_from_settings() : array { + try { + return $this->settings->has( 'disable_funding' ) + ? $this->settings->get( 'disable_funding' ) + : array(); + } catch ( NotFoundException $exception ) { + return array(); + } + } + + /** + * Gets disabled funding sources for free trial carts. + * + * Rule: Carts that include a free trial product can ONLY use the + * funding source "card" - all other sources are disabled. + * + * @return array + */ + private function get_sources_for_free_trial() : array { + $disable_funding = array_keys( $this->all_funding_sources ); + $payment_flags = $this->get_payment_method_flags(); + + if ( $payment_flags['is_using_cards'] ) { + $disable_funding = array_filter( + $disable_funding, + static fn( string $funding_source ) => $funding_source !== 'card' + ); + } + + return $disable_funding; + } + + /** + * Gets context flags based on the current page and context. + * + * @param string $context The context. + * @return array + */ + private function get_context_flags( string $context ) : array { $is_checkout_page = is_checkout(); $is_block_context = in_array( $context, array( 'checkout-block', 'cart-block' ), true ); $is_classic_checkout = $is_checkout_page && ! $is_block_context; - // Determine payment method availability flags. - $is_dcc_enabled = $this->settings->has( 'dcc_enabled' ) && $this->settings->get( 'dcc_enabled' ); + return array( + 'is_checkout_page' => $is_checkout_page, + 'is_block_context' => $is_block_context, + 'is_classic_checkout' => $is_classic_checkout, + ); + } + + /** + * Gets payment method availability flags. + * + * @return array + */ + private function get_payment_method_flags() : array { + try { + $is_dcc_enabled = $this->settings->get( 'dcc_enabled' ); + } catch ( NotFoundException $exception ) { + $is_dcc_enabled = false; + } + $available_gateways = WC()->payment_gateways->get_available_payment_gateways(); $is_card_gateway_enabled = isset( $available_gateways[ CardButtonGateway::ID ] ); $is_using_cards = $is_dcc_enabled || $is_card_gateway_enabled; - if ( $is_block_context && $is_dcc_enabled ) { + return array( + 'is_dcc_enabled' => $is_dcc_enabled, + 'is_card_gateway_enabled' => $is_card_gateway_enabled, + 'is_using_cards' => $is_using_cards, + ); + } + + /** + * Applies rules based on context and payment methods. + * + * @param array $disable_funding The current disabled funding sources. + * @param array $context_flags Context flags. + * @param array $payment_flags Payment method flags. + * @return array + */ + private function apply_context_rules( array $disable_funding, array $context_flags, array $payment_flags ) : array { + if ( $context_flags['is_block_context'] && $payment_flags['is_dcc_enabled'] ) { // Rule 1: Block checkout with DCC - do not load ACDC. if ( ! in_array( 'card', $disable_funding, true ) ) { $disable_funding[] = 'card'; } - } elseif ( ! $is_checkout_page ) { + } elseif ( ! $context_flags['is_checkout_page'] ) { // Rule 2: Non-checkout pages - do not load ACDC. if ( ! in_array( 'card', $disable_funding, true ) ) { $disable_funding[] = 'card'; } - } elseif ( $is_classic_checkout && $is_using_cards ) { + } elseif ( $context_flags['is_classic_checkout'] && $payment_flags['is_using_cards'] ) { // Rule 3: Standard checkout with card methods - load ACDC. $disable_funding = array_filter( $disable_funding, @@ -87,6 +184,16 @@ class DisabledFundingSources { ); } + return $disable_funding; + } + + /** + * Applies special rules for block checkout. + * + * @param array $disable_funding The current disabled funding sources. + * @return array + */ + private function apply_block_checkout_rules( array $disable_funding ) : array { /** * Block checkout only supports the following funding methods: * - PayPal @@ -94,29 +201,24 @@ class DisabledFundingSources { * - Venmo * - ACDC ("card", conditionally) */ - if ( $is_block_context ) { - $allowed_in_blocks = array( 'venmo', 'paylater', 'paypal', 'card' ); + $allowed_in_blocks = array( 'venmo', 'paylater', 'paypal', 'card' ); - $disable_funding = array_merge( - $disable_funding, - array_diff( array_keys( $this->all_funding_sources ), $allowed_in_blocks ) - ); - } + return array_merge( + $disable_funding, + array_diff( array_keys( $this->all_funding_sources ), $allowed_in_blocks ) + ); + } + /** + * Filters the disabled "funding-sources" list and returns a sanitized array. + * + * @param array $disable_funding The disabled funding sources. + * @return string[] + */ + private function sanitize_and_filter_sources( array $disable_funding ) : array { /** - * Free trials only support the funding method ACDC ("card"). + * Filters the final list of disabled funding sources. */ - if ( $this->is_free_trial_cart() ) { - $disable_funding = array_keys( $this->all_funding_sources ); - - if ( $is_using_cards ) { - $disable_funding = array_filter( - $disable_funding, - static fn( string $funding_source ) => $funding_source !== 'card' - ); - } - } - $disable_funding = apply_filters( 'woocommerce_paypal_payments_disabled_funding_sources', $disable_funding From 791a5d33da4aea338abff9f295e00f2bfa774f26 Mon Sep 17 00:00:00 2001 From: Philipp Stracker Date: Wed, 12 Mar 2025 17:04:38 +0100 Subject: [PATCH 09/62] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20Make=20DCC=20check?= =?UTF-8?q?=20clearer=20in=20SmartButton=20class?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Done during debugging to better understand the data flow, does not change/solve anything --- .../ppcp-button/src/Assets/SmartButton.php | 30 +++++++++++-------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/modules/ppcp-button/src/Assets/SmartButton.php b/modules/ppcp-button/src/Assets/SmartButton.php index 3375ecd31..f95eeacfd 100644 --- a/modules/ppcp-button/src/Assets/SmartButton.php +++ b/modules/ppcp-button/src/Assets/SmartButton.php @@ -1575,6 +1575,7 @@ document.querySelector("#payment").before(document.querySelector(".ppcp-messages if ( $this->dcc_is_enabled() ) { $components[] = 'hosted-fields'; } + /** * Filter to add further components from the extensions. * @@ -1597,24 +1598,27 @@ document.querySelector("#payment").before(document.querySelector(".ppcp-messages * * @return bool */ - private function dcc_is_enabled(): bool { - if ( ! is_checkout() ) { + private function dcc_is_enabled() : bool { + // Card payments are only available on the checkout page, and for certain seller countries. + if ( ! is_checkout() || ! $this->dcc_applies->for_country_currency() ) { return false; } - if ( ! $this->dcc_applies->for_country_currency() ) { - return false; - } - $keys = array( - 'client_id', - 'client_secret', - 'dcc_enabled', - ); - foreach ( $keys as $key ) { - if ( ! $this->settings->has( $key ) || ! $this->settings->get( $key ) ) { + + try { + // Bail, if the merchant is not fully onboarded yet. + if ( + ! $this->settings->get( 'client_id' ) + || ! $this->settings->get( 'client_secret' ) + ) { return false; } + + // The actual condition that must be met. + return (bool) $this->settings->get( 'dcc_enabled' ); + } catch ( NotFoundException $e ) { + // Bail, if the settings DB entries are missing. + return false; } - return true; } /** From de46e4ed088ceeaa1e7e29d9d3a20526705029e4 Mon Sep 17 00:00:00 2001 From: Philipp Stracker Date: Wed, 12 Mar 2025 17:33:44 +0100 Subject: [PATCH 10/62] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20Improve=20SDK=20comp?= =?UTF-8?q?onent=20inject=20logic?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Just make the filter callback more readable, still no change in the plugin logic --- .../ppcp-card-fields/src/CardFieldsModule.php | 21 +++++++++++-------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/modules/ppcp-card-fields/src/CardFieldsModule.php b/modules/ppcp-card-fields/src/CardFieldsModule.php index f87655f72..28354d9a6 100644 --- a/modules/ppcp-card-fields/src/CardFieldsModule.php +++ b/modules/ppcp-card-fields/src/CardFieldsModule.php @@ -53,19 +53,22 @@ class CardFieldsModule implements ServiceModule, ExtendingModule, ExecutableModu */ add_filter( 'woocommerce_paypal_payments_sdk_components_hook', - function( $components ) use ( $c ) { - if ( ! $c->get( 'wcgateway.configuration.dcc' )->is_enabled() ) { + static function( $components ) use ( $c ) { + $dcc_config = $c->get( 'wcgateway.configuration.dcc' ); + assert( $dcc_config instanceof DCCGatewayConfiguration ); + + if ( ! $dcc_config->is_enabled() ) { return $components; } - if ( in_array( 'hosted-fields', $components, true ) ) { - $key = array_search( 'hosted-fields', $components, true ); - if ( $key !== false ) { - unset( $components[ $key ] ); - } - } + + // Enable the new "card-fields" component. $components[] = 'card-fields'; - return $components; + // Ensure the older "hosted-fields" component is not loaded. + return array_filter( + $components, + static fn( string $component ) => $component !== 'hosted-fields' + ); } ); From 201f5ab20c15640953cb52257004f5fafc54746a Mon Sep 17 00:00:00 2001 From: Philipp Stracker Date: Wed, 12 Mar 2025 18:31:11 +0100 Subject: [PATCH 11/62] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20Implement=20DCCGatew?= =?UTF-8?q?ayConfiguration=20service?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Instead of fixing incorrect conditions in different files, we want to use a single source of truth for the DCC status --- modules/ppcp-button/services.php | 3 +- .../src/Helper/DisabledFundingSources.php | 52 +++++++++++-------- modules/ppcp-wc-gateway/services.php | 4 +- .../GatewayWithoutPayPalAdminNotice.php | 25 ++++++--- 4 files changed, 52 insertions(+), 32 deletions(-) diff --git a/modules/ppcp-button/services.php b/modules/ppcp-button/services.php index 44e9a52ac..098679c21 100644 --- a/modules/ppcp-button/services.php +++ b/modules/ppcp-button/services.php @@ -343,7 +343,8 @@ return array( 'button.helper.disabled-funding-sources' => static function ( ContainerInterface $container ): DisabledFundingSources { return new DisabledFundingSources( $container->get( 'wcgateway.settings' ), - $container->get( 'wcgateway.all-funding-sources' ) + $container->get( 'wcgateway.all-funding-sources' ), + $container->get( 'wcgateway.configuration.dcc' ) ); }, 'button.is-logged-in' => static function ( ContainerInterface $container ): bool { diff --git a/modules/ppcp-button/src/Helper/DisabledFundingSources.php b/modules/ppcp-button/src/Helper/DisabledFundingSources.php index 3ef1a1826..bc261589c 100644 --- a/modules/ppcp-button/src/Helper/DisabledFundingSources.php +++ b/modules/ppcp-button/src/Helper/DisabledFundingSources.php @@ -13,6 +13,7 @@ use WooCommerce\PayPalCommerce\WcGateway\Exception\NotFoundException; use WooCommerce\PayPalCommerce\WcGateway\Gateway\CardButtonGateway; use WooCommerce\PayPalCommerce\WcGateway\Settings\Settings; use WooCommerce\PayPalCommerce\WcSubscriptions\FreeTrialHandlerTrait; +use WooCommerce\PayPalCommerce\WcGateway\Helper\DCCGatewayConfiguration; /** * Class DisabledFundingSources @@ -35,15 +36,24 @@ class DisabledFundingSources { */ private array $all_funding_sources; + /** + * Provides details about the DCC configuration. + * + * @var DCCGatewayConfiguration + */ + private DCCGatewayConfiguration $dcc_configuration; + /** * DisabledFundingSources constructor. * - * @param Settings $settings The settings. - * @param array $all_funding_sources All existing funding sources. + * @param Settings $settings The settings. + * @param array $all_funding_sources All existing funding sources. + * @param DCCGatewayConfiguration $dcc_configuration DCC gateway configuration. */ - public function __construct( Settings $settings, array $all_funding_sources ) { + public function __construct( Settings $settings, array $all_funding_sources, DCCGatewayConfiguration $dcc_configuration ) { $this->settings = $settings; $this->all_funding_sources = $all_funding_sources; + $this->dcc_configuration = $dcc_configuration; } /** @@ -140,20 +150,18 @@ class DisabledFundingSources { * @return array */ private function get_payment_method_flags() : array { - try { - $is_dcc_enabled = $this->settings->get( 'dcc_enabled' ); - } catch ( NotFoundException $exception ) { - $is_dcc_enabled = false; - } + $is_dcc_enabled = $this->dcc_configuration->is_enabled(); + $available_gateways = WC()->payment_gateways->get_available_payment_gateways(); - $available_gateways = WC()->payment_gateways->get_available_payment_gateways(); + // TODO: This check does not make much sense in the new UI. The gateway is always available when the "dcc_enabled" flag is true. $is_card_gateway_enabled = isset( $available_gateways[ CardButtonGateway::ID ] ); - $is_using_cards = $is_dcc_enabled || $is_card_gateway_enabled; return array( - 'is_dcc_enabled' => $is_dcc_enabled, - 'is_card_gateway_enabled' => $is_card_gateway_enabled, - 'is_using_cards' => $is_using_cards, + // Whether the new Advanced Card Processing gateway is active. + 'is_dcc_enabled' => $is_dcc_enabled, + + // Whether card payments are generally used (DCC or BCDC). + 'is_using_cards' => $is_dcc_enabled || $is_card_gateway_enabled, ); } @@ -167,17 +175,13 @@ class DisabledFundingSources { */ private function apply_context_rules( array $disable_funding, array $context_flags, array $payment_flags ) : array { if ( $context_flags['is_block_context'] && $payment_flags['is_dcc_enabled'] ) { - // Rule 1: Block checkout with DCC - do not load ACDC. - if ( ! in_array( 'card', $disable_funding, true ) ) { - $disable_funding[] = 'card'; - } + // Rule 1: Block checkout with DCC - do not load card payments. + $disable_funding[] = 'card'; } elseif ( ! $context_flags['is_checkout_page'] ) { - // Rule 2: Non-checkout pages - do not load ACDC. - if ( ! in_array( 'card', $disable_funding, true ) ) { - $disable_funding[] = 'card'; - } + // Rule 2: Non-checkout pages - do not load card payments. + $disable_funding[] = 'card'; } elseif ( $context_flags['is_classic_checkout'] && $payment_flags['is_using_cards'] ) { - // Rule 3: Standard checkout with card methods - load ACDC. + // Rule 3: Standard checkout with card methods - load card payments. $disable_funding = array_filter( $disable_funding, static fn( string $funding_source ) => $funding_source !== 'card' @@ -225,9 +229,11 @@ class DisabledFundingSources { ); // Make sure "paypal" is never disabled in the funding-sources. - return array_filter( + $disable_funding = array_filter( $disable_funding, static fn( string $funding_source ) => $funding_source !== 'paypal' ); + + return array_unique( $disable_funding ); } } diff --git a/modules/ppcp-wc-gateway/services.php b/modules/ppcp-wc-gateway/services.php index 9bb5ae0c9..43e447f86 100644 --- a/modules/ppcp-wc-gateway/services.php +++ b/modules/ppcp-wc-gateway/services.php @@ -333,7 +333,8 @@ return array( $container->get( 'settings.flag.is-connected' ), $container->get( 'wcgateway.settings' ), $container->get( 'wcgateway.is-wc-payments-page' ), - $container->get( 'wcgateway.is-ppcp-settings-page' ) + $container->get( 'wcgateway.is-ppcp-settings-page' ), + $container->get( 'wcgateway.configuration.dcc' ) ); }, 'wcgateway.notice.card-button-without-paypal' => static function ( ContainerInterface $container ): GatewayWithoutPayPalAdminNotice { @@ -343,6 +344,7 @@ return array( $container->get( 'wcgateway.settings' ), $container->get( 'wcgateway.is-wc-payments-page' ), $container->get( 'wcgateway.is-ppcp-settings-page' ), + $container->get( 'wcgateway.configuration.dcc' ), $container->get( 'wcgateway.settings.status' ) ); }, diff --git a/modules/ppcp-wc-gateway/src/Notice/GatewayWithoutPayPalAdminNotice.php b/modules/ppcp-wc-gateway/src/Notice/GatewayWithoutPayPalAdminNotice.php index 627d23e97..24ab7c68c 100644 --- a/modules/ppcp-wc-gateway/src/Notice/GatewayWithoutPayPalAdminNotice.php +++ b/modules/ppcp-wc-gateway/src/Notice/GatewayWithoutPayPalAdminNotice.php @@ -13,6 +13,7 @@ use WC_Payment_Gateway; use WooCommerce\PayPalCommerce\AdminNotices\Entity\Message; use WooCommerce\PayPalCommerce\Vendor\Psr\Container\ContainerInterface; use WooCommerce\PayPalCommerce\WcGateway\Helper\SettingsStatus; +use WooCommerce\PayPalCommerce\WcGateway\Helper\DCCGatewayConfiguration; /** * Creates the admin message about the gateway being enabled without the PayPal gateway. @@ -65,15 +66,23 @@ class GatewayWithoutPayPalAdminNotice { */ protected $settings_status; + /** + * Provides details about the DCC configuration. + * + * @var DCCGatewayConfiguration + */ + private DCCGatewayConfiguration $dcc_configuration; + /** * ConnectAdminNotice constructor. * - * @param string $id The gateway ID. - * @param bool $is_connected Whether onboading was completed. - * @param ContainerInterface $settings The settings. - * @param bool $is_payments_page Whether the current page is the WC payment page. - * @param bool $is_ppcp_settings_page Whether the current page is the PPCP settings page. - * @param SettingsStatus|null $settings_status The Settings status helper. + * @param string $id The gateway ID. + * @param bool $is_connected Whether onboading was completed. + * @param ContainerInterface $settings The settings. + * @param bool $is_payments_page Whether the current page is the WC payment page. + * @param bool $is_ppcp_settings_page Whether the current page is the PPCP settings page. + * @param DCCGatewayConfiguration $dcc_configuration DCC gateway configuration. + * @param SettingsStatus|null $settings_status The Settings status helper. */ public function __construct( string $id, @@ -81,6 +90,7 @@ class GatewayWithoutPayPalAdminNotice { ContainerInterface $settings, bool $is_payments_page, bool $is_ppcp_settings_page, + DCCGatewayConfiguration $dcc_configuration, ?SettingsStatus $settings_status = null ) { $this->id = $id; @@ -88,6 +98,7 @@ class GatewayWithoutPayPalAdminNotice { $this->settings = $settings; $this->is_payments_page = $is_payments_page; $this->is_ppcp_settings_page = $is_ppcp_settings_page; + $this->dcc_configuration = $dcc_configuration; $this->settings_status = $settings_status; } @@ -181,7 +192,7 @@ class GatewayWithoutPayPalAdminNotice { return self::NOTICE_DISABLED_LOCATION; } - $is_dcc_enabled = $this->settings->has( 'dcc_enabled' ) && $this->settings->get( 'dcc_enabled' ) ?? false; + $is_dcc_enabled = $this->dcc_configuration->is_enabled(); $is_card_button_allowed = $this->settings->has( 'allow_card_button_gateway' ) && $this->settings->get( 'allow_card_button_gateway' ); if ( $is_dcc_enabled && $is_card_button_allowed ) { From ca846e76789bbb78cc8ca6dbb68e6c86dfdcfeb0 Mon Sep 17 00:00:00 2001 From: Philipp Stracker Date: Wed, 12 Mar 2025 18:39:12 +0100 Subject: [PATCH 12/62] =?UTF-8?q?=F0=9F=92=A1=20Add=20a=20few=20comments?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/Helper/DCCGatewayConfiguration.php | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/modules/ppcp-wc-gateway/src/Helper/DCCGatewayConfiguration.php b/modules/ppcp-wc-gateway/src/Helper/DCCGatewayConfiguration.php index 19c31f56d..a59dd3e8b 100644 --- a/modules/ppcp-wc-gateway/src/Helper/DCCGatewayConfiguration.php +++ b/modules/ppcp-wc-gateway/src/Helper/DCCGatewayConfiguration.php @@ -2,6 +2,10 @@ /** * Encapsulates all configuration details for "Credit & Debit Card" gateway. * + * The DCC gateway is also referred to as ACDC or "Advanced Card Processing". + * When active, we load the newer "card-fields" SDK component, instead of the + * old "hosted-fields" component. + * * @package WooCommerce\PayPalCommerce\WcGateway\Helper */ @@ -18,6 +22,8 @@ use WooCommerce\PayPalCommerce\Axo\Helper\PropertiesDictionary; * * This class should not implement business logic, but only provide a convenient * way to access gateway settings by wrapping the Settings instance. + * + * DI container: 'wcgateway.configuration.dcc' */ class DCCGatewayConfiguration { /** @@ -74,9 +80,8 @@ class DCCGatewayConfiguration { /** * Initializes the gateway details based on the provided Settings instance. * - * @throws NotFoundException If an expected gateway setting is not found. - * * @param Settings $settings Plugin settings instance. + * @throws NotFoundException If an expected gateway setting is not found. */ public function __construct( Settings $settings ) { $this->settings = $settings; From 62d14aa5ef40fe55d2c1c17d14d9f6616a9d9621 Mon Sep 17 00:00:00 2001 From: Emili Castells Guasch Date: Thu, 13 Mar 2025 11:48:15 +0100 Subject: [PATCH 13/62] Activate plugin after wc is activated --- .../{40_setup_and_activate.sh => 51_setup_and_activate.sh} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename .ddev/commands/web/orchestrate.d/{40_setup_and_activate.sh => 51_setup_and_activate.sh} (100%) diff --git a/.ddev/commands/web/orchestrate.d/40_setup_and_activate.sh b/.ddev/commands/web/orchestrate.d/51_setup_and_activate.sh similarity index 100% rename from .ddev/commands/web/orchestrate.d/40_setup_and_activate.sh rename to .ddev/commands/web/orchestrate.d/51_setup_and_activate.sh From 532543f4906ab3c03d988bd0b025363e92c10e86 Mon Sep 17 00:00:00 2001 From: Philipp Stracker Date: Wed, 12 Mar 2025 18:39:45 +0100 Subject: [PATCH 14/62] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20Use=20the=20DCCGatew?= =?UTF-8?q?ayConfiguration=20service?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- modules/ppcp-button/services.php | 3 +- .../ppcp-button/src/Assets/SmartButton.php | 81 ++++++++++--------- 2 files changed, 43 insertions(+), 41 deletions(-) diff --git a/modules/ppcp-button/services.php b/modules/ppcp-button/services.php index 098679c21..9aa7c15bf 100644 --- a/modules/ppcp-button/services.php +++ b/modules/ppcp-button/services.php @@ -167,7 +167,8 @@ return array( $container->get( 'api.endpoint.payment-tokens' ), $container->get( 'woocommerce.logger.woocommerce' ), $container->get( 'button.handle-shipping-in-paypal' ), - $container->get( 'button.helper.disabled-funding-sources' ) + $container->get( 'button.helper.disabled-funding-sources' ), + $container->get( 'wcgateway.configuration.dcc' ) ); }, 'button.url' => static function ( ContainerInterface $container ): string { diff --git a/modules/ppcp-button/src/Assets/SmartButton.php b/modules/ppcp-button/src/Assets/SmartButton.php index f95eeacfd..268fa2673 100644 --- a/modules/ppcp-button/src/Assets/SmartButton.php +++ b/modules/ppcp-button/src/Assets/SmartButton.php @@ -54,6 +54,7 @@ use WooCommerce\PayPalCommerce\WcGateway\Helper\SettingsStatus; use WooCommerce\PayPalCommerce\WcGateway\Settings\Settings; use WC_Shipping_Method; use WC_Cart; +use WooCommerce\PayPalCommerce\WcGateway\Helper\DCCGatewayConfiguration; /** * Class SmartButton @@ -237,33 +238,41 @@ class SmartButton implements SmartButtonInterface { */ private $disabled_funding_sources; + /** + * Provides details about the DCC configuration. + * + * @var DCCGatewayConfiguration + */ + private DCCGatewayConfiguration $dcc_configuration; + /** * SmartButton constructor. * - * @param string $module_url The URL to the module. - * @param string $version The assets version. - * @param SessionHandler $session_handler The Session handler. - * @param Settings $settings The Settings. - * @param PayerFactory $payer_factory The Payer factory. - * @param string $client_id The client ID. - * @param RequestData $request_data The Request Data helper. - * @param DccApplies $dcc_applies The DCC applies helper. - * @param SubscriptionHelper $subscription_helper The subscription helper. - * @param MessagesApply $messages_apply The Messages apply helper. - * @param Environment $environment The environment object. - * @param PaymentTokenRepository $payment_token_repository The payment token repository. - * @param SettingsStatus $settings_status The Settings status helper. - * @param CurrencyGetter $currency The getter of the 3-letter currency code of the shop. - * @param array $all_funding_sources All existing funding sources. - * @param bool $basic_checkout_validation_enabled Whether the basic JS validation of the form iss enabled. - * @param bool $early_validation_enabled Whether to execute WC validation of the checkout form. - * @param array $pay_now_contexts The contexts that should have the Pay Now button. - * @param string[] $funding_sources_without_redirect The sources that do not cause issues about redirecting (on mobile, ...) and sometimes not returning back. - * @param bool $vault_v3_enabled Whether Vault v3 module is enabled. - * @param PaymentTokensEndpoint $payment_tokens_endpoint Payment tokens endpoint. - * @param LoggerInterface $logger The logger. - * @param bool $should_handle_shipping_in_paypal Whether the shipping should be handled in PayPal. - * @param DisabledFundingSources $disabled_funding_sources List of funding sources to be disabled. + * @param string $module_url The URL to the module. + * @param string $version The assets version. + * @param SessionHandler $session_handler The Session handler. + * @param Settings $settings The Settings. + * @param PayerFactory $payer_factory The Payer factory. + * @param string $client_id The client ID. + * @param RequestData $request_data The Request Data helper. + * @param DccApplies $dcc_applies The DCC applies helper. + * @param SubscriptionHelper $subscription_helper The subscription helper. + * @param MessagesApply $messages_apply The Messages apply helper. + * @param Environment $environment The environment object. + * @param PaymentTokenRepository $payment_token_repository The payment token repository. + * @param SettingsStatus $settings_status The Settings status helper. + * @param CurrencyGetter $currency The getter of the 3-letter currency code of the shop. + * @param array $all_funding_sources All existing funding sources. + * @param bool $basic_checkout_validation_enabled Whether the basic JS validation of the form iss enabled. + * @param bool $early_validation_enabled Whether to execute WC validation of the checkout form. + * @param array $pay_now_contexts The contexts that should have the Pay Now button. + * @param string[] $funding_sources_without_redirect The sources that do not cause issues about redirecting (on mobile, ...) and sometimes not returning back. + * @param bool $vault_v3_enabled Whether Vault v3 module is enabled. + * @param PaymentTokensEndpoint $payment_tokens_endpoint Payment tokens endpoint. + * @param LoggerInterface $logger The logger. + * @param bool $should_handle_shipping_in_paypal Whether the shipping should be handled in PayPal. + * @param DisabledFundingSources $disabled_funding_sources List of funding sources to be disabled. + * @param DCCGatewayConfiguration $dcc_configuration The DCC Gateway Configuration. */ public function __construct( string $module_url, @@ -289,9 +298,9 @@ class SmartButton implements SmartButtonInterface { PaymentTokensEndpoint $payment_tokens_endpoint, LoggerInterface $logger, bool $should_handle_shipping_in_paypal, - DisabledFundingSources $disabled_funding_sources + DisabledFundingSources $disabled_funding_sources, + DCCGatewayConfiguration $dcc_configuration ) { - $this->module_url = $module_url; $this->version = $version; $this->session_handler = $session_handler; @@ -316,6 +325,7 @@ class SmartButton implements SmartButtonInterface { $this->payment_tokens_endpoint = $payment_tokens_endpoint; $this->should_handle_shipping_in_paypal = $should_handle_shipping_in_paypal; $this->disabled_funding_sources = $disabled_funding_sources; + $this->dcc_configuration = $dcc_configuration; } /** @@ -331,25 +341,16 @@ class SmartButton implements SmartButtonInterface { $this->render_message_wrapper_registrar(); } - if ( - $this->settings->has( 'dcc_enabled' ) - && $this->settings->get( 'dcc_enabled' ) - ) { + if ( $this->dcc_configuration->is_enabled() ) { add_action( $this->checkout_dcc_button_renderer_hook(), - array( - $this, - 'dcc_renderer', - ), + array( $this, 'dcc_renderer' ), 11 ); add_action( $this->pay_order_renderer_hook(), - array( - $this, - 'dcc_renderer', - ), + array( $this, 'dcc_renderer' ), 11 ); @@ -719,7 +720,7 @@ document.querySelector("#payment").before(document.querySelector(".ppcp-messages * Whether DCC fields can be rendered. */ public function can_render_dcc() : bool { - return $this->settings->has( 'dcc_enabled' ) && $this->settings->get( 'dcc_enabled' ) + return $this->dcc_configuration->is_enabled() && $this->settings->has( 'client_id' ) && $this->settings->get( 'client_id' ) && $this->dcc_applies->for_country_currency() && in_array( @@ -1614,7 +1615,7 @@ document.querySelector("#payment").before(document.querySelector(".ppcp-messages } // The actual condition that must be met. - return (bool) $this->settings->get( 'dcc_enabled' ); + return $this->dcc_configuration->is_enabled(); } catch ( NotFoundException $e ) { // Bail, if the settings DB entries are missing. return false; From 60bdf6dea13c4abb7221864c8d079e03c51179d7 Mon Sep 17 00:00:00 2001 From: Philipp Stracker Date: Fri, 14 Mar 2025 10:57:40 +0100 Subject: [PATCH 15/62] =?UTF-8?q?=F0=9F=92=A1=20Document=20DI=20service=20?= =?UTF-8?q?names?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- modules/ppcp-axo/src/Helper/CompatibilityChecker.php | 2 ++ modules/ppcp-wc-gateway/src/Helper/DCCGatewayConfiguration.php | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/modules/ppcp-axo/src/Helper/CompatibilityChecker.php b/modules/ppcp-axo/src/Helper/CompatibilityChecker.php index f06b3e144..1c7cba46e 100644 --- a/modules/ppcp-axo/src/Helper/CompatibilityChecker.php +++ b/modules/ppcp-axo/src/Helper/CompatibilityChecker.php @@ -16,6 +16,8 @@ use WooCommerce\PayPalCommerce\WcGateway\Exception\NotFoundException; /** * Class CompatibilityChecker + * + * DI service: 'axo.helpers.compatibility-checker' */ class CompatibilityChecker { /** diff --git a/modules/ppcp-wc-gateway/src/Helper/DCCGatewayConfiguration.php b/modules/ppcp-wc-gateway/src/Helper/DCCGatewayConfiguration.php index a59dd3e8b..59b3b88ee 100644 --- a/modules/ppcp-wc-gateway/src/Helper/DCCGatewayConfiguration.php +++ b/modules/ppcp-wc-gateway/src/Helper/DCCGatewayConfiguration.php @@ -23,7 +23,7 @@ use WooCommerce\PayPalCommerce\Axo\Helper\PropertiesDictionary; * This class should not implement business logic, but only provide a convenient * way to access gateway settings by wrapping the Settings instance. * - * DI container: 'wcgateway.configuration.dcc' + * DI service: 'wcgateway.configuration.dcc' */ class DCCGatewayConfiguration { /** From 0d69dff0f46a11c5ffc0883243b52f0b2ddfd289 Mon Sep 17 00:00:00 2001 From: Philipp Stracker Date: Fri, 14 Mar 2025 11:13:44 +0100 Subject: [PATCH 16/62] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20Use=20DCCGatewayConf?= =?UTF-8?q?iguration=20service?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- modules/ppcp-axo/services.php | 10 +++--- .../src/Helper/CompatibilityChecker.php | 36 ++++++------------- 2 files changed, 17 insertions(+), 29 deletions(-) diff --git a/modules/ppcp-axo/services.php b/modules/ppcp-axo/services.php index 7db0b0dc5..cf37030d0 100644 --- a/modules/ppcp-axo/services.php +++ b/modules/ppcp-axo/services.php @@ -39,7 +39,10 @@ return array( }, 'axo.helpers.compatibility-checker' => static function ( ContainerInterface $container ) : CompatibilityChecker { - return new CompatibilityChecker( $container->get( 'axo.fastlane-incompatible-plugin-names' ) ); + return new CompatibilityChecker( + $container->get( 'axo.fastlane-incompatible-plugin-names' ), + $container->get( 'wcgateway.configuration.dcc' ) + ); }, // If AXO is configured and onboarded. @@ -221,9 +224,8 @@ return array( }, 'axo.incompatible-plugins-notice.raw' => static function ( ContainerInterface $container ) : string { - $settings_notice_generator = new CompatibilityChecker( - $container->get( 'axo.fastlane-incompatible-plugin-names' ) - ); + $settings_notice_generator = $container->get( 'axo.helpers.compatibility-checker' ); + assert( $settings_notice_generator instanceof CompatibilityChecker ); return $settings_notice_generator->generate_incompatible_plugins_notice( true ); }, diff --git a/modules/ppcp-axo/src/Helper/CompatibilityChecker.php b/modules/ppcp-axo/src/Helper/CompatibilityChecker.php index 1c7cba46e..161d2a3bd 100644 --- a/modules/ppcp-axo/src/Helper/CompatibilityChecker.php +++ b/modules/ppcp-axo/src/Helper/CompatibilityChecker.php @@ -13,6 +13,7 @@ namespace WooCommerce\PayPalCommerce\Axo\Helper; use WooCommerce\PayPalCommerce\WcGateway\Helper\CartCheckoutDetector; use WooCommerce\PayPalCommerce\WcGateway\Settings\Settings; use WooCommerce\PayPalCommerce\WcGateway\Exception\NotFoundException; +use WooCommerce\PayPalCommerce\WcGateway\Helper\DCCGatewayConfiguration; /** * Class CompatibilityChecker @@ -35,20 +36,23 @@ class CompatibilityChecker { protected array $checkout_compatibility; /** - * Stores whether DCC is enabled. + * Provides details about the DCC configuration. * - * @var bool|null + * @var DCCGatewayConfiguration */ - protected ?bool $is_dcc_enabled = null; + private DCCGatewayConfiguration $dcc_configuration; /** * CompatibilityChecker constructor. * - * @param string[] $incompatible_plugin_names The list of Fastlane incompatible plugin names. + * @param string[] $incompatible_plugin_names The list of Fastlane incompatible plugin names. + * @param DCCGatewayConfiguration $dcc_configuration DCC gateway configuration. */ - public function __construct( array $incompatible_plugin_names ) { + public function __construct( array $incompatible_plugin_names, DCCGatewayConfiguration $dcc_configuration ) { $this->incompatible_plugin_names = $incompatible_plugin_names; - $this->checkout_compatibility = array( + $this->dcc_configuration = $dcc_configuration; + + $this->checkout_compatibility = array( 'has_elementor_checkout' => null, 'has_classic_checkout' => null, 'has_block_checkout' => null, @@ -94,24 +98,6 @@ class CompatibilityChecker { return $this->checkout_compatibility['has_block_checkout']; } - /** - * Checks if DCC is enabled. - * - * @param Settings $settings The plugin settings container. - * @return bool Whether DCC is enabled. - */ - protected function is_dcc_enabled( Settings $settings ): bool { - if ( $this->is_dcc_enabled === null ) { - try { - $this->is_dcc_enabled = $settings->has( 'dcc_enabled' ) && $settings->get( 'dcc_enabled' ); - } catch ( NotFoundException $ignored ) { - $this->is_dcc_enabled = false; - } - } - - return $this->is_dcc_enabled; - } - /** * Generates the full HTML of the notification. * @@ -242,7 +228,7 @@ class CompatibilityChecker { * @return string */ public function generate_settings_conflict_notice( Settings $settings, bool $raw_message = false ) : string { - if ( $this->is_dcc_enabled( $settings ) ) { + if ( $this->dcc_configuration->is_enabled() ) { return ''; } From 0d54c84e66858d43af1212d56203d61757e5212b Mon Sep 17 00:00:00 2001 From: Philipp Stracker Date: Fri, 14 Mar 2025 11:33:28 +0100 Subject: [PATCH 17/62] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20Refactor=20DCCGatewa?= =?UTF-8?q?yConfiguration=20=E2=80=9Creset=E2=80=9D=20logic?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/Helper/DCCGatewayConfiguration.php | 78 +++++++++++-------- 1 file changed, 46 insertions(+), 32 deletions(-) diff --git a/modules/ppcp-wc-gateway/src/Helper/DCCGatewayConfiguration.php b/modules/ppcp-wc-gateway/src/Helper/DCCGatewayConfiguration.php index 59b3b88ee..3cf55c0b3 100644 --- a/modules/ppcp-wc-gateway/src/Helper/DCCGatewayConfiguration.php +++ b/modules/ppcp-wc-gateway/src/Helper/DCCGatewayConfiguration.php @@ -80,11 +80,11 @@ class DCCGatewayConfiguration { /** * Initializes the gateway details based on the provided Settings instance. * - * @param Settings $settings Plugin settings instance. + * @param Settings $settings Plugin settings instance. * @throws NotFoundException If an expected gateway setting is not found. */ public function __construct( Settings $settings ) { - $this->settings = $settings; + $this->settings = $settings; $this->refresh(); } @@ -94,42 +94,57 @@ class DCCGatewayConfiguration { * * This method should be used sparingly, usually only on the settings page * when changes in gateway settings must be reflected immediately. - * - * @throws NotFoundException If an expected gateway setting is not found. */ public function refresh() : void { - $is_paypal_enabled = $this->settings->has( 'enabled' ) - && filter_var( $this->settings->get( 'enabled' ), FILTER_VALIDATE_BOOLEAN ); - $is_dcc_enabled = $this->settings->has( 'dcc_enabled' ) - && filter_var( $this->settings->get( 'dcc_enabled' ), FILTER_VALIDATE_BOOLEAN ); - $is_axo_enabled = $this->settings->has( 'axo_enabled' ) - && filter_var( $this->settings->get( 'axo_enabled' ), FILTER_VALIDATE_BOOLEAN ); + $show_on_card_options = array_keys( PropertiesDictionary::cardholder_name_options() ); + $show_on_card_value = null; + + $this->is_enabled = false; + $this->use_fastlane = false; + $this->gateway_title = ''; + $this->gateway_description = ''; + $this->show_name_on_card = $show_on_card_options[0]; + + try { + /* + * In case one of the following three settings is missing in the DB the + * Settings instance throws an exception and all features are set to "not available". + */ + $is_paypal_enabled = filter_var( $this->settings->get( 'enabled' ), FILTER_VALIDATE_BOOLEAN ); + $is_dcc_enabled = filter_var( $this->settings->get( 'dcc_enabled' ), FILTER_VALIDATE_BOOLEAN ); + $is_axo_enabled = filter_var( $this->settings->get( 'axo_enabled' ), FILTER_VALIDATE_BOOLEAN ); + + if ( $this->settings->has( 'dcc_gateway_title' ) ) { + $this->gateway_title = $this->settings->get( 'dcc_gateway_title' ); + } + if ( $this->settings->has( 'dcc_gateway_description' ) ) { + $this->gateway_description = $this->settings->get( 'dcc_gateway_description' ); + } + + if ( $this->settings->has( 'dcc_name_on_card' ) ) { + $show_on_card_value = $this->settings->get( 'dcc_name_on_card' ); + } elseif ( $this->settings->has( 'axo_name_on_card' ) ) { + // Legacy. The AXO gateway setting was replaced by the DCC setting. + $show_on_card_value = $this->settings->get( 'axo_name_on_card' ); + } + if ( in_array( $show_on_card_value, $show_on_card_options, true ) ) { + $this->show_name_on_card = $show_on_card_value; + } + } catch ( NotFoundException $exception ) { + // A setting is missing in the DB, disable card payments. + $is_paypal_enabled = false; + $is_dcc_enabled = false; + $is_axo_enabled = false; + } $this->is_enabled = $is_paypal_enabled && $is_dcc_enabled; $this->use_fastlane = $this->is_enabled && $is_axo_enabled; - $this->gateway_title = $this->settings->has( 'dcc_gateway_title' ) ? - $this->settings->get( 'dcc_gateway_title' ) : ''; - $this->gateway_description = $this->settings->has( 'dcc_gateway_description' ) ? - $this->settings->get( 'dcc_gateway_description' ) : ''; - - $show_on_card = ''; - if ( $this->settings->has( 'dcc_name_on_card' ) ) { - $show_on_card = $this->settings->get( 'dcc_name_on_card' ); - } elseif ( $this->settings->has( 'axo_name_on_card' ) ) { - // Legacy. The AXO gateway setting was replaced by the DCC setting. - $show_on_card = $this->settings->get( 'axo_name_on_card' ); - } - $valid_options = array_keys( PropertiesDictionary::cardholder_name_options() ); - - $this->show_name_on_card = in_array( $show_on_card, $valid_options, true ) - ? $show_on_card - : $valid_options[0]; - /** - * Moved from setting "axo_privacy" to a hook-only filter: * Changing this to true (and hiding the watermark) has potential legal * consequences, and therefore is generally discouraged. + * + * @since 2024-09-26 - replace the UI checkbox "axo_privacy" with a filter. */ $this->hide_fastlane_watermark = add_filter( 'woocommerce_paypal_payments_fastlane_watermark_enabled', @@ -138,12 +153,11 @@ class DCCGatewayConfiguration { } /** - * Whether the Credit Card gateway is enabled. + * Whether the "Advanced Card Payments" gateway is enabled. * * Requires PayPal features to be enabled. * * @return bool - * @todo Some classes still directly access `$settings->get('dcc_enabled')` */ public function is_enabled() : bool { return $this->is_enabled; @@ -153,7 +167,7 @@ class DCCGatewayConfiguration { * Whether to prefer Fastlane instead of the default Credit Card UI, if * available in the shop's region. * - * Requires PayPal features and the Credit Card gateway to be enabled. + * Requires PayPal features and the "Advanced Card Payments" gateway to be enabled. * * @return bool */ From 31686a6214cac7fe55b21c220f6d22612ee52090 Mon Sep 17 00:00:00 2001 From: Philipp Stracker Date: Fri, 14 Mar 2025 11:38:30 +0100 Subject: [PATCH 18/62] =?UTF-8?q?=E2=9C=A8=20Early=20exit=20if=20merchant?= =?UTF-8?q?=20is=20not=20onboarded?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- modules/ppcp-wc-gateway/services.php | 6 ++++- .../src/Helper/DCCGatewayConfiguration.php | 27 ++++++++++++++----- 2 files changed, 25 insertions(+), 8 deletions(-) diff --git a/modules/ppcp-wc-gateway/services.php b/modules/ppcp-wc-gateway/services.php index 43e447f86..d95c84de1 100644 --- a/modules/ppcp-wc-gateway/services.php +++ b/modules/ppcp-wc-gateway/services.php @@ -84,6 +84,7 @@ use WooCommerce\PayPalCommerce\WcGateway\Settings\SettingsRenderer; use WooCommerce\PayPalCommerce\Axo\Helper\PropertiesDictionary; use WooCommerce\PayPalCommerce\Applepay\ApplePayGateway; use WooCommerce\PayPalCommerce\WcGateway\Helper\DCCGatewayConfiguration; +use WooCommerce\PayPalCommerce\WcGateway\Helper\ConnectionState; return array( 'wcgateway.paypal-gateway' => static function ( ContainerInterface $container ): PayPalGateway { @@ -1362,10 +1363,13 @@ return array( }, 'wcgateway.configuration.dcc' => static function ( ContainerInterface $container ) : DCCGatewayConfiguration { + $connection_state = $container->get( 'settings.connection-state' ); + assert( $connection_state instanceof ConnectionState ); + $settings = $container->get( 'wcgateway.settings' ); assert( $settings instanceof Settings ); - return new DCCGatewayConfiguration( $settings ); + return new DCCGatewayConfiguration( $connection_state, $settings ); }, 'wcgateway.helper.dcc-product-status' => static function ( ContainerInterface $container ) : DCCProductStatus { diff --git a/modules/ppcp-wc-gateway/src/Helper/DCCGatewayConfiguration.php b/modules/ppcp-wc-gateway/src/Helper/DCCGatewayConfiguration.php index 3cf55c0b3..8781efa74 100644 --- a/modules/ppcp-wc-gateway/src/Helper/DCCGatewayConfiguration.php +++ b/modules/ppcp-wc-gateway/src/Helper/DCCGatewayConfiguration.php @@ -26,6 +26,13 @@ use WooCommerce\PayPalCommerce\Axo\Helper\PropertiesDictionary; * DI service: 'wcgateway.configuration.dcc' */ class DCCGatewayConfiguration { + /** + * The connection state. + * + * @var ConnectionState + */ + private ConnectionState $connection_state; + /** * The plugin settings instance. * @@ -80,10 +87,11 @@ class DCCGatewayConfiguration { /** * Initializes the gateway details based on the provided Settings instance. * + * @param ConnectionState $connection_state Connection state instance. * @param Settings $settings Plugin settings instance. - * @throws NotFoundException If an expected gateway setting is not found. */ - public function __construct( Settings $settings ) { + public function __construct( ConnectionState $connection_state, Settings $settings ) { + $this->connection_state = $connection_state; $this->settings = $settings; $this->refresh(); @@ -99,11 +107,16 @@ class DCCGatewayConfiguration { $show_on_card_options = array_keys( PropertiesDictionary::cardholder_name_options() ); $show_on_card_value = null; - $this->is_enabled = false; - $this->use_fastlane = false; - $this->gateway_title = ''; - $this->gateway_description = ''; - $this->show_name_on_card = $show_on_card_options[0]; + $this->is_enabled = false; + $this->use_fastlane = false; + $this->gateway_title = ''; + $this->gateway_description = ''; + $this->show_name_on_card = $show_on_card_options[0]; + $this->hide_fastlane_watermark = false; + + if ( ! $this->connection_state->is_connected() ) { + return; + } try { /* From ad0085ee8fdd51b84c51be03ed17e1feb26c1ff2 Mon Sep 17 00:00:00 2001 From: Philipp Stracker Date: Fri, 14 Mar 2025 11:38:56 +0100 Subject: [PATCH 19/62] =?UTF-8?q?=F0=9F=92=A1=20Document=20DI=20service=20?= =?UTF-8?q?name?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- modules/ppcp-wc-gateway/src/Helper/ConnectionState.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/modules/ppcp-wc-gateway/src/Helper/ConnectionState.php b/modules/ppcp-wc-gateway/src/Helper/ConnectionState.php index 3ee969a84..0950af29a 100644 --- a/modules/ppcp-wc-gateway/src/Helper/ConnectionState.php +++ b/modules/ppcp-wc-gateway/src/Helper/ConnectionState.php @@ -14,6 +14,8 @@ namespace WooCommerce\PayPalCommerce\WcGateway\Helper; * * Manages the merchants' connection status details and provides inspection * methods to describe the current state. + * + * DI service: 'settings.connection-state' */ class ConnectionState { /** From 16b4e235f2e464b018d7960343ef1c6480922ebb Mon Sep 17 00:00:00 2001 From: Philipp Stracker Date: Fri, 14 Mar 2025 11:39:34 +0100 Subject: [PATCH 20/62] =?UTF-8?q?=F0=9F=92=A1=20Fix=20typo?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/Notice/GatewayWithoutPayPalAdminNotice.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/ppcp-wc-gateway/src/Notice/GatewayWithoutPayPalAdminNotice.php b/modules/ppcp-wc-gateway/src/Notice/GatewayWithoutPayPalAdminNotice.php index 24ab7c68c..660a39754 100644 --- a/modules/ppcp-wc-gateway/src/Notice/GatewayWithoutPayPalAdminNotice.php +++ b/modules/ppcp-wc-gateway/src/Notice/GatewayWithoutPayPalAdminNotice.php @@ -77,7 +77,7 @@ class GatewayWithoutPayPalAdminNotice { * ConnectAdminNotice constructor. * * @param string $id The gateway ID. - * @param bool $is_connected Whether onboading was completed. + * @param bool $is_connected Whether onboarding was completed. * @param ContainerInterface $settings The settings. * @param bool $is_payments_page Whether the current page is the WC payment page. * @param bool $is_ppcp_settings_page Whether the current page is the PPCP settings page. From a39edd02251053e561960c23e633316e6784d720 Mon Sep 17 00:00:00 2001 From: Philipp Stracker Date: Fri, 14 Mar 2025 11:42:41 +0100 Subject: [PATCH 21/62] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20Remove=20an=20unused?= =?UTF-8?q?=20param=20to=20avoid=20confusion?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The DCC status is not defered from the Settings instance, but from the specific DCCGatewayConfiguration service. --- modules/ppcp-axo/services.php | 5 +---- modules/ppcp-axo/src/Helper/CompatibilityChecker.php | 3 +-- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/modules/ppcp-axo/services.php b/modules/ppcp-axo/services.php index cf37030d0..3700b4bbb 100644 --- a/modules/ppcp-axo/services.php +++ b/modules/ppcp-axo/services.php @@ -196,10 +196,7 @@ return array( $compatibility_checker = $container->get( 'axo.helpers.compatibility-checker' ); assert( $compatibility_checker instanceof CompatibilityChecker ); - $settings = $container->get( 'wcgateway.settings' ); - assert( $settings instanceof Settings ); - - return $compatibility_checker->generate_settings_conflict_notice( $settings ); + return $compatibility_checker->generate_settings_conflict_notice(); }, 'axo.checkout-config-notice' => static function ( ContainerInterface $container ) : string { diff --git a/modules/ppcp-axo/src/Helper/CompatibilityChecker.php b/modules/ppcp-axo/src/Helper/CompatibilityChecker.php index 161d2a3bd..e8d8595c3 100644 --- a/modules/ppcp-axo/src/Helper/CompatibilityChecker.php +++ b/modules/ppcp-axo/src/Helper/CompatibilityChecker.php @@ -223,11 +223,10 @@ class CompatibilityChecker { /** * Generates a warning notice with instructions on conflicting plugin-internal settings. * - * @param Settings $settings The plugin settings container, which is checked for conflicting values. * @param bool $raw_message Whether to return raw message without HTML wrappers. * @return string */ - public function generate_settings_conflict_notice( Settings $settings, bool $raw_message = false ) : string { + public function generate_settings_conflict_notice( bool $raw_message = false ) : string { if ( $this->dcc_configuration->is_enabled() ) { return ''; } From b7d9e2c8fdd24a7507762ab5c29f56b9d37b28c8 Mon Sep 17 00:00:00 2001 From: Philipp Stracker Date: Fri, 14 Mar 2025 11:43:33 +0100 Subject: [PATCH 22/62] =?UTF-8?q?=F0=9F=8E=A8=20Apply=20phpcs=20styles?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/Helper/CompatibilityChecker.php | 27 ++++++++++--------- 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/modules/ppcp-axo/src/Helper/CompatibilityChecker.php b/modules/ppcp-axo/src/Helper/CompatibilityChecker.php index e8d8595c3..1ab4d15a3 100644 --- a/modules/ppcp-axo/src/Helper/CompatibilityChecker.php +++ b/modules/ppcp-axo/src/Helper/CompatibilityChecker.php @@ -6,7 +6,7 @@ * @package WooCommerce\PayPalCommerce\Axo\Helper */ -declare(strict_types=1); +declare( strict_types = 1 ); namespace WooCommerce\PayPalCommerce\Axo\Helper; @@ -45,7 +45,8 @@ class CompatibilityChecker { /** * CompatibilityChecker constructor. * - * @param string[] $incompatible_plugin_names The list of Fastlane incompatible plugin names. + * @param string[] $incompatible_plugin_names The list of Fastlane incompatible + * plugin names. * @param DCCGatewayConfiguration $dcc_configuration DCC gateway configuration. */ public function __construct( array $incompatible_plugin_names, DCCGatewayConfiguration $dcc_configuration ) { @@ -64,7 +65,7 @@ class CompatibilityChecker { * * @return bool Whether the checkout uses Elementor. */ - protected function has_elementor_checkout(): bool { + protected function has_elementor_checkout() : bool { if ( $this->checkout_compatibility['has_elementor_checkout'] === null ) { $this->checkout_compatibility['has_elementor_checkout'] = CartCheckoutDetector::has_elementor_checkout(); } @@ -77,7 +78,7 @@ class CompatibilityChecker { * * @return bool Whether the checkout uses classic checkout. */ - protected function has_classic_checkout(): bool { + protected function has_classic_checkout() : bool { if ( $this->checkout_compatibility['has_classic_checkout'] === null ) { $this->checkout_compatibility['has_classic_checkout'] = CartCheckoutDetector::has_classic_checkout(); } @@ -90,7 +91,7 @@ class CompatibilityChecker { * * @return bool Whether the checkout uses block checkout. */ - protected function has_block_checkout(): bool { + protected function has_block_checkout() : bool { if ( $this->checkout_compatibility['has_block_checkout'] === null ) { $this->checkout_compatibility['has_block_checkout'] = CartCheckoutDetector::has_block_checkout(); } @@ -101,8 +102,9 @@ class CompatibilityChecker { /** * Generates the full HTML of the notification. * - * @param string $message HTML of the inner message contents. - * @param bool $is_error Whether the provided message is an error. Affects the notice color. + * @param string $message HTML of the inner message contents. + * @param bool $is_error Whether the provided message is an error. Affects the notice + * color. * @param bool $raw_message Whether to return raw message without HTML wrappers. * * @return string The full HTML code of the notification, or an empty string, or raw message. @@ -124,11 +126,12 @@ class CompatibilityChecker { } /** - * Check if there aren't any incompatibilities that would prevent Fastlane from working properly. + * Check if there aren't any incompatibilities that would prevent Fastlane from working + * properly. * * @return bool Whether the setup is compatible. */ - public function is_fastlane_compatible(): bool { + public function is_fastlane_compatible() : bool { // Check for incompatible plugins. if ( ! empty( $this->incompatible_plugin_names ) ) { return false; @@ -153,7 +156,7 @@ class CompatibilityChecker { * @param bool $raw_message Whether to return raw message without HTML wrappers. * @return string */ - public function generate_checkout_notice( bool $raw_message = false ): string { + public function generate_checkout_notice( bool $raw_message = false ) : string { $notice_content = ''; // Check for checkout incompatibilities. @@ -201,7 +204,7 @@ class CompatibilityChecker { * @param bool $raw_message Whether to return raw message without HTML wrappers. * @return string */ - public function generate_incompatible_plugins_notice( bool $raw_message = false ): string { + public function generate_incompatible_plugins_notice( bool $raw_message = false ) : string { if ( empty( $this->incompatible_plugin_names ) ) { return ''; } @@ -223,7 +226,7 @@ class CompatibilityChecker { /** * Generates a warning notice with instructions on conflicting plugin-internal settings. * - * @param bool $raw_message Whether to return raw message without HTML wrappers. + * @param bool $raw_message Whether to return raw message without HTML wrappers. * @return string */ public function generate_settings_conflict_notice( bool $raw_message = false ) : string { From a7f736c52cc2925dab80f04e8d5922dd7ed8653f Mon Sep 17 00:00:00 2001 From: Philipp Stracker Date: Fri, 14 Mar 2025 11:59:52 +0100 Subject: [PATCH 23/62] =?UTF-8?q?=F0=9F=A7=AA=20Update=20existing=20unit?= =?UTF-8?q?=20test=20cases?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Helper/DisabledFundingSourcesTest.php | 24 +++++++++++++------ 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/tests/PHPUnit/Button/Helper/DisabledFundingSourcesTest.php b/tests/PHPUnit/Button/Helper/DisabledFundingSourcesTest.php index 5651c8393..3c73c04fb 100644 --- a/tests/PHPUnit/Button/Helper/DisabledFundingSourcesTest.php +++ b/tests/PHPUnit/Button/Helper/DisabledFundingSourcesTest.php @@ -8,17 +8,20 @@ use WC_Payment_Gateways; use WooCommerce; use WooCommerce\PayPalCommerce\TestCase; use WooCommerce\PayPalCommerce\WcGateway\Settings\Settings; +use WooCommerce\PayPalCommerce\WcGateway\Helper\DCCGatewayConfiguration; use function Brain\Monkey\Functions\when; class DisabledFundingSourcesTest extends TestCase { private $settings; + private $dcc_configuration; public function setUp(): void { parent::setUp(); $this->settings = Mockery::mock(Settings::class); + $this->dcc_configuration = Mockery::mock(DCCGatewayConfiguration::class); } /** @@ -27,7 +30,8 @@ class DisabledFundingSourcesTest extends TestCase */ public function test_is_checkout_true_add_card_when_checkout_block_context() { - $sut = new DisabledFundingSources($this->settings, []); + $this->dcc_configuration->shouldReceive('is_enabled')->andReturn(true); + $sut = new DisabledFundingSources($this->settings, [], $this->dcc_configuration); $this->setExpectations(); $this->setWcPaymentGateways(); @@ -43,7 +47,8 @@ class DisabledFundingSourcesTest extends TestCase */ public function test_is_checkout_false_add_card_when_checkout_context() { - $sut = new DisabledFundingSources($this->settings, []); + $this->dcc_configuration->shouldReceive('is_enabled')->andReturn(true); + $sut = new DisabledFundingSources($this->settings, [], $this->dcc_configuration); $this->setExpectations(); $this->setWcPaymentGateways(); @@ -55,11 +60,16 @@ class DisabledFundingSourcesTest extends TestCase public function test_is_checkout_true_add_allowed_sources_when_checkout_block_context() { - $sut = new DisabledFundingSources($this->settings, [ - 'card' => 'Credit or debit cards', - 'paypal' => 'PayPal', - 'foo' => 'Bar', - ]); + $this->dcc_configuration->shouldReceive('is_enabled')->andReturn(true); + $sut = new DisabledFundingSources( + $this->settings, + [ + 'card' => 'Credit or debit cards', + 'paypal' => 'PayPal', + 'foo' => 'Bar', + ], + $this->dcc_configuration + ); $this->setExpectations(); $this->setWcPaymentGateways(); From cad53780891c0b20bd381ac293fd805f3de87ddd Mon Sep 17 00:00:00 2001 From: Philipp Stracker Date: Fri, 14 Mar 2025 12:13:06 +0100 Subject: [PATCH 24/62] =?UTF-8?q?=F0=9F=92=A1=20Update=20the=20class=20doc?= =?UTF-8?q?umentation?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/Helper/DCCGatewayConfiguration.php | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/modules/ppcp-wc-gateway/src/Helper/DCCGatewayConfiguration.php b/modules/ppcp-wc-gateway/src/Helper/DCCGatewayConfiguration.php index 8781efa74..e15cc713c 100644 --- a/modules/ppcp-wc-gateway/src/Helper/DCCGatewayConfiguration.php +++ b/modules/ppcp-wc-gateway/src/Helper/DCCGatewayConfiguration.php @@ -18,12 +18,25 @@ use WooCommerce\PayPalCommerce\WcGateway\Exception\NotFoundException; use WooCommerce\PayPalCommerce\Axo\Helper\PropertiesDictionary; /** - * A simple DTO that provides access to the DCC/AXO gateway settings. + * A configuration proxy service that provides details about credit card gateway + * configuration. * - * This class should not implement business logic, but only provide a convenient - * way to access gateway settings by wrapping the Settings instance. + * Terminology: + * - DCC or ACDC refers to the new "Advanced Card Processing" integration. + * - BCDC is the older "Credit and Debit Cards" integration. + * - AXO is Fastlane, which is an improved UI for ACDC. + * + * Technical implementation via the JS SDK: + * + * a. Funding source + * - All card payment options require the funding-source "card" + * b. Components + * - ACDC and AXO use "card-fields" + * - BCDC uses "hosted-fields" * * DI service: 'wcgateway.configuration.dcc' + * + * @todo: Rename this class to CardPaymentsConfiguration! */ class DCCGatewayConfiguration { /** From d4857102fe88ce1eee3738e019bd4d50a38cc874 Mon Sep 17 00:00:00 2001 From: Philipp Stracker Date: Fri, 14 Mar 2025 12:17:15 +0100 Subject: [PATCH 25/62] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20Apply=20more=20suita?= =?UTF-8?q?ble=20DI=20service=20name?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- modules/ppcp-axo-block/services.php | 2 +- modules/ppcp-axo-block/src/AxoBlockModule.php | 2 +- modules/ppcp-axo/services.php | 6 +++--- modules/ppcp-axo/src/AxoModule.php | 10 +++++----- modules/ppcp-button/services.php | 6 +++--- modules/ppcp-card-fields/src/CardFieldsModule.php | 6 +++--- modules/ppcp-wc-gateway/services.php | 12 ++++++------ .../src/Helper/DCCGatewayConfiguration.php | 2 +- modules/ppcp-wc-gateway/src/WCGatewayModule.php | 4 ++-- 9 files changed, 25 insertions(+), 25 deletions(-) diff --git a/modules/ppcp-axo-block/services.php b/modules/ppcp-axo-block/services.php index b93513148..a93d9096c 100644 --- a/modules/ppcp-axo-block/services.php +++ b/modules/ppcp-axo-block/services.php @@ -35,7 +35,7 @@ return array( $container->get( 'axo.gateway' ), fn(): SmartButtonInterface => $container->get( 'button.smart-button' ), $container->get( 'wcgateway.settings' ), - $container->get( 'wcgateway.configuration.dcc' ), + $container->get( 'wcgateway.configuration.card-configuration' ), $container->get( 'settings.environment' ), $container->get( 'wcgateway.url' ), $container->get( 'axo.payment_method_selected_map' ), diff --git a/modules/ppcp-axo-block/src/AxoBlockModule.php b/modules/ppcp-axo-block/src/AxoBlockModule.php index cd5b0fa25..55acb4455 100644 --- a/modules/ppcp-axo-block/src/AxoBlockModule.php +++ b/modules/ppcp-axo-block/src/AxoBlockModule.php @@ -188,7 +188,7 @@ class AxoBlockModule implements ServiceModule, ExtendingModule, ExecutableModule return; } - $dcc_configuration = $c->get( 'wcgateway.configuration.dcc' ); + $dcc_configuration = $c->get( 'wcgateway.configuration.card-configuration' ); if ( ! $dcc_configuration->use_fastlane() ) { return; } diff --git a/modules/ppcp-axo/services.php b/modules/ppcp-axo/services.php index 3700b4bbb..c3d79ab08 100644 --- a/modules/ppcp-axo/services.php +++ b/modules/ppcp-axo/services.php @@ -41,7 +41,7 @@ return array( 'axo.helpers.compatibility-checker' => static function ( ContainerInterface $container ) : CompatibilityChecker { return new CompatibilityChecker( $container->get( 'axo.fastlane-incompatible-plugin-names' ), - $container->get( 'wcgateway.configuration.dcc' ) + $container->get( 'wcgateway.configuration.card-configuration' ) ); }, @@ -83,7 +83,7 @@ return array( return new AxoGateway( $container->get( 'wcgateway.settings.render' ), $container->get( 'wcgateway.settings' ), - $container->get( 'wcgateway.configuration.dcc' ), + $container->get( 'wcgateway.configuration.card-configuration' ), $container->get( 'wcgateway.url' ), $container->get( 'session.handler' ), $container->get( 'wcgateway.order-processor' ), @@ -228,7 +228,7 @@ return array( }, 'axo.smart-button-location-notice' => static function ( ContainerInterface $container ) : string { - $dcc_configuration = $container->get( 'wcgateway.configuration.dcc' ); + $dcc_configuration = $container->get( 'wcgateway.configuration.card-configuration' ); assert( $dcc_configuration instanceof DCCGatewayConfiguration ); if ( $dcc_configuration->use_fastlane() ) { diff --git a/modules/ppcp-axo/src/AxoModule.php b/modules/ppcp-axo/src/AxoModule.php index 21ee84a35..bd81f04cb 100644 --- a/modules/ppcp-axo/src/AxoModule.php +++ b/modules/ppcp-axo/src/AxoModule.php @@ -98,7 +98,7 @@ class AxoModule implements ServiceModule, ExtendingModule, ExecutableModule { return $methods; } - $dcc_configuration = $c->get( 'wcgateway.configuration.dcc' ); + $dcc_configuration = $c->get( 'wcgateway.configuration.card-configuration' ); assert( $dcc_configuration instanceof DCCGatewayConfiguration ); if ( ! $dcc_configuration->is_enabled() ) { @@ -164,7 +164,7 @@ class AxoModule implements ServiceModule, ExtendingModule, ExecutableModule { $listener = $c->get( 'wcgateway.settings.listener' ); assert( $listener instanceof SettingsListener ); - $dcc_configuration = $c->get( 'wcgateway.configuration.dcc' ); + $dcc_configuration = $c->get( 'wcgateway.configuration.card-configuration' ); assert( $dcc_configuration instanceof DCCGatewayConfiguration ); $listener->filter_settings( @@ -247,7 +247,7 @@ class AxoModule implements ServiceModule, ExtendingModule, ExecutableModule { add_filter( 'woocommerce_paypal_payments_sdk_components_hook', function( $components ) use ( $c ) { - $dcc_configuration = $c->get( 'wcgateway.configuration.dcc' ); + $dcc_configuration = $c->get( 'wcgateway.configuration.card-configuration' ); assert( $dcc_configuration instanceof DCCGatewayConfiguration ); if ( ! $dcc_configuration->use_fastlane() ) { @@ -262,7 +262,7 @@ class AxoModule implements ServiceModule, ExtendingModule, ExecutableModule { 'wp_head', function () use ( $c ) { // Add meta tag to allow feature-detection of the site's AXO payment state. - $dcc_configuration = $c->get( 'wcgateway.configuration.dcc' ); + $dcc_configuration = $c->get( 'wcgateway.configuration.card-configuration' ); assert( $dcc_configuration instanceof DCCGatewayConfiguration ); if ( $dcc_configuration->use_fastlane() ) { @@ -403,7 +403,7 @@ class AxoModule implements ServiceModule, ExtendingModule, ExecutableModule { * @return bool */ private function should_render_fastlane( ContainerInterface $c ): bool { - $dcc_configuration = $c->get( 'wcgateway.configuration.dcc' ); + $dcc_configuration = $c->get( 'wcgateway.configuration.card-configuration' ); assert( $dcc_configuration instanceof DCCGatewayConfiguration ); $subscription_helper = $c->get( 'wc-subscriptions.helper' ); diff --git a/modules/ppcp-button/services.php b/modules/ppcp-button/services.php index 9aa7c15bf..d2ccb9e64 100644 --- a/modules/ppcp-button/services.php +++ b/modules/ppcp-button/services.php @@ -115,7 +115,7 @@ return array( } $no_smart_buttons = ! $settings_status->is_smart_button_enabled_for_location( $context ); - $dcc_configuration = $container->get( 'wcgateway.configuration.dcc' ); + $dcc_configuration = $container->get( 'wcgateway.configuration.card-configuration' ); assert( $dcc_configuration instanceof DCCGatewayConfiguration ); if ( $no_smart_buttons && ! $dcc_configuration->is_enabled() ) { @@ -168,7 +168,7 @@ return array( $container->get( 'woocommerce.logger.woocommerce' ), $container->get( 'button.handle-shipping-in-paypal' ), $container->get( 'button.helper.disabled-funding-sources' ), - $container->get( 'wcgateway.configuration.dcc' ) + $container->get( 'wcgateway.configuration.card-configuration' ) ); }, 'button.url' => static function ( ContainerInterface $container ): string { @@ -345,7 +345,7 @@ return array( return new DisabledFundingSources( $container->get( 'wcgateway.settings' ), $container->get( 'wcgateway.all-funding-sources' ), - $container->get( 'wcgateway.configuration.dcc' ) + $container->get( 'wcgateway.configuration.card-configuration' ) ); }, 'button.is-logged-in' => static function ( ContainerInterface $container ): bool { diff --git a/modules/ppcp-card-fields/src/CardFieldsModule.php b/modules/ppcp-card-fields/src/CardFieldsModule.php index 28354d9a6..47c86bdf4 100644 --- a/modules/ppcp-card-fields/src/CardFieldsModule.php +++ b/modules/ppcp-card-fields/src/CardFieldsModule.php @@ -54,7 +54,7 @@ class CardFieldsModule implements ServiceModule, ExtendingModule, ExecutableModu add_filter( 'woocommerce_paypal_payments_sdk_components_hook', static function( $components ) use ( $c ) { - $dcc_config = $c->get( 'wcgateway.configuration.dcc' ); + $dcc_config = $c->get( 'wcgateway.configuration.card-configuration' ); assert( $dcc_config instanceof DCCGatewayConfiguration ); if ( ! $dcc_config->is_enabled() ) { @@ -81,7 +81,7 @@ class CardFieldsModule implements ServiceModule, ExtendingModule, ExecutableModu * @psalm-suppress MissingClosureParamType */ function( $default_fields, $id ) use ( $c ) { - if ( ! $c->get( 'wcgateway.configuration.dcc' )->is_enabled() ) { + if ( ! $c->get( 'wcgateway.configuration.card-configuration' )->is_enabled() ) { return $default_fields; } if ( CreditCardGateway::ID === $id && apply_filters( 'woocommerce_paypal_payments_enable_cardholder_name_field', false ) ) { @@ -116,7 +116,7 @@ class CardFieldsModule implements ServiceModule, ExtendingModule, ExecutableModu add_filter( 'ppcp_create_order_request_body_data', function( array $data, string $payment_method ) use ( $c ): array { - if ( ! $c->get( 'wcgateway.configuration.dcc' )->is_enabled() ) { + if ( ! $c->get( 'wcgateway.configuration.card-configuration' )->is_enabled() ) { return $data; } // phpcs:ignore WordPress.Security.NonceVerification.Missing diff --git a/modules/ppcp-wc-gateway/services.php b/modules/ppcp-wc-gateway/services.php index d95c84de1..b415c5c6b 100644 --- a/modules/ppcp-wc-gateway/services.php +++ b/modules/ppcp-wc-gateway/services.php @@ -118,7 +118,7 @@ return array( $container->get( 'wcgateway.settings.render' ), $container->get( 'wcgateway.order-processor' ), $container->get( 'wcgateway.settings' ), - $container->get( 'wcgateway.configuration.dcc' ), + $container->get( 'wcgateway.configuration.card-configuration' ), $container->get( 'wcgateway.credit-card-icons' ), $container->get( 'wcgateway.url' ), $container->get( 'session.handler' ), @@ -335,7 +335,7 @@ return array( $container->get( 'wcgateway.settings' ), $container->get( 'wcgateway.is-wc-payments-page' ), $container->get( 'wcgateway.is-ppcp-settings-page' ), - $container->get( 'wcgateway.configuration.dcc' ) + $container->get( 'wcgateway.configuration.card-configuration' ) ); }, 'wcgateway.notice.card-button-without-paypal' => static function ( ContainerInterface $container ): GatewayWithoutPayPalAdminNotice { @@ -345,7 +345,7 @@ return array( $container->get( 'wcgateway.settings' ), $container->get( 'wcgateway.is-wc-payments-page' ), $container->get( 'wcgateway.is-ppcp-settings-page' ), - $container->get( 'wcgateway.configuration.dcc' ), + $container->get( 'wcgateway.configuration.card-configuration' ), $container->get( 'wcgateway.settings.status' ) ); }, @@ -464,7 +464,7 @@ return array( assert( $settings instanceof Settings ); $axo_available = $container->has( 'axo.available' ) && $container->get( 'axo.available' ); - $dcc_configuration = $container->get( 'wcgateway.configuration.dcc' ); + $dcc_configuration = $container->get( 'wcgateway.configuration.card-configuration' ); assert( $dcc_configuration instanceof DCCGatewayConfiguration ); if ( $axo_available && $dcc_configuration->use_fastlane() ) { @@ -687,7 +687,7 @@ return array( $subscription_helper = $container->get( 'wc-subscriptions.helper' ); assert( $subscription_helper instanceof SubscriptionHelper ); - $dcc_configuration = $container->get( 'wcgateway.configuration.dcc' ); + $dcc_configuration = $container->get( 'wcgateway.configuration.card-configuration' ); assert( $dcc_configuration instanceof DCCGatewayConfiguration ); $fields = array( @@ -1362,7 +1362,7 @@ return array( return new TransactionUrlProvider( $sandbox_url_base, $live_url_base ); }, - 'wcgateway.configuration.dcc' => static function ( ContainerInterface $container ) : DCCGatewayConfiguration { + 'wcgateway.configuration.card-configuration' => static function ( ContainerInterface $container ) : DCCGatewayConfiguration { $connection_state = $container->get( 'settings.connection-state' ); assert( $connection_state instanceof ConnectionState ); diff --git a/modules/ppcp-wc-gateway/src/Helper/DCCGatewayConfiguration.php b/modules/ppcp-wc-gateway/src/Helper/DCCGatewayConfiguration.php index e15cc713c..68637f1c1 100644 --- a/modules/ppcp-wc-gateway/src/Helper/DCCGatewayConfiguration.php +++ b/modules/ppcp-wc-gateway/src/Helper/DCCGatewayConfiguration.php @@ -34,7 +34,7 @@ use WooCommerce\PayPalCommerce\Axo\Helper\PropertiesDictionary; * - ACDC and AXO use "card-fields" * - BCDC uses "hosted-fields" * - * DI service: 'wcgateway.configuration.dcc' + * DI service: 'wcgateway.configuration.card-configuration' * * @todo: Rename this class to CardPaymentsConfiguration! */ diff --git a/modules/ppcp-wc-gateway/src/WCGatewayModule.php b/modules/ppcp-wc-gateway/src/WCGatewayModule.php index 2f82c5636..172e97706 100644 --- a/modules/ppcp-wc-gateway/src/WCGatewayModule.php +++ b/modules/ppcp-wc-gateway/src/WCGatewayModule.php @@ -195,7 +195,7 @@ class WCGatewayModule implements ServiceModule, ExtendingModule, ExecutableModul $settings = $c->get( 'wcgateway.settings' ); assert( $settings instanceof Settings ); - $dcc_configuration = $c->get( 'wcgateway.configuration.dcc' ); + $dcc_configuration = $c->get( 'wcgateway.configuration.card-configuration' ); assert( $dcc_configuration instanceof DCCGatewayConfiguration ); $assets = new SettingsPageAssets( @@ -614,7 +614,7 @@ class WCGatewayModule implements ServiceModule, ExtendingModule, ExecutableModul return $methods; } - $dcc_configuration = $container->get( 'wcgateway.configuration.dcc' ); + $dcc_configuration = $container->get( 'wcgateway.configuration.card-configuration' ); assert( $dcc_configuration instanceof DCCGatewayConfiguration ); $standard_card_button = get_option( 'woocommerce_ppcp-card-button-gateway_settings' ); From a693ca4455046d5886b545a4b44c006dfda2a46c Mon Sep 17 00:00:00 2001 From: Philipp Stracker Date: Fri, 14 Mar 2025 15:14:12 +0100 Subject: [PATCH 26/62] =?UTF-8?q?=E2=9C=A8=20Add=20legacy=20service=20?= =?UTF-8?q?=E2=80=98settings.connection-state=E2=80=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The service is required for DCC configuration (in legacy and new UI mode) --- modules/ppcp-onboarding/services.php | 37 ++++++++++++++++++++-------- 1 file changed, 27 insertions(+), 10 deletions(-) diff --git a/modules/ppcp-onboarding/services.php b/modules/ppcp-onboarding/services.php index 64d136092..2e26885e4 100644 --- a/modules/ppcp-onboarding/services.php +++ b/modules/ppcp-onboarding/services.php @@ -19,6 +19,8 @@ use WooCommerce\PayPalCommerce\Onboarding\Render\OnboardingSendOnlyNoticeRendere use WooCommerce\PayPalCommerce\Onboarding\Render\OnboardingRenderer; use WooCommerce\PayPalCommerce\WcGateway\Helper\Environment; use WooCommerce\PayPalCommerce\WcGateway\Settings\Settings; +use WooCommerce\PayPalCommerce\WcGateway\Helper\ConnectionState; +use WooCommerce\PayPalCommerce\Settings\Data\GeneralSettings; return array( 'api.paypal-host' => function( ContainerInterface $container ) : string { @@ -48,25 +50,40 @@ return array( return new State( $settings ); }, /** - * Checks if the onboarding process is completed and the merchant API can be used. - * This service is overwritten by the ppcp-settings module, when it's active. + * Merchant connection details, which includes the connection status + * (onboarding/connected) and connection-aware environment checks. + * This is the preferred solution to check environment and connection state. */ - 'settings.flag.is-connected' => static function ( ContainerInterface $container ) : bool { + 'settings.connection-state' => static function ( ContainerInterface $container ) : ConnectionState { $state = $container->get( 'onboarding.state' ); assert( $state instanceof State ); - return $state->current_state() >= State::STATE_ONBOARDED; - }, - 'settings.flag.is-sandbox' => static function ( ContainerInterface $container ) : bool { $settings = $container->get( 'wcgateway.settings' ); assert( $settings instanceof Settings ); - return $settings->has( 'sandbox_on' ) && $settings->get( 'sandbox_on' ); + $is_sandbox = $settings->has( 'sandbox_on' ) && $settings->get( 'sandbox_on' ); + $is_connected = $state->current_state() >= State::STATE_ONBOARDED; + $environment = new Environment( $is_sandbox ); + + return new ConnectionState( $is_connected, $environment ); + }, + 'settings.flag.is-connected' => static function ( ContainerInterface $container ) : bool { + $state = $container->get( 'settings.connection-state' ); + assert( $state instanceof ConnectionState ); + + return $state->is_connected(); + }, + 'settings.flag.is-sandbox' => static function ( ContainerInterface $container ) : bool { + $state = $container->get( 'settings.connection-state' ); + assert( $state instanceof ConnectionState ); + + return $state->is_sandbox(); }, 'settings.environment' => function ( ContainerInterface $container ) : Environment { - return new Environment( - $container->get( 'settings.flag.is-sandbox' ) - ); + $state = $container->get( 'settings.connection-state' ); + assert( $state instanceof ConnectionState ); + + return $state->get_environment(); }, 'onboarding.assets' => function( ContainerInterface $container ) : OnboardingAssets { From 4afa8dd4ddc512ea057bae7cd3ff2f97eb32fb03 Mon Sep 17 00:00:00 2001 From: Philipp Stracker Date: Fri, 14 Mar 2025 15:14:41 +0100 Subject: [PATCH 27/62] =?UTF-8?q?=F0=9F=92=A1=20Improve=20comments=20for?= =?UTF-8?q?=20connection-services?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- modules/ppcp-onboarding/services.php | 17 +++++++++++++++++ modules/ppcp-settings/services.php | 24 +++++++++++++----------- 2 files changed, 30 insertions(+), 11 deletions(-) diff --git a/modules/ppcp-onboarding/services.php b/modules/ppcp-onboarding/services.php index 2e26885e4..8a87e4288 100644 --- a/modules/ppcp-onboarding/services.php +++ b/modules/ppcp-onboarding/services.php @@ -67,18 +67,35 @@ return array( return new ConnectionState( $is_connected, $environment ); }, + /** + * Checks if the onboarding process is completed and the merchant API can be used. + * This service only resolves the connection status once per request. + * + * @deprecated Use 'settings.connection-state' instead. + */ 'settings.flag.is-connected' => static function ( ContainerInterface $container ) : bool { $state = $container->get( 'settings.connection-state' ); assert( $state instanceof ConnectionState ); return $state->is_connected(); }, + /** + * Determines whether the merchant is connected to a sandbox account. + * This service only resolves the sandbox flag once per request. + * + * @deprecated Use 'settings.connection-state' instead. + */ 'settings.flag.is-sandbox' => static function ( ContainerInterface $container ) : bool { $state = $container->get( 'settings.connection-state' ); assert( $state instanceof ConnectionState ); return $state->is_sandbox(); }, + /** + * Returns details about the connected environment (production/sandbox). + * + * @deprecated Directly use 'settings.connection-state' instead of this. + */ 'settings.environment' => function ( ContainerInterface $container ) : Environment { $state = $container->get( 'settings.connection-state' ); assert( $state instanceof ConnectionState ); diff --git a/modules/ppcp-settings/services.php b/modules/ppcp-settings/services.php index 71ad9a724..2270d5738 100644 --- a/modules/ppcp-settings/services.php +++ b/modules/ppcp-settings/services.php @@ -137,34 +137,36 @@ return array( return new ConnectionState( $is_connected, $environment ); }, + /** + * Returns details about the connected environment (production/sandbox). + * + * @deprecated Directly use 'settings.connection-state' instead of this. + */ 'settings.environment' => static function ( ContainerInterface $container ) : Environment { - // We should remove this service in favor of directly using `settings.connection-state`. $state = $container->get( 'settings.connection-state' ); assert( $state instanceof ConnectionState ); return $state->get_environment(); }, /** - * Checks if valid merchant connection details are stored in the DB. + * Checks if the onboarding process is completed and the merchant API can be used. + * This service only resolves the connection status once per request. + * + * @deprecated Use 'settings.connection-state' instead. */ 'settings.flag.is-connected' => static function ( ContainerInterface $container ) : bool { - /* - * This service only resolves the connection status once per request. - * We should remove this service in favor of directly using `settings.connection-state`. - */ $state = $container->get( 'settings.connection-state' ); assert( $state instanceof ConnectionState ); return $state->is_connected(); }, /** - * Checks if the merchant is connected to a sandbox environment. + * Determines whether the merchant is connected to a sandbox account. + * This service only resolves the sandbox flag once per request. + * + * @deprecated Use 'settings.connection-state' instead. */ 'settings.flag.is-sandbox' => static function ( ContainerInterface $container ) : bool { - /* - * This service only resolves the sandbox flag once per request. - * We should remove this service in favor of directly using `settings.connection-state`. - */ $state = $container->get( 'settings.connection-state' ); assert( $state instanceof ConnectionState ); From b9d757441805d81389f51ab2e4a5d165808d7637 Mon Sep 17 00:00:00 2001 From: Philipp Stracker Date: Fri, 14 Mar 2025 15:30:01 +0100 Subject: [PATCH 28/62] =?UTF-8?q?=F0=9F=92=A1=20Add/update=20comments=20re?= =?UTF-8?q?lated=20to=20#legacy-ui=20todos?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ppcp-api-client/src/Repository/PartnerReferralsData.php | 4 ++-- modules/ppcp-button/src/Helper/DisabledFundingSources.php | 1 + modules/ppcp-settings/src/SettingsModule.php | 2 +- .../src/Gateway/PayUponInvoice/PayUponInvoice.php | 4 ---- .../ppcp-wc-gateway/src/Helper/DCCGatewayConfiguration.php | 1 + modules/ppcp-wc-gateway/src/Settings/SettingsListener.php | 6 +++--- woocommerce-paypal-payments.php | 2 +- 7 files changed, 9 insertions(+), 11 deletions(-) diff --git a/modules/ppcp-api-client/src/Repository/PartnerReferralsData.php b/modules/ppcp-api-client/src/Repository/PartnerReferralsData.php index d214c9df7..b95ae1ca3 100644 --- a/modules/ppcp-api-client/src/Repository/PartnerReferralsData.php +++ b/modules/ppcp-api-client/src/Repository/PartnerReferralsData.php @@ -21,7 +21,7 @@ class PartnerReferralsData { * @deprecated Deprecates with the new UI. In this class, the products are * always explicit, and should not be deducted from the * DccApplies state at this point. - * Remove this with the legacy UI code. + * Remove this with the #legacy-ui code. * @var DccApplies */ private DccApplies $dcc_applies; @@ -92,7 +92,7 @@ class PartnerReferralsData { $first_party_features[] = 'BILLING_AGREEMENT'; } - // Backwards compatibility. Keep those features in the legacy UI (null-value). + // Backwards compatibility. Keep those features in the #legacy-ui (null-value). // Move this into the previous condition, once legacy code is removed. if ( false !== $use_subscriptions ) { $first_party_features[] = 'FUTURE_PAYMENT'; diff --git a/modules/ppcp-button/src/Helper/DisabledFundingSources.php b/modules/ppcp-button/src/Helper/DisabledFundingSources.php index bc261589c..6883ec687 100644 --- a/modules/ppcp-button/src/Helper/DisabledFundingSources.php +++ b/modules/ppcp-button/src/Helper/DisabledFundingSources.php @@ -154,6 +154,7 @@ class DisabledFundingSources { $available_gateways = WC()->payment_gateways->get_available_payment_gateways(); // TODO: This check does not make much sense in the new UI. The gateway is always available when the "dcc_enabled" flag is true. + // Review and adjust when removing #legacy-ui code. $is_card_gateway_enabled = isset( $available_gateways[ CardButtonGateway::ID ] ); return array( diff --git a/modules/ppcp-settings/src/SettingsModule.php b/modules/ppcp-settings/src/SettingsModule.php index 7ca6f5a20..6656af219 100644 --- a/modules/ppcp-settings/src/SettingsModule.php +++ b/modules/ppcp-settings/src/SettingsModule.php @@ -56,7 +56,7 @@ class SettingsModule implements ServiceModule, ExecutableModule { * Returns whether the old settings UI should be loaded. */ public static function should_use_the_old_ui() : bool { - // New merchants should never see the legacy UI. + // New merchants should never see the #legacy-ui. $show_new_ux = '1' === get_option( 'woocommerce-ppcp-is-new-merchant' ); if ( $show_new_ux ) { diff --git a/modules/ppcp-wc-gateway/src/Gateway/PayUponInvoice/PayUponInvoice.php b/modules/ppcp-wc-gateway/src/Gateway/PayUponInvoice/PayUponInvoice.php index 10ec5ab2c..7ed9532e8 100644 --- a/modules/ppcp-wc-gateway/src/Gateway/PayUponInvoice/PayUponInvoice.php +++ b/modules/ppcp-wc-gateway/src/Gateway/PayUponInvoice/PayUponInvoice.php @@ -137,10 +137,6 @@ class PayUponInvoice { */ public function init(): void { if ( $this->pui_helper->is_pui_gateway_enabled() ) { - /* - * TODO new-ux: Check if we still support this setting, or if it's always enabled. - * If fraudnet is not configurable in new UI, we can ignore this. - */ $this->settings->set( 'fraudnet_enabled', true ); $this->settings->persist(); } diff --git a/modules/ppcp-wc-gateway/src/Helper/DCCGatewayConfiguration.php b/modules/ppcp-wc-gateway/src/Helper/DCCGatewayConfiguration.php index 68637f1c1..9ec3c67d2 100644 --- a/modules/ppcp-wc-gateway/src/Helper/DCCGatewayConfiguration.php +++ b/modules/ppcp-wc-gateway/src/Helper/DCCGatewayConfiguration.php @@ -151,6 +151,7 @@ class DCCGatewayConfiguration { $show_on_card_value = $this->settings->get( 'dcc_name_on_card' ); } elseif ( $this->settings->has( 'axo_name_on_card' ) ) { // Legacy. The AXO gateway setting was replaced by the DCC setting. + // Remove this condition with the #legacy-ui. $show_on_card_value = $this->settings->get( 'axo_name_on_card' ); } if ( in_array( $show_on_card_value, $show_on_card_options, true ) ) { diff --git a/modules/ppcp-wc-gateway/src/Settings/SettingsListener.php b/modules/ppcp-wc-gateway/src/Settings/SettingsListener.php index b612de369..9eb5990c2 100644 --- a/modules/ppcp-wc-gateway/src/Settings/SettingsListener.php +++ b/modules/ppcp-wc-gateway/src/Settings/SettingsListener.php @@ -263,7 +263,7 @@ class SettingsListener { // phpcs:enable WordPress.Security.NonceVerification.Missing // phpcs:enable WordPress.Security.NonceVerification.Recommended - // This method is only used for legacy UI, `settings->set` is valid here. + // This method is only used for #legacy-ui, `settings->set` is valid here. $this->settings->set( 'merchant_id', $merchant_id ); $this->settings->set( 'merchant_email', $merchant_email ); @@ -367,7 +367,7 @@ class SettingsListener { return; } - // This method is only used for legacy UI, `settings->set` is valid here. + // This method is only used for #legacy-ui, `settings->set` is valid here. try { $token = $this->bearer->bearer(); @@ -777,7 +777,7 @@ class SettingsListener { return; } - // This method is only used for legacy UI, `settings->set` is valid here. + // This method is only used for #legacy-ui, `settings->set` is valid here. $existing_setting_value = $this->settings->has( $setting_slug ) ? $this->settings->get( $setting_slug ) : null; diff --git a/woocommerce-paypal-payments.php b/woocommerce-paypal-payments.php index 6f9be629f..9de262f48 100644 --- a/woocommerce-paypal-payments.php +++ b/woocommerce-paypal-payments.php @@ -235,7 +235,7 @@ define( 'PPCP_PAYPAL_BN_CODE', 'Woo_PPCP' ); * Set new merchant flag on plugin install. * * When installing the plugin for the first time, we direct the user to - * the new UI without a data migration, and fully hide the legacy UI. + * the new UI without a data migration, and fully hide the #legacy-ui. * * @param string|false $version String with previous installed plugin version. * Boolean false on first installation on a new site. From 197e3ef0ed72edec04f3fcc5a2e4a0e8f2b3b7a8 Mon Sep 17 00:00:00 2001 From: Philipp Stracker Date: Fri, 14 Mar 2025 15:39:51 +0100 Subject: [PATCH 29/62] =?UTF-8?q?=E2=9C=A8=20New=20filter=20to=20disable?= =?UTF-8?q?=20card=20payments?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is a preparation for the planned branded-experience. --- .../src/Helper/DCCGatewayConfiguration.php | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/modules/ppcp-wc-gateway/src/Helper/DCCGatewayConfiguration.php b/modules/ppcp-wc-gateway/src/Helper/DCCGatewayConfiguration.php index 9ec3c67d2..c0de17066 100644 --- a/modules/ppcp-wc-gateway/src/Helper/DCCGatewayConfiguration.php +++ b/modules/ppcp-wc-gateway/src/Helper/DCCGatewayConfiguration.php @@ -127,6 +127,18 @@ class DCCGatewayConfiguration { $this->show_name_on_card = $show_on_card_options[0]; $this->hide_fastlane_watermark = false; + /** + * Allow modules or other plugins to disable card payments for this shop. + */ + $disable_card_payments = apply_filters( + 'woocommerce_paypal_payments_card_payments_disabled', + false + ); + + if ( $disable_card_payments ) { + return; + } + if ( ! $this->connection_state->is_connected() ) { return; } From 282d273c96a8d79b7f1d3d9246b493854b998b86 Mon Sep 17 00:00:00 2001 From: Philipp Stracker Date: Fri, 14 Mar 2025 15:44:47 +0100 Subject: [PATCH 30/62] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20Simplify=20the=20car?= =?UTF-8?q?d=20payments=20flag=20logic?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/Helper/DCCGatewayConfiguration.php | 25 ++++++++++--------- 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/modules/ppcp-wc-gateway/src/Helper/DCCGatewayConfiguration.php b/modules/ppcp-wc-gateway/src/Helper/DCCGatewayConfiguration.php index c0de17066..8369891be 100644 --- a/modules/ppcp-wc-gateway/src/Helper/DCCGatewayConfiguration.php +++ b/modules/ppcp-wc-gateway/src/Helper/DCCGatewayConfiguration.php @@ -120,11 +120,13 @@ class DCCGatewayConfiguration { $show_on_card_options = array_keys( PropertiesDictionary::cardholder_name_options() ); $show_on_card_value = null; + // Reset all flags, disable everything. + $this->use_acdc = false; $this->is_enabled = false; $this->use_fastlane = false; $this->gateway_title = ''; $this->gateway_description = ''; - $this->show_name_on_card = $show_on_card_options[0]; + $this->show_name_on_card = $show_on_card_options[0]; // 'no'. $this->hide_fastlane_watermark = false; /** @@ -144,13 +146,15 @@ class DCCGatewayConfiguration { } try { - /* - * In case one of the following three settings is missing in the DB the - * Settings instance throws an exception and all features are set to "not available". - */ $is_paypal_enabled = filter_var( $this->settings->get( 'enabled' ), FILTER_VALIDATE_BOOLEAN ); - $is_dcc_enabled = filter_var( $this->settings->get( 'dcc_enabled' ), FILTER_VALIDATE_BOOLEAN ); - $is_axo_enabled = filter_var( $this->settings->get( 'axo_enabled' ), FILTER_VALIDATE_BOOLEAN ); + + // When the core payment logic of the plugin is disabled, we cannot handle card payments. + if ( ! $is_paypal_enabled ) { + return; + } + + $is_dcc_enabled = filter_var( $this->settings->get( 'dcc_enabled' ), FILTER_VALIDATE_BOOLEAN ); + $this->use_fastlane = filter_var( $this->settings->get( 'axo_enabled' ), FILTER_VALIDATE_BOOLEAN ); if ( $this->settings->has( 'dcc_gateway_title' ) ) { $this->gateway_title = $this->settings->get( 'dcc_gateway_title' ); @@ -171,13 +175,10 @@ class DCCGatewayConfiguration { } } catch ( NotFoundException $exception ) { // A setting is missing in the DB, disable card payments. - $is_paypal_enabled = false; - $is_dcc_enabled = false; - $is_axo_enabled = false; + return; } - $this->is_enabled = $is_paypal_enabled && $is_dcc_enabled; - $this->use_fastlane = $this->is_enabled && $is_axo_enabled; + $this->is_enabled = $is_dcc_enabled; /** * Changing this to true (and hiding the watermark) has potential legal From 640c324842dd3e0f164a045071acd9568170a6bc Mon Sep 17 00:00:00 2001 From: Philipp Stracker Date: Fri, 14 Mar 2025 15:48:09 +0100 Subject: [PATCH 31/62] =?UTF-8?q?=E2=9C=A8=20Prepare=20config=20getters=20?= =?UTF-8?q?for=20ACDC/BCDC=20detection?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/Helper/DCCGatewayConfiguration.php | 37 ++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/modules/ppcp-wc-gateway/src/Helper/DCCGatewayConfiguration.php b/modules/ppcp-wc-gateway/src/Helper/DCCGatewayConfiguration.php index 8369891be..8ce883136 100644 --- a/modules/ppcp-wc-gateway/src/Helper/DCCGatewayConfiguration.php +++ b/modules/ppcp-wc-gateway/src/Helper/DCCGatewayConfiguration.php @@ -53,6 +53,13 @@ class DCCGatewayConfiguration { */ private Settings $settings; + /** + * Indicates whether the merchant uses ACDC (true) or BCDC (false). + * + * @var bool + */ + private bool $use_acdc = false; + /** * Whether the Credit Card gateway is enabled. * @@ -193,16 +200,44 @@ class DCCGatewayConfiguration { } /** - * Whether the "Advanced Card Payments" gateway is enabled. + * Indicated whether the merchant is in ACDC mode. + * + * @return bool + */ + public function use_acdc() : bool { + return $this->use_acdc; + } + + /** + * Whether card payments are enabled. * * Requires PayPal features to be enabled. * + * @internal Use "is_acdc_enabled()" or "is_bcdc_enabled()" instead. * @return bool */ public function is_enabled() : bool { return $this->is_enabled; } + /** + * True, if the card payments are enabled and the merchant is in ACDC mode. + * + * @return bool + */ + public function is_acdc_enabled() : bool { + return $this->is_enabled() && $this->use_acdc(); + } + + /** + * True, if card payments are enabled and the merchant is in BCDC mode. + * + * @return bool + */ + public function is_bcdc_enabled() : bool { + return $this->is_enabled() && ! $this->use_acdc(); + } + /** * Whether to prefer Fastlane instead of the default Credit Card UI, if * available in the shop's region. From 29f56a7db86cfedc94bb81384074ec201874083e Mon Sep 17 00:00:00 2001 From: Philipp Stracker Date: Fri, 14 Mar 2025 16:02:35 +0100 Subject: [PATCH 32/62] =?UTF-8?q?=E2=9C=A8=20Lazily=20resolve=20card=20pay?= =?UTF-8?q?ment=20configuration?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/Helper/DCCGatewayConfiguration.php | 57 +++++++++++++++++-- 1 file changed, 52 insertions(+), 5 deletions(-) diff --git a/modules/ppcp-wc-gateway/src/Helper/DCCGatewayConfiguration.php b/modules/ppcp-wc-gateway/src/Helper/DCCGatewayConfiguration.php index 8ce883136..0adf93861 100644 --- a/modules/ppcp-wc-gateway/src/Helper/DCCGatewayConfiguration.php +++ b/modules/ppcp-wc-gateway/src/Helper/DCCGatewayConfiguration.php @@ -30,6 +30,7 @@ use WooCommerce\PayPalCommerce\Axo\Helper\PropertiesDictionary; * * a. Funding source * - All card payment options require the funding-source "card" + * * b. Components * - ACDC and AXO use "card-fields" * - BCDC uses "hosted-fields" @@ -53,6 +54,14 @@ class DCCGatewayConfiguration { */ private Settings $settings; + /** + * This classes lazily resolves settings on first access. This flag indicates + * whether the setting values were resolved, or still need to be evaluated. + * + * @var bool + */ + public bool $is_resolved = false; + /** * Indicates whether the merchant uses ACDC (true) or BCDC (false). * @@ -114,16 +123,38 @@ class DCCGatewayConfiguration { $this->connection_state = $connection_state; $this->settings = $settings; - $this->refresh(); + $this->is_resolved = false; } /** - * Refreshes the gateway configuration based on the current settings. + * Marks the current settings as "outdated". The next time a setting is accessed + * it will be resolved using the current settings. * - * This method should be used sparingly, usually only on the settings page - * when changes in gateway settings must be reflected immediately. + * @return void */ public function refresh() : void { + $this->is_resolved = false; + } + + /** + * Ensures the internally cached flags correctly reflect the current settings. + * + * @return void + */ + private function ensure_resolved_values() : void { + if ( ! $this->is_resolved ) { + return; + } + + $this->resolve(); + + $this->is_resolved = true; + } + + /** + * Refreshes the internal gateway configuration based on the current settings. + */ + private function resolve() : void { $show_on_card_options = array_keys( PropertiesDictionary::cardholder_name_options() ); $show_on_card_value = null; @@ -205,6 +236,8 @@ class DCCGatewayConfiguration { * @return bool */ public function use_acdc() : bool { + $this->ensure_resolved_values(); + return $this->use_acdc; } @@ -217,12 +250,20 @@ class DCCGatewayConfiguration { * @return bool */ public function is_enabled() : bool { + $this->ensure_resolved_values(); + return $this->is_enabled; } /** * True, if the card payments are enabled and the merchant is in ACDC mode. * + * If this returns false, the following payment methods are unavailable: + * - Advanced Card Processing + * - Fastlane + * - Google Pay + * - Apple Pay + * * @return bool */ public function is_acdc_enabled() : bool { @@ -247,7 +288,7 @@ class DCCGatewayConfiguration { * @return bool */ public function use_fastlane() : bool { - return $this->use_fastlane; + return $this->is_acdc_enabled() && $this->use_fastlane; } /** @@ -258,6 +299,7 @@ class DCCGatewayConfiguration { * @return string Display title of the gateway. */ public function gateway_title( string $fallback = '' ) : string { + $this->ensure_resolved_values(); if ( $this->gateway_title ) { return $this->gateway_title; } @@ -273,6 +315,7 @@ class DCCGatewayConfiguration { * @return string Display description of the gateway. */ public function gateway_description( string $fallback = '' ) : string { + $this->ensure_resolved_values(); if ( $this->gateway_description ) { return $this->gateway_description; } @@ -292,6 +335,8 @@ class DCCGatewayConfiguration { * @return string ['yes'|'no'] */ public function show_name_on_card() : string { + $this->ensure_resolved_values(); + return $this->show_name_on_card; } @@ -304,6 +349,8 @@ class DCCGatewayConfiguration { * @retun bool True means, the default watermark is displayed to customers. */ public function show_fastlane_watermark() : bool { + $this->ensure_resolved_values(); + return ! $this->hide_fastlane_watermark; } } From afb7044b03410daea455a151b09b6808ce239656 Mon Sep 17 00:00:00 2001 From: Philipp Stracker Date: Fri, 14 Mar 2025 16:15:23 +0100 Subject: [PATCH 33/62] =?UTF-8?q?=F0=9F=9A=9A=20Rename=20configuration=20c?= =?UTF-8?q?lass?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The class name does not reflect the purpose of the class --- modules/ppcp-axo-block/src/AxoBlockModule.php | 4 -- .../src/AxoBlockPaymentMethod.php | 10 ++-- modules/ppcp-axo/services.php | 4 +- modules/ppcp-axo/src/AxoModule.php | 12 ++-- modules/ppcp-axo/src/Gateway/AxoGateway.php | 32 +++++----- .../src/Helper/CompatibilityChecker.php | 14 ++--- modules/ppcp-button/services.php | 4 +- .../ppcp-button/src/Assets/SmartButton.php | 58 +++++++++---------- .../src/Helper/DisabledFundingSources.php | 14 ++--- .../ppcp-card-fields/src/CardFieldsModule.php | 4 +- modules/ppcp-wc-gateway/services.php | 10 ++-- .../src/Gateway/CreditCardGateway.php | 46 +++++++-------- ...tion.php => CardPaymentsConfiguration.php} | 4 +- .../GatewayWithoutPayPalAdminNotice.php | 22 +++---- .../ppcp-wc-gateway/src/WCGatewayModule.php | 6 +- .../Helper/DisabledFundingSourcesTest.php | 4 +- .../Gateway/CreditCardGatewayTest.php | 4 +- 17 files changed, 123 insertions(+), 129 deletions(-) rename modules/ppcp-wc-gateway/src/Helper/{DCCGatewayConfiguration.php => CardPaymentsConfiguration.php} (99%) diff --git a/modules/ppcp-axo-block/src/AxoBlockModule.php b/modules/ppcp-axo-block/src/AxoBlockModule.php index 55acb4455..d5d4021da 100644 --- a/modules/ppcp-axo-block/src/AxoBlockModule.php +++ b/modules/ppcp-axo-block/src/AxoBlockModule.php @@ -14,15 +14,11 @@ use Psr\Log\LoggerInterface; use WooCommerce\PayPalCommerce\ApiClient\Authentication\SdkClientToken; use WooCommerce\PayPalCommerce\ApiClient\Exception\PayPalApiException; use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException; -use WooCommerce\PayPalCommerce\Blocks\Endpoint\UpdateShippingEndpoint; -use WooCommerce\PayPalCommerce\Button\Assets\SmartButtonInterface; -use WooCommerce\PayPalCommerce\WcGateway\Gateway\CreditCardGateway; use WooCommerce\PayPalCommerce\Vendor\Inpsyde\Modularity\Module\ExecutableModule; use WooCommerce\PayPalCommerce\Vendor\Inpsyde\Modularity\Module\ExtendingModule; use WooCommerce\PayPalCommerce\Vendor\Inpsyde\Modularity\Module\ModuleClassNameIdTrait; use WooCommerce\PayPalCommerce\Vendor\Inpsyde\Modularity\Module\ServiceModule; use WooCommerce\PayPalCommerce\Vendor\Psr\Container\ContainerInterface; -use WooCommerce\PayPalCommerce\WcGateway\Helper\DCCGatewayConfiguration; /** * Class AxoBlockModule diff --git a/modules/ppcp-axo-block/src/AxoBlockPaymentMethod.php b/modules/ppcp-axo-block/src/AxoBlockPaymentMethod.php index db4d5438e..92a76e101 100644 --- a/modules/ppcp-axo-block/src/AxoBlockPaymentMethod.php +++ b/modules/ppcp-axo-block/src/AxoBlockPaymentMethod.php @@ -16,7 +16,7 @@ use WooCommerce\PayPalCommerce\Button\Assets\SmartButtonInterface; use WooCommerce\PayPalCommerce\WcGateway\Helper\Environment; use WooCommerce\PayPalCommerce\Axo\Gateway\AxoGateway; use WooCommerce\PayPalCommerce\WcGateway\Settings\Settings; -use WooCommerce\PayPalCommerce\WcGateway\Helper\DCCGatewayConfiguration; +use WooCommerce\PayPalCommerce\WcGateway\Helper\CardPaymentsConfiguration; /** * Class AxoBlockPaymentMethod @@ -61,9 +61,9 @@ class AxoBlockPaymentMethod extends AbstractPaymentMethodType { /** * The DCC gateway settings. * - * @var DCCGatewayConfiguration + * @var CardPaymentsConfiguration */ - protected DCCGatewayConfiguration $dcc_configuration; + protected CardPaymentsConfiguration $dcc_configuration; /** * The environment object. @@ -101,7 +101,7 @@ class AxoBlockPaymentMethod extends AbstractPaymentMethodType { * @param WC_Payment_Gateway $gateway Credit card gateway. * @param SmartButtonInterface|callable $smart_button The smart button script loading handler. * @param Settings $settings The settings. - * @param DCCGatewayConfiguration $dcc_configuration The DCC gateway settings. + * @param CardPaymentsConfiguration $dcc_configuration The DCC gateway settings. * @param Environment $environment The environment object. * @param string $wcgateway_module_url The WcGateway module URL. * @param array $payment_method_selected_map Mapping of payment methods to the PayPal Insights 'payment_method_selected' types. @@ -113,7 +113,7 @@ class AxoBlockPaymentMethod extends AbstractPaymentMethodType { WC_Payment_Gateway $gateway, $smart_button, Settings $settings, - DCCGatewayConfiguration $dcc_configuration, + CardPaymentsConfiguration $dcc_configuration, Environment $environment, string $wcgateway_module_url, array $payment_method_selected_map, diff --git a/modules/ppcp-axo/services.php b/modules/ppcp-axo/services.php index c3d79ab08..91d8b49e8 100644 --- a/modules/ppcp-axo/services.php +++ b/modules/ppcp-axo/services.php @@ -17,7 +17,7 @@ use WooCommerce\PayPalCommerce\Vendor\Psr\Container\ContainerInterface; use WooCommerce\PayPalCommerce\WcGateway\Gateway\CreditCardGateway; use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayPalGateway; use WooCommerce\PayPalCommerce\WcGateway\Settings\Settings; -use WooCommerce\PayPalCommerce\WcGateway\Helper\DCCGatewayConfiguration; +use WooCommerce\PayPalCommerce\WcGateway\Helper\CardPaymentsConfiguration; use WooCommerce\PayPalCommerce\ApiClient\Helper\CurrencyGetter; return array( @@ -229,7 +229,7 @@ return array( 'axo.smart-button-location-notice' => static function ( ContainerInterface $container ) : string { $dcc_configuration = $container->get( 'wcgateway.configuration.card-configuration' ); - assert( $dcc_configuration instanceof DCCGatewayConfiguration ); + assert( $dcc_configuration instanceof CardPaymentsConfiguration ); if ( $dcc_configuration->use_fastlane() ) { $fastlane_settings_url = admin_url( diff --git a/modules/ppcp-axo/src/AxoModule.php b/modules/ppcp-axo/src/AxoModule.php index bd81f04cb..d4a68f956 100644 --- a/modules/ppcp-axo/src/AxoModule.php +++ b/modules/ppcp-axo/src/AxoModule.php @@ -30,7 +30,7 @@ use WooCommerce\PayPalCommerce\WcGateway\Helper\CartCheckoutDetector; use WooCommerce\PayPalCommerce\WcGateway\Settings\SettingsListener; use WooCommerce\PayPalCommerce\WcSubscriptions\Helper\SubscriptionHelper; use WC_Payment_Gateways; -use WooCommerce\PayPalCommerce\WcGateway\Helper\DCCGatewayConfiguration; +use WooCommerce\PayPalCommerce\WcGateway\Helper\CardPaymentsConfiguration; /** * Class AxoModule @@ -99,7 +99,7 @@ class AxoModule implements ServiceModule, ExtendingModule, ExecutableModule { } $dcc_configuration = $c->get( 'wcgateway.configuration.card-configuration' ); - assert( $dcc_configuration instanceof DCCGatewayConfiguration ); + assert( $dcc_configuration instanceof CardPaymentsConfiguration ); if ( ! $dcc_configuration->is_enabled() ) { return $methods; @@ -165,7 +165,7 @@ class AxoModule implements ServiceModule, ExtendingModule, ExecutableModule { assert( $listener instanceof SettingsListener ); $dcc_configuration = $c->get( 'wcgateway.configuration.card-configuration' ); - assert( $dcc_configuration instanceof DCCGatewayConfiguration ); + assert( $dcc_configuration instanceof CardPaymentsConfiguration ); $listener->filter_settings( $dcc_configuration->use_fastlane(), @@ -248,7 +248,7 @@ class AxoModule implements ServiceModule, ExtendingModule, ExecutableModule { 'woocommerce_paypal_payments_sdk_components_hook', function( $components ) use ( $c ) { $dcc_configuration = $c->get( 'wcgateway.configuration.card-configuration' ); - assert( $dcc_configuration instanceof DCCGatewayConfiguration ); + assert( $dcc_configuration instanceof CardPaymentsConfiguration ); if ( ! $dcc_configuration->use_fastlane() ) { return $components; @@ -263,7 +263,7 @@ class AxoModule implements ServiceModule, ExtendingModule, ExecutableModule { function () use ( $c ) { // Add meta tag to allow feature-detection of the site's AXO payment state. $dcc_configuration = $c->get( 'wcgateway.configuration.card-configuration' ); - assert( $dcc_configuration instanceof DCCGatewayConfiguration ); + assert( $dcc_configuration instanceof CardPaymentsConfiguration ); if ( $dcc_configuration->use_fastlane() ) { // phpcs:ignore WordPress.WP.EnqueuedResources.NonEnqueuedScript @@ -404,7 +404,7 @@ class AxoModule implements ServiceModule, ExtendingModule, ExecutableModule { */ private function should_render_fastlane( ContainerInterface $c ): bool { $dcc_configuration = $c->get( 'wcgateway.configuration.card-configuration' ); - assert( $dcc_configuration instanceof DCCGatewayConfiguration ); + assert( $dcc_configuration instanceof CardPaymentsConfiguration ); $subscription_helper = $c->get( 'wc-subscriptions.helper' ); assert( $subscription_helper instanceof SubscriptionHelper ); diff --git a/modules/ppcp-axo/src/Gateway/AxoGateway.php b/modules/ppcp-axo/src/Gateway/AxoGateway.php index ead4f291a..5e2577000 100644 --- a/modules/ppcp-axo/src/Gateway/AxoGateway.php +++ b/modules/ppcp-axo/src/Gateway/AxoGateway.php @@ -29,7 +29,7 @@ use WooCommerce\PayPalCommerce\WcGateway\Settings\SettingsRenderer; use WooCommerce\PayPalCommerce\WcGateway\Gateway\ProcessPaymentTrait; use WooCommerce\PayPalCommerce\WcGateway\Exception\GatewayGenericException; use WooCommerce\PayPalCommerce\Session\SessionHandler; -use WooCommerce\PayPalCommerce\WcGateway\Helper\DCCGatewayConfiguration; +use WooCommerce\PayPalCommerce\WcGateway\Helper\CardPaymentsConfiguration; /** * Class AXOGateway. @@ -56,9 +56,9 @@ class AxoGateway extends WC_Payment_Gateway { /** * Gateway configuration object, providing relevant settings. * - * @var DCCGatewayConfiguration + * @var CardPaymentsConfiguration */ - protected DCCGatewayConfiguration $dcc_configuration; + protected CardPaymentsConfiguration $dcc_configuration; /** * The WcGateway module URL. @@ -133,24 +133,24 @@ class AxoGateway extends WC_Payment_Gateway { /** * AXOGateway constructor. * - * @param SettingsRenderer $settings_renderer The settings renderer. - * @param ContainerInterface $ppcp_settings The settings. - * @param DCCGatewayConfiguration $dcc_configuration The DCC Gateway configuration. - * @param string $wcgateway_module_url The WcGateway module URL. - * @param SessionHandler $session_handler The Session Handler. - * @param OrderProcessor $order_processor The Order processor. - * @param array $card_icons The card icons. - * @param OrderEndpoint $order_endpoint The order endpoint. - * @param PurchaseUnitFactory $purchase_unit_factory The purchase unit factory. + * @param SettingsRenderer $settings_renderer The settings renderer. + * @param ContainerInterface $ppcp_settings The settings. + * @param CardPaymentsConfiguration $dcc_configuration The DCC Gateway configuration. + * @param string $wcgateway_module_url The WcGateway module URL. + * @param SessionHandler $session_handler The Session Handler. + * @param OrderProcessor $order_processor The Order processor. + * @param array $card_icons The card icons. + * @param OrderEndpoint $order_endpoint The order endpoint. + * @param PurchaseUnitFactory $purchase_unit_factory The purchase unit factory. * @param ShippingPreferenceFactory $shipping_preference_factory The shipping preference factory. - * @param TransactionUrlProvider $transaction_url_provider The transaction url provider. - * @param Environment $environment The environment. - * @param LoggerInterface $logger The logger. + * @param TransactionUrlProvider $transaction_url_provider The transaction url provider. + * @param Environment $environment The environment. + * @param LoggerInterface $logger The logger. */ public function __construct( SettingsRenderer $settings_renderer, ContainerInterface $ppcp_settings, - DCCGatewayConfiguration $dcc_configuration, + CardPaymentsConfiguration $dcc_configuration, string $wcgateway_module_url, SessionHandler $session_handler, OrderProcessor $order_processor, diff --git a/modules/ppcp-axo/src/Helper/CompatibilityChecker.php b/modules/ppcp-axo/src/Helper/CompatibilityChecker.php index 1ab4d15a3..9d27781db 100644 --- a/modules/ppcp-axo/src/Helper/CompatibilityChecker.php +++ b/modules/ppcp-axo/src/Helper/CompatibilityChecker.php @@ -13,7 +13,7 @@ namespace WooCommerce\PayPalCommerce\Axo\Helper; use WooCommerce\PayPalCommerce\WcGateway\Helper\CartCheckoutDetector; use WooCommerce\PayPalCommerce\WcGateway\Settings\Settings; use WooCommerce\PayPalCommerce\WcGateway\Exception\NotFoundException; -use WooCommerce\PayPalCommerce\WcGateway\Helper\DCCGatewayConfiguration; +use WooCommerce\PayPalCommerce\WcGateway\Helper\CardPaymentsConfiguration; /** * Class CompatibilityChecker @@ -38,18 +38,18 @@ class CompatibilityChecker { /** * Provides details about the DCC configuration. * - * @var DCCGatewayConfiguration + * @var CardPaymentsConfiguration */ - private DCCGatewayConfiguration $dcc_configuration; + private CardPaymentsConfiguration $dcc_configuration; /** * CompatibilityChecker constructor. * - * @param string[] $incompatible_plugin_names The list of Fastlane incompatible - * plugin names. - * @param DCCGatewayConfiguration $dcc_configuration DCC gateway configuration. + * @param string[] $incompatible_plugin_names The list of Fastlane incompatible + * plugin names. + * @param CardPaymentsConfiguration $dcc_configuration DCC gateway configuration. */ - public function __construct( array $incompatible_plugin_names, DCCGatewayConfiguration $dcc_configuration ) { + public function __construct( array $incompatible_plugin_names, CardPaymentsConfiguration $dcc_configuration ) { $this->incompatible_plugin_names = $incompatible_plugin_names; $this->dcc_configuration = $dcc_configuration; diff --git a/modules/ppcp-button/services.php b/modules/ppcp-button/services.php index d2ccb9e64..a11516b82 100644 --- a/modules/ppcp-button/services.php +++ b/modules/ppcp-button/services.php @@ -37,7 +37,7 @@ use WooCommerce\PayPalCommerce\Button\Helper\MessagesApply; use WooCommerce\PayPalCommerce\Button\Helper\ThreeDSecure; use WooCommerce\PayPalCommerce\WcGateway\Helper\Environment; use WooCommerce\PayPalCommerce\WcGateway\Helper\SettingsStatus; -use WooCommerce\PayPalCommerce\WcGateway\Helper\DCCGatewayConfiguration; +use WooCommerce\PayPalCommerce\WcGateway\Helper\CardPaymentsConfiguration; return array( 'button.client_id' => static function ( ContainerInterface $container ): string { @@ -116,7 +116,7 @@ return array( $no_smart_buttons = ! $settings_status->is_smart_button_enabled_for_location( $context ); $dcc_configuration = $container->get( 'wcgateway.configuration.card-configuration' ); - assert( $dcc_configuration instanceof DCCGatewayConfiguration ); + assert( $dcc_configuration instanceof CardPaymentsConfiguration ); if ( $no_smart_buttons && ! $dcc_configuration->is_enabled() ) { // Smart buttons disabled, and also not using advanced card payments. diff --git a/modules/ppcp-button/src/Assets/SmartButton.php b/modules/ppcp-button/src/Assets/SmartButton.php index 268fa2673..62dcd9f0f 100644 --- a/modules/ppcp-button/src/Assets/SmartButton.php +++ b/modules/ppcp-button/src/Assets/SmartButton.php @@ -54,7 +54,7 @@ use WooCommerce\PayPalCommerce\WcGateway\Helper\SettingsStatus; use WooCommerce\PayPalCommerce\WcGateway\Settings\Settings; use WC_Shipping_Method; use WC_Cart; -use WooCommerce\PayPalCommerce\WcGateway\Helper\DCCGatewayConfiguration; +use WooCommerce\PayPalCommerce\WcGateway\Helper\CardPaymentsConfiguration; /** * Class SmartButton @@ -241,38 +241,38 @@ class SmartButton implements SmartButtonInterface { /** * Provides details about the DCC configuration. * - * @var DCCGatewayConfiguration + * @var CardPaymentsConfiguration */ - private DCCGatewayConfiguration $dcc_configuration; + private CardPaymentsConfiguration $dcc_configuration; /** * SmartButton constructor. * - * @param string $module_url The URL to the module. - * @param string $version The assets version. - * @param SessionHandler $session_handler The Session handler. - * @param Settings $settings The Settings. - * @param PayerFactory $payer_factory The Payer factory. - * @param string $client_id The client ID. - * @param RequestData $request_data The Request Data helper. - * @param DccApplies $dcc_applies The DCC applies helper. - * @param SubscriptionHelper $subscription_helper The subscription helper. - * @param MessagesApply $messages_apply The Messages apply helper. - * @param Environment $environment The environment object. - * @param PaymentTokenRepository $payment_token_repository The payment token repository. - * @param SettingsStatus $settings_status The Settings status helper. - * @param CurrencyGetter $currency The getter of the 3-letter currency code of the shop. - * @param array $all_funding_sources All existing funding sources. - * @param bool $basic_checkout_validation_enabled Whether the basic JS validation of the form iss enabled. - * @param bool $early_validation_enabled Whether to execute WC validation of the checkout form. - * @param array $pay_now_contexts The contexts that should have the Pay Now button. - * @param string[] $funding_sources_without_redirect The sources that do not cause issues about redirecting (on mobile, ...) and sometimes not returning back. - * @param bool $vault_v3_enabled Whether Vault v3 module is enabled. - * @param PaymentTokensEndpoint $payment_tokens_endpoint Payment tokens endpoint. - * @param LoggerInterface $logger The logger. - * @param bool $should_handle_shipping_in_paypal Whether the shipping should be handled in PayPal. - * @param DisabledFundingSources $disabled_funding_sources List of funding sources to be disabled. - * @param DCCGatewayConfiguration $dcc_configuration The DCC Gateway Configuration. + * @param string $module_url The URL to the module. + * @param string $version The assets version. + * @param SessionHandler $session_handler The Session handler. + * @param Settings $settings The Settings. + * @param PayerFactory $payer_factory The Payer factory. + * @param string $client_id The client ID. + * @param RequestData $request_data The Request Data helper. + * @param DccApplies $dcc_applies The DCC applies helper. + * @param SubscriptionHelper $subscription_helper The subscription helper. + * @param MessagesApply $messages_apply The Messages apply helper. + * @param Environment $environment The environment object. + * @param PaymentTokenRepository $payment_token_repository The payment token repository. + * @param SettingsStatus $settings_status The Settings status helper. + * @param CurrencyGetter $currency The getter of the 3-letter currency code of the shop. + * @param array $all_funding_sources All existing funding sources. + * @param bool $basic_checkout_validation_enabled Whether the basic JS validation of the form iss enabled. + * @param bool $early_validation_enabled Whether to execute WC validation of the checkout form. + * @param array $pay_now_contexts The contexts that should have the Pay Now button. + * @param string[] $funding_sources_without_redirect The sources that do not cause issues about redirecting (on mobile, ...) and sometimes not returning back. + * @param bool $vault_v3_enabled Whether Vault v3 module is enabled. + * @param PaymentTokensEndpoint $payment_tokens_endpoint Payment tokens endpoint. + * @param LoggerInterface $logger The logger. + * @param bool $should_handle_shipping_in_paypal Whether the shipping should be handled in PayPal. + * @param DisabledFundingSources $disabled_funding_sources List of funding sources to be disabled. + * @param CardPaymentsConfiguration $dcc_configuration The DCC Gateway Configuration. */ public function __construct( string $module_url, @@ -299,7 +299,7 @@ class SmartButton implements SmartButtonInterface { LoggerInterface $logger, bool $should_handle_shipping_in_paypal, DisabledFundingSources $disabled_funding_sources, - DCCGatewayConfiguration $dcc_configuration + CardPaymentsConfiguration $dcc_configuration ) { $this->module_url = $module_url; $this->version = $version; diff --git a/modules/ppcp-button/src/Helper/DisabledFundingSources.php b/modules/ppcp-button/src/Helper/DisabledFundingSources.php index 6883ec687..7d24974a9 100644 --- a/modules/ppcp-button/src/Helper/DisabledFundingSources.php +++ b/modules/ppcp-button/src/Helper/DisabledFundingSources.php @@ -13,7 +13,7 @@ use WooCommerce\PayPalCommerce\WcGateway\Exception\NotFoundException; use WooCommerce\PayPalCommerce\WcGateway\Gateway\CardButtonGateway; use WooCommerce\PayPalCommerce\WcGateway\Settings\Settings; use WooCommerce\PayPalCommerce\WcSubscriptions\FreeTrialHandlerTrait; -use WooCommerce\PayPalCommerce\WcGateway\Helper\DCCGatewayConfiguration; +use WooCommerce\PayPalCommerce\WcGateway\Helper\CardPaymentsConfiguration; /** * Class DisabledFundingSources @@ -39,18 +39,18 @@ class DisabledFundingSources { /** * Provides details about the DCC configuration. * - * @var DCCGatewayConfiguration + * @var CardPaymentsConfiguration */ - private DCCGatewayConfiguration $dcc_configuration; + private CardPaymentsConfiguration $dcc_configuration; /** * DisabledFundingSources constructor. * - * @param Settings $settings The settings. - * @param array $all_funding_sources All existing funding sources. - * @param DCCGatewayConfiguration $dcc_configuration DCC gateway configuration. + * @param Settings $settings The settings. + * @param array $all_funding_sources All existing funding sources. + * @param CardPaymentsConfiguration $dcc_configuration DCC gateway configuration. */ - public function __construct( Settings $settings, array $all_funding_sources, DCCGatewayConfiguration $dcc_configuration ) { + public function __construct( Settings $settings, array $all_funding_sources, CardPaymentsConfiguration $dcc_configuration ) { $this->settings = $settings; $this->all_funding_sources = $all_funding_sources; $this->dcc_configuration = $dcc_configuration; diff --git a/modules/ppcp-card-fields/src/CardFieldsModule.php b/modules/ppcp-card-fields/src/CardFieldsModule.php index 47c86bdf4..1fb2a6ddf 100644 --- a/modules/ppcp-card-fields/src/CardFieldsModule.php +++ b/modules/ppcp-card-fields/src/CardFieldsModule.php @@ -16,7 +16,7 @@ use WooCommerce\PayPalCommerce\Vendor\Inpsyde\Modularity\Module\ServiceModule; use WooCommerce\PayPalCommerce\Vendor\Psr\Container\ContainerInterface; use WooCommerce\PayPalCommerce\WcGateway\Gateway\CreditCardGateway; use WooCommerce\PayPalCommerce\WcGateway\Settings\Settings; -use WooCommerce\PayPalCommerce\WcGateway\Helper\DCCGatewayConfiguration; +use WooCommerce\PayPalCommerce\WcGateway\Helper\CardPaymentsConfiguration; /** * Class CardFieldsModule @@ -55,7 +55,7 @@ class CardFieldsModule implements ServiceModule, ExtendingModule, ExecutableModu 'woocommerce_paypal_payments_sdk_components_hook', static function( $components ) use ( $c ) { $dcc_config = $c->get( 'wcgateway.configuration.card-configuration' ); - assert( $dcc_config instanceof DCCGatewayConfiguration ); + assert( $dcc_config instanceof CardPaymentsConfiguration ); if ( ! $dcc_config->is_enabled() ) { return $components; diff --git a/modules/ppcp-wc-gateway/services.php b/modules/ppcp-wc-gateway/services.php index b415c5c6b..29631d796 100644 --- a/modules/ppcp-wc-gateway/services.php +++ b/modules/ppcp-wc-gateway/services.php @@ -83,7 +83,7 @@ use WooCommerce\PayPalCommerce\WcGateway\Settings\SettingsListener; use WooCommerce\PayPalCommerce\WcGateway\Settings\SettingsRenderer; use WooCommerce\PayPalCommerce\Axo\Helper\PropertiesDictionary; use WooCommerce\PayPalCommerce\Applepay\ApplePayGateway; -use WooCommerce\PayPalCommerce\WcGateway\Helper\DCCGatewayConfiguration; +use WooCommerce\PayPalCommerce\WcGateway\Helper\CardPaymentsConfiguration; use WooCommerce\PayPalCommerce\WcGateway\Helper\ConnectionState; return array( @@ -465,7 +465,7 @@ return array( $axo_available = $container->has( 'axo.available' ) && $container->get( 'axo.available' ); $dcc_configuration = $container->get( 'wcgateway.configuration.card-configuration' ); - assert( $dcc_configuration instanceof DCCGatewayConfiguration ); + assert( $dcc_configuration instanceof CardPaymentsConfiguration ); if ( $axo_available && $dcc_configuration->use_fastlane() ) { return ''; @@ -688,7 +688,7 @@ return array( assert( $subscription_helper instanceof SubscriptionHelper ); $dcc_configuration = $container->get( 'wcgateway.configuration.card-configuration' ); - assert( $dcc_configuration instanceof DCCGatewayConfiguration ); + assert( $dcc_configuration instanceof CardPaymentsConfiguration ); $fields = array( 'checkout_settings_heading' => array( @@ -1362,14 +1362,14 @@ return array( return new TransactionUrlProvider( $sandbox_url_base, $live_url_base ); }, - 'wcgateway.configuration.card-configuration' => static function ( ContainerInterface $container ) : DCCGatewayConfiguration { + 'wcgateway.configuration.card-configuration' => static function ( ContainerInterface $container ) : CardPaymentsConfiguration { $connection_state = $container->get( 'settings.connection-state' ); assert( $connection_state instanceof ConnectionState ); $settings = $container->get( 'wcgateway.settings' ); assert( $settings instanceof Settings ); - return new DCCGatewayConfiguration( $connection_state, $settings ); + return new CardPaymentsConfiguration( $connection_state, $settings ); }, 'wcgateway.helper.dcc-product-status' => static function ( ContainerInterface $container ) : DCCProductStatus { diff --git a/modules/ppcp-wc-gateway/src/Gateway/CreditCardGateway.php b/modules/ppcp-wc-gateway/src/Gateway/CreditCardGateway.php index 76e53b0b5..a958c32e0 100644 --- a/modules/ppcp-wc-gateway/src/Gateway/CreditCardGateway.php +++ b/modules/ppcp-wc-gateway/src/Gateway/CreditCardGateway.php @@ -34,7 +34,7 @@ use WooCommerce\PayPalCommerce\WcGateway\Processor\TransactionIdHandlingTrait; use WooCommerce\PayPalCommerce\WcGateway\Settings\SettingsRenderer; use WooCommerce\PayPalCommerce\WcSubscriptions\FreeTrialHandlerTrait; use WooCommerce\PayPalCommerce\WcSubscriptions\Helper\SubscriptionHelper; -use WooCommerce\PayPalCommerce\WcGateway\Helper\DCCGatewayConfiguration; +use WooCommerce\PayPalCommerce\WcGateway\Helper\CardPaymentsConfiguration; /** * Class CreditCardGateway @@ -76,9 +76,9 @@ class CreditCardGateway extends \WC_Payment_Gateway_CC { /** * The DCC Gateway Configuration. * - * @var DCCGatewayConfiguration + * @var CardPaymentsConfiguration */ - protected DCCGatewayConfiguration $dcc_configuration; + protected CardPaymentsConfiguration $dcc_configuration; /** * The vaulted credit card handler. @@ -188,31 +188,31 @@ class CreditCardGateway extends \WC_Payment_Gateway_CC { /** * CreditCardGateway constructor. * - * @param SettingsRenderer $settings_renderer The Settings Renderer. - * @param OrderProcessor $order_processor The Order processor. - * @param ContainerInterface $config The settings. - * @param DCCGatewayConfiguration $dcc_configuration The DCC Gateway Configuration. - * @param array $card_icons The card icons. - * @param string $module_url The URL to the module. - * @param SessionHandler $session_handler The Session Handler. - * @param RefundProcessor $refund_processor The refund processor. - * @param TransactionUrlProvider $transaction_url_provider Service able to provide view transaction url base. - * @param SubscriptionHelper $subscription_helper The subscription helper. - * @param PaymentsEndpoint $payments_endpoint The payments endpoint. - * @param VaultedCreditCardHandler $vaulted_credit_card_handler The vaulted credit card handler. - * @param Environment $environment The environment. - * @param OrderEndpoint $order_endpoint The order endpoint. - * @param CaptureCardPayment $capture_card_payment Capture card payment. - * @param string $prefix The prefix. - * @param PaymentTokensEndpoint $payment_tokens_endpoint Payment tokens endpoint. - * @param WooCommercePaymentTokens $wc_payment_tokens WooCommerce payment tokens factory. - * @param LoggerInterface $logger The logger. + * @param SettingsRenderer $settings_renderer The Settings Renderer. + * @param OrderProcessor $order_processor The Order processor. + * @param ContainerInterface $config The settings. + * @param CardPaymentsConfiguration $dcc_configuration The DCC Gateway Configuration. + * @param array $card_icons The card icons. + * @param string $module_url The URL to the module. + * @param SessionHandler $session_handler The Session Handler. + * @param RefundProcessor $refund_processor The refund processor. + * @param TransactionUrlProvider $transaction_url_provider Service able to provide view transaction url base. + * @param SubscriptionHelper $subscription_helper The subscription helper. + * @param PaymentsEndpoint $payments_endpoint The payments endpoint. + * @param VaultedCreditCardHandler $vaulted_credit_card_handler The vaulted credit card handler. + * @param Environment $environment The environment. + * @param OrderEndpoint $order_endpoint The order endpoint. + * @param CaptureCardPayment $capture_card_payment Capture card payment. + * @param string $prefix The prefix. + * @param PaymentTokensEndpoint $payment_tokens_endpoint Payment tokens endpoint. + * @param WooCommercePaymentTokens $wc_payment_tokens WooCommerce payment tokens factory. + * @param LoggerInterface $logger The logger. */ public function __construct( SettingsRenderer $settings_renderer, OrderProcessor $order_processor, ContainerInterface $config, - DCCGatewayConfiguration $dcc_configuration, + CardPaymentsConfiguration $dcc_configuration, array $card_icons, string $module_url, SessionHandler $session_handler, diff --git a/modules/ppcp-wc-gateway/src/Helper/DCCGatewayConfiguration.php b/modules/ppcp-wc-gateway/src/Helper/CardPaymentsConfiguration.php similarity index 99% rename from modules/ppcp-wc-gateway/src/Helper/DCCGatewayConfiguration.php rename to modules/ppcp-wc-gateway/src/Helper/CardPaymentsConfiguration.php index 0adf93861..6204d9b91 100644 --- a/modules/ppcp-wc-gateway/src/Helper/DCCGatewayConfiguration.php +++ b/modules/ppcp-wc-gateway/src/Helper/CardPaymentsConfiguration.php @@ -36,10 +36,8 @@ use WooCommerce\PayPalCommerce\Axo\Helper\PropertiesDictionary; * - BCDC uses "hosted-fields" * * DI service: 'wcgateway.configuration.card-configuration' - * - * @todo: Rename this class to CardPaymentsConfiguration! */ -class DCCGatewayConfiguration { +class CardPaymentsConfiguration { /** * The connection state. * diff --git a/modules/ppcp-wc-gateway/src/Notice/GatewayWithoutPayPalAdminNotice.php b/modules/ppcp-wc-gateway/src/Notice/GatewayWithoutPayPalAdminNotice.php index 660a39754..61f9723f1 100644 --- a/modules/ppcp-wc-gateway/src/Notice/GatewayWithoutPayPalAdminNotice.php +++ b/modules/ppcp-wc-gateway/src/Notice/GatewayWithoutPayPalAdminNotice.php @@ -13,7 +13,7 @@ use WC_Payment_Gateway; use WooCommerce\PayPalCommerce\AdminNotices\Entity\Message; use WooCommerce\PayPalCommerce\Vendor\Psr\Container\ContainerInterface; use WooCommerce\PayPalCommerce\WcGateway\Helper\SettingsStatus; -use WooCommerce\PayPalCommerce\WcGateway\Helper\DCCGatewayConfiguration; +use WooCommerce\PayPalCommerce\WcGateway\Helper\CardPaymentsConfiguration; /** * Creates the admin message about the gateway being enabled without the PayPal gateway. @@ -69,20 +69,20 @@ class GatewayWithoutPayPalAdminNotice { /** * Provides details about the DCC configuration. * - * @var DCCGatewayConfiguration + * @var CardPaymentsConfiguration */ - private DCCGatewayConfiguration $dcc_configuration; + private CardPaymentsConfiguration $dcc_configuration; /** * ConnectAdminNotice constructor. * - * @param string $id The gateway ID. - * @param bool $is_connected Whether onboarding was completed. - * @param ContainerInterface $settings The settings. - * @param bool $is_payments_page Whether the current page is the WC payment page. - * @param bool $is_ppcp_settings_page Whether the current page is the PPCP settings page. - * @param DCCGatewayConfiguration $dcc_configuration DCC gateway configuration. - * @param SettingsStatus|null $settings_status The Settings status helper. + * @param string $id The gateway ID. + * @param bool $is_connected Whether onboarding was completed. + * @param ContainerInterface $settings The settings. + * @param bool $is_payments_page Whether the current page is the WC payment page. + * @param bool $is_ppcp_settings_page Whether the current page is the PPCP settings page. + * @param CardPaymentsConfiguration $dcc_configuration DCC gateway configuration. + * @param SettingsStatus|null $settings_status The Settings status helper. */ public function __construct( string $id, @@ -90,7 +90,7 @@ class GatewayWithoutPayPalAdminNotice { ContainerInterface $settings, bool $is_payments_page, bool $is_ppcp_settings_page, - DCCGatewayConfiguration $dcc_configuration, + CardPaymentsConfiguration $dcc_configuration, ?SettingsStatus $settings_status = null ) { $this->id = $id; diff --git a/modules/ppcp-wc-gateway/src/WCGatewayModule.php b/modules/ppcp-wc-gateway/src/WCGatewayModule.php index 172e97706..25b01f5e1 100644 --- a/modules/ppcp-wc-gateway/src/WCGatewayModule.php +++ b/modules/ppcp-wc-gateway/src/WCGatewayModule.php @@ -58,7 +58,7 @@ use WooCommerce\PayPalCommerce\WcGateway\Settings\SettingsListener; use WooCommerce\PayPalCommerce\WcGateway\Settings\SettingsRenderer; use WooCommerce\PayPalCommerce\Vendor\Psr\Container\ContainerInterface; use WooCommerce\PayPalCommerce\WcGateway\Settings\WcTasks\Registrar\TaskRegistrarInterface; -use WooCommerce\PayPalCommerce\WcGateway\Helper\DCCGatewayConfiguration; +use WooCommerce\PayPalCommerce\WcGateway\Helper\CardPaymentsConfiguration; use WooCommerce\PayPalCommerce\LocalAlternativePaymentMethods\LocalApmProductStatus; /** @@ -196,7 +196,7 @@ class WCGatewayModule implements ServiceModule, ExtendingModule, ExecutableModul assert( $settings instanceof Settings ); $dcc_configuration = $c->get( 'wcgateway.configuration.card-configuration' ); - assert( $dcc_configuration instanceof DCCGatewayConfiguration ); + assert( $dcc_configuration instanceof CardPaymentsConfiguration ); $assets = new SettingsPageAssets( $c->get( 'wcgateway.url' ), @@ -615,7 +615,7 @@ class WCGatewayModule implements ServiceModule, ExtendingModule, ExecutableModul } $dcc_configuration = $container->get( 'wcgateway.configuration.card-configuration' ); - assert( $dcc_configuration instanceof DCCGatewayConfiguration ); + assert( $dcc_configuration instanceof CardPaymentsConfiguration ); $standard_card_button = get_option( 'woocommerce_ppcp-card-button-gateway_settings' ); diff --git a/tests/PHPUnit/Button/Helper/DisabledFundingSourcesTest.php b/tests/PHPUnit/Button/Helper/DisabledFundingSourcesTest.php index 3c73c04fb..334119788 100644 --- a/tests/PHPUnit/Button/Helper/DisabledFundingSourcesTest.php +++ b/tests/PHPUnit/Button/Helper/DisabledFundingSourcesTest.php @@ -8,7 +8,7 @@ use WC_Payment_Gateways; use WooCommerce; use WooCommerce\PayPalCommerce\TestCase; use WooCommerce\PayPalCommerce\WcGateway\Settings\Settings; -use WooCommerce\PayPalCommerce\WcGateway\Helper\DCCGatewayConfiguration; +use WooCommerce\PayPalCommerce\WcGateway\Helper\CardPaymentsConfiguration; use function Brain\Monkey\Functions\when; class DisabledFundingSourcesTest extends TestCase @@ -21,7 +21,7 @@ class DisabledFundingSourcesTest extends TestCase parent::setUp(); $this->settings = Mockery::mock(Settings::class); - $this->dcc_configuration = Mockery::mock(DCCGatewayConfiguration::class); + $this->dcc_configuration = Mockery::mock(CardPaymentsConfiguration::class); } /** diff --git a/tests/PHPUnit/WcGateway/Gateway/CreditCardGatewayTest.php b/tests/PHPUnit/WcGateway/Gateway/CreditCardGatewayTest.php index 7fd20cc2f..27c4850b7 100644 --- a/tests/PHPUnit/WcGateway/Gateway/CreditCardGatewayTest.php +++ b/tests/PHPUnit/WcGateway/Gateway/CreditCardGatewayTest.php @@ -19,7 +19,7 @@ use WooCommerce\PayPalCommerce\WcGateway\Endpoint\CaptureCardPayment; use WooCommerce\PayPalCommerce\WcGateway\Processor\OrderProcessor; use WooCommerce\PayPalCommerce\WcGateway\Processor\RefundProcessor; use WooCommerce\PayPalCommerce\WcGateway\Settings\SettingsRenderer; -use WooCommerce\PayPalCommerce\WcGateway\Helper\DCCGatewayConfiguration; +use WooCommerce\PayPalCommerce\WcGateway\Helper\CardPaymentsConfiguration; use WooCommerce\PayPalCommerce\WcSubscriptions\Helper\SubscriptionHelper; use function Brain\Monkey\Functions\when; @@ -53,7 +53,7 @@ class CreditCardGatewayTest extends TestCase $this->settingsRenderer = Mockery::mock(SettingsRenderer::class); $this->orderProcessor = Mockery::mock(OrderProcessor::class); $this->config = Mockery::mock(ContainerInterface::class); - $this->dcc_configuration = Mockery::mock(DCCGatewayConfiguration::class); + $this->dcc_configuration = Mockery::mock(CardPaymentsConfiguration::class); $this->creditCardIcons = []; $this->moduleUrl = ''; $this->sessionHandler = Mockery::mock(SessionHandler::class); From eb26712fb6a21256d25cbf97a298a9ea769e6ca8 Mon Sep 17 00:00:00 2001 From: Philipp Stracker Date: Fri, 14 Mar 2025 16:15:43 +0100 Subject: [PATCH 34/62] =?UTF-8?q?=F0=9F=90=9B=20Fix=20wrong=20condition!?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ppcp-wc-gateway/src/Helper/CardPaymentsConfiguration.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/ppcp-wc-gateway/src/Helper/CardPaymentsConfiguration.php b/modules/ppcp-wc-gateway/src/Helper/CardPaymentsConfiguration.php index 6204d9b91..b2c9c88c5 100644 --- a/modules/ppcp-wc-gateway/src/Helper/CardPaymentsConfiguration.php +++ b/modules/ppcp-wc-gateway/src/Helper/CardPaymentsConfiguration.php @@ -140,7 +140,7 @@ class CardPaymentsConfiguration { * @return void */ private function ensure_resolved_values() : void { - if ( ! $this->is_resolved ) { + if ( $this->is_resolved ) { return; } From 752dae14083aac16fa9c0be09ac9e0665d547aed Mon Sep 17 00:00:00 2001 From: Philipp Stracker Date: Fri, 14 Mar 2025 16:26:09 +0100 Subject: [PATCH 35/62] =?UTF-8?q?=E2=9C=A8=20Resolve=20ACDC=20eligibility?= =?UTF-8?q?=20from=20DccApplies=20helper?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- modules/ppcp-wc-gateway/services.php | 12 +++++------- .../src/Helper/CardPaymentsConfiguration.php | 16 +++++++++++++++- 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/modules/ppcp-wc-gateway/services.php b/modules/ppcp-wc-gateway/services.php index 29631d796..e8d5238ab 100644 --- a/modules/ppcp-wc-gateway/services.php +++ b/modules/ppcp-wc-gateway/services.php @@ -1363,13 +1363,11 @@ return array( }, 'wcgateway.configuration.card-configuration' => static function ( ContainerInterface $container ) : CardPaymentsConfiguration { - $connection_state = $container->get( 'settings.connection-state' ); - assert( $connection_state instanceof ConnectionState ); - - $settings = $container->get( 'wcgateway.settings' ); - assert( $settings instanceof Settings ); - - return new CardPaymentsConfiguration( $connection_state, $settings ); + return new CardPaymentsConfiguration( + $container->get( 'settings.connection-state' ), + $container->get( 'wcgateway.settings' ), + $container->get( 'api.helpers.dccapplies' ) + ); }, 'wcgateway.helper.dcc-product-status' => static function ( ContainerInterface $container ) : DCCProductStatus { diff --git a/modules/ppcp-wc-gateway/src/Helper/CardPaymentsConfiguration.php b/modules/ppcp-wc-gateway/src/Helper/CardPaymentsConfiguration.php index b2c9c88c5..979c7e97c 100644 --- a/modules/ppcp-wc-gateway/src/Helper/CardPaymentsConfiguration.php +++ b/modules/ppcp-wc-gateway/src/Helper/CardPaymentsConfiguration.php @@ -16,6 +16,7 @@ namespace WooCommerce\PayPalCommerce\WcGateway\Helper; use WooCommerce\PayPalCommerce\WcGateway\Settings\Settings; use WooCommerce\PayPalCommerce\WcGateway\Exception\NotFoundException; use WooCommerce\PayPalCommerce\Axo\Helper\PropertiesDictionary; +use WooCommerce\PayPalCommerce\ApiClient\Helper\DccApplies; /** * A configuration proxy service that provides details about credit card gateway @@ -52,6 +53,13 @@ class CardPaymentsConfiguration { */ private Settings $settings; + /** + * Helper to determine availability of DCC features. + * + * @var DccApplies + */ + private DccApplies $dcc_applies; + /** * This classes lazily resolves settings on first access. This flag indicates * whether the setting values were resolved, or still need to be evaluated. @@ -116,10 +124,12 @@ class CardPaymentsConfiguration { * * @param ConnectionState $connection_state Connection state instance. * @param Settings $settings Plugin settings instance. + * @param DccApplies $dcc_applies DCC eligibility helper. */ - public function __construct( ConnectionState $connection_state, Settings $settings ) { + public function __construct( ConnectionState $connection_state, Settings $settings, DccApplies $dcc_applies ) { $this->connection_state = $connection_state; $this->settings = $settings; + $this->dcc_applies = $dcc_applies; $this->is_resolved = false; } @@ -216,6 +226,10 @@ class CardPaymentsConfiguration { $this->is_enabled = $is_dcc_enabled; + if ( $this->dcc_applies->for_country_currency() ) { + $this->use_acdc = true; + } + /** * Changing this to true (and hiding the watermark) has potential legal * consequences, and therefore is generally discouraged. From 433e7f7c8bf68b7f5cd790eed3d7c2063626535b Mon Sep 17 00:00:00 2001 From: Philipp Stracker Date: Fri, 14 Mar 2025 16:27:01 +0100 Subject: [PATCH 36/62] =?UTF-8?q?=F0=9F=94=A5=20Remove=20redundant=20check?= =?UTF-8?q?s=20from=20SmartButton?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Most checks are already implemented in the CardPaymentsConfiguration class. --- .../ppcp-button/src/Assets/SmartButton.php | 29 +++---------------- 1 file changed, 4 insertions(+), 25 deletions(-) diff --git a/modules/ppcp-button/src/Assets/SmartButton.php b/modules/ppcp-button/src/Assets/SmartButton.php index 62dcd9f0f..8e284e0a4 100644 --- a/modules/ppcp-button/src/Assets/SmartButton.php +++ b/modules/ppcp-button/src/Assets/SmartButton.php @@ -720,9 +720,7 @@ document.querySelector("#payment").before(document.querySelector(".ppcp-messages * Whether DCC fields can be rendered. */ public function can_render_dcc() : bool { - return $this->dcc_configuration->is_enabled() - && $this->settings->has( 'client_id' ) && $this->settings->get( 'client_id' ) - && $this->dcc_applies->for_country_currency() + return $this->dcc_configuration->is_acdc_enabled() && in_array( $this->context(), apply_filters( 'woocommerce_paypal_payments_can_render_dcc_contexts', array( 'checkout', 'pay-now', 'add-payment-method' ) ), @@ -1126,7 +1124,7 @@ document.querySelector("#payment").before(document.querySelector(".ppcp-messages 'client_id' => $this->client_id, 'currency' => $this->currency->get(), 'data_client_id' => array( - 'set_attribute' => ( is_checkout() && $this->dcc_is_enabled() ) || $this->can_save_vault_token(), + 'set_attribute' => $this->dcc_is_enabled() || $this->can_save_vault_token(), 'endpoint' => \WC_AJAX::get_endpoint( DataClientIdEndpoint::ENDPOINT ), 'nonce' => wp_create_nonce( DataClientIdEndpoint::nonce() ), 'user' => get_current_user_id(), @@ -1595,31 +1593,12 @@ document.querySelector("#payment").before(document.querySelector(".ppcp-messages } /** - * Whether DCC is enabled or not. + * Whether ACDC is available on the current page. * * @return bool */ private function dcc_is_enabled() : bool { - // Card payments are only available on the checkout page, and for certain seller countries. - if ( ! is_checkout() || ! $this->dcc_applies->for_country_currency() ) { - return false; - } - - try { - // Bail, if the merchant is not fully onboarded yet. - if ( - ! $this->settings->get( 'client_id' ) - || ! $this->settings->get( 'client_secret' ) - ) { - return false; - } - - // The actual condition that must be met. - return $this->dcc_configuration->is_enabled(); - } catch ( NotFoundException $e ) { - // Bail, if the settings DB entries are missing. - return false; - } + return is_checkout() && $this->dcc_configuration->is_acdc_enabled(); } /** From 901e7761e17e2ced5d8037bcedcef37e31097981 Mon Sep 17 00:00:00 2001 From: Philipp Stracker Date: Fri, 14 Mar 2025 18:05:21 +0100 Subject: [PATCH 37/62] =?UTF-8?q?=E2=9C=A8=20Consolidate=20ACDC=20logic=20?= =?UTF-8?q?in=20CardFieldsModule?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/Helper/DisabledFundingSources.php | 2 +- .../ppcp-card-fields/src/CardFieldsModule.php | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/modules/ppcp-button/src/Helper/DisabledFundingSources.php b/modules/ppcp-button/src/Helper/DisabledFundingSources.php index 7d24974a9..343823bef 100644 --- a/modules/ppcp-button/src/Helper/DisabledFundingSources.php +++ b/modules/ppcp-button/src/Helper/DisabledFundingSources.php @@ -225,7 +225,7 @@ class DisabledFundingSources { * Filters the final list of disabled funding sources. */ $disable_funding = apply_filters( - 'woocommerce_paypal_payments_disabled_funding_sources', + 'woocommerce_paypal_payments_sdk_disabled_funding_hook', $disable_funding ); diff --git a/modules/ppcp-card-fields/src/CardFieldsModule.php b/modules/ppcp-card-fields/src/CardFieldsModule.php index 1fb2a6ddf..45d1d6b51 100644 --- a/modules/ppcp-card-fields/src/CardFieldsModule.php +++ b/modules/ppcp-card-fields/src/CardFieldsModule.php @@ -72,6 +72,24 @@ class CardFieldsModule implements ServiceModule, ExtendingModule, ExecutableModu } ); + add_filter( + 'woocommerce_paypal_payments_sdk_disabled_funding_hook', + static function ( array $disable_funding ) use ( $c ) { + $dcc_config = $c->get( 'wcgateway.configuration.card-configuration' ); + assert( $dcc_config instanceof CardPaymentsConfiguration ); + + if ( ! $dcc_config->is_acdc_enabled() ) { + return $disable_funding; + } + + // For ACDC payments we need the funding source "card"! + return array_filter( + $disable_funding, + static fn( string $funding_source ) => $funding_source !== 'card' + ); + } + ); + add_filter( 'woocommerce_credit_card_form_fields', /** From 73c70e3f38cd05182a55fbd4ba77bfae0fd56c98 Mon Sep 17 00:00:00 2001 From: Philipp Stracker Date: Fri, 14 Mar 2025 18:07:21 +0100 Subject: [PATCH 38/62] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20Add=20type-hint=20fo?= =?UTF-8?q?r=20filter?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The filter is mainly used internally and it must receive an array. --- modules/ppcp-card-fields/src/CardFieldsModule.php | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/modules/ppcp-card-fields/src/CardFieldsModule.php b/modules/ppcp-card-fields/src/CardFieldsModule.php index 45d1d6b51..eff370b35 100644 --- a/modules/ppcp-card-fields/src/CardFieldsModule.php +++ b/modules/ppcp-card-fields/src/CardFieldsModule.php @@ -46,14 +46,9 @@ class CardFieldsModule implements ServiceModule, ExtendingModule, ExecutableModu return true; } - /** - * Param types removed to avoid third-party issues. - * - * @psalm-suppress MissingClosureParamType - */ add_filter( 'woocommerce_paypal_payments_sdk_components_hook', - static function( $components ) use ( $c ) { + static function( array $components ) use ( $c ) { $dcc_config = $c->get( 'wcgateway.configuration.card-configuration' ); assert( $dcc_config instanceof CardPaymentsConfiguration ); From 8a42cd610e4ed7c8865dec22cdddf639e4d2b668 Mon Sep 17 00:00:00 2001 From: Philipp Stracker Date: Fri, 14 Mar 2025 18:16:17 +0100 Subject: [PATCH 39/62] =?UTF-8?q?=F0=9F=92=A1=20Update=20documentation=20i?= =?UTF-8?q?n=20comments?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ppcp-wc-gateway/src/Helper/CardPaymentsConfiguration.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/modules/ppcp-wc-gateway/src/Helper/CardPaymentsConfiguration.php b/modules/ppcp-wc-gateway/src/Helper/CardPaymentsConfiguration.php index 979c7e97c..a8ae300cf 100644 --- a/modules/ppcp-wc-gateway/src/Helper/CardPaymentsConfiguration.php +++ b/modules/ppcp-wc-gateway/src/Helper/CardPaymentsConfiguration.php @@ -269,6 +269,7 @@ class CardPaymentsConfiguration { /** * True, if the card payments are enabled and the merchant is in ACDC mode. + * This also unlocks card payments on block pages. * * If this returns false, the following payment methods are unavailable: * - Advanced Card Processing @@ -285,6 +286,9 @@ class CardPaymentsConfiguration { /** * True, if card payments are enabled and the merchant is in BCDC mode. * + * The BCDC integration is not supported by block checkout: + * When this returns true, disable card payments on block pages. + * * @return bool */ public function is_bcdc_enabled() : bool { From ed4bb14ad74b087c00650089ab82abcc481c3697 Mon Sep 17 00:00:00 2001 From: Philipp Stracker Date: Fri, 14 Mar 2025 18:24:12 +0100 Subject: [PATCH 40/62] =?UTF-8?q?=F0=9F=90=9B=20Fix=20condition=20in=20ACD?= =?UTF-8?q?C=20module?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- modules/ppcp-card-fields/src/CardFieldsModule.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/ppcp-card-fields/src/CardFieldsModule.php b/modules/ppcp-card-fields/src/CardFieldsModule.php index eff370b35..36349c21f 100644 --- a/modules/ppcp-card-fields/src/CardFieldsModule.php +++ b/modules/ppcp-card-fields/src/CardFieldsModule.php @@ -52,7 +52,7 @@ class CardFieldsModule implements ServiceModule, ExtendingModule, ExecutableModu $dcc_config = $c->get( 'wcgateway.configuration.card-configuration' ); assert( $dcc_config instanceof CardPaymentsConfiguration ); - if ( ! $dcc_config->is_enabled() ) { + if ( ! $dcc_config->is_acdc_enabled() ) { return $components; } From 480315943672f68b200182c688004dfb039aba73 Mon Sep 17 00:00:00 2001 From: Philipp Stracker Date: Fri, 14 Mar 2025 18:27:06 +0100 Subject: [PATCH 41/62] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20Refactor=20the=20Dis?= =?UTF-8?q?abledFundingSource=20logic?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Simplify condiitons and code structure, as the old logic was overly complex. Also, ACDC logic is outsourced to the CardFieldsModule via filters and does not need to be considered here. --- .../src/Helper/DisabledFundingSources.php | 88 ++++--------------- 1 file changed, 18 insertions(+), 70 deletions(-) diff --git a/modules/ppcp-button/src/Helper/DisabledFundingSources.php b/modules/ppcp-button/src/Helper/DisabledFundingSources.php index 343823bef..ed3506fc9 100644 --- a/modules/ppcp-button/src/Helper/DisabledFundingSources.php +++ b/modules/ppcp-button/src/Helper/DisabledFundingSources.php @@ -10,7 +10,6 @@ declare( strict_types = 1 ); namespace WooCommerce\PayPalCommerce\Button\Helper; use WooCommerce\PayPalCommerce\WcGateway\Exception\NotFoundException; -use WooCommerce\PayPalCommerce\WcGateway\Gateway\CardButtonGateway; use WooCommerce\PayPalCommerce\WcGateway\Settings\Settings; use WooCommerce\PayPalCommerce\WcSubscriptions\FreeTrialHandlerTrait; use WooCommerce\PayPalCommerce\WcGateway\Helper\CardPaymentsConfiguration; @@ -70,19 +69,14 @@ class DisabledFundingSources { return $this->sanitize_and_filter_sources( $disable_funding ); } - $disable_funding = $this->get_sources_from_settings(); - $payment_flags = $this->get_payment_method_flags(); - $context_flags = $this->get_context_flags( $context ); + $disable_funding = $this->get_sources_from_settings(); + $is_block_context = in_array( $context, array( 'checkout-block', 'cart-block' ), true ); // Apply rules based on context and payment methods. - $disable_funding = $this->apply_context_rules( - $disable_funding, - $context_flags, - $payment_flags - ); + $disable_funding = $this->apply_context_rules( $disable_funding ); // Apply special rules for block checkout. - if ( $context_flags['is_block_context'] ) { + if ( $is_block_context ) { $disable_funding = $this->apply_block_checkout_rules( $disable_funding ); } @@ -96,9 +90,7 @@ class DisabledFundingSources { */ private function get_sources_from_settings() : array { try { - return $this->settings->has( 'disable_funding' ) - ? $this->settings->get( 'disable_funding' ) - : array(); + return $this->settings->get( 'disable_funding' ); } catch ( NotFoundException $exception ) { return array(); } @@ -113,10 +105,11 @@ class DisabledFundingSources { * @return array */ private function get_sources_for_free_trial() : array { + // Disable all sources. $disable_funding = array_keys( $this->all_funding_sources ); - $payment_flags = $this->get_payment_method_flags(); - if ( $payment_flags['is_using_cards'] ) { + if ( is_checkout() && $this->dcc_configuration->is_bcdc_enabled() ) { + // If BCDC is used, re-enable card payments. $disable_funding = array_filter( $disable_funding, static fn( string $funding_source ) => $funding_source !== 'card' @@ -126,70 +119,25 @@ class DisabledFundingSources { return $disable_funding; } - /** - * Gets context flags based on the current page and context. - * - * @param string $context The context. - * @return array - */ - private function get_context_flags( string $context ) : array { - $is_checkout_page = is_checkout(); - $is_block_context = in_array( $context, array( 'checkout-block', 'cart-block' ), true ); - $is_classic_checkout = $is_checkout_page && ! $is_block_context; - - return array( - 'is_checkout_page' => $is_checkout_page, - 'is_block_context' => $is_block_context, - 'is_classic_checkout' => $is_classic_checkout, - ); - } - - /** - * Gets payment method availability flags. - * - * @return array - */ - private function get_payment_method_flags() : array { - $is_dcc_enabled = $this->dcc_configuration->is_enabled(); - $available_gateways = WC()->payment_gateways->get_available_payment_gateways(); - - // TODO: This check does not make much sense in the new UI. The gateway is always available when the "dcc_enabled" flag is true. - // Review and adjust when removing #legacy-ui code. - $is_card_gateway_enabled = isset( $available_gateways[ CardButtonGateway::ID ] ); - - return array( - // Whether the new Advanced Card Processing gateway is active. - 'is_dcc_enabled' => $is_dcc_enabled, - - // Whether card payments are generally used (DCC or BCDC). - 'is_using_cards' => $is_dcc_enabled || $is_card_gateway_enabled, - ); - } - /** * Applies rules based on context and payment methods. * * @param array $disable_funding The current disabled funding sources. - * @param array $context_flags Context flags. - * @param array $payment_flags Payment method flags. * @return array */ - private function apply_context_rules( array $disable_funding, array $context_flags, array $payment_flags ) : array { - if ( $context_flags['is_block_context'] && $payment_flags['is_dcc_enabled'] ) { - // Rule 1: Block checkout with DCC - do not load card payments. + private function apply_context_rules( array $disable_funding ) : array { + if ( ! is_checkout() || ! $this->dcc_configuration->is_bcdc_enabled() ) { + // Non-checkout pages, or BCDC disabled: Don't load card payments. $disable_funding[] = 'card'; - } elseif ( ! $context_flags['is_checkout_page'] ) { - // Rule 2: Non-checkout pages - do not load card payments. - $disable_funding[] = 'card'; - } elseif ( $context_flags['is_classic_checkout'] && $payment_flags['is_using_cards'] ) { - // Rule 3: Standard checkout with card methods - load card payments. - $disable_funding = array_filter( - $disable_funding, - static fn( string $funding_source ) => $funding_source !== 'card' - ); + + return $disable_funding; } - return $disable_funding; + // A checkout page and BCDC is enabled: Load card payments. + return array_filter( + $disable_funding, + static fn( string $funding_source ) => $funding_source !== 'card' + ); } /** From 42b357d8a6e3eefe056665f0a02075c4d92802dc Mon Sep 17 00:00:00 2001 From: Philipp Stracker Date: Fri, 14 Mar 2025 18:28:12 +0100 Subject: [PATCH 42/62] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20Simplify=20SmartButt?= =?UTF-8?q?on=20code=20a=20bit?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- modules/ppcp-button/src/Assets/SmartButton.php | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/modules/ppcp-button/src/Assets/SmartButton.php b/modules/ppcp-button/src/Assets/SmartButton.php index 8e284e0a4..054fe8c41 100644 --- a/modules/ppcp-button/src/Assets/SmartButton.php +++ b/modules/ppcp-button/src/Assets/SmartButton.php @@ -1113,6 +1113,7 @@ document.querySelector("#payment").before(document.querySelector(".ppcp-messages */ public function script_data(): array { $is_free_trial_cart = $this->is_free_trial_cart(); + $is_acdc_enabled = $this->dcc_configuration->is_acdc_enabled(); $url_params = $this->url_params(); @@ -1124,7 +1125,7 @@ document.querySelector("#payment").before(document.querySelector(".ppcp-messages 'client_id' => $this->client_id, 'currency' => $this->currency->get(), 'data_client_id' => array( - 'set_attribute' => $this->dcc_is_enabled() || $this->can_save_vault_token(), + 'set_attribute' => ( is_checkout() && $is_acdc_enabled ) || $this->can_save_vault_token(), 'endpoint' => \WC_AJAX::get_endpoint( DataClientIdEndpoint::ENDPOINT ), 'nonce' => wp_create_nonce( DataClientIdEndpoint::nonce() ), 'user' => get_current_user_id(), @@ -1559,7 +1560,6 @@ document.querySelector("#payment").before(document.querySelector(".ppcp-messages * The JS SKD components we need to load. * * @return array - * @throws NotFoundException If a setting was not found. */ private function components(): array { $components = array(); @@ -1571,7 +1571,9 @@ document.querySelector("#payment").before(document.querySelector(".ppcp-messages if ( $this->should_load_messages() ) { $components[] = 'messages'; } - if ( $this->dcc_is_enabled() ) { + + // Card payments are only available on a checkout page. + if ( is_checkout() && $this->dcc_configuration->is_bcdc_enabled() ) { $components[] = 'hosted-fields'; } @@ -1592,15 +1594,6 @@ document.querySelector("#payment").before(document.querySelector(".ppcp-messages ); } - /** - * Whether ACDC is available on the current page. - * - * @return bool - */ - private function dcc_is_enabled() : bool { - return is_checkout() && $this->dcc_configuration->is_acdc_enabled(); - } - /** * Determines the style for a given property in a given context. * From 704bf7f20c1fac6177408dde82208b089f2d63e3 Mon Sep 17 00:00:00 2001 From: Philipp Stracker Date: Fri, 14 Mar 2025 18:56:50 +0100 Subject: [PATCH 43/62] =?UTF-8?q?=E2=9C=A8=20Allow=20filtering=20of=20card?= =?UTF-8?q?-payment=20flags?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit These filters allow to add backwards compatibility --- .../src/Helper/CardPaymentsConfiguration.php | 20 +++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/modules/ppcp-wc-gateway/src/Helper/CardPaymentsConfiguration.php b/modules/ppcp-wc-gateway/src/Helper/CardPaymentsConfiguration.php index a8ae300cf..ab9c4ed3f 100644 --- a/modules/ppcp-wc-gateway/src/Helper/CardPaymentsConfiguration.php +++ b/modules/ppcp-wc-gateway/src/Helper/CardPaymentsConfiguration.php @@ -224,11 +224,23 @@ class CardPaymentsConfiguration { return; } - $this->is_enabled = $is_dcc_enabled; + /** + * Filters the "Card Payments Enabled" status. This allows other modules + * to override the flag. + */ + $this->is_enabled = (bool) apply_filters( + 'woocommerce_paypal_payments_is_card_payment_enabled', + $is_dcc_enabled + ); - if ( $this->dcc_applies->for_country_currency() ) { - $this->use_acdc = true; - } + /** + * Filters the "ACDC" state. When a filter callback sets this to false + * the plugin assumes to be in BCDC mode. + */ + $this->use_acdc = (bool) apply_filters( + 'woocommerce_paypal_payments_is_acdc_active', + $this->dcc_applies->for_country_currency() + ); /** * Changing this to true (and hiding the watermark) has potential legal From b5faa08bfdd05e766b855a0d26d208023625ab52 Mon Sep 17 00:00:00 2001 From: Philipp Stracker Date: Mon, 17 Mar 2025 13:07:20 +0100 Subject: [PATCH 44/62] =?UTF-8?q?=E2=9C=A8=20Prepare=20a=20compat=20method?= =?UTF-8?q?=20for=20legacy=20UI?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- modules/ppcp-compat/src/CompatModule.php | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/modules/ppcp-compat/src/CompatModule.php b/modules/ppcp-compat/src/CompatModule.php index c8fdc9d8e..afd0a368f 100644 --- a/modules/ppcp-compat/src/CompatModule.php +++ b/modules/ppcp-compat/src/CompatModule.php @@ -10,7 +10,6 @@ declare(strict_types=1); namespace WooCommerce\PayPalCommerce\Compat; use Exception; -use Psr\Log\LoggerInterface; use WC_Cart; use WC_Order; use WC_Order_Item_Product; @@ -89,6 +88,8 @@ class CompatModule implements ServiceModule, ExtendingModule, ExecutableModule { add_action( 'woocommerce_paypal_payments_gateway_migrate', static fn() => delete_transient( 'ppcp_has_ppec_subscriptions' ) ); + $this->legacy_ui_card_payment_mapping( $c ); + return true; } @@ -491,4 +492,22 @@ class CompatModule implements ServiceModule, ExtendingModule, ExecutableModule { 2 ); } + + /** + * Responsible to keep the credit card payment configuration backwards + * compatible with the legacy UI. + * + * This method can be removed with the #legacy-ui code. + * + * @param ContainerInterface $container DI container instance. + * @return void + */ + protected function legacy_ui_card_payment_mapping( ContainerInterface $container ) : void { + $new_ui = $container->get( 'wcgateway.settings.admin-settings-enabled' ); + if ( $new_ui ) { + return; + } + + // Add filters here... + } } From f5194c0be42fb62e30965afa032fe20ad7eea68f Mon Sep 17 00:00:00 2001 From: Philipp Stracker Date: Mon, 17 Mar 2025 14:45:37 +0100 Subject: [PATCH 45/62] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20Improve=20code=20sty?= =?UTF-8?q?le=20and=20readability?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../resources/js/modules/Renderer/Renderer.js | 50 ++++++++++--------- 1 file changed, 26 insertions(+), 24 deletions(-) diff --git a/modules/ppcp-button/resources/js/modules/Renderer/Renderer.js b/modules/ppcp-button/resources/js/modules/Renderer/Renderer.js index 005ee6248..e438f9a4e 100644 --- a/modules/ppcp-button/resources/js/modules/Renderer/Renderer.js +++ b/modules/ppcp-button/resources/js/modules/Renderer/Renderer.js @@ -54,7 +54,7 @@ class Renderer { const enabledSeparateGateways = Object.fromEntries( Object.entries( settings.separate_buttons ).filter( - ( [ s, data ] ) => document.querySelector( data.wrapper ) + ( [ , data ] ) => document.querySelector( data.wrapper ) ) ); const hasEnabledSeparateGateways = @@ -70,10 +70,12 @@ class Renderer { ); } } else { + const allFundingSources = paypal.getFundingSources(); + const separateFunding = allFundingSources.filter( + ( s ) => ! ( s in enabledSeparateGateways ) + ); // render each button separately - for ( const fundingSource of paypal - .getFundingSources() - .filter( ( s ) => ! ( s in enabledSeparateGateways ) ) ) { + for ( const fundingSource of separateFunding ) { const style = normalizeStyleForFundingSource( settings.button.style, fundingSource @@ -161,29 +163,29 @@ class Renderer { if ( this.shouldEnableShippingCallback() ) { options.onShippingOptionsChange = ( data, actions ) => { const shippingOptionsChange = - ! this.isVenmoButtonClickedWhenVaultingIsEnabled( - venmoButtonClicked - ) - ? handleShippingOptionsChange( - data, - actions, - this.defaultSettings - ) - : null; + ! this.isVenmoButtonClickedWhenVaultingIsEnabled( + venmoButtonClicked + ) + ? handleShippingOptionsChange( + data, + actions, + this.defaultSettings + ) + : null; return shippingOptionsChange; }; options.onShippingAddressChange = ( data, actions ) => { const shippingAddressChange = - ! this.isVenmoButtonClickedWhenVaultingIsEnabled( - venmoButtonClicked - ) - ? handleShippingAddressChange( - data, - actions, - this.defaultSettings - ) - : null; + ! this.isVenmoButtonClickedWhenVaultingIsEnabled( + venmoButtonClicked + ) + ? handleShippingAddressChange( + data, + actions, + this.defaultSettings + ) + : null; return shippingAddressChange; }; @@ -246,7 +248,7 @@ class Renderer { return venmoButtonClicked && this.defaultSettings.vaultingEnabled; }; - shouldEnableShippingCallback = () => { + shouldEnableShippingCallback = () => { const needShipping = this.defaultSettings.needShipping || this.defaultSettings.context === 'product'; @@ -254,7 +256,7 @@ class Renderer { this.defaultSettings.should_handle_shipping_in_paypal && needShipping ); - }; + }; isAlreadyRendered( wrapper, fundingSource ) { return this.renderedSources.has( wrapper + ( fundingSource ?? '' ) ); From 745c1cc88c8cd30886bd57a937102ad78e6b60aa Mon Sep 17 00:00:00 2001 From: Philipp Stracker Date: Mon, 17 Mar 2025 14:57:51 +0100 Subject: [PATCH 46/62] =?UTF-8?q?=F0=9F=94=A5=20Remove=20an=20unused=20fun?= =?UTF-8?q?ction=20argument?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../resources/js/modules/Renderer/Renderer.js | 19 +++---------------- 1 file changed, 3 insertions(+), 16 deletions(-) diff --git a/modules/ppcp-button/resources/js/modules/Renderer/Renderer.js b/modules/ppcp-button/resources/js/modules/Renderer/Renderer.js index e438f9a4e..7c5bbc193 100644 --- a/modules/ppcp-button/resources/js/modules/Renderer/Renderer.js +++ b/modules/ppcp-button/resources/js/modules/Renderer/Renderer.js @@ -65,8 +65,7 @@ class Renderer { this.renderButtons( settings.button.wrapper, settings.button.style, - contextConfig, - hasEnabledSeparateGateways + contextConfig ); } } else { @@ -85,7 +84,6 @@ class Renderer { settings.button.wrapper, style, contextConfig, - hasEnabledSeparateGateways, fundingSource ); } @@ -105,26 +103,15 @@ class Renderer { data.wrapper, data.style, contextConfig, - hasEnabledSeparateGateways, fundingSource ); } } - renderButtons( - wrapper, - style, - contextConfig, - hasEnabledSeparateGateways, - fundingSource = null - ) { + renderButtons( wrapper, style, contextConfig, fundingSource = null ) { if ( ! document.querySelector( wrapper ) || - this.isAlreadyRendered( - wrapper, - fundingSource, - hasEnabledSeparateGateways - ) + this.isAlreadyRendered( wrapper, fundingSource ) ) { // Try to render registered buttons again in case they were removed from the DOM by an external source. widgetBuilder.renderButtons( [ wrapper, fundingSource ] ); From 3cfbd1002f927cb61af1970176749104280aa7de Mon Sep 17 00:00:00 2001 From: Philipp Stracker Date: Mon, 17 Mar 2025 14:59:03 +0100 Subject: [PATCH 47/62] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20Slightly=20improve?= =?UTF-8?q?=20code=20readability?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../resources/js/modules/Renderer/Renderer.js | 27 +++++++++---------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/modules/ppcp-button/resources/js/modules/Renderer/Renderer.js b/modules/ppcp-button/resources/js/modules/Renderer/Renderer.js index 7c5bbc193..5131f03b4 100644 --- a/modules/ppcp-button/resources/js/modules/Renderer/Renderer.js +++ b/modules/ppcp-button/resources/js/modules/Renderer/Renderer.js @@ -133,10 +133,7 @@ class Renderer { this.onSmartButtonClick( data, actions ); } - venmoButtonClicked = false; - if ( data.fundingSource === 'venmo' ) { - venmoButtonClicked = true; - } + venmoButtonClicked = data.fundingSource === 'venmo'; }, onInit: ( data, actions ) => { if ( this.onSmartButtonsInit ) { @@ -219,10 +216,7 @@ class Renderer { this.renderedSources.add( wrapper + ( fundingSource ?? '' ) ); - if ( - typeof paypal !== 'undefined' && - typeof paypal.Buttons !== 'undefined' - ) { + if ( window.paypal?.Buttons ) { widgetBuilder.registerButtons( [ wrapper, fundingSource ], buttonsOptions() @@ -239,6 +233,7 @@ class Renderer { const needShipping = this.defaultSettings.needShipping || this.defaultSettings.context === 'product'; + return ( this.defaultSettings.should_handle_shipping_in_paypal && needShipping @@ -261,6 +256,7 @@ class Renderer { this.onButtonsInitListeners[ wrapper ] = reset ? [] : this.onButtonsInitListeners[ wrapper ] || []; + this.onButtonsInitListeners[ wrapper ].push( handler ); } @@ -272,12 +268,11 @@ class Renderer { if ( this.onButtonsInitListeners[ wrapper ] ) { for ( const handler of this.onButtonsInitListeners[ wrapper ] ) { - if ( typeof handler === 'function' ) { - handler( { - wrapper, - ...this.buttonsOptions[ wrapper ], - } ); + if ( typeof handler !== 'function' ) { + continue; } + + handler( { wrapper, ...this.buttonsOptions[ wrapper ] } ); } } } @@ -286,10 +281,11 @@ class Renderer { if ( ! this.buttonsOptions[ wrapper ] ) { return; } + try { this.buttonsOptions[ wrapper ].actions.disable(); } catch ( err ) { - console.log( 'Failed to disable buttons: ' + err ); + console.warn( 'Failed to disable buttons: ' + err ); } } @@ -297,10 +293,11 @@ class Renderer { if ( ! this.buttonsOptions[ wrapper ] ) { return; } + try { this.buttonsOptions[ wrapper ].actions.enable(); } catch ( err ) { - console.log( 'Failed to enable buttons: ' + err ); + console.warn( 'Failed to enable buttons: ' + err ); } } } From 3fead84a70e6c5f14b2228d506ad0e9946cc8c19 Mon Sep 17 00:00:00 2001 From: Philipp Stracker Date: Mon, 17 Mar 2025 15:23:29 +0100 Subject: [PATCH 48/62] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20Move=20DCC=20hooks?= =?UTF-8?q?=20to=20separate=20helper=20method?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ppcp-button/src/Assets/SmartButton.php | 129 ++++++++++-------- 1 file changed, 69 insertions(+), 60 deletions(-) diff --git a/modules/ppcp-button/src/Assets/SmartButton.php b/modules/ppcp-button/src/Assets/SmartButton.php index 054fe8c41..477f73cb8 100644 --- a/modules/ppcp-button/src/Assets/SmartButton.php +++ b/modules/ppcp-button/src/Assets/SmartButton.php @@ -342,66 +342,7 @@ class SmartButton implements SmartButtonInterface { } if ( $this->dcc_configuration->is_enabled() ) { - add_action( - $this->checkout_dcc_button_renderer_hook(), - array( $this, 'dcc_renderer' ), - 11 - ); - - add_action( - $this->pay_order_renderer_hook(), - array( $this, 'dcc_renderer' ), - 11 - ); - - $subscription_helper = $this->subscription_helper; - add_filter( - 'woocommerce_credit_card_form_fields', - function ( array $default_fields, $id ) use ( $subscription_helper ) : array { - if ( - is_user_logged_in() - && $this->settings->has( 'vault_enabled_dcc' ) - && $this->settings->get( 'vault_enabled_dcc' ) - && CreditCardGateway::ID === $id - && apply_filters( 'woocommerce_paypal_payments_should_render_card_custom_fields', true ) - ) { - - $default_fields['card-vault'] = sprintf( - '

', - esc_html__( 'Save your Credit Card', 'woocommerce-paypal-payments' ) - ); - if ( $subscription_helper->cart_contains_subscription() || $subscription_helper->order_pay_contains_subscription() ) { - $default_fields['card-vault'] = ''; - } - - $tokens = $this->payment_token_repository->all_for_user_id( get_current_user_id() ); - if ( $tokens && $this->payment_token_repository->tokens_contains_card( $tokens ) ) { - $output = sprintf( - '

'; - - $default_fields['saved-credit-card'] = $output; - } - } - - return $default_fields; - }, - 10, - 2 - ); + $this->render_dcc_wrapper(); } if ( $this->is_free_trial_cart() ) { @@ -440,6 +381,74 @@ class SmartButton implements SmartButtonInterface { return true; } + /** + * Registers hooks and callbacks that are only relevant for DCC (ACDC) payments. + * + * @return void + */ + private function render_dcc_wrapper(): void { + add_action( + $this->checkout_dcc_button_renderer_hook(), + array( $this, 'dcc_renderer' ), + 11 + ); + + add_action( + $this->pay_order_renderer_hook(), + array( $this, 'dcc_renderer' ), + 11 + ); + + $subscription_helper = $this->subscription_helper; + add_filter( + 'woocommerce_credit_card_form_fields', + function ( array $default_fields, $id ) use ( $subscription_helper ) : array { + if ( + CreditCardGateway::ID === $id + && is_user_logged_in() + && $this->settings->has( 'vault_enabled_dcc' ) + && $this->settings->get( 'vault_enabled_dcc' ) + && apply_filters( 'woocommerce_paypal_payments_should_render_card_custom_fields', true ) + ) { + + $default_fields['card-vault'] = sprintf( + '

', + esc_html__( 'Save your Credit Card', 'woocommerce-paypal-payments' ) + ); + if ( $subscription_helper->cart_contains_subscription() || $subscription_helper->order_pay_contains_subscription() ) { + $default_fields['card-vault'] = ''; + } + + $tokens = $this->payment_token_repository->all_for_user_id( get_current_user_id() ); + if ( $tokens && $this->payment_token_repository->tokens_contains_card( $tokens ) ) { + $output = sprintf( + '

'; + + $default_fields['saved-credit-card'] = $output; + } + } + + return $default_fields; + }, + 10, + 2 + ); + } + /** * Registers the hooks to render the credit messaging HTML depending on the settings. * From a1f8022574c227a692aee218ae0126140da0b193 Mon Sep 17 00:00:00 2001 From: Philipp Stracker Date: Mon, 17 Mar 2025 16:59:01 +0100 Subject: [PATCH 49/62] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20Pass=20decision=20fl?= =?UTF-8?q?ags=20to=20disabled-funding=20hook?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/Helper/DisabledFundingSources.php | 31 ++++++++++++++----- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/modules/ppcp-button/src/Helper/DisabledFundingSources.php b/modules/ppcp-button/src/Helper/DisabledFundingSources.php index ed3506fc9..c23b9eed4 100644 --- a/modules/ppcp-button/src/Helper/DisabledFundingSources.php +++ b/modules/ppcp-button/src/Helper/DisabledFundingSources.php @@ -62,25 +62,31 @@ class DisabledFundingSources { * @return string[] List of disabled sources */ public function sources( string $context ) : array { + $block_contexts = array( 'checkout-block', 'cart-block' ); + $flags = array( + 'context' => $context, + 'is_block_context' => in_array( $context, $block_contexts, true ), + 'is_free_trial' => $this->is_free_trial_cart(), + ); + // Free trials have a shorter, special funding-source rule. - if ( $this->is_free_trial_cart() ) { + if ( $flags['is_free_trial'] ) { $disable_funding = $this->get_sources_for_free_trial(); - return $this->sanitize_and_filter_sources( $disable_funding ); + return $this->sanitize_and_filter_sources( $disable_funding, $flags ); } - $disable_funding = $this->get_sources_from_settings(); - $is_block_context = in_array( $context, array( 'checkout-block', 'cart-block' ), true ); + $disable_funding = $this->get_sources_from_settings(); // Apply rules based on context and payment methods. $disable_funding = $this->apply_context_rules( $disable_funding ); // Apply special rules for block checkout. - if ( $is_block_context ) { + if ( $flags['is_block_context'] ) { $disable_funding = $this->apply_block_checkout_rules( $disable_funding ); } - return $this->sanitize_and_filter_sources( $disable_funding ); + return $this->sanitize_and_filter_sources( $disable_funding, $flags ); } /** @@ -166,15 +172,24 @@ class DisabledFundingSources { * Filters the disabled "funding-sources" list and returns a sanitized array. * * @param array $disable_funding The disabled funding sources. + * @param array $flags Decision flags. * @return string[] */ - private function sanitize_and_filter_sources( array $disable_funding ) : array { + private function sanitize_and_filter_sources( array $disable_funding, array $flags ) : array { /** * Filters the final list of disabled funding sources. + * + * @param array $diabled_funding The filter value, funding sources to be disabled. + * @param array $flags Decision flags to provide more context to filters. */ $disable_funding = apply_filters( 'woocommerce_paypal_payments_sdk_disabled_funding_hook', - $disable_funding + $disable_funding, + array( + 'context' => (string) ( $flags['context'] ?? '' ), + 'is_block_context' => (bool) ( $flags['is_block_context'] ?? false ), + 'is_free_trial' => (bool) ( $flags['is_free_trial'] ?? false ), + ) ); // Make sure "paypal" is never disabled in the funding-sources. From 122be6dcd7bfd7532da7b95bd3f14037b1edcdb0 Mon Sep 17 00:00:00 2001 From: Philipp Stracker Date: Mon, 17 Mar 2025 16:59:37 +0100 Subject: [PATCH 50/62] =?UTF-8?q?=F0=9F=90=9B=20Disable=20=E2=80=9CCredit?= =?UTF-8?q?=20Card=E2=80=9D=20express=20payment?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- modules/ppcp-card-fields/src/CardFieldsModule.php | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/modules/ppcp-card-fields/src/CardFieldsModule.php b/modules/ppcp-card-fields/src/CardFieldsModule.php index 36349c21f..3d5f41ce1 100644 --- a/modules/ppcp-card-fields/src/CardFieldsModule.php +++ b/modules/ppcp-card-fields/src/CardFieldsModule.php @@ -69,7 +69,11 @@ class CardFieldsModule implements ServiceModule, ExtendingModule, ExecutableModu add_filter( 'woocommerce_paypal_payments_sdk_disabled_funding_hook', - static function ( array $disable_funding ) use ( $c ) { + static function ( array $disable_funding, array $flags ) use ( $c ) { + if ( true === $flags['is_block_context'] ) { + return $disable_funding; + } + $dcc_config = $c->get( 'wcgateway.configuration.card-configuration' ); assert( $dcc_config instanceof CardPaymentsConfiguration ); @@ -82,7 +86,9 @@ class CardFieldsModule implements ServiceModule, ExtendingModule, ExecutableModu $disable_funding, static fn( string $funding_source ) => $funding_source !== 'card' ); - } + }, + 10, + 2 ); add_filter( From 60fad34e7a96792b1d623dc064f0bc880dd1e0f0 Mon Sep 17 00:00:00 2001 From: Emili Castells Guasch Date: Mon, 17 Mar 2025 17:27:24 +0100 Subject: [PATCH 51/62] Add group to skip tests in ci --- .env.integration | 40 ------------------- .github/workflows/integration.yml | 2 +- .gitignore | 3 +- .../PayPalSubscriptionsRenewalTest.php | 3 ++ tests/integration/README.md | 8 ++++ 5 files changed, 14 insertions(+), 42 deletions(-) delete mode 100644 .env.integration create mode 100644 tests/integration/README.md diff --git a/.env.integration b/.env.integration deleted file mode 100644 index 8ed93a99d..000000000 --- a/.env.integration +++ /dev/null @@ -1,40 +0,0 @@ -PPCP_INTEGRATION_WP_DIR=${ROOT_DIR}/.ddev/wordpress - -BASEURL="https://woocommerce-paypal-payments.ddev.site" -AUTHORIZATION="Bearer ABC123" - -CHECKOUT_URL="/checkout" -CHECKOUT_PAGE_ID=7 -CART_URL="/cart" -BLOCK_CHECKOUT_URL="/checkout-block" -BLOCK_CHECKOUT_PAGE_ID=22 -BLOCK_CART_URL="/cart-block" - -PRODUCT_URL="/product/prod" -PRODUCT_ID=123 - -SUBSCRIPTION_URL="/product/sub" - -PAYPAL_SUBSCRIPTIONS_PRODUCT_ID=252 - -APM_ID="sofort" - -WP_MERCHANT_USER="admin" -WP_MERCHANT_PASSWORD="admin" - -WP_CUSTOMER_USER="customer" -WP_CUSTOMER_PASSWORD="password" - -CUSTOMER_EMAIL="customer@example.com" -CUSTOMER_PASSWORD="password" -CUSTOMER_FIRST_NAME="John" -CUSTOMER_LAST_NAME="Doe" -CUSTOMER_COUNTRY="DE" -CUSTOMER_ADDRESS="street 1" -CUSTOMER_POSTCODE="12345" -CUSTOMER_CITY="city" -CUSTOMER_PHONE="1234567890" - -CREDIT_CARD_NUMBER="1234567890" -CREDIT_CARD_EXPIRATION="01/2042" -CREDIT_CARD_CVV="123" diff --git a/.github/workflows/integration.yml b/.github/workflows/integration.yml index 716a4a0b7..e02629141 100644 --- a/.github/workflows/integration.yml +++ b/.github/workflows/integration.yml @@ -36,4 +36,4 @@ jobs: run: ddev php tests/integration/PHPUnit/setup.php - name: Run PHPUnit - run: ddev exec phpunit -c tests/integration/phpunit.xml.dist + run: ddev exec phpunit --exclude skip-ci -c tests/integration/phpunit.xml.dist diff --git a/.gitignore b/.gitignore index 0da873dac..69f38eab7 100644 --- a/.gitignore +++ b/.gitignore @@ -9,8 +9,9 @@ modules/*/assets/* !modules/ppcp-wc-gateway/assets/images *.zip .env -.env.e2e +.env.integration auth.json .DS_Store tests/.DS_Store .composer_compiled_assets + diff --git a/tests/integration/PHPUnit/PayPalSubscriptionsRenewalTest.php b/tests/integration/PHPUnit/PayPalSubscriptionsRenewalTest.php index 16b966b51..e40eea149 100644 --- a/tests/integration/PHPUnit/PayPalSubscriptionsRenewalTest.php +++ b/tests/integration/PHPUnit/PayPalSubscriptionsRenewalTest.php @@ -5,6 +5,9 @@ namespace WooCommerce\PayPalCommerce\Tests\Integration; use WC_Product_Simple; use WooCommerce\PayPalCommerce\PayPalSubscriptions\RenewalHandler; +/** + * @group skip-ci + */ class PayPalSubscriptionsRenewalTest extends TestCase { public function test_renewal_order_is_not_created_just_after_receiving_webhook() { $c = $this->getContainer(); diff --git a/tests/integration/README.md b/tests/integration/README.md new file mode 100644 index 000000000..d027a72f8 --- /dev/null +++ b/tests/integration/README.md @@ -0,0 +1,8 @@ +# Integration Tests +PHPUnit tests that runs against a working WP site. Useful to test modules (ex. classes) together without having the use test doubles but the real infrastructure. + +### How to run tests +- Copy and rename `.env.integration.example` to `.env.integration` from the root of the plugin, set configurations if needed. +- Run configuration: `ddev php tests/integration/PHPUnit/setup.php` +- Run tests: `ddev exec phpunit -c tests/integration/phpunit.xml.dist` +- Run a single test: `ddev exec phpunit --filter testSomeTestName -c tests/integration/phpunit.xml.dist` From 73d3e3c642173dd8bc8f8f96c6666e7606758463 Mon Sep 17 00:00:00 2001 From: Emili Castells Guasch Date: Mon, 17 Mar 2025 17:44:09 +0100 Subject: [PATCH 52/62] Remove test --- tests/integration/PHPUnit/OrdersTest.php | 49 ------------------------ 1 file changed, 49 deletions(-) delete mode 100644 tests/integration/PHPUnit/OrdersTest.php diff --git a/tests/integration/PHPUnit/OrdersTest.php b/tests/integration/PHPUnit/OrdersTest.php deleted file mode 100644 index 3ece8227a..000000000 --- a/tests/integration/PHPUnit/OrdersTest.php +++ /dev/null @@ -1,49 +0,0 @@ -getContainer(); - - $orders = new Orders( - $host, - $container->get('api.bearer'), - $container->get( 'woocommerce.logger.woocommerce' ) - ); - - $requestBody = [ - "intent" => "CAPTURE", - "payment_source" => [ - "bancontact" => [ - "country_code" => "BE", - "name" => "John Doe" - ] - ], - "processing_instruction" => "ORDER_COMPLETE_ON_PAYMENT_APPROVAL", - "purchase_units" => [ - [ - "reference_id" => "d9f80740-38f0-11e8-b467-0ed5f89f718b", - "amount" => [ - "currency_code" => "EUR", - "value" => "1.00" - ], - ] - ], - "application_context" => [ - "locale" => "en-BE", - "return_url" => "https://example.com/returnUrl", - "cancel_url" => "https://example.com/cancelUrl" - ] - ]; - - $result = $orders->create($requestBody); - - $this->assertEquals(200, $result['response']['code']); - } -} From b5c08e842eb0c7295aaf0d6c7e6bdd54b150307f Mon Sep 17 00:00:00 2001 From: Philipp Stracker Date: Tue, 18 Mar 2025 14:53:49 +0100 Subject: [PATCH 53/62] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20Make=20code=20more?= =?UTF-8?q?=20readable,=20resolve=20one=20warning?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../resources/js/modules/Renderer/Renderer.js | 4 +++- .../resources/js/modules/Renderer/WidgetBuilder.js | 9 +++++---- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/modules/ppcp-button/resources/js/modules/Renderer/Renderer.js b/modules/ppcp-button/resources/js/modules/Renderer/Renderer.js index 5131f03b4..ab9da6a0b 100644 --- a/modules/ppcp-button/resources/js/modules/Renderer/Renderer.js +++ b/modules/ppcp-button/resources/js/modules/Renderer/Renderer.js @@ -214,7 +214,9 @@ class Renderer { } ); - this.renderedSources.add( wrapper + ( fundingSource ?? '' ) ); + this.renderedSources.add( + wrapper + ( fundingSource ? fundingSource : '' ) + ); if ( window.paypal?.Buttons ) { widgetBuilder.registerButtons( diff --git a/modules/ppcp-button/resources/js/modules/Renderer/WidgetBuilder.js b/modules/ppcp-button/resources/js/modules/Renderer/WidgetBuilder.js index baa031ca6..13d915df2 100644 --- a/modules/ppcp-button/resources/js/modules/Renderer/WidgetBuilder.js +++ b/modules/ppcp-button/resources/js/modules/Renderer/WidgetBuilder.js @@ -40,8 +40,9 @@ class WidgetBuilder { renderButtons( wrapper ) { wrapper = this.sanitizeWrapper( wrapper ); + const entryKey = this.toKey( wrapper ); - if ( ! this.buttons.has( this.toKey( wrapper ) ) ) { + if ( ! this.buttons.has( entryKey ) ) { return; } @@ -49,11 +50,11 @@ class WidgetBuilder { return; } - const entry = this.buttons.get( this.toKey( wrapper ) ); + const entry = this.buttons.get( entryKey ); const btn = this.paypal.Buttons( entry.options ); if ( ! btn.isEligible() ) { - this.buttons.delete( this.toKey( wrapper ) ); + this.buttons.delete( entryKey ); return; } @@ -67,7 +68,7 @@ class WidgetBuilder { } renderAllButtons() { - for ( const [ wrapper, entry ] of this.buttons ) { + for ( const [ wrapper ] of this.buttons ) { this.renderButtons( wrapper ); } } From ee5237adf58499dcbfebafd274c4298792d65e99 Mon Sep 17 00:00:00 2001 From: Philipp Stracker Date: Tue, 18 Mar 2025 16:11:42 +0100 Subject: [PATCH 54/62] =?UTF-8?q?=F0=9F=90=9B=20Fix=20the=20=E2=80=9Cdisab?= =?UTF-8?q?le=20card=20funding=E2=80=9D=20condition?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- modules/ppcp-button/src/Helper/DisabledFundingSources.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/ppcp-button/src/Helper/DisabledFundingSources.php b/modules/ppcp-button/src/Helper/DisabledFundingSources.php index c23b9eed4..c2cf3bd43 100644 --- a/modules/ppcp-button/src/Helper/DisabledFundingSources.php +++ b/modules/ppcp-button/src/Helper/DisabledFundingSources.php @@ -132,14 +132,14 @@ class DisabledFundingSources { * @return array */ private function apply_context_rules( array $disable_funding ) : array { - if ( ! is_checkout() || ! $this->dcc_configuration->is_bcdc_enabled() ) { - // Non-checkout pages, or BCDC disabled: Don't load card payments. + if ( ! is_checkout() || $this->dcc_configuration->is_acdc_enabled() ) { + // Non-checkout pages, or ACDC enabled: Don't load card button. $disable_funding[] = 'card'; return $disable_funding; } - // A checkout page and BCDC is enabled: Load card payments. + // A checkout page without ACDC: Load card button. return array_filter( $disable_funding, static fn( string $funding_source ) => $funding_source !== 'card' From e9b3cc61d2c7e07814a6ad4d661f7a41c9137693 Mon Sep 17 00:00:00 2001 From: Philipp Stracker Date: Tue, 18 Mar 2025 16:18:19 +0100 Subject: [PATCH 55/62] =?UTF-8?q?=E2=9C=A8=20Add=20new=20hook=20to=20custo?= =?UTF-8?q?mize=20disabled-funding=20list?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/Helper/DisabledFundingSources.php | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/modules/ppcp-button/src/Helper/DisabledFundingSources.php b/modules/ppcp-button/src/Helper/DisabledFundingSources.php index c2cf3bd43..4c8e98da9 100644 --- a/modules/ppcp-button/src/Helper/DisabledFundingSources.php +++ b/modules/ppcp-button/src/Helper/DisabledFundingSources.php @@ -96,10 +96,23 @@ class DisabledFundingSources { */ private function get_sources_from_settings() : array { try { - return $this->settings->get( 'disable_funding' ); + // Settings field present in the legacy UI. + $disabled_funding = $this->settings->get( 'disable_funding' ); } catch ( NotFoundException $exception ) { - return array(); + $disabled_funding = array(); } + + /** + * Filters the list of disabled funding methods. In the legacy UI, this + * list was accessible via a settings field. + * + * This filter allows merchants to programmatically disable funding sources + * in the new UI. + */ + return (array) apply_filters( + 'woocommerce_paypal_payments_disabled_funding', + $disabled_funding + ); } /** From 09c4f176d037f20b1acbbb2aab120f0836ecf1a7 Mon Sep 17 00:00:00 2001 From: Philipp Stracker Date: Tue, 18 Mar 2025 16:21:34 +0100 Subject: [PATCH 56/62] =?UTF-8?q?=F0=9F=90=9B=20Stop=20enforcing=20card=20?= =?UTF-8?q?payments=20in=20checkout?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Removed a filter that reverted settings entered in the legacy UI’s “Disable Alternative Payment Methods” field. --- modules/ppcp-button/src/Helper/DisabledFundingSources.php | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/modules/ppcp-button/src/Helper/DisabledFundingSources.php b/modules/ppcp-button/src/Helper/DisabledFundingSources.php index 4c8e98da9..ecf7d5f6f 100644 --- a/modules/ppcp-button/src/Helper/DisabledFundingSources.php +++ b/modules/ppcp-button/src/Helper/DisabledFundingSources.php @@ -152,11 +152,7 @@ class DisabledFundingSources { return $disable_funding; } - // A checkout page without ACDC: Load card button. - return array_filter( - $disable_funding, - static fn( string $funding_source ) => $funding_source !== 'card' - ); + return $disable_funding; } /** From fb27373c1bb2f11a5ea7ca2590dda3fe9e8a7c17 Mon Sep 17 00:00:00 2001 From: Philipp Stracker Date: Tue, 18 Mar 2025 16:31:38 +0100 Subject: [PATCH 57/62] =?UTF-8?q?=F0=9F=90=9B=20Fix=20=E2=80=9Cuse-ACDC?= =?UTF-8?q?=E2=80=9D=20flag=20in=20legacy=20UI?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A new filter adds backwards compatibility by overwriting the ACDC decision with a settings choice. --- modules/ppcp-compat/src/CompatModule.php | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/modules/ppcp-compat/src/CompatModule.php b/modules/ppcp-compat/src/CompatModule.php index afd0a368f..81b603feb 100644 --- a/modules/ppcp-compat/src/CompatModule.php +++ b/modules/ppcp-compat/src/CompatModule.php @@ -508,6 +508,18 @@ class CompatModule implements ServiceModule, ExtendingModule, ExecutableModule { return; } - // Add filters here... + add_filter( + 'woocommerce_paypal_payments_is_acdc_active', + static function ( bool $is_acdc ) use ( $container ) : bool { + $settings = $container->get( 'wcgateway.settings' ); + assert( $settings instanceof Settings ); + + try { + return (bool) $settings->get( 'dcc_enabled' ); + } catch ( NotFoundException $exception ) { + return $is_acdc; + } + } + ); } } From aab21b62b4affa7b356d5b10189ea7958830ddf6 Mon Sep 17 00:00:00 2001 From: Philipp Stracker Date: Tue, 18 Mar 2025 16:32:38 +0100 Subject: [PATCH 58/62] =?UTF-8?q?=F0=9F=90=9B=20New=20UI:=20Disable=20BCDC?= =?UTF-8?q?=20on=20store-level?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Instead of checking “is enabled” we now check “has capability” - i.e. if a merchant has ACDC capability we will always disable the BCDC funding source --- modules/ppcp-button/src/Helper/DisabledFundingSources.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/ppcp-button/src/Helper/DisabledFundingSources.php b/modules/ppcp-button/src/Helper/DisabledFundingSources.php index ecf7d5f6f..66fb8fc07 100644 --- a/modules/ppcp-button/src/Helper/DisabledFundingSources.php +++ b/modules/ppcp-button/src/Helper/DisabledFundingSources.php @@ -145,8 +145,8 @@ class DisabledFundingSources { * @return array */ private function apply_context_rules( array $disable_funding ) : array { - if ( ! is_checkout() || $this->dcc_configuration->is_acdc_enabled() ) { - // Non-checkout pages, or ACDC enabled: Don't load card button. + if ( ! is_checkout() || $this->dcc_configuration->use_acdc() ) { + // Non-checkout pages, or ACDC capability: Don't load card button. $disable_funding[] = 'card'; return $disable_funding; From ae3bd15cb61f1bd065002a91c179a834dd87e51d Mon Sep 17 00:00:00 2001 From: Philipp Stracker Date: Tue, 18 Mar 2025 16:46:56 +0100 Subject: [PATCH 59/62] =?UTF-8?q?=F0=9F=92=A1=20Update=20code=20documentat?= =?UTF-8?q?ion?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/Helper/CardPaymentsConfiguration.php | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/modules/ppcp-wc-gateway/src/Helper/CardPaymentsConfiguration.php b/modules/ppcp-wc-gateway/src/Helper/CardPaymentsConfiguration.php index ab9c4ed3f..8f1420428 100644 --- a/modules/ppcp-wc-gateway/src/Helper/CardPaymentsConfiguration.php +++ b/modules/ppcp-wc-gateway/src/Helper/CardPaymentsConfiguration.php @@ -30,11 +30,13 @@ use WooCommerce\PayPalCommerce\ApiClient\Helper\DccApplies; * Technical implementation via the JS SDK: * * a. Funding source - * - All card payment options require the funding-source "card" + * - When the funding-source "card" controls the black "Debit or Credit Cards" button: + * It's hidden when the funding-source is disabled, and displayed otherwise. + * See implementation in class `DisabledFundingSources`. * * b. Components - * - ACDC and AXO use "card-fields" - * - BCDC uses "hosted-fields" + * - "card-fields" is used by ACDC and AXO. + * - The component "hosted-fields" is mentioned in the code, but unclear where/when it's used. * * DI service: 'wcgateway.configuration.card-configuration' */ From f9212b1713ab17983106d0cb735a1e6b8a99537b Mon Sep 17 00:00:00 2001 From: Philipp Stracker Date: Tue, 18 Mar 2025 17:03:59 +0100 Subject: [PATCH 60/62] =?UTF-8?q?=F0=9F=A7=AA=20Fix=20unit=20tests=20with?= =?UTF-8?q?=20missing=20assertion?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/PHPUnit/Button/Helper/DisabledFundingSourcesTest.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/PHPUnit/Button/Helper/DisabledFundingSourcesTest.php b/tests/PHPUnit/Button/Helper/DisabledFundingSourcesTest.php index 334119788..58ffa76d8 100644 --- a/tests/PHPUnit/Button/Helper/DisabledFundingSourcesTest.php +++ b/tests/PHPUnit/Button/Helper/DisabledFundingSourcesTest.php @@ -31,6 +31,7 @@ class DisabledFundingSourcesTest extends TestCase public function test_is_checkout_true_add_card_when_checkout_block_context() { $this->dcc_configuration->shouldReceive('is_enabled')->andReturn(true); + $this->dcc_configuration->shouldReceive('use_acdc')->andReturn(true); $sut = new DisabledFundingSources($this->settings, [], $this->dcc_configuration); $this->setExpectations(); @@ -48,6 +49,7 @@ class DisabledFundingSourcesTest extends TestCase public function test_is_checkout_false_add_card_when_checkout_context() { $this->dcc_configuration->shouldReceive('is_enabled')->andReturn(true); + $this->dcc_configuration->shouldReceive('use_acdc')->andReturn(true); $sut = new DisabledFundingSources($this->settings, [], $this->dcc_configuration); $this->setExpectations(); @@ -61,6 +63,7 @@ class DisabledFundingSourcesTest extends TestCase public function test_is_checkout_true_add_allowed_sources_when_checkout_block_context() { $this->dcc_configuration->shouldReceive('is_enabled')->andReturn(true); + $this->dcc_configuration->shouldReceive('use_acdc')->andReturn(true); $sut = new DisabledFundingSources( $this->settings, [ From bb3bdbbe5c78eafc36b13fdb284630f30b801010 Mon Sep 17 00:00:00 2001 From: Emili Castells Guasch Date: Thu, 20 Mar 2025 12:17:12 +0100 Subject: [PATCH 61/62] Add new ui active item to status report --- modules/ppcp-status-report/src/StatusReportModule.php | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/modules/ppcp-status-report/src/StatusReportModule.php b/modules/ppcp-status-report/src/StatusReportModule.php index 2baa411eb..e6749fc23 100644 --- a/modules/ppcp-status-report/src/StatusReportModule.php +++ b/modules/ppcp-status-report/src/StatusReportModule.php @@ -94,6 +94,17 @@ class StatusReportModule implements ServiceModule, ExtendingModule, ExecutableMo $this->onboarded( $bearer, $is_connected ) ), ), + array( + 'label' => esc_html__( 'New UI active', 'woocommerce-paypal-payments' ), + 'exported_label' => 'New UI active', + 'description' => esc_html__( 'Whether the new Settings UI is active or not.', 'woocommerce-paypal-payments' ), + 'value' => $this->bool_to_html( + apply_filters( + 'woocommerce.feature-flags.woocommerce_paypal_payments.settings_enabled', + '1' === get_option( 'woocommerce-ppcp-is-new-merchant' ) || getenv( 'PCP_SETTINGS_ENABLED' ) === '1' + ) + ), + ), array( 'label' => esc_html__( 'Shop country code', 'woocommerce-paypal-payments' ), 'exported_label' => 'Shop country code', From ceda9942308c35a94a2694c46ef513f6511030af Mon Sep 17 00:00:00 2001 From: Emili Castells Guasch Date: Thu, 20 Mar 2025 12:37:55 +0100 Subject: [PATCH 62/62] Improve item description --- modules/ppcp-status-report/src/StatusReportModule.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/ppcp-status-report/src/StatusReportModule.php b/modules/ppcp-status-report/src/StatusReportModule.php index e6749fc23..10159f8c7 100644 --- a/modules/ppcp-status-report/src/StatusReportModule.php +++ b/modules/ppcp-status-report/src/StatusReportModule.php @@ -97,7 +97,7 @@ class StatusReportModule implements ServiceModule, ExtendingModule, ExecutableMo array( 'label' => esc_html__( 'New UI active', 'woocommerce-paypal-payments' ), 'exported_label' => 'New UI active', - 'description' => esc_html__( 'Whether the new Settings UI is active or not.', 'woocommerce-paypal-payments' ), + 'description' => esc_html__( 'Indicates whether the new Settings UI is enabled.', 'woocommerce-paypal-payments' ), 'value' => $this->bool_to_html( apply_filters( 'woocommerce.feature-flags.woocommerce_paypal_payments.settings_enabled',