diff --git a/modules/ppcp-axo-block/resources/js/hooks/useAllowedLocations.js b/modules/ppcp-axo-block/resources/js/hooks/useAllowedLocations.js new file mode 100644 index 000000000..67b36036a --- /dev/null +++ b/modules/ppcp-axo-block/resources/js/hooks/useAllowedLocations.js @@ -0,0 +1,21 @@ +import { useMemo } from '@wordpress/element'; + +/** + * Custom hook returning the allowed shipping locations based on configuration. + * + * @param {Object} axoConfig - The AXO configuration object. + * @param {Array|undefined} axoConfig.enabled_shipping_locations - The list of enabled shipping locations. + * @return {Array} The final list of allowed shipping locations. + */ +const useAllowedLocations = ( axoConfig ) => { + return useMemo( () => { + const enabledShippingLocations = + axoConfig.enabled_shipping_locations || []; + + return Array.isArray( enabledShippingLocations ) + ? enabledShippingLocations + : []; + }, [ axoConfig.enabled_shipping_locations ] ); +}; + +export default useAllowedLocations; diff --git a/modules/ppcp-axo-block/resources/js/hooks/useFastlaneSdk.js b/modules/ppcp-axo-block/resources/js/hooks/useFastlaneSdk.js index 7e68ccab1..ae93a67af 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 useAllowedLocations from './useAllowedLocations'; import { STORE_NAME } from '../stores/axoStore'; /** @@ -30,6 +31,8 @@ const useFastlaneSdk = ( namespace, axoConfig, ppcpConfig ) => { return deleteEmptyKeys( configRef.current.axoConfig.style_options ); }, [ deleteEmptyKeys ] ); + const allowedLocations = useAllowedLocations( axoConfig ); + // Effect to initialize Fastlane SDK useEffect( () => { const initFastlane = async () => { @@ -52,6 +55,9 @@ const useFastlaneSdk = ( namespace, axoConfig, ppcpConfig ) => { await fastlane.connect( { locale: configRef.current.ppcpConfig.locale, styles: styleOptions, + shippingAddressOptions: { + allowedLocations, + }, } ); // Set locale (hardcoded to 'en_us' for now) @@ -66,7 +72,13 @@ const useFastlaneSdk = ( namespace, axoConfig, ppcpConfig ) => { }; initFastlane(); - }, [ fastlaneSdk, styleOptions, isPayPalLoaded, namespace ] ); + }, [ + fastlaneSdk, + styleOptions, + isPayPalLoaded, + namespace, + allowedLocations, + ] ); // Effect to update the config ref when configs change useEffect( () => { diff --git a/modules/ppcp-axo-block/services.php b/modules/ppcp-axo-block/services.php index 270b69260..35a253881 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.shipping-wc-enabled-locations' ) ); }, ); diff --git a/modules/ppcp-axo-block/src/AxoBlockPaymentMethod.php b/modules/ppcp-axo-block/src/AxoBlockPaymentMethod.php index 136db8233..e7d43608d 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 list of WooCommerce enabled shipping locations. + * + * @var array + */ + private array $enabled_shipping_locations; + /** * 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 $enabled_shipping_locations The list of WooCommerce enabled shipping locations. */ public function __construct( string $module_url, @@ -100,18 +108,19 @@ class AxoBlockPaymentMethod extends AbstractPaymentMethodType { Settings $settings, DCCGatewayConfiguration $dcc_configuration, Environment $environment, - string $wcgateway_module_url + string $wcgateway_module_url, + array $enabled_shipping_locations ) { - $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->enabled_shipping_locations = $enabled_shipping_locations; } /** @@ -187,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' => @@ -207,7 +216,8 @@ class AxoBlockPaymentMethod extends AbstractPaymentMethodType { : null, // Set to null if WC()->cart is null or get_total doesn't exist. ), ), - 'style_options' => array( + 'enabled_shipping_locations' => $this->enabled_shipping_locations, + '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' ) : '', @@ -226,23 +236,23 @@ 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, + 'logging_enabled' => $this->settings->has( 'logging_enabled' ) ? $this->settings->get( 'logging_enabled' ) : '', + 'wp_debug' => defined( 'WP_DEBUG' ) && WP_DEBUG, ); } } diff --git a/modules/ppcp-axo/resources/js/AxoManager.js b/modules/ppcp-axo/resources/js/AxoManager.js index 0bd204672..de9fcff5c 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,9 @@ class AxoManager { }, }; + this.enabledShippingLocations = + this.axoConfig.enabled_shipping_locations; + this.registerEventHandlers(); this.shippingView = new ShippingView( @@ -661,6 +664,9 @@ class AxoManager { await this.fastlane.connect( { locale: this.locale, styles: this.styles, + shippingAddressOptions: { + allowedLocations: this.enabledShippingLocations, + }, } ); this.fastlane.setLocale( 'en_us' ); diff --git a/modules/ppcp-axo/services.php b/modules/ppcp-axo/services.php index ebeb0f394..10062b290 100644 --- a/modules/ppcp-axo/services.php +++ b/modules/ppcp-axo/services.php @@ -22,14 +22,14 @@ use WooCommerce\PayPalCommerce\WcGateway\Helper\DCCGatewayConfiguration; return array( // If AXO can be configured. - 'axo.eligible' => static function ( ContainerInterface $container ): bool { + 'axo.eligible' => static function ( ContainerInterface $container ): bool { $apm_applies = $container->get( 'axo.helpers.apm-applies' ); assert( $apm_applies instanceof ApmApplies ); return $apm_applies->for_country_currency(); }, - 'axo.helpers.apm-applies' => static function ( ContainerInterface $container ) : ApmApplies { + 'axo.helpers.apm-applies' => static function ( ContainerInterface $container ) : ApmApplies { return new ApmApplies( $container->get( 'axo.supported-country-currency-matrix' ), $container->get( 'api.shop.currency.getter' ), @@ -37,16 +37,16 @@ return array( ); }, - 'axo.helpers.settings-notice-generator' => static function ( ContainerInterface $container ) : SettingsNoticeGenerator { + 'axo.helpers.settings-notice-generator' => static function ( ContainerInterface $container ) : SettingsNoticeGenerator { return new SettingsNoticeGenerator( $container->get( 'axo.fastlane-incompatible-plugin-names' ) ); }, // If AXO is configured and onboarded. - 'axo.available' => static function ( ContainerInterface $container ): bool { + 'axo.available' => static function ( ContainerInterface $container ): bool { return true; }, - 'axo.url' => static function ( ContainerInterface $container ): string { + 'axo.url' => static function ( ContainerInterface $container ): string { $path = realpath( __FILE__ ); if ( false === $path ) { return ''; @@ -57,7 +57,7 @@ return array( ); }, - 'axo.manager' => static function ( ContainerInterface $container ): AxoManager { + 'axo.manager' => static function ( ContainerInterface $container ): AxoManager { return new AxoManager( $container->get( 'axo.url' ), $container->get( 'ppcp.asset-version' ), @@ -67,11 +67,12 @@ 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.shipping-wc-enabled-locations' ) ); }, - 'axo.gateway' => static function ( ContainerInterface $container ): AxoGateway { + 'axo.gateway' => static function ( ContainerInterface $container ): AxoGateway { return new AxoGateway( $container->get( 'wcgateway.settings.render' ), $container->get( 'wcgateway.settings' ), @@ -92,7 +93,7 @@ return array( /** * The matrix which countries and currency combinations can be used for AXO. */ - 'axo.supported-country-currency-matrix' => static function ( ContainerInterface $container ) : array { + 'axo.supported-country-currency-matrix' => static function ( ContainerInterface $container ) : array { /** * Returns which countries and currency combinations can be used for AXO. */ @@ -111,7 +112,7 @@ return array( ); }, - 'axo.settings-conflict-notice' => static function ( ContainerInterface $container ) : string { + '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 ); @@ -121,21 +122,21 @@ return array( return $settings_notice_generator->generate_settings_conflict_notice( $settings ); }, - 'axo.checkout-config-notice' => static function ( ContainerInterface $container ) : string { + 'axo.checkout-config-notice' => static function ( ContainerInterface $container ) : string { $settings_notice_generator = $container->get( 'axo.helpers.settings-notice-generator' ); assert( $settings_notice_generator instanceof SettingsNoticeGenerator ); return $settings_notice_generator->generate_checkout_notice(); }, - 'axo.incompatible-plugins-notice' => static function ( ContainerInterface $container ) : string { + 'axo.incompatible-plugins-notice' => static function ( ContainerInterface $container ) : string { $settings_notice_generator = $container->get( 'axo.helpers.settings-notice-generator' ); assert( $settings_notice_generator instanceof SettingsNoticeGenerator ); return $settings_notice_generator->generate_incompatible_plugins_notice(); }, - 'axo.smart-button-location-notice' => static function ( ContainerInterface $container ) : string { + 'axo.smart-button-location-notice' => static function ( ContainerInterface $container ) : string { $dcc_configuration = $container->get( 'wcgateway.configuration.dcc' ); assert( $dcc_configuration instanceof DCCGatewayConfiguration ); @@ -163,7 +164,7 @@ return array( return '

' . $notice_content . '

'; }, - 'axo.endpoint.frontend-logger' => static function ( ContainerInterface $container ): FrontendLoggerEndpoint { + 'axo.endpoint.frontend-logger' => static function ( ContainerInterface $container ): FrontendLoggerEndpoint { return new FrontendLoggerEndpoint( $container->get( 'button.request-data' ), $container->get( 'woocommerce.logger.woocommerce' ) @@ -175,7 +176,7 @@ return array( * * @returns array */ - 'axo.fastlane-incompatible-plugins' => static function () : array { + 'axo.fastlane-incompatible-plugins' => static function () : array { /** * Filters the list of Fastlane incompatible plugins. */ @@ -230,7 +231,7 @@ return array( ); }, - 'axo.fastlane-incompatible-plugin-names' => static function ( ContainerInterface $container ) : array { + 'axo.fastlane-incompatible-plugin-names' => static function ( ContainerInterface $container ) : array { $incompatible_plugins = $container->get( 'axo.fastlane-incompatible-plugins' ); $active_plugins_list = array_filter( @@ -251,4 +252,45 @@ return array( $active_plugins_list ); }, + + 'axo.shipping-wc-enabled-locations' => static function ( ContainerInterface $container ): array { + $default_zone = new \WC_Shipping_Zone( 0 ); + + $is_method_enabled = fn( $method) => $method->enabled === 'yes'; + + $is_default_zone_enabled = ! empty( + array_filter( + $default_zone->get_shipping_methods(), + $is_method_enabled + ) + ); + + if ( $is_default_zone_enabled ) { + return array(); + } + + $shipping_zones = \WC_Shipping_Zones::get_zones(); + + $get_zone_locations = fn($zone) => + !empty(array_filter($zone->get_shipping_methods(), $is_method_enabled)) + ? array_map( + fn($location) => $location->code, + $zone->get_zone_locations() + ) + : []; + + $enabled_locations = array_unique( + array_merge( + ...array_map( + $get_zone_locations, + array_map( + fn( $zone) => $zone instanceof \WC_Shipping_Zone ? $zone : new \WC_Shipping_Zone( $zone['id'] ), + $shipping_zones + ) + ) + ) + ); + + return $enabled_locations; + }, ); diff --git a/modules/ppcp-axo/src/Assets/AxoManager.php b/modules/ppcp-axo/src/Assets/AxoManager.php index 6fa196719..f0ad8b012 100644 --- a/modules/ppcp-axo/src/Assets/AxoManager.php +++ b/modules/ppcp-axo/src/Assets/AxoManager.php @@ -87,6 +87,13 @@ class AxoManager { */ private $wcgateway_module_url; + /** + * The list of WooCommerce enabled shipping locations. + * + * @var array + */ + private array $enabled_shipping_locations; + /** * AxoManager constructor. * @@ -99,6 +106,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 $enabled_shipping_locations The list of WooCommerce enabled shipping locations. */ public function __construct( string $module_url, @@ -109,18 +117,20 @@ class AxoManager { SettingsStatus $settings_status, CurrencyGetter $currency, LoggerInterface $logger, - string $wcgateway_module_url + string $wcgateway_module_url, + array $enabled_shipping_locations ) { - $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->enabled_shipping_locations = $enabled_shipping_locations; } /** @@ -163,13 +173,13 @@ class AxoManager { */ private function script_data() { 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' => @@ -183,7 +193,8 @@ class AxoManager { 'value' => WC()->cart->get_total( 'numeric' ), ), ), - 'style_options' => array( + 'enabled_shipping_locations' => $this->enabled_shipping_locations, + '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' ) : '', @@ -202,24 +213,24 @@ class AxoManager { 'focusBorderColor' => $this->settings->has( 'axo_style_input_focus_border_color' ) ? $this->settings->get( 'axo_style_input_focus_border_color' ) : '', ), ), - 'name_on_card' => $this->settings->has( 'axo_name_on_card' ) ? $this->settings->get( 'axo_name_on_card' ) : '', - 'woocommerce' => array( + 'name_on_card' => $this->settings->has( 'axo_name_on_card' ) ? $this->settings->get( 'axo_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, - 'billing_email_button_text' => __( 'Continue', 'woocommerce-paypal-payments' ), + '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' ), ); }