From 42805c4fb5836107b0beb90425206ca481e9677a Mon Sep 17 00:00:00 2001 From: Daniel Dudzic Date: Wed, 16 Oct 2024 12:51:26 +0200 Subject: [PATCH 01/17] Add support for card icons to Axo Block and move the Change Card Link handling to the store. Also migrate the Change Card Link markup management logic to React --- .../ppcp-axo-block/resources/css/gateway.scss | 24 ++++++--- .../js/components/Card/CardChangeButton.js | 26 +++++++--- .../Card/CardChangeButtonManager.js | 51 ------------------- .../resources/js/components/Card/index.js | 2 - .../resources/js/components/Card/utils.js | 32 ------------ .../js/components/TitleLabel/TitleLabel.js | 24 +++++++++ .../js/components/TitleLabel/index.js | 1 + .../resources/js/events/emailLookupManager.js | 8 +-- .../resources/js/hooks/useAxoCleanup.js | 2 - .../resources/js/hooks/useAxoSetup.js | 5 +- .../resources/js/hooks/useCardOptions.js | 36 +++++++++++++ .../resources/js/hooks/useFastlaneSdk.js | 10 +++- modules/ppcp-axo-block/resources/js/index.js | 8 +-- .../resources/js/stores/axoStore.js | 17 +++++++ modules/ppcp-axo-block/services.php | 3 +- .../src/AxoBlockPaymentMethod.php | 17 ++++++- modules/ppcp-axo/services.php | 26 +++++++++- 17 files changed, 172 insertions(+), 120 deletions(-) delete mode 100644 modules/ppcp-axo-block/resources/js/components/Card/CardChangeButtonManager.js delete mode 100644 modules/ppcp-axo-block/resources/js/components/Card/utils.js create mode 100644 modules/ppcp-axo-block/resources/js/components/TitleLabel/TitleLabel.js create mode 100644 modules/ppcp-axo-block/resources/js/components/TitleLabel/index.js create mode 100644 modules/ppcp-axo-block/resources/js/hooks/useCardOptions.js diff --git a/modules/ppcp-axo-block/resources/css/gateway.scss b/modules/ppcp-axo-block/resources/css/gateway.scss index b1296ea1b..4611bfa35 100644 --- a/modules/ppcp-axo-block/resources/css/gateway.scss +++ b/modules/ppcp-axo-block/resources/css/gateway.scss @@ -17,10 +17,19 @@ $fast-transition-duration: 0.5s; } // 1. AXO Block Radio Label -#ppcp-axo-block-radio-label { - @include flex-space-between; +.wc-block-checkout__payment-method label[for="radio-control-wc-payment-method-options-ppcp-axo-gateway"] { + padding-right: .875em; +} + +#radio-control-wc-payment-method-options-ppcp-axo-gateway__label { + display: flex; + align-items: center; width: 100%; padding-right: 1em; + + .wc-block-components-payment-method-icons { + margin: 0; + } } // 2. AXO Block Card @@ -70,15 +79,16 @@ $fast-transition-duration: 0.5s; } &__edit { - background-color: transparent; + flex-grow: 1; + margin-left: auto; + text-align: right; border: 0; - color: inherit; - cursor: pointer; - display: block; font-family: inherit; - margin: 0 0 0 auto; font-size: 0.875em; font-weight: normal; + color: inherit; + background-color: transparent; + cursor: pointer; &:hover { text-decoration: underline; diff --git a/modules/ppcp-axo-block/resources/js/components/Card/CardChangeButton.js b/modules/ppcp-axo-block/resources/js/components/Card/CardChangeButton.js index c2a4eaa65..d3b27b17a 100644 --- a/modules/ppcp-axo-block/resources/js/components/Card/CardChangeButton.js +++ b/modules/ppcp-axo-block/resources/js/components/Card/CardChangeButton.js @@ -1,15 +1,28 @@ import { createElement } from '@wordpress/element'; +import { useSelect } from '@wordpress/data'; import { __ } from '@wordpress/i18n'; +import { STORE_NAME } from '../../stores/axoStore'; /** * Renders a button to change the selected card in the checkout process. * - * @param {Object} props - * @param {Function} props.onChangeButtonClick - Callback function to handle the click event. - * @return {JSX.Element} The rendered button as an anchor tag. + * @return {JSX.Element|null} The rendered button as an anchor tag, or null if conditions aren't met. */ -const CardChangeButton = ( { onChangeButtonClick } ) => - createElement( +const CardChangeButton = () => { + const { isGuest, cardDetails, cardChangeHandler } = useSelect( + ( select ) => ( { + isGuest: select( STORE_NAME ).getIsGuest(), + cardDetails: select( STORE_NAME ).getCardDetails(), + cardChangeHandler: select( STORE_NAME ).getCardChangeHandler(), + } ), + [] + ); + + if ( isGuest || ! cardDetails || ! cardChangeHandler ) { + return null; + } + + return createElement( 'a', { className: @@ -19,10 +32,11 @@ const CardChangeButton = ( { onChangeButtonClick } ) => // Prevent default anchor behavior event.preventDefault(); // Call the provided click handler - onChangeButtonClick(); + cardChangeHandler(); }, }, __( 'Choose a different card', 'woocommerce-paypal-payments' ) ); +}; export default CardChangeButton; diff --git a/modules/ppcp-axo-block/resources/js/components/Card/CardChangeButtonManager.js b/modules/ppcp-axo-block/resources/js/components/Card/CardChangeButtonManager.js deleted file mode 100644 index 2b6deba4f..000000000 --- a/modules/ppcp-axo-block/resources/js/components/Card/CardChangeButtonManager.js +++ /dev/null @@ -1,51 +0,0 @@ -import { createElement, createRoot, useEffect } from '@wordpress/element'; -import CardChangeButton from './CardChangeButton'; - -/** - * Manages the insertion and removal of the CardChangeButton in the DOM. - * - * @param {Object} props - * @param {Function} props.onChangeButtonClick - Callback function for when the card change button is clicked. - * @return {null} This component doesn't render any visible elements directly. - */ -const CardChangeButtonManager = ( { onChangeButtonClick } ) => { - useEffect( () => { - const radioLabelElement = document.getElementById( - 'ppcp-axo-block-radio-label' - ); - - if ( radioLabelElement ) { - // Check if the change button doesn't already exist - if ( - ! radioLabelElement.querySelector( - '.wc-block-checkout-axo-block-card__edit' - ) - ) { - // Create a new container for the button - const buttonContainer = document.createElement( 'div' ); - radioLabelElement.appendChild( buttonContainer ); - - // Create a React root and render the CardChangeButton - const root = createRoot( buttonContainer ); - root.render( - createElement( CardChangeButton, { onChangeButtonClick } ) - ); - } - } - - // Cleanup function to remove the button when the component unmounts - return () => { - const button = document.querySelector( - '.wc-block-checkout-axo-block-card__edit' - ); - if ( button && button.parentNode ) { - button.parentNode.remove(); - } - }; - }, [ onChangeButtonClick ] ); - - // This component doesn't render anything directly - return null; -}; - -export default CardChangeButtonManager; diff --git a/modules/ppcp-axo-block/resources/js/components/Card/index.js b/modules/ppcp-axo-block/resources/js/components/Card/index.js index c9250078e..7c44148bc 100644 --- a/modules/ppcp-axo-block/resources/js/components/Card/index.js +++ b/modules/ppcp-axo-block/resources/js/components/Card/index.js @@ -1,4 +1,2 @@ export { default as Card } from './Card'; export { default as CardChangeButton } from './CardChangeButton'; -export { default as CardChangeButtonManager } from './CardChangeButtonManager'; -export { injectCardChangeButton, removeCardChangeButton } from './utils'; diff --git a/modules/ppcp-axo-block/resources/js/components/Card/utils.js b/modules/ppcp-axo-block/resources/js/components/Card/utils.js deleted file mode 100644 index 915511885..000000000 --- a/modules/ppcp-axo-block/resources/js/components/Card/utils.js +++ /dev/null @@ -1,32 +0,0 @@ -import { createElement, createRoot } from '@wordpress/element'; -import CardChangeButtonManager from './CardChangeButtonManager'; - -/** - * Injects a card change button into the DOM. - * - * @param {Function} onChangeButtonClick - Callback function for when the card change button is clicked. - */ -export const injectCardChangeButton = ( onChangeButtonClick ) => { - // Create a container for the button - const container = document.createElement( 'div' ); - document.body.appendChild( container ); - - // Render the CardChangeButtonManager in the new container - createRoot( container ).render( - createElement( CardChangeButtonManager, { onChangeButtonClick } ) - ); -}; - -/** - * Removes the card change button from the DOM if it exists. - */ -export const removeCardChangeButton = () => { - const button = document.querySelector( - '.wc-block-checkout-axo-block-card__edit' - ); - - // Remove the button's parent node if it exists - if ( button && button.parentNode ) { - button.parentNode.remove(); - } -}; diff --git a/modules/ppcp-axo-block/resources/js/components/TitleLabel/TitleLabel.js b/modules/ppcp-axo-block/resources/js/components/TitleLabel/TitleLabel.js new file mode 100644 index 000000000..6435e23de --- /dev/null +++ b/modules/ppcp-axo-block/resources/js/components/TitleLabel/TitleLabel.js @@ -0,0 +1,24 @@ +import CardChangeButton from './../Card/CardChangeButton'; + +/** + * TitleLabel component for displaying a payment method title with icons and a change card button. + * + * @param {Object} props - Component props + * @param {Object} props.components - Object containing WooCommerce components + * @param {Object} props.config - Configuration object for the payment method + * @return {JSX.Element} WordPress element + */ +const TitleLabel = ( { components, config } ) => { + const axoConfig = window.wc_ppcp_axo; + const { PaymentMethodIcons } = components; + + return ( + <> + + + + + ); +}; + +export default TitleLabel; diff --git a/modules/ppcp-axo-block/resources/js/components/TitleLabel/index.js b/modules/ppcp-axo-block/resources/js/components/TitleLabel/index.js new file mode 100644 index 000000000..9ca79db8f --- /dev/null +++ b/modules/ppcp-axo-block/resources/js/components/TitleLabel/index.js @@ -0,0 +1 @@ +export { default as TitleLabel } from './TitleLabel'; diff --git a/modules/ppcp-axo-block/resources/js/events/emailLookupManager.js b/modules/ppcp-axo-block/resources/js/events/emailLookupManager.js index 563f9510d..8cc887668 100644 --- a/modules/ppcp-axo-block/resources/js/events/emailLookupManager.js +++ b/modules/ppcp-axo-block/resources/js/events/emailLookupManager.js @@ -1,7 +1,6 @@ import { log } from '../../../../ppcp-axo/resources/js/Helper/Debug'; import { populateWooFields } from '../helpers/fieldHelpers'; import { injectShippingChangeButton } from '../components/Shipping'; -import { injectCardChangeButton } from '../components/Card'; import { setIsGuest, setIsEmailLookupCompleted } from '../stores/axoStore'; /** @@ -16,7 +15,6 @@ import { setIsGuest, setIsEmailLookupCompleted } from '../stores/axoStore'; * @param {Function} setWooShippingAddress - Function to update WooCommerce shipping address. * @param {Function} setWooBillingAddress - Function to update WooCommerce billing address. * @param {Function} onChangeShippingAddressClick - Handler for shipping address change. - * @param {Function} onChangeCardButtonClick - Handler for card change. * @return {Function} The email lookup handler function. */ export const createEmailLookupHandler = ( @@ -28,8 +26,7 @@ export const createEmailLookupHandler = ( wooBillingAddress, setWooShippingAddress, setWooBillingAddress, - onChangeShippingAddressClick, - onChangeCardButtonClick + onChangeShippingAddressClick ) => { return async ( email ) => { try { @@ -102,9 +99,8 @@ export const createEmailLookupHandler = ( setWooBillingAddress ); - // Inject change buttons for shipping and card + // Inject the change button for shipping injectShippingChangeButton( onChangeShippingAddressClick ); - injectCardChangeButton( onChangeCardButtonClick ); } else { log( 'Authentication failed or did not succeed', 'warn' ); } diff --git a/modules/ppcp-axo-block/resources/js/hooks/useAxoCleanup.js b/modules/ppcp-axo-block/resources/js/hooks/useAxoCleanup.js index 1da3cca85..07247f2e3 100644 --- a/modules/ppcp-axo-block/resources/js/hooks/useAxoCleanup.js +++ b/modules/ppcp-axo-block/resources/js/hooks/useAxoCleanup.js @@ -3,7 +3,6 @@ import { useDispatch } from '@wordpress/data'; import { log } from '../../../../ppcp-axo/resources/js/Helper/Debug'; import { STORE_NAME } from '../stores/axoStore'; import { removeShippingChangeButton } from '../components/Shipping'; -import { removeCardChangeButton } from '../components/Card'; import { removeWatermark } from '../components/Watermark'; import { removeEmailFunctionality, @@ -50,7 +49,6 @@ const useAxoCleanup = () => { // Remove AXO UI elements removeShippingChangeButton(); - removeCardChangeButton(); removeWatermark(); // Remove email functionality if it was set up diff --git a/modules/ppcp-axo-block/resources/js/hooks/useAxoSetup.js b/modules/ppcp-axo-block/resources/js/hooks/useAxoSetup.js index af1aaca38..629ce05d4 100644 --- a/modules/ppcp-axo-block/resources/js/hooks/useAxoSetup.js +++ b/modules/ppcp-axo-block/resources/js/hooks/useAxoSetup.js @@ -35,6 +35,7 @@ const useAxoSetup = ( setIsAxoScriptLoaded, setShippingAddress, setCardDetails, + setCardChangeHandler, } = useDispatch( STORE_NAME ); // Check if PayPal script has loaded @@ -73,6 +74,7 @@ const useAxoSetup = ( if ( paypalLoaded && fastlaneSdk ) { setIsAxoScriptLoaded( true ); setIsAxoActive( true ); + setCardChangeHandler( onChangeCardButtonClick ); // Create and set up email lookup handler const emailLookupHandler = createEmailLookupHandler( @@ -84,8 +86,7 @@ const useAxoSetup = ( wooBillingAddress, setWooShippingAddress, setWooBillingAddress, - onChangeShippingAddressClick, - onChangeCardButtonClick + onChangeShippingAddressClick ); setupEmailFunctionality( emailLookupHandler ); } diff --git a/modules/ppcp-axo-block/resources/js/hooks/useCardOptions.js b/modules/ppcp-axo-block/resources/js/hooks/useCardOptions.js new file mode 100644 index 000000000..94c727784 --- /dev/null +++ b/modules/ppcp-axo-block/resources/js/hooks/useCardOptions.js @@ -0,0 +1,36 @@ +import { useMemo } from '@wordpress/element'; + +const DEFAULT_ALLOWED_CARDS = [ 'VISA', 'MASTERCARD', 'AMEX', 'DISCOVER' ]; + +/** + * Custom hook to determine the allowed card options based on configuration. + * + * @param {Object} axoConfig - The AXO configuration object. + * @return {Array} The final list of allowed card options. + */ +const useCardOptions = ( axoConfig ) => { + const merchantCountry = axoConfig.merchant_country || 'US'; + + return useMemo( () => { + const allowedCards = new Set( + axoConfig.allowed_cards?.[ merchantCountry ] || + DEFAULT_ALLOWED_CARDS + ); + + // Create a Set of disabled cards, converting each to uppercase + const disabledCards = new Set( + ( axoConfig.disable_cards || [] ).map( ( card ) => + card.toUpperCase() + ) + ); + + // Filter out disabled cards from the allowed cards + const finalCardOptions = [ ...allowedCards ].filter( + ( card ) => ! disabledCards.has( card ) + ); + + return finalCardOptions; + }, [ axoConfig.allowed_cards, axoConfig.disable_cards, merchantCountry ] ); +}; + +export default useCardOptions; diff --git a/modules/ppcp-axo-block/resources/js/hooks/useFastlaneSdk.js b/modules/ppcp-axo-block/resources/js/hooks/useFastlaneSdk.js index 7e68ccab1..a32c90c3b 100644 --- a/modules/ppcp-axo-block/resources/js/hooks/useFastlaneSdk.js +++ b/modules/ppcp-axo-block/resources/js/hooks/useFastlaneSdk.js @@ -3,6 +3,7 @@ import { useSelect } from '@wordpress/data'; import Fastlane from '../../../../ppcp-axo/resources/js/Connection/Fastlane'; import { log } from '../../../../ppcp-axo/resources/js/Helper/Debug'; import { useDeleteEmptyKeys } from './useDeleteEmptyKeys'; +import useCardOptions from './useCardOptions'; import { STORE_NAME } from '../stores/axoStore'; /** @@ -26,6 +27,8 @@ const useFastlaneSdk = ( namespace, axoConfig, ppcpConfig ) => { [] ); + const cardOptions = useCardOptions( axoConfig ); + const styleOptions = useMemo( () => { return deleteEmptyKeys( configRef.current.axoConfig.style_options ); }, [ deleteEmptyKeys ] ); @@ -48,10 +51,13 @@ const useFastlaneSdk = ( namespace, axoConfig, ppcpConfig ) => { window.localStorage.setItem( 'axoEnv', 'sandbox' ); } - // Connect to Fastlane with locale and style options + // Connect to Fastlane with locale, style options, and allowed card brands await fastlane.connect( { locale: configRef.current.ppcpConfig.locale, styles: styleOptions, + cardOptions: { + allowedBrands: cardOptions, + }, } ); // Set locale (hardcoded to 'en_us' for now) @@ -66,7 +72,7 @@ const useFastlaneSdk = ( namespace, axoConfig, ppcpConfig ) => { }; initFastlane(); - }, [ fastlaneSdk, styleOptions, isPayPalLoaded, namespace ] ); + }, [ fastlaneSdk, styleOptions, isPayPalLoaded, namespace, cardOptions ] ); // Effect to update the config ref when configs change useEffect( () => { diff --git a/modules/ppcp-axo-block/resources/js/index.js b/modules/ppcp-axo-block/resources/js/index.js index a45473e50..f58279af5 100644 --- a/modules/ppcp-axo-block/resources/js/index.js +++ b/modules/ppcp-axo-block/resources/js/index.js @@ -13,6 +13,7 @@ import usePayPalCommerceGateway from './hooks/usePayPalCommerceGateway'; // Components import { Payment } from './components/Payment/Payment'; +import { TitleLabel } from './components/TitleLabel'; const gatewayHandle = 'ppcp-axo-gateway'; const namespace = 'ppcpBlocksPaypalAxo'; @@ -89,12 +90,7 @@ const Axo = ( props ) => { registerPaymentMethod( { name: initialConfig.id, - label: ( -
- ), + label: , content: , edit: createElement( initialConfig.title ), ariaLabel: initialConfig.title, diff --git a/modules/ppcp-axo-block/resources/js/stores/axoStore.js b/modules/ppcp-axo-block/resources/js/stores/axoStore.js index f779f983c..c7afb91ef 100644 --- a/modules/ppcp-axo-block/resources/js/stores/axoStore.js +++ b/modules/ppcp-axo-block/resources/js/stores/axoStore.js @@ -12,6 +12,7 @@ const DEFAULT_STATE = { shippingAddress: null, cardDetails: null, phoneNumber: '', + cardChangeHandler: null, }; // Action creators for updating the store state @@ -52,6 +53,10 @@ const actions = { type: 'SET_PHONE_NUMBER', payload: phoneNumber, } ), + setCardChangeHandler: ( cardChangeHandler ) => ( { + type: 'SET_CARD_CHANGE_HANDLER', + payload: cardChangeHandler, + } ), }; /** @@ -81,6 +86,8 @@ const reducer = ( state = DEFAULT_STATE, action ) => { return { ...state, cardDetails: action.payload }; case 'SET_PHONE_NUMBER': return { ...state, phoneNumber: action.payload }; + case 'SET_CARD_CHANGE_HANDLER': + return { ...state, cardChangeHandler: action.payload }; default: return state; } @@ -97,6 +104,7 @@ const selectors = { getShippingAddress: ( state ) => state.shippingAddress, getCardDetails: ( state ) => state.cardDetails, getPhoneNumber: ( state ) => state.phoneNumber, + getCardChangeHandler: ( state ) => state.cardChangeHandler, }; // Create and register the Redux store for the AXO block @@ -163,3 +171,12 @@ export const setCardDetails = ( cardDetails ) => { export const setPhoneNumber = ( phoneNumber ) => { dispatch( STORE_NAME ).setPhoneNumber( phoneNumber ); }; + +/** + * Action dispatcher to update the card change handler in the store. + * + * @param {Function} cardChangeHandler - The card change handler function. + */ +export const setCardChangeHandler = ( cardChangeHandler ) => { + dispatch( STORE_NAME ).setCardChangeHandler( cardChangeHandler ); +}; diff --git a/modules/ppcp-axo-block/services.php b/modules/ppcp-axo-block/services.php index 270b69260..04a2f37ea 100644 --- a/modules/ppcp-axo-block/services.php +++ b/modules/ppcp-axo-block/services.php @@ -37,7 +37,8 @@ return array( $container->get( 'wcgateway.settings' ), $container->get( 'wcgateway.configuration.dcc' ), $container->get( 'onboarding.environment' ), - $container->get( 'wcgateway.url' ) + $container->get( 'wcgateway.url' ), + $container->get( 'axo.supported-country-card-type-matrix' ), ); }, ); diff --git a/modules/ppcp-axo-block/src/AxoBlockPaymentMethod.php b/modules/ppcp-axo-block/src/AxoBlockPaymentMethod.php index 136db8233..c9712ab89 100644 --- a/modules/ppcp-axo-block/src/AxoBlockPaymentMethod.php +++ b/modules/ppcp-axo-block/src/AxoBlockPaymentMethod.php @@ -79,6 +79,13 @@ class AxoBlockPaymentMethod extends AbstractPaymentMethodType { */ private $wcgateway_module_url; + /** + * The supported country card type matrix. + * + * @var array + */ + private $supported_country_card_type_matrix; + /** * AdvancedCardPaymentMethod constructor. * @@ -91,6 +98,7 @@ class AxoBlockPaymentMethod extends AbstractPaymentMethodType { * @param DCCGatewayConfiguration $dcc_configuration The DCC gateway settings. * @param Environment $environment The environment object. * @param string $wcgateway_module_url The WcGateway module URL. + * @param array $supported_country_card_type_matrix The supported country card type matrix for Axo. */ public function __construct( string $module_url, @@ -100,7 +108,8 @@ class AxoBlockPaymentMethod extends AbstractPaymentMethodType { Settings $settings, DCCGatewayConfiguration $dcc_configuration, Environment $environment, - string $wcgateway_module_url + string $wcgateway_module_url, + array $supported_country_card_type_matrix ) { $this->name = AxoGateway::ID; $this->module_url = $module_url; @@ -111,7 +120,7 @@ class AxoBlockPaymentMethod extends AbstractPaymentMethodType { $this->dcc_configuration = $dcc_configuration; $this->environment = $environment; $this->wcgateway_module_url = $wcgateway_module_url; - + $this->supported_country_card_type_matrix = $supported_country_card_type_matrix; } /** @@ -207,6 +216,8 @@ class AxoBlockPaymentMethod extends AbstractPaymentMethodType { : null, // Set to null if WC()->cart is null or get_total doesn't exist. ), ), + 'allowed_cards' => $this->supported_country_card_type_matrix, + 'disable_cards' => $this->settings->has( 'disable_cards' ) ? (array) $this->settings->get( 'disable_cards' ) : array(), 'style_options' => array( 'root' => array( 'backgroundColor' => $this->settings->has( 'axo_style_root_bg_color' ) ? $this->settings->get( 'axo_style_root_bg_color' ) : '', @@ -243,6 +254,8 @@ class AxoBlockPaymentMethod extends AbstractPaymentMethodType { ), 'logging_enabled' => $this->settings->has( 'logging_enabled' ) ? $this->settings->get( 'logging_enabled' ) : '', 'wp_debug' => defined( 'WP_DEBUG' ) && WP_DEBUG, + 'card_icons' => $this->settings->has( 'card_icons' ) ? (array) $this->settings->get( 'card_icons' ) : array(), + 'merchant_country' => WC()->countries->get_base_country(), ); } } diff --git a/modules/ppcp-axo/services.php b/modules/ppcp-axo/services.php index ebeb0f394..b9af329f8 100644 --- a/modules/ppcp-axo/services.php +++ b/modules/ppcp-axo/services.php @@ -110,7 +110,31 @@ return array( ) ); }, - + /** + * The matrix which countries and card type combinations can be used for AXO. + */ + 'axo.supported-country-card-type-matrix' => static function ( ContainerInterface $container ) : array { + /** + * Returns which countries and card type combinations can be used for AXO. + */ + return apply_filters( + 'woocommerce_paypal_payments_axo_supported_country_card_type_matrix', + array( + 'US' => array( + 'VISA', + 'MASTERCARD', + 'AMEX', + 'DISCOVER', + ), + 'CA' => array( + 'VISA', + 'MASTERCARD', + 'AMEX', + 'DISCOVER', + ), + ) + ); + }, 'axo.settings-conflict-notice' => static function ( ContainerInterface $container ) : string { $settings_notice_generator = $container->get( 'axo.helpers.settings-notice-generator' ); assert( $settings_notice_generator instanceof SettingsNoticeGenerator ); From 17fd55d3c0131863cb9a7261097f94a147ac19f2 Mon Sep 17 00:00:00 2001 From: inpsyde-maticluznar Date: Wed, 16 Oct 2024 13:33:48 +0200 Subject: [PATCH 02/17] Don't display methods before paypal is connected --- .../src/LocalAlternativePaymentMethodsModule.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/modules/ppcp-local-alternative-payment-methods/src/LocalAlternativePaymentMethodsModule.php b/modules/ppcp-local-alternative-payment-methods/src/LocalAlternativePaymentMethodsModule.php index 6db9de464..a2d3f66eb 100644 --- a/modules/ppcp-local-alternative-payment-methods/src/LocalAlternativePaymentMethodsModule.php +++ b/modules/ppcp-local-alternative-payment-methods/src/LocalAlternativePaymentMethodsModule.php @@ -11,6 +11,7 @@ namespace WooCommerce\PayPalCommerce\LocalAlternativePaymentMethods; use WC_Order; use Automattic\WooCommerce\Blocks\Payments\PaymentMethodRegistry; +use WooCommerce\PayPalCommerce\Onboarding\State; use WooCommerce\PayPalCommerce\Vendor\Inpsyde\Modularity\Module\ExecutableModule; use WooCommerce\PayPalCommerce\Vendor\Inpsyde\Modularity\Module\ExtendingModule; use WooCommerce\PayPalCommerce\Vendor\Inpsyde\Modularity\Module\ModuleClassNameIdTrait; @@ -58,6 +59,11 @@ class LocalAlternativePaymentMethodsModule implements ServiceModule, ExtendingMo * @psalm-suppress MissingClosureParamType */ function ( $methods ) use ( $c ) { + $onboarding_state = $c->get( 'onboarding.state' ); + if ( $onboarding_state->current_state() >= State::STATE_START ) { + return $methods; + } + if ( ! is_array( $methods ) ) { return $methods; } From 910bffed03d7bcb37ff1f31745c648cb248602f0 Mon Sep 17 00:00:00 2001 From: inpsyde-maticluznar Date: Wed, 16 Oct 2024 13:42:27 +0200 Subject: [PATCH 03/17] Fix state check --- .../src/LocalAlternativePaymentMethodsModule.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/ppcp-local-alternative-payment-methods/src/LocalAlternativePaymentMethodsModule.php b/modules/ppcp-local-alternative-payment-methods/src/LocalAlternativePaymentMethodsModule.php index a2d3f66eb..17680864c 100644 --- a/modules/ppcp-local-alternative-payment-methods/src/LocalAlternativePaymentMethodsModule.php +++ b/modules/ppcp-local-alternative-payment-methods/src/LocalAlternativePaymentMethodsModule.php @@ -60,7 +60,7 @@ class LocalAlternativePaymentMethodsModule implements ServiceModule, ExtendingMo */ function ( $methods ) use ( $c ) { $onboarding_state = $c->get( 'onboarding.state' ); - if ( $onboarding_state->current_state() >= State::STATE_START ) { + if ( $onboarding_state->current_state() === State::STATE_START ) { return $methods; } From bbde7f7890e41aba9e4c17396da04a6056fa51e3 Mon Sep 17 00:00:00 2001 From: Daniel Dudzic Date: Wed, 16 Oct 2024 14:01:11 +0200 Subject: [PATCH 04/17] Axo: Add support for the card type limiting in the Fastlane classic checkout --- modules/ppcp-axo/resources/js/AxoManager.js | 32 ++++++++++++++++++++- modules/ppcp-axo/services.php | 3 +- modules/ppcp-axo/src/Assets/AxoManager.php | 29 +++++++++++++------ 3 files changed, 53 insertions(+), 11 deletions(-) diff --git a/modules/ppcp-axo/resources/js/AxoManager.js b/modules/ppcp-axo/resources/js/AxoManager.js index 0bd204672..fd22006a1 100644 --- a/modules/ppcp-axo/resources/js/AxoManager.js +++ b/modules/ppcp-axo/resources/js/AxoManager.js @@ -53,7 +53,7 @@ class AxoManager { cardView = null; constructor( namespace, axoConfig, ppcpConfig ) { - this.namespace = namespace; + this.namespace = namespace; this.axoConfig = axoConfig; this.ppcpConfig = ppcpConfig; @@ -85,6 +85,8 @@ class AxoManager { }, }; + this.cardOptions = this.getCardOptions(); + this.registerEventHandlers(); this.shippingView = new ShippingView( @@ -661,6 +663,9 @@ class AxoManager { await this.fastlane.connect( { locale: this.locale, styles: this.styles, + cardOptions: { + allowedBrands: this.cardOptions, + }, } ); this.fastlane.setLocale( 'en_us' ); @@ -1245,6 +1250,31 @@ class AxoManager { return this.axoConfig?.widgets?.email === 'use_widget'; } + getCardOptions() { + const DEFAULT_ALLOWED_CARDS = [ + 'VISA', + 'MASTERCARD', + 'AMEX', + 'DISCOVER', + ]; + const merchantCountry = this.axoConfig.merchant_country || 'US'; + + const allowedCards = new Set( + this.axoConfig.allowed_cards?.[ merchantCountry ] || + DEFAULT_ALLOWED_CARDS + ); + + const disabledCards = new Set( + ( this.axoConfig.disable_cards || [] ).map( ( card ) => + card.toUpperCase() + ) + ); + + return [ ...allowedCards ].filter( + ( card ) => ! disabledCards.has( card ) + ); + } + deleteKeysWithEmptyString = ( obj ) => { for ( const key of Object.keys( obj ) ) { if ( obj[ key ] === '' ) { diff --git a/modules/ppcp-axo/services.php b/modules/ppcp-axo/services.php index b9af329f8..657805172 100644 --- a/modules/ppcp-axo/services.php +++ b/modules/ppcp-axo/services.php @@ -67,7 +67,8 @@ return array( $container->get( 'wcgateway.settings.status' ), $container->get( 'api.shop.currency.getter' ), $container->get( 'woocommerce.logger.woocommerce' ), - $container->get( 'wcgateway.url' ) + $container->get( 'wcgateway.url' ), + $container->get( 'axo.supported-country-card-type-matrix' ) ); }, diff --git a/modules/ppcp-axo/src/Assets/AxoManager.php b/modules/ppcp-axo/src/Assets/AxoManager.php index 6fa196719..cedfafac1 100644 --- a/modules/ppcp-axo/src/Assets/AxoManager.php +++ b/modules/ppcp-axo/src/Assets/AxoManager.php @@ -29,28 +29,28 @@ class AxoManager { * * @var string */ - private $module_url; + private string $module_url; /** * The assets version. * * @var string */ - private $version; + private string $version; /** * The settings. * * @var Settings */ - private $settings; + private Settings $settings; /** * The environment object. * * @var Environment */ - private $environment; + private Environment $environment; /** * The Settings status helper. @@ -71,22 +71,27 @@ class AxoManager { * * @var LoggerInterface */ - private $logger; + private LoggerInterface $logger; /** * Session handler. * * @var SessionHandler */ - private $session_handler; + private SessionHandler $session_handler; /** * The WcGateway module URL. * * @var string */ - private $wcgateway_module_url; - + private string $wcgateway_module_url; + /** + * The supported country card type matrix. + * + * @var array + */ + private array $supported_country_card_type_matrix; /** * AxoManager constructor. * @@ -99,6 +104,7 @@ class AxoManager { * @param CurrencyGetter $currency The getter of the 3-letter currency code of the shop. * @param LoggerInterface $logger The logger. * @param string $wcgateway_module_url The WcGateway module URL. + * @param array $supported_country_card_type_matrix The supported country card type matrix for Axo. */ public function __construct( string $module_url, @@ -109,7 +115,8 @@ class AxoManager { SettingsStatus $settings_status, CurrencyGetter $currency, LoggerInterface $logger, - string $wcgateway_module_url + string $wcgateway_module_url, + array $supported_country_card_type_matrix ) { $this->module_url = $module_url; @@ -121,6 +128,7 @@ class AxoManager { $this->currency = $currency; $this->logger = $logger; $this->wcgateway_module_url = $wcgateway_module_url; + $this->supported_country_card_type_matrix = $supported_country_card_type_matrix; } /** @@ -183,6 +191,8 @@ class AxoManager { 'value' => WC()->cart->get_total( 'numeric' ), ), ), + 'allowed_cards' => $this->supported_country_card_type_matrix, + 'disable_cards' => $this->settings->has( 'disable_cards' ) ? (array) $this->settings->get( 'disable_cards' ) : array(), 'style_options' => array( 'root' => array( 'backgroundColor' => $this->settings->has( 'axo_style_root_bg_color' ) ? $this->settings->get( 'axo_style_root_bg_color' ) : '', @@ -220,6 +230,7 @@ class AxoManager { 'logging_enabled' => $this->settings->has( 'logging_enabled' ) ? $this->settings->get( 'logging_enabled' ) : '', 'wp_debug' => defined( 'WP_DEBUG' ) && WP_DEBUG, 'billing_email_button_text' => __( 'Continue', 'woocommerce-paypal-payments' ), + 'merchant_country' => WC()->countries->get_base_country(), ); } From 46f49574e7a8bd4d5c00cdb4af80993cdb5bb9ba Mon Sep 17 00:00:00 2001 From: Daniel Dudzic Date: Wed, 16 Oct 2024 14:26:08 +0200 Subject: [PATCH 05/17] Add PHPCS fixes --- .../src/AxoBlockPaymentMethod.php | 46 +++++++++---------- modules/ppcp-axo/services.php | 2 +- modules/ppcp-axo/src/Assets/AxoManager.php | 26 +++++------ 3 files changed, 37 insertions(+), 37 deletions(-) diff --git a/modules/ppcp-axo-block/src/AxoBlockPaymentMethod.php b/modules/ppcp-axo-block/src/AxoBlockPaymentMethod.php index c9712ab89..5eb0191be 100644 --- a/modules/ppcp-axo-block/src/AxoBlockPaymentMethod.php +++ b/modules/ppcp-axo-block/src/AxoBlockPaymentMethod.php @@ -111,15 +111,15 @@ class AxoBlockPaymentMethod extends AbstractPaymentMethodType { string $wcgateway_module_url, array $supported_country_card_type_matrix ) { - $this->name = AxoGateway::ID; - $this->module_url = $module_url; - $this->version = $version; - $this->gateway = $gateway; - $this->smart_button = $smart_button; - $this->settings = $settings; - $this->dcc_configuration = $dcc_configuration; - $this->environment = $environment; - $this->wcgateway_module_url = $wcgateway_module_url; + $this->name = AxoGateway::ID; + $this->module_url = $module_url; + $this->version = $version; + $this->gateway = $gateway; + $this->smart_button = $smart_button; + $this->settings = $settings; + $this->dcc_configuration = $dcc_configuration; + $this->environment = $environment; + $this->wcgateway_module_url = $wcgateway_module_url; $this->supported_country_card_type_matrix = $supported_country_card_type_matrix; } @@ -196,13 +196,13 @@ class AxoBlockPaymentMethod extends AbstractPaymentMethodType { } return array( - 'environment' => array( + 'environment' => array( 'is_sandbox' => $this->environment->current_environment() === 'sandbox', ), - 'widgets' => array( + 'widgets' => array( 'email' => 'render', ), - 'insights' => array( + 'insights' => array( 'enabled' => defined( 'WP_DEBUG' ) && WP_DEBUG, 'client_id' => ( $this->settings->has( 'client_id' ) ? $this->settings->get( 'client_id' ) : null ), 'session_id' => @@ -216,9 +216,9 @@ class AxoBlockPaymentMethod extends AbstractPaymentMethodType { : null, // Set to null if WC()->cart is null or get_total doesn't exist. ), ), - 'allowed_cards' => $this->supported_country_card_type_matrix, - 'disable_cards' => $this->settings->has( 'disable_cards' ) ? (array) $this->settings->get( 'disable_cards' ) : array(), - 'style_options' => array( + 'allowed_cards' => $this->supported_country_card_type_matrix, + 'disable_cards' => $this->settings->has( 'disable_cards' ) ? (array) $this->settings->get( 'disable_cards' ) : array(), + 'style_options' => array( 'root' => array( 'backgroundColor' => $this->settings->has( 'axo_style_root_bg_color' ) ? $this->settings->get( 'axo_style_root_bg_color' ) : '', 'errorColor' => $this->settings->has( 'axo_style_root_error_color' ) ? $this->settings->get( 'axo_style_root_error_color' ) : '', @@ -237,24 +237,24 @@ class AxoBlockPaymentMethod extends AbstractPaymentMethodType { 'focusBorderColor' => $this->settings->has( 'axo_style_input_focus_border_color' ) ? $this->settings->get( 'axo_style_input_focus_border_color' ) : '', ), ), - 'name_on_card' => $this->dcc_configuration->show_name_on_card(), - 'woocommerce' => array( + 'name_on_card' => $this->dcc_configuration->show_name_on_card(), + 'woocommerce' => array( 'states' => array( 'US' => WC()->countries->get_states( 'US' ), 'CA' => WC()->countries->get_states( 'CA' ), ), ), - 'icons_directory' => esc_url( $this->wcgateway_module_url ) . 'assets/images/axo/', - 'module_url' => untrailingslashit( $this->module_url ), - 'ajax' => array( + 'icons_directory' => esc_url( $this->wcgateway_module_url ) . 'assets/images/axo/', + 'module_url' => untrailingslashit( $this->module_url ), + 'ajax' => array( 'frontend_logger' => array( 'endpoint' => \WC_AJAX::get_endpoint( FrontendLoggerEndpoint::ENDPOINT ), 'nonce' => wp_create_nonce( FrontendLoggerEndpoint::nonce() ), ), ), - 'logging_enabled' => $this->settings->has( 'logging_enabled' ) ? $this->settings->get( 'logging_enabled' ) : '', - 'wp_debug' => defined( 'WP_DEBUG' ) && WP_DEBUG, - 'card_icons' => $this->settings->has( 'card_icons' ) ? (array) $this->settings->get( 'card_icons' ) : array(), + 'logging_enabled' => $this->settings->has( 'logging_enabled' ) ? $this->settings->get( 'logging_enabled' ) : '', + 'wp_debug' => defined( 'WP_DEBUG' ) && WP_DEBUG, + 'card_icons' => $this->settings->has( 'card_icons' ) ? (array) $this->settings->get( 'card_icons' ) : array(), 'merchant_country' => WC()->countries->get_base_country(), ); } diff --git a/modules/ppcp-axo/services.php b/modules/ppcp-axo/services.php index 657805172..61a034fcc 100644 --- a/modules/ppcp-axo/services.php +++ b/modules/ppcp-axo/services.php @@ -114,7 +114,7 @@ return array( /** * The matrix which countries and card type combinations can be used for AXO. */ - 'axo.supported-country-card-type-matrix' => static function ( ContainerInterface $container ) : array { + 'axo.supported-country-card-type-matrix' => static function ( ContainerInterface $container ) : array { /** * Returns which countries and card type combinations can be used for AXO. */ diff --git a/modules/ppcp-axo/src/Assets/AxoManager.php b/modules/ppcp-axo/src/Assets/AxoManager.php index cedfafac1..0d3459a7a 100644 --- a/modules/ppcp-axo/src/Assets/AxoManager.php +++ b/modules/ppcp-axo/src/Assets/AxoManager.php @@ -104,7 +104,7 @@ class AxoManager { * @param CurrencyGetter $currency The getter of the 3-letter currency code of the shop. * @param LoggerInterface $logger The logger. * @param string $wcgateway_module_url The WcGateway module URL. - * @param array $supported_country_card_type_matrix The supported country card type matrix for Axo. + * @param array $supported_country_card_type_matrix The supported country card type matrix for Axo. */ public function __construct( string $module_url, @@ -119,15 +119,15 @@ class AxoManager { array $supported_country_card_type_matrix ) { - $this->module_url = $module_url; - $this->version = $version; - $this->session_handler = $session_handler; - $this->settings = $settings; - $this->environment = $environment; - $this->settings_status = $settings_status; - $this->currency = $currency; - $this->logger = $logger; - $this->wcgateway_module_url = $wcgateway_module_url; + $this->module_url = $module_url; + $this->version = $version; + $this->session_handler = $session_handler; + $this->settings = $settings; + $this->environment = $environment; + $this->settings_status = $settings_status; + $this->currency = $currency; + $this->logger = $logger; + $this->wcgateway_module_url = $wcgateway_module_url; $this->supported_country_card_type_matrix = $supported_country_card_type_matrix; } @@ -191,8 +191,8 @@ class AxoManager { 'value' => WC()->cart->get_total( 'numeric' ), ), ), - 'allowed_cards' => $this->supported_country_card_type_matrix, - 'disable_cards' => $this->settings->has( 'disable_cards' ) ? (array) $this->settings->get( 'disable_cards' ) : array(), + 'allowed_cards' => $this->supported_country_card_type_matrix, + 'disable_cards' => $this->settings->has( 'disable_cards' ) ? (array) $this->settings->get( 'disable_cards' ) : array(), 'style_options' => array( 'root' => array( 'backgroundColor' => $this->settings->has( 'axo_style_root_bg_color' ) ? $this->settings->get( 'axo_style_root_bg_color' ) : '', @@ -230,7 +230,7 @@ class AxoManager { 'logging_enabled' => $this->settings->has( 'logging_enabled' ) ? $this->settings->get( 'logging_enabled' ) : '', 'wp_debug' => defined( 'WP_DEBUG' ) && WP_DEBUG, 'billing_email_button_text' => __( 'Continue', 'woocommerce-paypal-payments' ), - 'merchant_country' => WC()->countries->get_base_country(), + 'merchant_country' => WC()->countries->get_base_country(), ); } From de609be21b40cda90192e1642f96e46f357b52fb Mon Sep 17 00:00:00 2001 From: inpsyde-maticluznar Date: Fri, 18 Oct 2024 08:14:50 +0200 Subject: [PATCH 06/17] Add paypal & ratepay default icons to classic checkout --- modules/ppcp-wc-gateway/assets/images/paypal.svg | 3 +++ modules/ppcp-wc-gateway/assets/images/ratepay.svg | 3 +++ modules/ppcp-wc-gateway/services.php | 6 ++++-- .../ppcp-wc-gateway/src/Gateway/PayPalGateway.php | 13 ++++++++++++- .../PayUponInvoice/PayUponInvoiceGateway.php | 14 +++++++++++++- 5 files changed, 35 insertions(+), 4 deletions(-) create mode 100644 modules/ppcp-wc-gateway/assets/images/paypal.svg create mode 100644 modules/ppcp-wc-gateway/assets/images/ratepay.svg diff --git a/modules/ppcp-wc-gateway/assets/images/paypal.svg b/modules/ppcp-wc-gateway/assets/images/paypal.svg new file mode 100644 index 000000000..0d82f0b74 --- /dev/null +++ b/modules/ppcp-wc-gateway/assets/images/paypal.svg @@ -0,0 +1,3 @@ + + + diff --git a/modules/ppcp-wc-gateway/assets/images/ratepay.svg b/modules/ppcp-wc-gateway/assets/images/ratepay.svg new file mode 100644 index 000000000..1e8030e33 --- /dev/null +++ b/modules/ppcp-wc-gateway/assets/images/ratepay.svg @@ -0,0 +1,3 @@ + + + diff --git a/modules/ppcp-wc-gateway/services.php b/modules/ppcp-wc-gateway/services.php index 9ed1a83a8..8d2c8e051 100644 --- a/modules/ppcp-wc-gateway/services.php +++ b/modules/ppcp-wc-gateway/services.php @@ -118,7 +118,8 @@ return array( $container->get( 'wcgateway.place-order-button-text' ), $container->get( 'api.endpoint.payment-tokens' ), $container->get( 'vaulting.vault-v3-enabled' ), - $container->get( 'vaulting.wc-payment-tokens' ) + $container->get( 'vaulting.wc-payment-tokens' ), + $container->get( 'wcgateway.url' ) ); }, 'wcgateway.credit-card-gateway' => static function ( ContainerInterface $container ): CreditCardGateway { @@ -1376,7 +1377,8 @@ return array( $container->get( 'wcgateway.pay-upon-invoice-helper' ), $container->get( 'wcgateway.checkout-helper' ), $container->get( 'onboarding.state' ), - $container->get( 'wcgateway.processor.refunds' ) + $container->get( 'wcgateway.processor.refunds' ), + $container->get( 'wcgateway.url' ) ); }, 'wcgateway.fraudnet-source-website-id' => static function ( ContainerInterface $container ): FraudNetSourceWebsiteId { diff --git a/modules/ppcp-wc-gateway/src/Gateway/PayPalGateway.php b/modules/ppcp-wc-gateway/src/Gateway/PayPalGateway.php index 4a00b8d5e..3012d5885 100644 --- a/modules/ppcp-wc-gateway/src/Gateway/PayPalGateway.php +++ b/modules/ppcp-wc-gateway/src/Gateway/PayPalGateway.php @@ -202,6 +202,13 @@ class PayPalGateway extends \WC_Payment_Gateway { */ private $wc_payment_tokens; + /** + * The module URL + * + * @var string + */ + private $module_url; + /** * PayPalGateway constructor. * @@ -225,6 +232,7 @@ class PayPalGateway extends \WC_Payment_Gateway { * @param PaymentTokensEndpoint $payment_tokens_endpoint Payment tokens endpoint. * @param bool $vault_v3_enabled Whether Vault v3 module is enabled. * @param WooCommercePaymentTokens $wc_payment_tokens WooCommerce payment tokens. + * @param string $module_url The module URL */ public function __construct( SettingsRenderer $settings_renderer, @@ -246,7 +254,8 @@ class PayPalGateway extends \WC_Payment_Gateway { string $place_order_button_text, PaymentTokensEndpoint $payment_tokens_endpoint, bool $vault_v3_enabled, - WooCommercePaymentTokens $wc_payment_tokens + WooCommercePaymentTokens $wc_payment_tokens, + string $module_url ) { $this->id = self::ID; $this->settings_renderer = $settings_renderer; @@ -270,6 +279,8 @@ class PayPalGateway extends \WC_Payment_Gateway { $this->payment_tokens_endpoint = $payment_tokens_endpoint; $this->vault_v3_enabled = $vault_v3_enabled; $this->wc_payment_tokens = $wc_payment_tokens; + $this->module_url = $module_url; + $this->icon = apply_filters('woocommerce_paypal_payments_paypal_gateway_icon', esc_url( $this->module_url ) . 'assets/images/paypal.svg'); $default_support = array( 'products', diff --git a/modules/ppcp-wc-gateway/src/Gateway/PayUponInvoice/PayUponInvoiceGateway.php b/modules/ppcp-wc-gateway/src/Gateway/PayUponInvoice/PayUponInvoiceGateway.php index d4ca29121..a1a4e4113 100644 --- a/modules/ppcp-wc-gateway/src/Gateway/PayUponInvoice/PayUponInvoiceGateway.php +++ b/modules/ppcp-wc-gateway/src/Gateway/PayUponInvoice/PayUponInvoiceGateway.php @@ -103,6 +103,13 @@ class PayUponInvoiceGateway extends WC_Payment_Gateway { */ protected $refund_processor; + /** + * The module URL + * + * @var string + */ + private $module_url; + /** * PayUponInvoiceGateway constructor. * @@ -116,6 +123,7 @@ class PayUponInvoiceGateway extends WC_Payment_Gateway { * @param CheckoutHelper $checkout_helper The checkout helper. * @param State $state The onboarding state. * @param RefundProcessor $refund_processor The refund processor. + * @param string $module_url The module URL */ public function __construct( PayUponInvoiceOrderEndpoint $order_endpoint, @@ -127,7 +135,8 @@ class PayUponInvoiceGateway extends WC_Payment_Gateway { PayUponInvoiceHelper $pui_helper, CheckoutHelper $checkout_helper, State $state, - RefundProcessor $refund_processor + RefundProcessor $refund_processor, + string $module_url ) { $this->id = self::ID; @@ -157,6 +166,9 @@ class PayUponInvoiceGateway extends WC_Payment_Gateway { $this->transaction_url_provider = $transaction_url_provider; $this->pui_helper = $pui_helper; $this->checkout_helper = $checkout_helper; + $this->module_url = $module_url; + $this->icon = apply_filters('woocommerce_paypal_payments_pay_upon_invoice_gateway_icon', esc_url( $this->module_url ) . 'assets/images/ratepay.svg'); + $this->state = $state; if ( $state->current_state() === State::STATE_ONBOARDED ) { From 82faf9370b5148045ad5d9920ed5e946ac865ae7 Mon Sep 17 00:00:00 2001 From: inpsyde-maticluznar Date: Fri, 18 Oct 2024 09:47:42 +0200 Subject: [PATCH 07/17] Add paypal icon to the block checkout --- .../ppcp-blocks/resources/js/checkout-block.js | 17 ++++++++++++++++- modules/ppcp-blocks/src/PayPalPaymentMethod.php | 7 +++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/modules/ppcp-blocks/resources/js/checkout-block.js b/modules/ppcp-blocks/resources/js/checkout-block.js index 97590838e..fb012dbde 100644 --- a/modules/ppcp-blocks/resources/js/checkout-block.js +++ b/modules/ppcp-blocks/resources/js/checkout-block.js @@ -768,9 +768,24 @@ if ( block_enabled && config.enabled ) { ); } + const PaypalLabel = ( { components, config } ) => { + const { PaymentMethodIcons } = components; + + return ( + <> + + + + ); + }; + registerPaymentMethod( { name: config.id, - label:
, + label: , content: descriptionElement, edit: descriptionElement, placeOrderButtonLabel: config.placeOrderButtonText, diff --git a/modules/ppcp-blocks/src/PayPalPaymentMethod.php b/modules/ppcp-blocks/src/PayPalPaymentMethod.php index 50340b574..d6a617af0 100644 --- a/modules/ppcp-blocks/src/PayPalPaymentMethod.php +++ b/modules/ppcp-blocks/src/PayPalPaymentMethod.php @@ -248,6 +248,13 @@ class PayPalPaymentMethod extends AbstractPaymentMethodType { return array( 'id' => $this->gateway->id, 'title' => $this->gateway->title, + 'icon' => [ + [ + 'id' => 'paypal', + 'alt' => 'PayPal', + 'src' => $this->gateway->icon + ] + ], 'description' => $this->gateway->description, 'enabled' => $this->settings_status->is_smart_button_enabled_for_location( $script_data['context'] ?? 'checkout' ), 'fundingSource' => $this->session_handler->funding_source(), From 6f354828476769d87e4bb212d4833b7413c6fd98 Mon Sep 17 00:00:00 2001 From: inpsyde-maticluznar Date: Fri, 18 Oct 2024 11:29:07 +0200 Subject: [PATCH 08/17] Update icons, fix errors --- modules/ppcp-blocks/src/PayPalPaymentMethod.php | 12 ++++++------ modules/ppcp-wc-gateway/assets/images/paypal.png | Bin modules/ppcp-wc-gateway/assets/images/paypal.svg | 2 +- .../ppcp-wc-gateway/src/Gateway/PayPalGateway.php | 6 +++--- .../PayUponInvoice/PayUponInvoiceGateway.php | 7 +++---- 5 files changed, 13 insertions(+), 14 deletions(-) mode change 100755 => 100644 modules/ppcp-wc-gateway/assets/images/paypal.png diff --git a/modules/ppcp-blocks/src/PayPalPaymentMethod.php b/modules/ppcp-blocks/src/PayPalPaymentMethod.php index d6a617af0..3cb122cbc 100644 --- a/modules/ppcp-blocks/src/PayPalPaymentMethod.php +++ b/modules/ppcp-blocks/src/PayPalPaymentMethod.php @@ -248,13 +248,13 @@ class PayPalPaymentMethod extends AbstractPaymentMethodType { return array( 'id' => $this->gateway->id, 'title' => $this->gateway->title, - 'icon' => [ - [ - 'id' => 'paypal', + 'icon' => array( + array( + 'id' => 'paypal', 'alt' => 'PayPal', - 'src' => $this->gateway->icon - ] - ], + 'src' => $this->gateway->icon, + ), + ), 'description' => $this->gateway->description, 'enabled' => $this->settings_status->is_smart_button_enabled_for_location( $script_data['context'] ?? 'checkout' ), 'fundingSource' => $this->session_handler->funding_source(), diff --git a/modules/ppcp-wc-gateway/assets/images/paypal.png b/modules/ppcp-wc-gateway/assets/images/paypal.png old mode 100755 new mode 100644 diff --git a/modules/ppcp-wc-gateway/assets/images/paypal.svg b/modules/ppcp-wc-gateway/assets/images/paypal.svg index 0d82f0b74..9aa54566c 100644 --- a/modules/ppcp-wc-gateway/assets/images/paypal.svg +++ b/modules/ppcp-wc-gateway/assets/images/paypal.svg @@ -1,3 +1,3 @@ - + diff --git a/modules/ppcp-wc-gateway/src/Gateway/PayPalGateway.php b/modules/ppcp-wc-gateway/src/Gateway/PayPalGateway.php index 3012d5885..aafb50cb2 100644 --- a/modules/ppcp-wc-gateway/src/Gateway/PayPalGateway.php +++ b/modules/ppcp-wc-gateway/src/Gateway/PayPalGateway.php @@ -232,7 +232,7 @@ class PayPalGateway extends \WC_Payment_Gateway { * @param PaymentTokensEndpoint $payment_tokens_endpoint Payment tokens endpoint. * @param bool $vault_v3_enabled Whether Vault v3 module is enabled. * @param WooCommercePaymentTokens $wc_payment_tokens WooCommerce payment tokens. - * @param string $module_url The module URL + * @param string $module_url The module URL. */ public function __construct( SettingsRenderer $settings_renderer, @@ -279,8 +279,8 @@ class PayPalGateway extends \WC_Payment_Gateway { $this->payment_tokens_endpoint = $payment_tokens_endpoint; $this->vault_v3_enabled = $vault_v3_enabled; $this->wc_payment_tokens = $wc_payment_tokens; - $this->module_url = $module_url; - $this->icon = apply_filters('woocommerce_paypal_payments_paypal_gateway_icon', esc_url( $this->module_url ) . 'assets/images/paypal.svg'); + $this->module_url = $module_url; + $this->icon = apply_filters( 'woocommerce_paypal_payments_paypal_gateway_icon', esc_url( $this->module_url ) . 'assets/images/paypal.svg' ); $default_support = array( 'products', diff --git a/modules/ppcp-wc-gateway/src/Gateway/PayUponInvoice/PayUponInvoiceGateway.php b/modules/ppcp-wc-gateway/src/Gateway/PayUponInvoice/PayUponInvoiceGateway.php index a1a4e4113..69ae3b522 100644 --- a/modules/ppcp-wc-gateway/src/Gateway/PayUponInvoice/PayUponInvoiceGateway.php +++ b/modules/ppcp-wc-gateway/src/Gateway/PayUponInvoice/PayUponInvoiceGateway.php @@ -123,7 +123,7 @@ class PayUponInvoiceGateway extends WC_Payment_Gateway { * @param CheckoutHelper $checkout_helper The checkout helper. * @param State $state The onboarding state. * @param RefundProcessor $refund_processor The refund processor. - * @param string $module_url The module URL + * @param string $module_url The module URL */ public function __construct( PayUponInvoiceOrderEndpoint $order_endpoint, @@ -166,9 +166,8 @@ class PayUponInvoiceGateway extends WC_Payment_Gateway { $this->transaction_url_provider = $transaction_url_provider; $this->pui_helper = $pui_helper; $this->checkout_helper = $checkout_helper; - $this->module_url = $module_url; - $this->icon = apply_filters('woocommerce_paypal_payments_pay_upon_invoice_gateway_icon', esc_url( $this->module_url ) . 'assets/images/ratepay.svg'); - + $this->module_url = $module_url; + $this->icon = apply_filters( 'woocommerce_paypal_payments_pay_upon_invoice_gateway_icon', esc_url( $this->module_url ) . 'assets/images/ratepay.svg' ); $this->state = $state; if ( $state->current_state() === State::STATE_ONBOARDED ) { From 2a9d028308118014547c04190eb185621755f618 Mon Sep 17 00:00:00 2001 From: inpsyde-maticluznar Date: Fri, 18 Oct 2024 11:36:33 +0200 Subject: [PATCH 09/17] Fix tests --- .../Gateway/PayUponInvoice/PayUponInvoiceGatewayTest.php | 3 ++- tests/PHPUnit/WcGateway/Gateway/WcGatewayTest.php | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/PHPUnit/WcGateway/Gateway/PayUponInvoice/PayUponInvoiceGatewayTest.php b/tests/PHPUnit/WcGateway/Gateway/PayUponInvoice/PayUponInvoiceGatewayTest.php index 0161f8c71..82c88449f 100644 --- a/tests/PHPUnit/WcGateway/Gateway/PayUponInvoice/PayUponInvoiceGatewayTest.php +++ b/tests/PHPUnit/WcGateway/Gateway/PayUponInvoice/PayUponInvoiceGatewayTest.php @@ -64,7 +64,8 @@ class PayUponInvoiceGatewayTest extends TestCase $this->pui_helper, $this->checkout_helper, $this->state, - $this->refund_processor + $this->refund_processor, + '' ); } diff --git a/tests/PHPUnit/WcGateway/Gateway/WcGatewayTest.php b/tests/PHPUnit/WcGateway/Gateway/WcGatewayTest.php index 041141492..5884572e7 100644 --- a/tests/PHPUnit/WcGateway/Gateway/WcGatewayTest.php +++ b/tests/PHPUnit/WcGateway/Gateway/WcGatewayTest.php @@ -123,7 +123,8 @@ class WcGatewayTest extends TestCase 'Pay via PayPal', $this->paymentTokensEndpoint, $this->vaultV3Enabled, - $this->wcPaymentTokens + $this->wcPaymentTokens, + '' ); } From 89a87c2f37d3f144b0f06b9c0a7ed09721526b67 Mon Sep 17 00:00:00 2001 From: inpsyde-maticluznar Date: Fri, 18 Oct 2024 11:46:23 +0200 Subject: [PATCH 10/17] Add a dot to the param comment --- .../src/Gateway/PayUponInvoice/PayUponInvoiceGateway.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/ppcp-wc-gateway/src/Gateway/PayUponInvoice/PayUponInvoiceGateway.php b/modules/ppcp-wc-gateway/src/Gateway/PayUponInvoice/PayUponInvoiceGateway.php index 69ae3b522..dbd6629bd 100644 --- a/modules/ppcp-wc-gateway/src/Gateway/PayUponInvoice/PayUponInvoiceGateway.php +++ b/modules/ppcp-wc-gateway/src/Gateway/PayUponInvoice/PayUponInvoiceGateway.php @@ -123,7 +123,7 @@ class PayUponInvoiceGateway extends WC_Payment_Gateway { * @param CheckoutHelper $checkout_helper The checkout helper. * @param State $state The onboarding state. * @param RefundProcessor $refund_processor The refund processor. - * @param string $module_url The module URL + * @param string $module_url The module URL. */ public function __construct( PayUponInvoiceOrderEndpoint $order_endpoint, From 4a688fb351f9d322795533e9be368d271f735b11 Mon Sep 17 00:00:00 2001 From: Daniel Dudzic Date: Wed, 30 Oct 2024 22:25:39 +0100 Subject: [PATCH 11/17] Load ACDC for Classic and Block checkouts for subscription products --- modules/ppcp-axo/src/AxoModule.php | 6 +- .../js/advanced-card-checkout-block.js | 74 ++++++++++++------- .../src/AdvancedCardPaymentMethod.php | 1 + modules/ppcp-blocks/src/BlocksModule.php | 6 +- 4 files changed, 55 insertions(+), 32 deletions(-) diff --git a/modules/ppcp-axo/src/AxoModule.php b/modules/ppcp-axo/src/AxoModule.php index a0470aeac..2c9b8c640 100644 --- a/modules/ppcp-axo/src/AxoModule.php +++ b/modules/ppcp-axo/src/AxoModule.php @@ -375,11 +375,15 @@ class AxoModule implements ServiceModule, ExtendingModule, ExecutableModule { $dcc_configuration = $c->get( 'wcgateway.configuration.dcc' ); assert( $dcc_configuration instanceof DCCGatewayConfiguration ); + $subscription_helper = $c->get( 'wc-subscriptions.helper' ); + assert( $subscription_helper instanceof SubscriptionHelper ); + return ! is_user_logged_in() && CartCheckoutDetector::has_classic_checkout() && $dcc_configuration->use_fastlane() && ! $this->is_excluded_endpoint() - && is_checkout(); + && is_checkout() + && ! $subscription_helper->cart_contains_subscription(); } /** diff --git a/modules/ppcp-blocks/resources/js/advanced-card-checkout-block.js b/modules/ppcp-blocks/resources/js/advanced-card-checkout-block.js index 24c53c5a5..92aa645a6 100644 --- a/modules/ppcp-blocks/resources/js/advanced-card-checkout-block.js +++ b/modules/ppcp-blocks/resources/js/advanced-card-checkout-block.js @@ -1,30 +1,50 @@ -import {registerPaymentMethod} from '@woocommerce/blocks-registry'; -import {CardFields} from './Components/card-fields'; +import { registerPaymentMethod } from '@woocommerce/blocks-registry'; +import { CardFields } from './Components/card-fields'; -const config = wc.wcSettings.getSetting('ppcp-credit-card-gateway_data'); +const config = wc.wcSettings.getSetting( 'ppcp-credit-card-gateway_data' ); +const isUserLoggedIn = config?.scriptData?.is_user_logged_in; +const axoConfig = wc.wcSettings.getSetting( 'ppcp-axo-gateway_data' ); +const axoEnabled = axoConfig !== false; -const Label = ({components, config}) => { - const {PaymentMethodIcons} = components; - return <> - - - -} +const Label = ( { components } ) => { + const { PaymentMethodIcons } = components; + return ( + <> + + + + ); +}; -registerPaymentMethod({ - name: config.id, - label: