From f3e3b1aa932b7483bc2099df8deece9f1d5124f2 Mon Sep 17 00:00:00 2001 From: Emili Castells Guasch Date: Thu, 22 May 2025 12:57:34 +0200 Subject: [PATCH 1/6] Adds mexico installments inbox note --- .../ppcp-admin-notices/src/AdminNotices.php | 11 ++ .../src/Notes/MexicoInstallmentsNote.php | 105 ++++++++++++++++++ 2 files changed, 116 insertions(+) create mode 100644 modules/ppcp-admin-notices/src/Notes/MexicoInstallmentsNote.php diff --git a/modules/ppcp-admin-notices/src/AdminNotices.php b/modules/ppcp-admin-notices/src/AdminNotices.php index 9fc269890..47067f25e 100644 --- a/modules/ppcp-admin-notices/src/AdminNotices.php +++ b/modules/ppcp-admin-notices/src/AdminNotices.php @@ -9,6 +9,7 @@ declare(strict_types=1); namespace WooCommerce\PayPalCommerce\AdminNotices; +use WooCommerce\PayPalCommerce\AdminNotices\Notes\MexicoInstallmentsNote; use WooCommerce\PayPalCommerce\AdminNotices\Repository\Repository; use WooCommerce\PayPalCommerce\Vendor\Inpsyde\Modularity\Module\ExecutableModule; use WooCommerce\PayPalCommerce\Vendor\Inpsyde\Modularity\Module\ExtendingModule; @@ -110,6 +111,16 @@ class AdminNotices implements ServiceModule, ExtendingModule, ExecutableModule { } ); + add_action( + 'woocommerce_init', + function() { + if ( is_admin() && is_callable( array( WC(), 'is_wc_admin_active' ) ) && WC()->is_wc_admin_active() && class_exists( 'Automattic\WooCommerce\Admin\Notes\Notes' ) ) { + MexicoInstallmentsNote::init(); + } + + } + ); + return true; } } diff --git a/modules/ppcp-admin-notices/src/Notes/MexicoInstallmentsNote.php b/modules/ppcp-admin-notices/src/Notes/MexicoInstallmentsNote.php new file mode 100644 index 000000000..b671a0157 --- /dev/null +++ b/modules/ppcp-admin-notices/src/Notes/MexicoInstallmentsNote.php @@ -0,0 +1,105 @@ +save(); + } + + /** + * Returns a new Note. + * + * @return Note + */ + public static function get_note(): Note { + $note = new Note(); + $note->set_name( self::NOTE_NAME ); + $note->set_type( Note::E_WC_ADMIN_NOTE_INFORMATIONAL ); + $note->set_source( 'woocommerce-paypal-payments' ); + $note->set_title( + __( 'Enable Installments with PayPal', 'woocommerce-paypal-payments' ) + ); + $note->set_content( + __( 'Allow your customers to pay in installments without interest while you receive the full payment.* Activate your Installments without interest with PayPal. *You will receive the full payment minus the applicable PayPal fee. See terms and conditions.', 'woocommerce-paypal-payments' ) + ); + $note->add_action( + 'enable-installments-action-link', + __( 'Enable Installments', 'woocommerce-paypal-payments' ), + esc_url( 'https://www.paypal.com/businessmanage/preferences/installmentplan' ), + Note::E_WC_ADMIN_NOTE_UNACTIONED, + true + ); + + return $note; + } + + /** + * Checks if a note can and should be added. + * + * @return bool + * @throws NotesUnavailableException Throws exception when notes are unavailable. + */ + public static function can_be_added(): bool { + $country = wc_get_base_location()['country'] ?? ''; + if ( $country !== 'MX' ) { + return false; + } + + $note = self::get_note(); + if ( ! $note instanceof Note || self::note_exists() ) { + return false; + } + + return true; + } +} From 2b549586ac6696dd961df698799132ce64b82ddd Mon Sep 17 00:00:00 2001 From: Emili Castells Guasch Date: Thu, 22 May 2025 15:37:49 +0200 Subject: [PATCH 2/6] Add installments section in classic ux --- .../src/Notes/MexicoInstallmentsNote.php | 13 ++- modules/ppcp-wc-gateway/services.php | 90 +++++++++++++------ 2 files changed, 74 insertions(+), 29 deletions(-) diff --git a/modules/ppcp-admin-notices/src/Notes/MexicoInstallmentsNote.php b/modules/ppcp-admin-notices/src/Notes/MexicoInstallmentsNote.php index b671a0157..6cdf0d3d8 100644 --- a/modules/ppcp-admin-notices/src/Notes/MexicoInstallmentsNote.php +++ b/modules/ppcp-admin-notices/src/Notes/MexicoInstallmentsNote.php @@ -70,8 +70,19 @@ class MexicoInstallmentsNote { __( 'Enable Installments with PayPal', 'woocommerce-paypal-payments' ) ); $note->set_content( - __( 'Allow your customers to pay in installments without interest while you receive the full payment.* Activate your Installments without interest with PayPal. *You will receive the full payment minus the applicable PayPal fee. See terms and conditions.', 'woocommerce-paypal-payments' ) + sprintf( + // translators: %1$s and %2$s are the opening and closing of HTML tag. + __( + 'Allow your customers to pay in installments without interest while you receive the full payment in a single transaction.* +

Activate your Installments without interest with PayPal.

+

You will receive the full payment minus the applicable PayPal fee. See %1$sterms and conditions%2$s.

', + 'woocommerce-paypal-payments' + ), + '
', + '' + ) ); + $note->add_action( 'enable-installments-action-link', __( 'Enable Installments', 'woocommerce-paypal-payments' ), diff --git a/modules/ppcp-wc-gateway/services.php b/modules/ppcp-wc-gateway/services.php index 90963a991..9a7204ef2 100644 --- a/modules/ppcp-wc-gateway/services.php +++ b/modules/ppcp-wc-gateway/services.php @@ -691,7 +691,7 @@ return array( assert( $dcc_configuration instanceof CardPaymentsConfiguration ); $fields = array( - 'checkout_settings_heading' => array( + 'checkout_settings_heading' => array( 'heading' => __( 'Standard Payments Settings', 'woocommerce-paypal-payments' ), 'type' => 'ppcp-heading', 'screens' => array( @@ -701,7 +701,7 @@ return array( 'requirements' => array(), 'gateway' => 'paypal', ), - 'title' => array( + 'title' => array( 'title' => __( 'Title', 'woocommerce-paypal-payments' ), 'type' => 'text', 'description' => __( @@ -717,7 +717,7 @@ return array( 'requirements' => array(), 'gateway' => 'paypal', ), - 'dcc_block_checkout_notice' => array( + 'dcc_block_checkout_notice' => array( 'heading' => '', 'html' => $container->get( 'wcgateway.notice.checkout-blocks' ), 'type' => 'ppcp-html', @@ -728,7 +728,7 @@ return array( 'requirements' => array( 'dcc' ), 'gateway' => 'dcc', ), - 'dcc_enabled' => array( + 'dcc_enabled' => array( 'title' => __( 'Enable/Disable', 'woocommerce-paypal-payments' ), 'desc_tip' => true, 'description' => __( 'Once enabled, the Credit Card option will show up in the checkout.', 'woocommerce-paypal-payments' ), @@ -743,7 +743,7 @@ return array( State::STATE_ONBOARDED, ), ), - 'dcc_gateway_title' => array( + 'dcc_gateway_title' => array( 'title' => __( 'Title', 'woocommerce-paypal-payments' ), 'type' => 'text', 'description' => __( @@ -760,7 +760,7 @@ return array( ), 'gateway' => 'dcc', ), - 'description' => array( + 'description' => array( 'title' => __( 'Description', 'woocommerce-paypal-payments' ), 'type' => 'text', 'desc_tip' => true, @@ -779,7 +779,7 @@ return array( 'requirements' => array(), 'gateway' => 'paypal', ), - 'intent' => array( + 'intent' => array( 'title' => __( 'Intent', 'woocommerce-paypal-payments' ), 'type' => 'select', 'class' => array(), @@ -801,7 +801,7 @@ return array( 'requirements' => array(), 'gateway' => 'paypal', ), - 'capture_on_status_change' => array( + 'capture_on_status_change' => array( 'title' => __( 'Capture On Status Change', 'woocommerce-paypal-payments' ), 'type' => 'checkbox', 'default' => false, @@ -818,7 +818,7 @@ return array( 'requirements' => array(), 'gateway' => 'paypal', ), - 'capture_for_virtual_only' => array( + 'capture_for_virtual_only' => array( 'title' => __( 'Capture Virtual-Only Orders ', 'woocommerce-paypal-payments' ), 'type' => 'checkbox', 'default' => false, @@ -835,7 +835,7 @@ return array( 'requirements' => array(), 'gateway' => 'paypal', ), - 'payee_preferred' => array( + 'payee_preferred' => array( 'title' => __( 'Instant Payments ', 'woocommerce-paypal-payments' ), 'type' => 'checkbox', 'default' => false, @@ -852,7 +852,7 @@ return array( 'requirements' => array(), 'gateway' => 'paypal', ), - 'brand_name' => array( + 'brand_name' => array( 'title' => __( 'Brand Name', 'woocommerce-paypal-payments' ), 'type' => 'text', 'default' => get_bloginfo( 'name' ), @@ -868,7 +868,7 @@ return array( 'requirements' => array(), 'gateway' => 'paypal', ), - 'landing_page' => array( + 'landing_page' => array( 'title' => __( 'Landing Page', 'woocommerce-paypal-payments' ), 'type' => 'select', 'class' => array(), @@ -890,7 +890,7 @@ return array( 'requirements' => array(), 'gateway' => 'paypal', ), - 'alternative_payment_methods' => array( + 'alternative_payment_methods' => array( 'heading' => __( 'Alternative Payment Methods', 'woocommerce-paypal-payments' ), 'description' => sprintf( // translators: %1$s, %2$s, %3$s and %4$s are a link tags. @@ -906,7 +906,7 @@ return array( 'requirements' => array(), 'gateway' => 'paypal', ), - 'disable_funding' => array( + 'disable_funding' => array( 'title' => __( 'Disable Alternative Payment Methods', 'woocommerce-paypal-payments' ), 'type' => 'ppcp-multiselect', 'class' => array(), @@ -930,7 +930,7 @@ return array( 'requirements' => array(), 'gateway' => 'paypal', ), - 'card_billing_data_mode' => array( + 'card_billing_data_mode' => array( 'title' => __( 'Send checkout billing data to card fields', 'woocommerce-paypal-payments' ), 'type' => 'select', 'class' => array(), @@ -950,7 +950,7 @@ return array( 'requirements' => array(), 'gateway' => array( 'paypal', CardButtonGateway::ID ), ), - 'allow_card_button_gateway' => array( + 'allow_card_button_gateway' => array( 'title' => __( 'Create gateway for Standard Card Button', 'woocommerce-paypal-payments' ), 'type' => 'checkbox', 'desc_tip' => true, @@ -964,7 +964,7 @@ return array( 'requirements' => array(), 'gateway' => 'paypal', ), - 'allow_local_apm_gateways' => array( + 'allow_local_apm_gateways' => array( 'title' => __( 'Create gateway for alternative payment methods', 'woocommerce-paypal-payments' ), 'type' => 'checkbox', 'desc_tip' => true, @@ -978,7 +978,7 @@ return array( 'requirements' => array(), 'gateway' => 'paypal', ), - 'disable_cards' => array( + 'disable_cards' => array( 'title' => __( 'Disable specific credit cards', 'woocommerce-paypal-payments' ), 'type' => 'ppcp-multiselect', 'class' => array(), @@ -1006,7 +1006,7 @@ return array( ), 'gateway' => 'dcc', ), - 'card_icons' => array( + 'card_icons' => array( 'title' => __( 'Show logo of the following credit cards', 'woocommerce-paypal-payments' ), 'type' => 'ppcp-multiselect', 'class' => array(), @@ -1045,7 +1045,7 @@ return array( ), 'gateway' => 'dcc', ), - 'dcc_name_on_card' => array( + 'dcc_name_on_card' => array( 'title' => __( 'Cardholder Name', 'woocommerce-paypal-payments' ), 'type' => 'select', 'default' => $dcc_configuration->show_name_on_card(), @@ -1059,7 +1059,7 @@ return array( 'gateway' => array( 'dcc', 'axo' ), 'requirements' => array( 'axo' ), ), - '3d_secure_heading' => array( + '3d_secure_heading' => array( 'heading' => __( '3D Secure', 'woocommerce-paypal-payments' ), 'type' => 'ppcp-heading', 'description' => wp_kses_post( @@ -1087,7 +1087,7 @@ return array( ), 'gateway' => 'dcc', ), - '3d_secure_contingency' => array( + '3d_secure_contingency' => array( 'title' => __( 'Contingency for 3D Secure', 'woocommerce-paypal-payments' ), 'type' => 'select', 'description' => sprintf( @@ -1115,7 +1115,7 @@ return array( ), 'gateway' => 'dcc', ), - 'saved_payments_heading' => array( + 'saved_payments_heading' => array( 'heading' => __( 'Saved Payments', 'woocommerce-paypal-payments' ), 'type' => 'ppcp-heading', 'description' => wp_kses_post( @@ -1142,7 +1142,7 @@ return array( ), 'gateway' => 'dcc', ), - 'vault_enabled_dcc' => array( + 'vault_enabled_dcc' => array( 'title' => __( 'Vaulting', 'woocommerce-paypal-payments' ), 'type' => 'checkbox', 'desc_tip' => true, @@ -1161,7 +1161,36 @@ return array( 'gateway' => 'dcc', 'input_class' => $container->get( 'wcgateway.helper.vaulting-scope' ) ? array() : array( 'ppcp-disabled-checkbox' ), ), - 'paypal_saved_payments' => array( + 'mexico_installments' => array( + 'heading' => __( 'Installments', 'woocommerce-paypal-payments' ), + 'type' => 'ppcp-heading', + 'screens' => array( + State::STATE_ONBOARDED, + ), + 'requirements' => array(), + 'gateway' => 'paypal', + 'description' => sprintf( + // translators: %1$s and %2$s are the opening and closing of HTML tag. + __( + 'Allow your customers to pay in installments without interest while you receive the full payment in a single transaction.* +

Terms and conditions: *You will receive the full payment minus the applicable PayPal fee. See %1$sterms and conditions%2$s.

', + 'woocommerce-paypal-payments' + ), + '
', + '' + ), + ), + 'mexico_installments_action_link' => array( + 'title' => __( 'Activate your Installments', 'woocommerce-paypal-payments' ), + 'type' => 'ppcp-text', + 'text' => '' . esc_html__( 'Enable Installments', 'woocommerce-paypal-payments' ) . '', + 'screens' => array( + State::STATE_ONBOARDED, + ), + 'requirements' => array(), + 'gateway' => 'paypal', + ), + 'paypal_saved_payments' => array( 'heading' => __( 'Saved payments', 'woocommerce-paypal-payments' ), 'description' => sprintf( // translators: %1$s, %2$s, %3$s and %4$s are a link tags. @@ -1179,8 +1208,8 @@ return array( 'requirements' => array(), 'gateway' => 'paypal', ), - 'subscriptions_mode' => $container->get( 'wcgateway.settings.fields.subscriptions_mode' ), - 'vault_enabled' => array( + 'subscriptions_mode' => $container->get( 'wcgateway.settings.fields.subscriptions_mode' ), + 'vault_enabled' => array( 'title' => __( 'Vaulting', 'woocommerce-paypal-payments' ), 'type' => 'checkbox', 'desc_tip' => true, @@ -1199,7 +1228,7 @@ return array( 'gateway' => 'paypal', 'input_class' => $container->get( 'wcgateway.helper.vaulting-scope' ) ? array() : array( 'ppcp-disabled-checkbox' ), ), - 'digital_wallet_heading' => array( + 'digital_wallet_heading' => array( 'heading' => __( 'Digital Wallet Services', 'woocommerce-paypal-payments' ), 'type' => 'ppcp-heading', 'description' => wp_kses_post( @@ -1254,6 +1283,11 @@ return array( $fields['disable_cards']['options'] = $card_options; $fields['card_icons']['options'] = array_merge( $dark_versions, $card_options ); + if ( $container->get( 'api.shop.country' ) !== 'MX' ) { + unset( $fields['mexico_installments'] ); + unset( $fields['mexico_installments_action_link'] ); + } + return $fields; }, From a9e5943ada346acad2d6be0cd7a68d4e5e5953ea Mon Sep 17 00:00:00 2001 From: Emili Castells Guasch Date: Thu, 22 May 2025 15:46:47 +0200 Subject: [PATCH 3/6] Fix psalm --- .../src/Notes/MexicoInstallmentsNote.php | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/modules/ppcp-admin-notices/src/Notes/MexicoInstallmentsNote.php b/modules/ppcp-admin-notices/src/Notes/MexicoInstallmentsNote.php index 6cdf0d3d8..f7e074c37 100644 --- a/modules/ppcp-admin-notices/src/Notes/MexicoInstallmentsNote.php +++ b/modules/ppcp-admin-notices/src/Notes/MexicoInstallmentsNote.php @@ -13,6 +13,7 @@ use Automattic\WooCommerce\Admin\Notes\Note; use Automattic\WooCommerce\Admin\Notes\NotesUnavailableException; use Automattic\WooCommerce\Admin\Notes\NoteTraits; use Exception; +use Mockery\Matcher\Not; /** * Class MexicoInstallmentsNote @@ -46,7 +47,7 @@ class MexicoInstallmentsNote { * * @throws NotesUnavailableException Throws exception when notes are unavailable. */ - public static function possibly_add_note() { + public static function possibly_add_note(): void { $note = self::get_note(); if ( ! self::can_be_added() ) { @@ -106,8 +107,12 @@ class MexicoInstallmentsNote { return false; } - $note = self::get_note(); - if ( ! $note instanceof Note || self::note_exists() ) { + /** + * The method exists in the NoteTraits trait. + * + * @psalm-suppress UndefinedMethod + */ + if ( self::note_exists() ) { return false; } From 12f26e230e572f3b7c3c28e58bba83974562fa51 Mon Sep 17 00:00:00 2001 From: Emili Castells Guasch Date: Thu, 22 May 2025 16:26:09 +0200 Subject: [PATCH 4/6] Remove unused import --- modules/ppcp-admin-notices/src/Notes/MexicoInstallmentsNote.php | 1 - 1 file changed, 1 deletion(-) diff --git a/modules/ppcp-admin-notices/src/Notes/MexicoInstallmentsNote.php b/modules/ppcp-admin-notices/src/Notes/MexicoInstallmentsNote.php index f7e074c37..9bf73e312 100644 --- a/modules/ppcp-admin-notices/src/Notes/MexicoInstallmentsNote.php +++ b/modules/ppcp-admin-notices/src/Notes/MexicoInstallmentsNote.php @@ -13,7 +13,6 @@ use Automattic\WooCommerce\Admin\Notes\Note; use Automattic\WooCommerce\Admin\Notes\NotesUnavailableException; use Automattic\WooCommerce\Admin\Notes\NoteTraits; use Exception; -use Mockery\Matcher\Not; /** * Class MexicoInstallmentsNote From 77fcf75aee0ca125a2deabbb0ae057ef319b3b2a Mon Sep 17 00:00:00 2001 From: Emili Castells Guasch Date: Thu, 22 May 2025 16:58:10 +0200 Subject: [PATCH 5/6] Extract html from translation strings --- .../src/Notes/MexicoInstallmentsNote.php | 10 ++++++---- modules/ppcp-wc-gateway/services.php | 8 +++++--- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/modules/ppcp-admin-notices/src/Notes/MexicoInstallmentsNote.php b/modules/ppcp-admin-notices/src/Notes/MexicoInstallmentsNote.php index 9bf73e312..ae815c7b1 100644 --- a/modules/ppcp-admin-notices/src/Notes/MexicoInstallmentsNote.php +++ b/modules/ppcp-admin-notices/src/Notes/MexicoInstallmentsNote.php @@ -71,15 +71,17 @@ class MexicoInstallmentsNote { ); $note->set_content( sprintf( - // translators: %1$s and %2$s are the opening and closing of HTML tag. + // translators: %1$s and %2$s are the opening and closing of HTML tag. %3$s and %4$s are the opening and closing of HTML

tag. __( 'Allow your customers to pay in installments without interest while you receive the full payment in a single transaction.* -

Activate your Installments without interest with PayPal.

-

You will receive the full payment minus the applicable PayPal fee. See %1$sterms and conditions%2$s.

', + %3$sActivate your Installments without interest with PayPal.%4$s + %3$sYou will receive the full payment minus the applicable PayPal fee. See %1$sterms and conditions%2$s.%4$s', 'woocommerce-paypal-payments' ), '
', - '' + '', + '

', + '

' ) ); diff --git a/modules/ppcp-wc-gateway/services.php b/modules/ppcp-wc-gateway/services.php index 9a7204ef2..3a5502231 100644 --- a/modules/ppcp-wc-gateway/services.php +++ b/modules/ppcp-wc-gateway/services.php @@ -1170,14 +1170,16 @@ return array( 'requirements' => array(), 'gateway' => 'paypal', 'description' => sprintf( - // translators: %1$s and %2$s are the opening and closing of HTML tag. + // translators: %1$s and %2$s are the opening and closing of HTML tag. %3$s and %4$s are the opening and closing of HTML

tag. __( 'Allow your customers to pay in installments without interest while you receive the full payment in a single transaction.* -

Terms and conditions: *You will receive the full payment minus the applicable PayPal fee. See %1$sterms and conditions%2$s.

', + %3$sTerms and conditions: *You will receive the full payment minus the applicable PayPal fee. See %1$sterms and conditions%2$s.%4$s', 'woocommerce-paypal-payments' ), '
', - '' + '', + '

', + '

' ), ), 'mexico_installments_action_link' => array( From f44f5478dde05b85dbfd5e1d7fa690e15411a1e1 Mon Sep 17 00:00:00 2001 From: Emili Castells Guasch Date: Thu, 22 May 2025 17:15:57 +0200 Subject: [PATCH 6/6] Update changelog --- changelog.txt | 2 ++ readme.txt | 2 ++ 2 files changed, 4 insertions(+) diff --git a/changelog.txt b/changelog.txt index 1caf9a335..971468101 100644 --- a/changelog.txt +++ b/changelog.txt @@ -7,6 +7,8 @@ * Enhancement - Enhance the accessibility of the new Settings UI #3294 * Enhancement - Add capture pre-conditions for card payment source #3300 * Enhancement - Enable all/Disable all toggle next to Alternative Payment methods on Payment Methods tab #3321 +* Enhancement - Add installment notifications for Mexico store locations #3404, #3405 +* Fix - Various issues for Mexico store locations during onboarding & plugin configuration #3403 * Fix - APFS plugin triggers incorrect renewal date for simple products as subscriptions #3272 * Fix - PayPal Smart Button incompatible with WooCommerce Subscription Switching #3291 * Fix - Fastlane gateway visible on Pay for Order page #3293 diff --git a/readme.txt b/readme.txt index 8228491f3..2671d46ba 100644 --- a/readme.txt +++ b/readme.txt @@ -163,6 +163,8 @@ If you encounter issues with the PayPal buttons not appearing after an update, p * Enhancement - Enhance the accessibility of the new Settings UI #3294 * Enhancement - Add capture pre-conditions for card payment source #3300 * Enhancement - Enable all/Disable all toggle next to Alternative Payment methods on Payment Methods tab #3321 +* Enhancement - Add installment notifications for Mexico store locations #3404, #3405 +* Fix - Various issues for Mexico store locations during onboarding & plugin configuration #3403 * Fix - APFS plugin triggers incorrect renewal date for simple products as subscriptions #3272 * Fix - PayPal Smart Button incompatible with WooCommerce Subscription Switching #3291 * Fix - Fastlane gateway visible on Pay for Order page #3293