mirror of
https://github.com/woocommerce/woocommerce-paypal-payments.git
synced 2025-09-05 08:59:14 +08:00
Merge branch 'trunk' into PCP-4210-features-refactor-to-use-rest-endpoints
# Conflicts: # modules/ppcp-settings/services.php
This commit is contained in:
commit
68fe134ed0
32 changed files with 1054 additions and 231 deletions
|
@ -670,6 +670,7 @@ return array(
|
|||
'FR' => $default_currencies,
|
||||
'DE' => $default_currencies,
|
||||
'GR' => $default_currencies,
|
||||
'HK' => $default_currencies,
|
||||
'HU' => $default_currencies,
|
||||
'IE' => $default_currencies,
|
||||
'IT' => $default_currencies,
|
||||
|
@ -687,6 +688,7 @@ return array(
|
|||
'PT' => $default_currencies,
|
||||
'RO' => $default_currencies,
|
||||
'SK' => $default_currencies,
|
||||
'SG' => $default_currencies,
|
||||
'SI' => $default_currencies,
|
||||
'ES' => $default_currencies,
|
||||
'SE' => $default_currencies,
|
||||
|
@ -735,6 +737,7 @@ return array(
|
|||
'FR' => $mastercard_visa_amex,
|
||||
'GB' => $mastercard_visa_amex,
|
||||
'GR' => $mastercard_visa_amex,
|
||||
'HK' => $mastercard_visa_amex,
|
||||
'HU' => $mastercard_visa_amex,
|
||||
'IE' => $mastercard_visa_amex,
|
||||
'IT' => $mastercard_visa_amex,
|
||||
|
@ -764,6 +767,7 @@ return array(
|
|||
'SE' => $mastercard_visa_amex,
|
||||
'SI' => $mastercard_visa_amex,
|
||||
'SK' => $mastercard_visa_amex,
|
||||
'SG' => $mastercard_visa_amex,
|
||||
'JP' => array(
|
||||
'mastercard' => array(),
|
||||
'visa' => array(),
|
||||
|
|
|
@ -190,6 +190,7 @@ return array(
|
|||
'FR', // France
|
||||
'DE', // Germany
|
||||
'GR', // Greece
|
||||
'HK', // Hong Kong
|
||||
'HU', // Hungary
|
||||
'IE', // Ireland
|
||||
'IT', // Italy
|
||||
|
@ -203,6 +204,7 @@ return array(
|
|||
'PL', // Poland
|
||||
'PT', // Portugal
|
||||
'RO', // Romania
|
||||
'SG', // Singapore
|
||||
'SK', // Slovakia
|
||||
'SI', // Slovenia
|
||||
'ES', // Spain
|
||||
|
@ -232,6 +234,7 @@ return array(
|
|||
'CZK', // Czech Koruna
|
||||
'DKK', // Danish Krone
|
||||
'EUR', // Euro
|
||||
'HKD', // Hong Kong Dollar
|
||||
'GBP', // British Pound Sterling
|
||||
'HUF', // Hungarian Forint
|
||||
'ILS', // Israeli New Shekel
|
||||
|
@ -241,6 +244,7 @@ return array(
|
|||
'NZD', // New Zealand Dollar
|
||||
'PHP', // Philippine Peso
|
||||
'PLN', // Polish Zloty
|
||||
'SGD', // Singapur-Dollar
|
||||
'SEK', // Swedish Krona
|
||||
'THB', // Thai Baht
|
||||
'TWD', // New Taiwan Dollar
|
||||
|
|
|
@ -43,6 +43,7 @@ return array(
|
|||
'FR',
|
||||
'DE',
|
||||
'GR',
|
||||
'HK',
|
||||
'HU',
|
||||
'IE',
|
||||
'IT',
|
||||
|
@ -56,6 +57,7 @@ return array(
|
|||
'PT',
|
||||
'RO',
|
||||
'SK',
|
||||
'SG',
|
||||
'SI',
|
||||
'ES',
|
||||
'SE',
|
||||
|
|
|
@ -10,10 +10,12 @@ declare(strict_types=1);
|
|||
namespace WooCommerce\PayPalCommerce\Compat;
|
||||
|
||||
use WooCommerce\PayPalCommerce\Compat\Assets\CompatAssets;
|
||||
use WooCommerce\PayPalCommerce\Compat\Settings\GeneralSettingsMapHelper;
|
||||
use WooCommerce\PayPalCommerce\Compat\Settings\SettingsMap;
|
||||
use WooCommerce\PayPalCommerce\Compat\Settings\SettingsMapHelper;
|
||||
use WooCommerce\PayPalCommerce\Compat\Settings\SettingsTabMapHelper;
|
||||
use WooCommerce\PayPalCommerce\Compat\Settings\StylingSettingsMapHelper;
|
||||
use WooCommerce\PayPalCommerce\Compat\Settings\SubscriptionSettingsMapHelper;
|
||||
use WooCommerce\PayPalCommerce\Vendor\Psr\Container\ContainerInterface;
|
||||
|
||||
return array(
|
||||
|
@ -137,30 +139,16 @@ return array(
|
|||
$settings_tab_map_helper = $container->get( 'compat.settings.settings_tab_map_helper' );
|
||||
assert( $settings_tab_map_helper instanceof SettingsTabMapHelper );
|
||||
|
||||
$subscription_map_helper = $container->get( 'compat.settings.subscription_map_helper' );
|
||||
assert( $subscription_map_helper instanceof SubscriptionSettingsMapHelper );
|
||||
|
||||
$general_map_helper = $container->get( 'compat.settings.general_map_helper' );
|
||||
assert( $general_map_helper instanceof GeneralSettingsMapHelper );
|
||||
|
||||
return array(
|
||||
new SettingsMap(
|
||||
$container->get( 'settings.data.general' ),
|
||||
/**
|
||||
* The new GeneralSettings class stores the current connection
|
||||
* details, without adding an environment-suffix (no `_sandbox`
|
||||
* or `_production` in the field name)
|
||||
* Only the `sandbox_merchant` flag indicates, which environment
|
||||
* the credentials are used for.
|
||||
*/
|
||||
array(
|
||||
'merchant_id' => 'merchant_id',
|
||||
'client_id' => 'client_id',
|
||||
'client_secret' => 'client_secret',
|
||||
'sandbox_on' => 'sandbox_merchant',
|
||||
'live_client_id' => 'client_id',
|
||||
'live_client_secret' => 'client_secret',
|
||||
'live_merchant_id' => 'merchant_id',
|
||||
'live_merchant_email' => 'merchant_email',
|
||||
'sandbox_client_id' => 'client_id',
|
||||
'sandbox_client_secret' => 'client_secret',
|
||||
'sandbox_merchant_id' => 'merchant_id',
|
||||
'sandbox_merchant_email' => 'merchant_email',
|
||||
)
|
||||
$general_map_helper->map()
|
||||
),
|
||||
new SettingsMap(
|
||||
$container->get( 'settings.data.settings' ),
|
||||
|
@ -180,13 +168,19 @@ return array(
|
|||
*/
|
||||
$styling_settings_map_helper->map()
|
||||
),
|
||||
new SettingsMap(
|
||||
$container->get( 'settings.data.settings' ),
|
||||
$subscription_map_helper->map()
|
||||
),
|
||||
);
|
||||
},
|
||||
'compat.settings.settings_map_helper' => static function( ContainerInterface $container ) : SettingsMapHelper {
|
||||
return new SettingsMapHelper(
|
||||
$container->get( 'compat.setting.new-to-old-map' ),
|
||||
$container->get( 'compat.settings.styling_map_helper' ),
|
||||
$container->get( 'compat.settings.settings_tab_map_helper' )
|
||||
$container->get( 'compat.settings.settings_tab_map_helper' ),
|
||||
$container->get( 'compat.settings.subscription_map_helper' ),
|
||||
$container->get( 'compat.settings.general_map_helper' )
|
||||
);
|
||||
},
|
||||
'compat.settings.styling_map_helper' => static function() : StylingSettingsMapHelper {
|
||||
|
@ -195,4 +189,10 @@ return array(
|
|||
'compat.settings.settings_tab_map_helper' => static function() : SettingsTabMapHelper {
|
||||
return new SettingsTabMapHelper();
|
||||
},
|
||||
'compat.settings.subscription_map_helper' => static function( ContainerInterface $container ) : SubscriptionSettingsMapHelper {
|
||||
return new SubscriptionSettingsMapHelper( $container->get( 'wc-subscriptions.helper' ) );
|
||||
},
|
||||
'compat.settings.general_map_helper' => static function() : GeneralSettingsMapHelper {
|
||||
return new GeneralSettingsMapHelper();
|
||||
},
|
||||
);
|
||||
|
|
|
@ -0,0 +1,70 @@
|
|||
<?php
|
||||
/**
|
||||
* A helper for mapping old and new general settings.
|
||||
*
|
||||
* @package WooCommerce\PayPalCommerce\Compat\Settings
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace WooCommerce\PayPalCommerce\Compat\Settings;
|
||||
|
||||
/**
|
||||
* Handles mapping between old and new general settings.
|
||||
*
|
||||
* @psalm-import-type newSettingsKey from SettingsMap
|
||||
* @psalm-import-type oldSettingsKey from SettingsMap
|
||||
*/
|
||||
class GeneralSettingsMapHelper {
|
||||
|
||||
/**
|
||||
* Maps old setting keys to new setting keys.
|
||||
*
|
||||
* The new GeneralSettings class stores the current connection
|
||||
* details, without adding an environment-suffix (no `_sandbox`
|
||||
* or `_production` in the field name)
|
||||
* Only the `sandbox_merchant` flag indicates, which environment
|
||||
* the credentials are used for.
|
||||
*
|
||||
* @psalm-return array<oldSettingsKey, newSettingsKey>
|
||||
*/
|
||||
public function map(): array {
|
||||
return array(
|
||||
'merchant_id' => 'merchant_id',
|
||||
'client_id' => 'client_id',
|
||||
'client_secret' => 'client_secret',
|
||||
'sandbox_on' => 'sandbox_merchant',
|
||||
'live_client_id' => 'client_id',
|
||||
'live_client_secret' => 'client_secret',
|
||||
'live_merchant_id' => 'merchant_id',
|
||||
'live_merchant_email' => 'merchant_email',
|
||||
'merchant_email' => 'merchant_email',
|
||||
'sandbox_client_id' => 'client_id',
|
||||
'sandbox_client_secret' => 'client_secret',
|
||||
'sandbox_merchant_id' => 'merchant_id',
|
||||
'sandbox_merchant_email' => 'merchant_email',
|
||||
'enabled' => '',
|
||||
'allow_local_apm_gateways' => '',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the mapped value for the given key from the new settings.
|
||||
*
|
||||
* @param string $old_key The key from the legacy settings.
|
||||
* @param array<string, scalar|array> $settings_model The new settings model data as an array.
|
||||
* @return mixed The value of the mapped setting, or null if not applicable.
|
||||
*/
|
||||
public function mapped_value( string $old_key, array $settings_model ) {
|
||||
$settings_map = $this->map();
|
||||
$new_key = $settings_map[ $old_key ] ?? false;
|
||||
switch ( $old_key ) {
|
||||
case 'enabled':
|
||||
case 'allow_local_apm_gateways':
|
||||
return true;
|
||||
|
||||
default:
|
||||
return $settings_model[ $new_key ] ?? null;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -10,6 +10,7 @@ declare( strict_types = 1 );
|
|||
namespace WooCommerce\PayPalCommerce\Compat\Settings;
|
||||
|
||||
use RuntimeException;
|
||||
use WooCommerce\PayPalCommerce\Settings\Data\GeneralSettings;
|
||||
use WooCommerce\PayPalCommerce\Settings\Data\SettingsModel;
|
||||
use WooCommerce\PayPalCommerce\Settings\Data\StylingSettings;
|
||||
|
||||
|
@ -57,23 +58,43 @@ class SettingsMapHelper {
|
|||
*/
|
||||
protected SettingsTabMapHelper $settings_tab_map_helper;
|
||||
|
||||
/**
|
||||
* A helper for mapping old and new subscription settings.
|
||||
*
|
||||
* @var SubscriptionSettingsMapHelper
|
||||
*/
|
||||
protected SubscriptionSettingsMapHelper $subscription_map_helper;
|
||||
|
||||
/**
|
||||
* A helper for mapping old and new general settings.
|
||||
*
|
||||
* @var GeneralSettingsMapHelper
|
||||
*/
|
||||
protected GeneralSettingsMapHelper $general_settings_map_helper;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param SettingsMap[] $settings_map A list of settings maps containing key definitions.
|
||||
* @param StylingSettingsMapHelper $styling_settings_map_helper A helper for mapping the old/new styling settings.
|
||||
* @param SettingsTabMapHelper $settings_tab_map_helper A helper for mapping the old/new settings tab settings.
|
||||
* @param SettingsMap[] $settings_map A list of settings maps containing key definitions.
|
||||
* @param StylingSettingsMapHelper $styling_settings_map_helper A helper for mapping the old/new styling settings.
|
||||
* @param SettingsTabMapHelper $settings_tab_map_helper A helper for mapping the old/new settings tab settings.
|
||||
* @param SubscriptionSettingsMapHelper $subscription_map_helper A helper for mapping old and new subscription settings.
|
||||
* @param GeneralSettingsMapHelper $general_settings_map_helper A helper for mapping old and new general settings.
|
||||
* @throws RuntimeException When an old key has multiple mappings.
|
||||
*/
|
||||
public function __construct(
|
||||
array $settings_map,
|
||||
StylingSettingsMapHelper $styling_settings_map_helper,
|
||||
SettingsTabMapHelper $settings_tab_map_helper
|
||||
SettingsTabMapHelper $settings_tab_map_helper,
|
||||
SubscriptionSettingsMapHelper $subscription_map_helper,
|
||||
GeneralSettingsMapHelper $general_settings_map_helper
|
||||
) {
|
||||
$this->validate_settings_map( $settings_map );
|
||||
$this->settings_map = $settings_map;
|
||||
$this->styling_settings_map_helper = $styling_settings_map_helper;
|
||||
$this->settings_tab_map_helper = $settings_tab_map_helper;
|
||||
$this->subscription_map_helper = $subscription_map_helper;
|
||||
$this->general_settings_map_helper = $general_settings_map_helper;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -150,8 +171,13 @@ class SettingsMapHelper {
|
|||
case $model instanceof StylingSettings:
|
||||
return $this->styling_settings_map_helper->mapped_value( $old_key, $this->model_cache[ $model_id ] );
|
||||
|
||||
case $model instanceof GeneralSettings:
|
||||
return $this->general_settings_map_helper->mapped_value( $old_key, $this->model_cache[ $model_id ] );
|
||||
|
||||
case $model instanceof SettingsModel:
|
||||
return $this->settings_tab_map_helper->mapped_value( $old_key, $this->model_cache[ $model_id ] );
|
||||
return $old_key === 'subscriptions_mode'
|
||||
? $this->subscription_map_helper->mapped_value( $old_key, $this->model_cache[ $model_id ] )
|
||||
: $this->settings_tab_map_helper->mapped_value( $old_key, $this->model_cache[ $model_id ] );
|
||||
|
||||
default:
|
||||
return $this->model_cache[ $model_id ][ $new_key ] ?? null;
|
||||
|
|
|
@ -0,0 +1,85 @@
|
|||
<?php
|
||||
/**
|
||||
* A helper for mapping old and new subscription settings.
|
||||
*
|
||||
* @package WooCommerce\PayPalCommerce\Compat\Settings
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace WooCommerce\PayPalCommerce\Compat\Settings;
|
||||
|
||||
use WooCommerce\PayPalCommerce\WcSubscriptions\Helper\SubscriptionHelper;
|
||||
|
||||
/**
|
||||
* Handles mapping between old and new subscription settings.
|
||||
*
|
||||
* In the new settings UI, the Subscriptions mode value is set automatically based on the merchant type.
|
||||
* This class fakes the mapping and injects the appropriate value based on the merchant:
|
||||
* - Non-vaulting merchants will use PayPal Subscriptions.
|
||||
* - Merchants with vaulting will use PayPal Vaulting.
|
||||
* - Disabled subscriptions can be controlled using a filter.
|
||||
*
|
||||
* @psalm-import-type newSettingsKey from SettingsMap
|
||||
* @psalm-import-type oldSettingsKey from SettingsMap
|
||||
*/
|
||||
class SubscriptionSettingsMapHelper {
|
||||
|
||||
public const OLD_SETTINGS_SUBSCRIPTION_MODE_VALUE_VAULTING = 'vaulting_api';
|
||||
public const OLD_SETTINGS_SUBSCRIPTION_MODE_VALUE_SUBSCRIPTIONS = 'subscriptions_api';
|
||||
public const OLD_SETTINGS_SUBSCRIPTION_MODE_VALUE_DISABLED = 'disable_paypal_subscriptions';
|
||||
|
||||
/**
|
||||
* The subscription helper.
|
||||
*
|
||||
* @var SubscriptionHelper $subscription_helper
|
||||
*/
|
||||
protected SubscriptionHelper $subscription_helper;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param SubscriptionHelper $subscription_helper The subscription helper.
|
||||
*/
|
||||
public function __construct( SubscriptionHelper $subscription_helper ) {
|
||||
$this->subscription_helper = $subscription_helper;
|
||||
}
|
||||
|
||||
/**
|
||||
* Maps the old subscription setting key.
|
||||
*
|
||||
* This method creates a placeholder mapping as this setting doesn't exist in the new settings.
|
||||
* The Subscriptions mode value is set automatically based on the merchant type.
|
||||
*
|
||||
* @psalm-return array<oldSettingsKey, newSettingsKey>
|
||||
*/
|
||||
public function map(): array {
|
||||
return array( 'subscriptions_mode' => '' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the mapped value for the subscriptions_mode key from the new settings.
|
||||
*
|
||||
* @param string $old_key The key from the legacy settings.
|
||||
* @param array<string, scalar|array> $settings_model The new settings model data as an array.
|
||||
*
|
||||
* @return 'vaulting_api'|'subscriptions_api'|'disable_paypal_subscriptions'|null The mapped subscriptions_mode value, or null if not applicable.
|
||||
*/
|
||||
public function mapped_value( string $old_key, array $settings_model ): ?string {
|
||||
if ( $old_key !== 'subscriptions_mode' || ! $this->subscription_helper->plugin_is_active() ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$vaulting = $settings_model['save_paypal_and_venmo'] ?? false;
|
||||
$subscription_mode_value = $vaulting ? self::OLD_SETTINGS_SUBSCRIPTION_MODE_VALUE_VAULTING : self::OLD_SETTINGS_SUBSCRIPTION_MODE_VALUE_SUBSCRIPTIONS;
|
||||
|
||||
/**
|
||||
* Allows disabling the subscription mode when using the new settings UI.
|
||||
*
|
||||
* @returns bool true if the subscription mode should be disabled, false otherwise (default is false).
|
||||
*/
|
||||
$subscription_mode_disabled = (bool) apply_filters( 'woocommerce_paypal_payments_subscription_mode_disabled', false );
|
||||
|
||||
return $subscription_mode_disabled ? self::OLD_SETTINGS_SUBSCRIPTION_MODE_VALUE_DISABLED : $subscription_mode_value;
|
||||
}
|
||||
}
|
|
@ -105,6 +105,7 @@ return array(
|
|||
'FR', // France
|
||||
'DE', // Germany
|
||||
'GR', // Greece
|
||||
'HK', // Hong Kong
|
||||
'HU', // Hungary
|
||||
'IE', // Ireland
|
||||
'IT', // Italy
|
||||
|
@ -118,6 +119,7 @@ return array(
|
|||
'PL', // Poland
|
||||
'PT', // Portugal
|
||||
'RO', // Romania
|
||||
'SG', // Singapore
|
||||
'SK', // Slovakia
|
||||
'SI', // Slovenia
|
||||
'ES', // Spain
|
||||
|
@ -147,6 +149,7 @@ return array(
|
|||
'CZK', // Czech Koruna
|
||||
'DKK', // Danish Krone
|
||||
'EUR', // Euro
|
||||
'HKD', // Hong Kong Dollar
|
||||
'GBP', // British Pound Sterling
|
||||
'HUF', // Hungarian Forint
|
||||
'ILS', // Israeli New Shekel
|
||||
|
@ -156,6 +159,7 @@ return array(
|
|||
'NZD', // New Zealand Dollar
|
||||
'PHP', // Philippine Peso
|
||||
'PLN', // Polish Zloty
|
||||
'SGD', // Singapur-Dollar
|
||||
'SEK', // Swedish Krona
|
||||
'THB', // Thai Baht
|
||||
'TWD', // New Taiwan Dollar
|
||||
|
|
|
@ -43,7 +43,16 @@ class LocalAlternativePaymentMethodsModule implements ServiceModule, ExtendingMo
|
|||
* {@inheritDoc}
|
||||
*/
|
||||
public function run( ContainerInterface $c ): bool {
|
||||
// When Local APMs are disabled, none of the following hooks are needed.
|
||||
if ( ! $this->should_add_local_apm_gateways( $c ) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* The "woocommerce_payment_gateways" filter is responsible for ADDING
|
||||
* custom payment gateways to WooCommerce. Here, we add all the local
|
||||
* APM gateways to the filtered list, so they become available later on.
|
||||
*/
|
||||
add_filter(
|
||||
'woocommerce_payment_gateways',
|
||||
/**
|
||||
|
@ -52,15 +61,6 @@ class LocalAlternativePaymentMethodsModule implements ServiceModule, ExtendingMo
|
|||
* @psalm-suppress MissingClosureParamType
|
||||
*/
|
||||
function ( $methods ) use ( $c ) {
|
||||
if ( ! self::should_add_local_apm_gateways( $c ) ) {
|
||||
return $methods;
|
||||
}
|
||||
|
||||
$is_connected = $c->get( 'settings.flag.is-connected' );
|
||||
if ( ! $is_connected ) {
|
||||
return $methods;
|
||||
}
|
||||
|
||||
if ( ! is_array( $methods ) ) {
|
||||
return $methods;
|
||||
}
|
||||
|
@ -74,6 +74,10 @@ class LocalAlternativePaymentMethodsModule implements ServiceModule, ExtendingMo
|
|||
}
|
||||
);
|
||||
|
||||
/**
|
||||
* Filters the "available gateways" list by REMOVING gateways that
|
||||
* are not available for the current customer.
|
||||
*/
|
||||
add_filter(
|
||||
'woocommerce_available_payment_gateways',
|
||||
/**
|
||||
|
@ -82,29 +86,22 @@ class LocalAlternativePaymentMethodsModule implements ServiceModule, ExtendingMo
|
|||
* @psalm-suppress MissingClosureParamType
|
||||
*/
|
||||
function ( $methods ) use ( $c ) {
|
||||
if ( ! self::should_add_local_apm_gateways( $c ) ) {
|
||||
return $methods;
|
||||
}
|
||||
if ( ! is_array( $methods ) ) {
|
||||
if ( ! is_array( $methods ) || is_admin() || empty( WC()->customer ) ) {
|
||||
// Don't restrict the gateway list on wp-admin or when no customer is known.
|
||||
return $methods;
|
||||
}
|
||||
|
||||
if ( ! is_admin() ) {
|
||||
if ( ! isset( WC()->customer ) ) {
|
||||
return $methods;
|
||||
}
|
||||
$payment_methods = $c->get( 'ppcp-local-apms.payment-methods' );
|
||||
$customer_country = WC()->customer->get_billing_country() ?: WC()->customer->get_shipping_country();
|
||||
$site_currency = get_woocommerce_currency();
|
||||
|
||||
$customer_country = WC()->customer->get_billing_country() ?: WC()->customer->get_shipping_country();
|
||||
$site_currency = get_woocommerce_currency();
|
||||
// Remove unsupported gateways from the customer's payment options.
|
||||
foreach ( $payment_methods as $payment_method ) {
|
||||
$is_currency_supported = in_array( $site_currency, $payment_method['currencies'], true );
|
||||
$is_country_supported = in_array( $customer_country, $payment_method['countries'], true );
|
||||
|
||||
$payment_methods = $c->get( 'ppcp-local-apms.payment-methods' );
|
||||
foreach ( $payment_methods as $payment_method ) {
|
||||
if (
|
||||
! in_array( $customer_country, $payment_method['countries'], true )
|
||||
|| ! in_array( $site_currency, $payment_method['currencies'], true )
|
||||
) {
|
||||
unset( $methods[ $payment_method['id'] ] );
|
||||
}
|
||||
if ( ! $is_currency_supported || ! $is_country_supported ) {
|
||||
unset( $methods[ $payment_method['id'] ] );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -112,12 +109,15 @@ class LocalAlternativePaymentMethodsModule implements ServiceModule, ExtendingMo
|
|||
}
|
||||
);
|
||||
|
||||
/**
|
||||
* Adds all local APM gateways in the "payment_method_type" block registry
|
||||
* to make the payment methods available in the Block Checkout.
|
||||
*
|
||||
* @see IntegrationRegistry::initialize
|
||||
*/
|
||||
add_action(
|
||||
'woocommerce_blocks_payment_method_type_registration',
|
||||
function( PaymentMethodRegistry $payment_method_registry ) use ( $c ): void {
|
||||
if ( ! self::should_add_local_apm_gateways( $c ) ) {
|
||||
return;
|
||||
}
|
||||
$payment_methods = $c->get( 'ppcp-local-apms.payment-methods' );
|
||||
foreach ( $payment_methods as $key => $value ) {
|
||||
$payment_method_registry->register( $c->get( 'ppcp-local-apms.' . $key . '.payment-method' ) );
|
||||
|
@ -128,9 +128,6 @@ class LocalAlternativePaymentMethodsModule implements ServiceModule, ExtendingMo
|
|||
add_filter(
|
||||
'woocommerce_paypal_payments_localized_script_data',
|
||||
function ( array $data ) use ( $c ) {
|
||||
if ( ! self::should_add_local_apm_gateways( $c ) ) {
|
||||
return $data;
|
||||
}
|
||||
$payment_methods = $c->get( 'ppcp-local-apms.payment-methods' );
|
||||
|
||||
$default_disable_funding = $data['url_params']['disable-funding'] ?? '';
|
||||
|
@ -149,9 +146,6 @@ class LocalAlternativePaymentMethodsModule implements ServiceModule, ExtendingMo
|
|||
* @psalm-suppress MissingClosureParamType
|
||||
*/
|
||||
function( $order_id ) use ( $c ) {
|
||||
if ( ! self::should_add_local_apm_gateways( $c ) ) {
|
||||
return;
|
||||
}
|
||||
$order = wc_get_order( $order_id );
|
||||
if ( ! $order instanceof WC_Order ) {
|
||||
return;
|
||||
|
@ -184,9 +178,6 @@ class LocalAlternativePaymentMethodsModule implements ServiceModule, ExtendingMo
|
|||
add_action(
|
||||
'woocommerce_paypal_payments_payment_capture_completed_webhook_handler',
|
||||
function( WC_Order $wc_order, string $order_id ) use ( $c ) {
|
||||
if ( ! self::should_add_local_apm_gateways( $c ) ) {
|
||||
return;
|
||||
}
|
||||
$payment_methods = $c->get( 'ppcp-local-apms.payment-methods' );
|
||||
if (
|
||||
! $this->is_local_apm( $wc_order->get_payment_method(), $payment_methods )
|
||||
|
@ -229,12 +220,35 @@ class LocalAlternativePaymentMethodsModule implements ServiceModule, ExtendingMo
|
|||
* @param ContainerInterface $container Container.
|
||||
* @return bool
|
||||
*/
|
||||
private function should_add_local_apm_gateways( ContainerInterface $container ): bool {
|
||||
private function should_add_local_apm_gateways( ContainerInterface $container ) : bool {
|
||||
// Merchant onboarding must be completed.
|
||||
$is_connected = $container->get( 'settings.flag.is-connected' );
|
||||
if ( ! $is_connected ) {
|
||||
/**
|
||||
* When the merchant is _not_ connected yet, we still need to
|
||||
* register the APM gateways in one case:
|
||||
*
|
||||
* During the authentication process (which happens via a REST call)
|
||||
* the gateways need to be present, so they can be correctly
|
||||
* pre-configured for new merchants.
|
||||
*
|
||||
* TODO is there a cleaner solution for this?
|
||||
*/
|
||||
// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
|
||||
$request_uri = wp_unslash( $_SERVER['REQUEST_URI'] ?? '' );
|
||||
|
||||
return str_contains( $request_uri, '/wp-json/wc/' );
|
||||
}
|
||||
|
||||
// The general plugin functionality must be enabled.
|
||||
$settings = $container->get( 'wcgateway.settings' );
|
||||
assert( $settings instanceof Settings );
|
||||
return $settings->has( 'enabled' )
|
||||
&& $settings->get( 'enabled' ) === true
|
||||
&& $settings->has( 'allow_local_apm_gateways' )
|
||||
if ( ! $settings->has( 'enabled' ) || ! $settings->get( 'enabled' ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Register APM gateways, when the relevant setting is active.
|
||||
return $settings->has( 'allow_local_apm_gateways' )
|
||||
&& $settings->get( 'allow_local_apm_gateways' ) === true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -82,3 +82,85 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Disabled state styling.
|
||||
.ppcp--method-item--disabled {
|
||||
position: relative;
|
||||
|
||||
// Apply grayscale and disable interactions.
|
||||
.ppcp--method-inner {
|
||||
opacity: 0.7;
|
||||
filter: grayscale(1);
|
||||
pointer-events: none;
|
||||
transition: filter 0.2s ease;
|
||||
}
|
||||
|
||||
// Override text colors.
|
||||
.ppcp--method-title {
|
||||
color: $color-gray-700 !important;
|
||||
}
|
||||
|
||||
.ppcp--method-description p {
|
||||
color: $color-gray-500 !important;
|
||||
}
|
||||
|
||||
.ppcp--method-disabled-message {
|
||||
opacity: 0;
|
||||
transform: translateY(-5px);
|
||||
transition: opacity 0.2s ease, transform 0.2s ease;
|
||||
}
|
||||
|
||||
// Style all buttons and toggle controls.
|
||||
.components-button,
|
||||
.components-form-toggle {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
// Hover state - only blur the inner content.
|
||||
&:hover {
|
||||
.ppcp--method-inner {
|
||||
filter: blur(2px) grayscale(1);
|
||||
}
|
||||
|
||||
.ppcp--method-disabled-message {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Disabled overlay.
|
||||
.ppcp--method-disabled-overlay {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background: rgba($color-white, 0.4);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
z-index: 50;
|
||||
border-radius: var(--container-border-radius);
|
||||
pointer-events: auto;
|
||||
opacity: 0;
|
||||
transition: opacity 0.2s ease;
|
||||
}
|
||||
|
||||
.ppcp--method-item--disabled:hover .ppcp--method-disabled-overlay {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.ppcp--method-disabled-message {
|
||||
padding: 14px 18px;
|
||||
text-align: center;
|
||||
@include font(13, 20, 500);
|
||||
color: $color-text-tertiary;
|
||||
position: relative;
|
||||
z-index: 51;
|
||||
border: none;
|
||||
|
||||
a {
|
||||
text-decoration: none;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,6 +11,8 @@ const PaymentMethodItemBlock = ( {
|
|||
onTriggerModal,
|
||||
onSelect,
|
||||
isSelected,
|
||||
isDisabled,
|
||||
disabledMessage,
|
||||
} ) => {
|
||||
const { activeHighlight, setActiveHighlight } = useActiveHighlight();
|
||||
const isHighlighted = activeHighlight === paymentMethod.id;
|
||||
|
@ -31,9 +33,16 @@ const PaymentMethodItemBlock = ( {
|
|||
id={ paymentMethod.id }
|
||||
className={ `ppcp--method-item ${
|
||||
isHighlighted ? 'ppcp-highlight' : ''
|
||||
}` }
|
||||
} ${ isDisabled ? 'ppcp--method-item--disabled' : '' }` }
|
||||
separatorAndGap={ false }
|
||||
>
|
||||
{ isDisabled && (
|
||||
<div className="ppcp--method-disabled-overlay">
|
||||
<p className="ppcp--method-disabled-message">
|
||||
{ disabledMessage }
|
||||
</p>
|
||||
</div>
|
||||
) }
|
||||
<div className="ppcp--method-inner">
|
||||
<div className="ppcp--method-title-wrapper">
|
||||
{ paymentMethod?.icon && (
|
||||
|
|
|
@ -19,12 +19,14 @@ const PaymentMethodsBlock = ( { paymentMethods = [], onTriggerModal } ) => {
|
|||
<SettingsBlock className="ppcp--grid ppcp-r-settings-block__payment-methods">
|
||||
{ paymentMethods
|
||||
// Remove empty/invalid payment method entries.
|
||||
.filter( ( m ) => m.id )
|
||||
.filter( ( m ) => m && m.id )
|
||||
.map( ( paymentMethod ) => (
|
||||
<PaymentMethodItemBlock
|
||||
key={ paymentMethod.id }
|
||||
paymentMethod={ paymentMethod }
|
||||
isSelected={ paymentMethod.enabled }
|
||||
isDisabled={ paymentMethod.isDisabled }
|
||||
disabledMessage={ paymentMethod.disabledMessage }
|
||||
onSelect={ ( checked ) =>
|
||||
handleSelect( paymentMethod.id, checked )
|
||||
}
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
import { createInterpolateElement } from '@wordpress/element';
|
||||
import { __ } from '@wordpress/i18n';
|
||||
import { scrollAndHighlight } from '../../../../../utils/scrollAndHighlight';
|
||||
|
||||
/**
|
||||
* Component to display a payment method dependency message
|
||||
*
|
||||
* @param {Object} props - Component props
|
||||
* @param {string} props.parentId - ID of the parent payment method
|
||||
* @param {string} props.parentName - Display name of the parent payment method
|
||||
* @return {JSX.Element} The formatted message with link
|
||||
*/
|
||||
const DependencyMessage = ( { parentId, parentName } ) => {
|
||||
// Using WordPress createInterpolateElement with proper React elements
|
||||
return createInterpolateElement(
|
||||
/* translators: %s: payment method name */
|
||||
__(
|
||||
'This payment method requires <methodLink /> to be enabled.',
|
||||
'woocommerce-paypal-payments'
|
||||
),
|
||||
{
|
||||
methodLink: (
|
||||
<strong>
|
||||
<a
|
||||
href="#"
|
||||
onClick={ ( e ) => {
|
||||
e.preventDefault();
|
||||
scrollAndHighlight( parentId );
|
||||
} }
|
||||
>
|
||||
{ parentName }
|
||||
</a>
|
||||
</strong>
|
||||
),
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
export default DependencyMessage;
|
|
@ -0,0 +1,71 @@
|
|||
import SettingsCard from '../../../../ReusableComponents/SettingsCard';
|
||||
import { PaymentMethodsBlock } from '../../../../ReusableComponents/SettingsBlocks';
|
||||
import usePaymentDependencyState from '../../../../../hooks/usePaymentDependencyState';
|
||||
import DependencyMessage from './DependencyMessage';
|
||||
|
||||
/**
|
||||
* Renders a payment method card with dependency handling
|
||||
*
|
||||
* @param {Object} props - Component props
|
||||
* @param {string} props.id - Unique identifier for the card
|
||||
* @param {string} props.title - Title of the payment method card
|
||||
* @param {string} props.description - Description of the payment method
|
||||
* @param {string} props.icon - Icon path for the payment method
|
||||
* @param {Array} props.methods - List of payment methods to display
|
||||
* @param {Object} props.methodsMap - Map of all payment methods by ID
|
||||
* @param {Function} props.onTriggerModal - Callback when a method is clicked
|
||||
* @param {boolean} props.isDisabled - Whether the entire card is disabled
|
||||
* @param {(string|JSX.Element)} props.disabledMessage - Message to show when disabled
|
||||
* @return {JSX.Element} The rendered component
|
||||
*/
|
||||
const PaymentMethodCard = ( {
|
||||
id,
|
||||
title,
|
||||
description,
|
||||
icon,
|
||||
methods,
|
||||
methodsMap = {},
|
||||
onTriggerModal,
|
||||
isDisabled = false,
|
||||
disabledMessage,
|
||||
} ) => {
|
||||
const dependencyState = usePaymentDependencyState( methods, methodsMap );
|
||||
|
||||
return (
|
||||
<SettingsCard
|
||||
id={ id }
|
||||
title={ title }
|
||||
description={ description }
|
||||
icon={ icon }
|
||||
contentContainer={ false }
|
||||
>
|
||||
<PaymentMethodsBlock
|
||||
paymentMethods={ methods.map( ( method ) => {
|
||||
const dependency = dependencyState[ method.id ];
|
||||
|
||||
const dependencyMessage = dependency ? (
|
||||
<DependencyMessage
|
||||
parentId={ dependency.parentId }
|
||||
parentName={ dependency.parentName }
|
||||
/>
|
||||
) : null;
|
||||
|
||||
return {
|
||||
...method,
|
||||
isDisabled:
|
||||
method.isDisabled ||
|
||||
isDisabled ||
|
||||
Boolean( dependency?.isDisabled ),
|
||||
disabledMessage:
|
||||
method.disabledMessage ||
|
||||
dependencyMessage ||
|
||||
disabledMessage,
|
||||
};
|
||||
} ) }
|
||||
onTriggerModal={ onTriggerModal }
|
||||
/>
|
||||
</SettingsCard>
|
||||
);
|
||||
};
|
||||
|
||||
export default PaymentMethodCard;
|
|
@ -1,17 +1,23 @@
|
|||
import { __ } from '@wordpress/i18n';
|
||||
import { useCallback } from '@wordpress/element';
|
||||
|
||||
import SettingsCard from '../../../ReusableComponents/SettingsCard';
|
||||
import { PaymentMethodsBlock } from '../../../ReusableComponents/SettingsBlocks';
|
||||
import { CommonHooks, OnboardingHooks, PaymentHooks } from '../../../../data';
|
||||
import { useActiveModal } from '../../../../data/common/hooks';
|
||||
import Modal from '../Components/Payment/Modal';
|
||||
import PaymentMethodCard from '../Components/Payment/PaymentMethodCard';
|
||||
|
||||
const TabPaymentMethods = () => {
|
||||
const methods = PaymentHooks.usePaymentMethods();
|
||||
const { setPersistent, changePaymentSettings } = PaymentHooks.useStore();
|
||||
const store = PaymentHooks.useStore();
|
||||
const { setPersistent, changePaymentSettings } = store;
|
||||
const { activeModal, setActiveModal } = useActiveModal();
|
||||
|
||||
// Get all methods as a map for dependency checking
|
||||
const methodsMap = {};
|
||||
methods.all.forEach( ( method ) => {
|
||||
methodsMap[ method.id ] = method;
|
||||
} );
|
||||
|
||||
const getActiveMethod = () => {
|
||||
if ( ! activeModal ) {
|
||||
return null;
|
||||
|
@ -60,6 +66,7 @@ const TabPaymentMethods = () => {
|
|||
icon="icon-checkout-standard.svg"
|
||||
methods={ methods.paypal }
|
||||
onTriggerModal={ setActiveModal }
|
||||
methodsMap={ methodsMap }
|
||||
/>
|
||||
{ merchant.isBusinessSeller && canUseCardPayments && (
|
||||
<PaymentMethodCard
|
||||
|
@ -75,6 +82,7 @@ const TabPaymentMethods = () => {
|
|||
icon="icon-checkout-online-methods.svg"
|
||||
methods={ methods.cardPayment }
|
||||
onTriggerModal={ setActiveModal }
|
||||
methodsMap={ methodsMap }
|
||||
/>
|
||||
) }
|
||||
<PaymentMethodCard
|
||||
|
@ -90,6 +98,7 @@ const TabPaymentMethods = () => {
|
|||
icon="icon-checkout-alternative-methods.svg"
|
||||
methods={ methods.apm }
|
||||
onTriggerModal={ setActiveModal }
|
||||
methodsMap={ methodsMap }
|
||||
/>
|
||||
|
||||
{ activeModal && (
|
||||
|
@ -104,25 +113,3 @@ const TabPaymentMethods = () => {
|
|||
};
|
||||
|
||||
export default TabPaymentMethods;
|
||||
|
||||
const PaymentMethodCard = ( {
|
||||
id,
|
||||
title,
|
||||
description,
|
||||
icon,
|
||||
methods,
|
||||
onTriggerModal,
|
||||
} ) => (
|
||||
<SettingsCard
|
||||
id={ id }
|
||||
title={ title }
|
||||
description={ description }
|
||||
icon={ icon }
|
||||
contentContainer={ false }
|
||||
>
|
||||
<PaymentMethodsBlock
|
||||
paymentMethods={ methods }
|
||||
onTriggerModal={ onTriggerModal }
|
||||
/>
|
||||
</SettingsCard>
|
||||
);
|
||||
|
|
|
@ -7,6 +7,8 @@
|
|||
export default {
|
||||
// Transient data.
|
||||
SET_TRANSIENT: 'PAYMENT:SET_TRANSIENT',
|
||||
SET_DISABLED_BY_DEPENDENCY: 'PAYMENT:SET_DISABLED_BY_DEPENDENCY',
|
||||
RESTORE_DEPENDENCY_STATE: 'PAYMENT:RESTORE_DEPENDENCY_STATE',
|
||||
|
||||
// Persistent data.
|
||||
SET_PERSISTENT: 'PAYMENT:SET_PERSISTENT',
|
||||
|
|
|
@ -7,6 +7,7 @@ import * as actions from './actions';
|
|||
import * as hooks from './hooks';
|
||||
import * as resolvers from './resolvers';
|
||||
import { initTodoSync } from '../sync/todo-state-sync';
|
||||
import { initPaymentDependencySync } from '../sync/payment-methods-sync';
|
||||
|
||||
/**
|
||||
* Initializes and registers the settings store with WordPress data layer.
|
||||
|
@ -24,9 +25,12 @@ export const initStore = () => {
|
|||
|
||||
register( store );
|
||||
|
||||
// Initialize todo sync after store registration. Potentially should be moved elsewhere.
|
||||
// Initialize todo sync after store registration.
|
||||
initTodoSync();
|
||||
|
||||
// Initialize payment method dependency sync.
|
||||
initPaymentDependencySync();
|
||||
|
||||
return Boolean( wp.data.select( STORE_NAME ) );
|
||||
};
|
||||
|
||||
|
|
|
@ -88,6 +88,56 @@ const reducer = createReducer( defaultTransient, defaultPersistent, {
|
|||
|
||||
[ ACTION_TYPES.HYDRATE ]: ( state, payload ) =>
|
||||
changePersistent( state, payload.data ),
|
||||
|
||||
[ ACTION_TYPES.SET_DISABLED_BY_DEPENDENCY ]: ( state, payload ) => {
|
||||
const { methodId } = payload;
|
||||
const method = state.data[ methodId ];
|
||||
|
||||
if ( ! method ) {
|
||||
return state;
|
||||
}
|
||||
|
||||
// Create a new state with the method disabled due to dependency
|
||||
const updatedData = {
|
||||
...state.data,
|
||||
[ methodId ]: {
|
||||
...method,
|
||||
enabled: false,
|
||||
_disabledByDependency: true,
|
||||
_originalState: method.enabled,
|
||||
},
|
||||
};
|
||||
|
||||
return {
|
||||
...state,
|
||||
data: updatedData,
|
||||
};
|
||||
},
|
||||
|
||||
[ ACTION_TYPES.RESTORE_DEPENDENCY_STATE ]: ( state, payload ) => {
|
||||
const { methodId } = payload;
|
||||
const method = state.data[ methodId ];
|
||||
|
||||
if ( ! method || ! method._disabledByDependency ) {
|
||||
return state;
|
||||
}
|
||||
|
||||
// Restore the method to its original state
|
||||
const updatedData = {
|
||||
...state.data,
|
||||
[ methodId ]: {
|
||||
...method,
|
||||
enabled: method._originalState === true,
|
||||
_disabledByDependency: false,
|
||||
_originalState: undefined,
|
||||
},
|
||||
};
|
||||
|
||||
return {
|
||||
...state,
|
||||
data: updatedData,
|
||||
};
|
||||
},
|
||||
} );
|
||||
|
||||
export default reducer;
|
||||
|
|
|
@ -0,0 +1,126 @@
|
|||
import { subscribe, select } from '@wordpress/data';
|
||||
|
||||
// Store name
|
||||
const PAYMENT_STORE = 'wc/paypal/payment';
|
||||
|
||||
// Track original states of dependent methods
|
||||
const originalStates = {};
|
||||
|
||||
/**
|
||||
* Initialize payment method dependency synchronization
|
||||
*/
|
||||
export const initPaymentDependencySync = () => {
|
||||
let previousPaymentState = null;
|
||||
let isProcessing = false;
|
||||
|
||||
const unsubscribe = subscribe( () => {
|
||||
if ( isProcessing ) {
|
||||
return;
|
||||
}
|
||||
|
||||
isProcessing = true;
|
||||
|
||||
try {
|
||||
const paymentHooks = select( PAYMENT_STORE );
|
||||
if ( ! paymentHooks ) {
|
||||
isProcessing = false;
|
||||
return;
|
||||
}
|
||||
|
||||
const methods = paymentHooks.persistentData();
|
||||
if ( ! methods ) {
|
||||
isProcessing = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if ( ! previousPaymentState ) {
|
||||
previousPaymentState = { ...methods };
|
||||
isProcessing = false;
|
||||
return;
|
||||
}
|
||||
|
||||
const changedMethods = Object.keys( methods )
|
||||
.filter(
|
||||
( key ) =>
|
||||
key !== '__meta' &&
|
||||
methods[ key ] &&
|
||||
previousPaymentState[ key ]
|
||||
)
|
||||
.filter(
|
||||
( methodId ) =>
|
||||
methods[ methodId ].enabled !==
|
||||
previousPaymentState[ methodId ].enabled
|
||||
);
|
||||
|
||||
if ( changedMethods.length > 0 ) {
|
||||
changedMethods.forEach( ( changedId ) => {
|
||||
const isNowEnabled = methods[ changedId ].enabled;
|
||||
|
||||
const dependents = Object.entries( methods )
|
||||
.filter(
|
||||
( [ key, method ] ) =>
|
||||
key !== '__meta' &&
|
||||
method &&
|
||||
method.depends_on &&
|
||||
method.depends_on.includes( changedId )
|
||||
)
|
||||
.map( ( [ key ] ) => key );
|
||||
|
||||
if ( dependents.length > 0 ) {
|
||||
if ( ! isNowEnabled ) {
|
||||
handleDisableDependents( dependents, methods );
|
||||
} else {
|
||||
handleRestoreDependents( dependents, methods );
|
||||
}
|
||||
}
|
||||
} );
|
||||
}
|
||||
|
||||
previousPaymentState = { ...methods };
|
||||
} catch ( error ) {
|
||||
// Keep error handling without the console.error
|
||||
} finally {
|
||||
isProcessing = false;
|
||||
}
|
||||
} );
|
||||
|
||||
return unsubscribe;
|
||||
};
|
||||
|
||||
const handleDisableDependents = ( dependentIds, methods ) => {
|
||||
dependentIds.forEach( ( methodId ) => {
|
||||
if ( methods[ methodId ] ) {
|
||||
if ( ! ( methodId in originalStates ) ) {
|
||||
originalStates[ methodId ] = methods[ methodId ].enabled;
|
||||
}
|
||||
methods[ methodId ].enabled = false;
|
||||
methods[ methodId ].isDisabled = true;
|
||||
}
|
||||
} );
|
||||
};
|
||||
|
||||
const handleRestoreDependents = ( dependentIds, methods ) => {
|
||||
dependentIds.forEach( ( methodId ) => {
|
||||
if (
|
||||
methods[ methodId ] &&
|
||||
methodId in originalStates &&
|
||||
checkAllDependenciesSatisfied( methodId, methods )
|
||||
) {
|
||||
methods[ methodId ].enabled = originalStates[ methodId ];
|
||||
methods[ methodId ].isDisabled = false;
|
||||
delete originalStates[ methodId ];
|
||||
}
|
||||
} );
|
||||
};
|
||||
|
||||
const checkAllDependenciesSatisfied = ( methodId, methods ) => {
|
||||
const method = methods[ methodId ];
|
||||
if ( ! method || ! method.depends_on ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return ! method.depends_on.some( ( parentId ) => {
|
||||
const parent = methods[ parentId ];
|
||||
return ! parent || parent.enabled === false;
|
||||
} );
|
||||
};
|
|
@ -0,0 +1,81 @@
|
|||
import { useSelect } from '@wordpress/data';
|
||||
|
||||
/**
|
||||
* Gets the display name for a parent payment method
|
||||
*
|
||||
* @param {string} parentId - ID of the parent payment method
|
||||
* @param {Object} methodsMap - Map of all payment methods by ID
|
||||
* @return {string} The display name to use for the parent method
|
||||
*/
|
||||
const getParentMethodName = ( parentId, methodsMap ) => {
|
||||
const parentMethod = methodsMap[ parentId ];
|
||||
return parentMethod
|
||||
? parentMethod.itemTitle || parentMethod.title || ''
|
||||
: '';
|
||||
};
|
||||
|
||||
/**
|
||||
* Finds disabled parent dependencies for a method
|
||||
*
|
||||
* @param {Object} method - The payment method to check
|
||||
* @param {Object} methodsMap - Map of all payment methods by ID
|
||||
* @return {Array} List of disabled parent IDs, empty if none
|
||||
*/
|
||||
const findDisabledParents = ( method, methodsMap ) => {
|
||||
if ( ! method.depends_on?.length && ! method._disabledByDependency ) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const parents = method.depends_on || [];
|
||||
|
||||
return parents.filter( ( parentId ) => {
|
||||
const parent = methodsMap[ parentId ];
|
||||
return parent && ! parent.enabled;
|
||||
} );
|
||||
};
|
||||
|
||||
/**
|
||||
* Custom hook to handle payment method dependencies
|
||||
*
|
||||
* @param {Array} methods - List of payment methods
|
||||
* @param {Object} methodsMap - Map of payment methods by ID
|
||||
* @return {Object} Dependency state object with methods that should be disabled
|
||||
*/
|
||||
const usePaymentDependencyState = ( methods, methodsMap ) => {
|
||||
return useSelect(
|
||||
( select ) => {
|
||||
const paymentStore = select( 'wc/paypal/payment' );
|
||||
if ( ! paymentStore ) {
|
||||
return {};
|
||||
}
|
||||
|
||||
const result = {};
|
||||
|
||||
methods.forEach( ( method ) => {
|
||||
const disabledParents = findDisabledParents(
|
||||
method,
|
||||
methodsMap
|
||||
);
|
||||
|
||||
if ( disabledParents.length > 0 ) {
|
||||
const parentId = disabledParents[ 0 ];
|
||||
const parentName = getParentMethodName(
|
||||
parentId,
|
||||
methodsMap
|
||||
);
|
||||
|
||||
result[ method.id ] = {
|
||||
isDisabled: true,
|
||||
parentId,
|
||||
parentName,
|
||||
};
|
||||
}
|
||||
} );
|
||||
|
||||
return result;
|
||||
},
|
||||
[ methods, methodsMap ]
|
||||
);
|
||||
};
|
||||
|
||||
export default usePaymentDependencyState;
|
|
@ -0,0 +1,49 @@
|
|||
/**
|
||||
* Scroll to a specific element and highlight it
|
||||
*
|
||||
* @param {string} elementId - ID of the element to scroll to
|
||||
* @param {boolean} [highlight=true] - Whether to highlight the element
|
||||
* @return {Promise} - Resolves when scroll and highlight are complete
|
||||
*/
|
||||
export const scrollAndHighlight = ( elementId, highlight = true ) => {
|
||||
return new Promise( ( resolve ) => {
|
||||
const scrollTarget = document.getElementById( elementId );
|
||||
|
||||
if ( scrollTarget ) {
|
||||
const navContainer = document.querySelector(
|
||||
'.ppcp-r-navigation-container'
|
||||
);
|
||||
const navHeight = navContainer ? navContainer.offsetHeight : 0;
|
||||
|
||||
// Get the current scroll position and element's position relative to viewport
|
||||
const rect = scrollTarget.getBoundingClientRect();
|
||||
|
||||
// Calculate the final position with offset
|
||||
const scrollPosition =
|
||||
rect.top + window.scrollY - ( navHeight + 55 );
|
||||
|
||||
window.scrollTo( {
|
||||
top: scrollPosition,
|
||||
behavior: 'smooth',
|
||||
} );
|
||||
|
||||
// Add highlight if requested
|
||||
if ( highlight ) {
|
||||
scrollTarget.classList.add( 'ppcp-highlight' );
|
||||
|
||||
// Remove highlight after animation
|
||||
setTimeout( () => {
|
||||
scrollTarget.classList.remove( 'ppcp-highlight' );
|
||||
}, 2000 );
|
||||
}
|
||||
|
||||
// Resolve after scroll animation
|
||||
setTimeout( resolve, 300 );
|
||||
} else {
|
||||
console.error(
|
||||
`Failed to scroll: Element with ID "${ elementId }" not found`
|
||||
);
|
||||
resolve();
|
||||
}
|
||||
} );
|
||||
};
|
|
@ -7,6 +7,8 @@ export const TAB_IDS = {
|
|||
PAY_LATER_MESSAGING: 'tab-panel-0-pay-later-messaging',
|
||||
};
|
||||
|
||||
import { scrollAndHighlight } from './scrollAndHighlight';
|
||||
|
||||
/**
|
||||
* Select a tab by simulating a click event and scroll to specified element,
|
||||
* accounting for navigation container height
|
||||
|
@ -23,40 +25,8 @@ export const selectTab = ( tabId, scrollToId ) => {
|
|||
if ( tab ) {
|
||||
tab.click();
|
||||
setTimeout( () => {
|
||||
const scrollTarget = scrollToId
|
||||
? document.getElementById( scrollToId )
|
||||
: document.getElementById( 'ppcp-settings-container' );
|
||||
|
||||
if ( scrollTarget ) {
|
||||
const navContainer = document.querySelector(
|
||||
'.ppcp-r-navigation-container'
|
||||
);
|
||||
const navHeight = navContainer
|
||||
? navContainer.offsetHeight
|
||||
: 0;
|
||||
|
||||
// Get the current scroll position and element's position relative to viewport
|
||||
const rect = scrollTarget.getBoundingClientRect();
|
||||
|
||||
// Calculate the final position with offset
|
||||
const scrollPosition =
|
||||
rect.top + window.scrollY - ( navHeight + 55 );
|
||||
|
||||
window.scrollTo( {
|
||||
top: scrollPosition,
|
||||
behavior: 'smooth',
|
||||
} );
|
||||
|
||||
// Resolve after scroll animation
|
||||
setTimeout( resolve, 300 );
|
||||
} else {
|
||||
console.error(
|
||||
`Failed to scroll: Element with ID "${
|
||||
scrollToId || 'ppcp-settings-container'
|
||||
}" not found`
|
||||
);
|
||||
resolve();
|
||||
}
|
||||
const targetId = scrollToId || 'ppcp-settings-container';
|
||||
scrollAndHighlight( targetId, false ).then( resolve );
|
||||
}, 100 );
|
||||
} else {
|
||||
console.error(
|
||||
|
|
|
@ -13,6 +13,7 @@ use WooCommerce\PayPalCommerce\ApiClient\Helper\Cache;
|
|||
use WooCommerce\PayPalCommerce\Button\Helper\MessagesApply;
|
||||
use WooCommerce\PayPalCommerce\Settings\Ajax\SwitchSettingsUiEndpoint;
|
||||
use WooCommerce\PayPalCommerce\Settings\Data\Definition\FeaturesDefinition;
|
||||
use WooCommerce\PayPalCommerce\Settings\Data\Definition\PaymentMethodsDependenciesDefinition;
|
||||
use WooCommerce\PayPalCommerce\Settings\Data\GeneralSettings;
|
||||
use WooCommerce\PayPalCommerce\Settings\Data\OnboardingProfile;
|
||||
use WooCommerce\PayPalCommerce\Settings\Data\PaymentSettings;
|
||||
|
@ -50,7 +51,7 @@ use WooCommerce\PayPalCommerce\WcGateway\Helper\Environment;
|
|||
use WooCommerce\PayPalCommerce\WcGateway\Helper\ConnectionState;
|
||||
|
||||
return array(
|
||||
'settings.url' => static function ( ContainerInterface $container ) : string {
|
||||
'settings.url' => static function ( ContainerInterface $container ) : string {
|
||||
/**
|
||||
* The path cannot be false.
|
||||
*
|
||||
|
@ -61,7 +62,7 @@ return array(
|
|||
dirname( realpath( __FILE__ ), 3 ) . '/woocommerce-paypal-payments.php'
|
||||
);
|
||||
},
|
||||
'settings.data.onboarding' => static function ( ContainerInterface $container ) : OnboardingProfile {
|
||||
'settings.data.onboarding' => static function ( ContainerInterface $container ) : OnboardingProfile {
|
||||
$can_use_casual_selling = $container->get( 'settings.casual-selling.eligible' );
|
||||
$can_use_vaulting = $container->has( 'save-payment-methods.eligible' ) && $container->get( 'save-payment-methods.eligible' );
|
||||
$can_use_card_payments = $container->has( 'card-fields.eligible' ) && $container->get( 'card-fields.eligible' );
|
||||
|
@ -81,27 +82,27 @@ return array(
|
|||
$can_use_subscriptions
|
||||
);
|
||||
},
|
||||
'settings.data.general' => static function ( ContainerInterface $container ) : GeneralSettings {
|
||||
'settings.data.general' => static function ( ContainerInterface $container ) : GeneralSettings {
|
||||
return new GeneralSettings(
|
||||
$container->get( 'api.shop.country' ),
|
||||
$container->get( 'api.shop.currency.getter' )->get(),
|
||||
$container->get( 'wcgateway.is-send-only-country' )
|
||||
);
|
||||
},
|
||||
'settings.data.styling' => static function ( ContainerInterface $container ) : StylingSettings {
|
||||
'settings.data.styling' => static function ( ContainerInterface $container ) : StylingSettings {
|
||||
return new StylingSettings(
|
||||
$container->get( 'settings.service.sanitizer' )
|
||||
);
|
||||
},
|
||||
'settings.data.payment' => static function ( ContainerInterface $container ) : PaymentSettings {
|
||||
'settings.data.payment' => static function ( ContainerInterface $container ) : PaymentSettings {
|
||||
return new PaymentSettings();
|
||||
},
|
||||
'settings.data.settings' => static function ( ContainerInterface $container ) : SettingsModel {
|
||||
'settings.data.settings' => static function ( ContainerInterface $container ) : SettingsModel {
|
||||
return new SettingsModel(
|
||||
$container->get( 'settings.service.sanitizer' )
|
||||
);
|
||||
},
|
||||
'settings.data.paylater-messaging' => static function ( ContainerInterface $container ) : array {
|
||||
'settings.data.paylater-messaging' => static function ( ContainerInterface $container ) : array {
|
||||
// TODO: Create an AbstractDataModel wrapper for this configuration!
|
||||
|
||||
$config_factors = $container->get( 'paylater-configurator.factory.config' );
|
||||
|
@ -125,7 +126,7 @@ return array(
|
|||
* (onboarding/connected) and connection-aware environment checks.
|
||||
* This is the preferred solution to check environment and connection state.
|
||||
*/
|
||||
'settings.connection-state' => static function ( ContainerInterface $container ) : ConnectionState {
|
||||
'settings.connection-state' => static function ( ContainerInterface $container ) : ConnectionState {
|
||||
$data = $container->get( 'settings.data.general' );
|
||||
assert( $data instanceof GeneralSettings );
|
||||
|
||||
|
@ -134,7 +135,7 @@ return array(
|
|||
|
||||
return new ConnectionState( $is_connected, $environment );
|
||||
},
|
||||
'settings.environment' => static function ( ContainerInterface $container ) : Environment {
|
||||
'settings.environment' => static function ( ContainerInterface $container ) : Environment {
|
||||
// We should remove this service in favor of directly using `settings.connection-state`.
|
||||
$state = $container->get( 'settings.connection-state' );
|
||||
assert( $state instanceof ConnectionState );
|
||||
|
@ -144,7 +145,7 @@ return array(
|
|||
/**
|
||||
* Checks if valid merchant connection details are stored in the DB.
|
||||
*/
|
||||
'settings.flag.is-connected' => static function ( ContainerInterface $container ) : bool {
|
||||
'settings.flag.is-connected' => static function ( ContainerInterface $container ) : bool {
|
||||
/*
|
||||
* This service only resolves the connection status once per request.
|
||||
* We should remove this service in favor of directly using `settings.connection-state`.
|
||||
|
@ -157,7 +158,7 @@ return array(
|
|||
/**
|
||||
* Checks if the merchant is connected to a sandbox environment.
|
||||
*/
|
||||
'settings.flag.is-sandbox' => static function ( ContainerInterface $container ) : bool {
|
||||
'settings.flag.is-sandbox' => static function ( ContainerInterface $container ) : bool {
|
||||
/*
|
||||
* This service only resolves the sandbox flag once per request.
|
||||
* We should remove this service in favor of directly using `settings.connection-state`.
|
||||
|
@ -167,61 +168,61 @@ return array(
|
|||
|
||||
return $state->is_sandbox();
|
||||
},
|
||||
'settings.rest.onboarding' => static function ( ContainerInterface $container ) : OnboardingRestEndpoint {
|
||||
'settings.rest.onboarding' => static function ( ContainerInterface $container ) : OnboardingRestEndpoint {
|
||||
return new OnboardingRestEndpoint( $container->get( 'settings.data.onboarding' ) );
|
||||
},
|
||||
'settings.rest.common' => static function ( ContainerInterface $container ) : CommonRestEndpoint {
|
||||
'settings.rest.common' => static function ( ContainerInterface $container ) : CommonRestEndpoint {
|
||||
return new CommonRestEndpoint( $container->get( 'settings.data.general' ) );
|
||||
},
|
||||
'settings.rest.payment' => static function ( ContainerInterface $container ) : PaymentRestEndpoint {
|
||||
'settings.rest.payment' => static function ( ContainerInterface $container ) : PaymentRestEndpoint {
|
||||
return new PaymentRestEndpoint(
|
||||
$container->get( 'settings.data.payment' ),
|
||||
$container->get( 'settings.data.definition.methods' )
|
||||
);
|
||||
},
|
||||
'settings.rest.styling' => static function ( ContainerInterface $container ) : StylingRestEndpoint {
|
||||
'settings.rest.styling' => static function ( ContainerInterface $container ) : StylingRestEndpoint {
|
||||
return new StylingRestEndpoint(
|
||||
$container->get( 'settings.data.styling' ),
|
||||
$container->get( 'settings.service.sanitizer' )
|
||||
);
|
||||
},
|
||||
'settings.rest.refresh_feature_status' => static function ( ContainerInterface $container ) : RefreshFeatureStatusEndpoint {
|
||||
'settings.rest.refresh_feature_status' => static function ( ContainerInterface $container ) : RefreshFeatureStatusEndpoint {
|
||||
return new RefreshFeatureStatusEndpoint(
|
||||
$container->get( 'wcgateway.settings' ),
|
||||
new Cache( 'ppcp-timeout' ),
|
||||
$container->get( 'woocommerce.logger.woocommerce' )
|
||||
);
|
||||
},
|
||||
'settings.rest.authentication' => static function ( ContainerInterface $container ) : AuthenticationRestEndpoint {
|
||||
'settings.rest.authentication' => static function ( ContainerInterface $container ) : AuthenticationRestEndpoint {
|
||||
return new AuthenticationRestEndpoint(
|
||||
$container->get( 'settings.service.authentication_manager' ),
|
||||
$container->get( 'settings.service.data-manager' )
|
||||
);
|
||||
},
|
||||
'settings.rest.login_link' => static function ( ContainerInterface $container ) : LoginLinkRestEndpoint {
|
||||
'settings.rest.login_link' => static function ( ContainerInterface $container ) : LoginLinkRestEndpoint {
|
||||
return new LoginLinkRestEndpoint(
|
||||
$container->get( 'settings.service.connection-url-generator' ),
|
||||
);
|
||||
},
|
||||
'settings.rest.webhooks' => static function ( ContainerInterface $container ) : WebhookSettingsEndpoint {
|
||||
'settings.rest.webhooks' => static function ( ContainerInterface $container ) : WebhookSettingsEndpoint {
|
||||
return new WebhookSettingsEndpoint(
|
||||
$container->get( 'api.endpoint.webhook' ),
|
||||
$container->get( 'webhook.registrar' ),
|
||||
$container->get( 'webhook.status.simulation' )
|
||||
);
|
||||
},
|
||||
'settings.rest.pay_later_messaging' => static function ( ContainerInterface $container ) : PayLaterMessagingEndpoint {
|
||||
'settings.rest.pay_later_messaging' => static function ( ContainerInterface $container ) : PayLaterMessagingEndpoint {
|
||||
return new PayLaterMessagingEndpoint(
|
||||
$container->get( 'wcgateway.settings' ),
|
||||
$container->get( 'paylater-configurator.endpoint.save-config' )
|
||||
);
|
||||
},
|
||||
'settings.rest.settings' => static function ( ContainerInterface $container ) : SettingsRestEndpoint {
|
||||
'settings.rest.settings' => static function ( ContainerInterface $container ) : SettingsRestEndpoint {
|
||||
return new SettingsRestEndpoint(
|
||||
$container->get( 'settings.data.settings' )
|
||||
);
|
||||
},
|
||||
'settings.casual-selling.supported-countries' => static function ( ContainerInterface $container ) : array {
|
||||
'settings.casual-selling.supported-countries' => static function ( ContainerInterface $container ) : array {
|
||||
return array(
|
||||
'AR',
|
||||
'AU',
|
||||
|
@ -271,13 +272,13 @@ return array(
|
|||
'VN',
|
||||
);
|
||||
},
|
||||
'settings.casual-selling.eligible' => static function ( ContainerInterface $container ) : bool {
|
||||
'settings.casual-selling.eligible' => static function ( ContainerInterface $container ) : bool {
|
||||
$country = $container->get( 'api.shop.country' );
|
||||
$eligible_countries = $container->get( 'settings.casual-selling.supported-countries' );
|
||||
|
||||
return in_array( $country, $eligible_countries, true );
|
||||
},
|
||||
'settings.handler.connection-listener' => static function ( ContainerInterface $container ) : ConnectionListener {
|
||||
'settings.handler.connection-listener' => static function ( ContainerInterface $container ) : ConnectionListener {
|
||||
$page_id = $container->has( 'wcgateway.current-ppcp-settings-page-id' ) ? $container->get( 'wcgateway.current-ppcp-settings-page-id' ) : '';
|
||||
|
||||
return new ConnectionListener(
|
||||
|
@ -288,16 +289,16 @@ return array(
|
|||
$container->get( 'woocommerce.logger.woocommerce' )
|
||||
);
|
||||
},
|
||||
'settings.service.signup-link-cache' => static function ( ContainerInterface $container ) : Cache {
|
||||
'settings.service.signup-link-cache' => static function ( ContainerInterface $container ) : Cache {
|
||||
return new Cache( 'ppcp-paypal-signup-link' );
|
||||
},
|
||||
'settings.service.onboarding-url-manager' => static function ( ContainerInterface $container ) : OnboardingUrlManager {
|
||||
'settings.service.onboarding-url-manager' => static function ( ContainerInterface $container ) : OnboardingUrlManager {
|
||||
return new OnboardingUrlManager(
|
||||
$container->get( 'settings.service.signup-link-cache' ),
|
||||
$container->get( 'woocommerce.logger.woocommerce' )
|
||||
);
|
||||
},
|
||||
'settings.service.connection-url-generator' => static function ( ContainerInterface $container ) : ConnectionUrlGenerator {
|
||||
'settings.service.connection-url-generator' => static function ( ContainerInterface $container ) : ConnectionUrlGenerator {
|
||||
return new ConnectionUrlGenerator(
|
||||
$container->get( 'api.env.endpoint.partner-referrals' ),
|
||||
$container->get( 'api.repository.partner-referrals-data' ),
|
||||
|
@ -305,7 +306,7 @@ return array(
|
|||
$container->get( 'woocommerce.logger.woocommerce' )
|
||||
);
|
||||
},
|
||||
'settings.service.authentication_manager' => static function ( ContainerInterface $container ) : AuthenticationManager {
|
||||
'settings.service.authentication_manager' => static function ( ContainerInterface $container ) : AuthenticationManager {
|
||||
return new AuthenticationManager(
|
||||
$container->get( 'settings.data.general' ),
|
||||
$container->get( 'api.env.paypal-host' ),
|
||||
|
@ -316,10 +317,10 @@ return array(
|
|||
$container->get( 'woocommerce.logger.woocommerce' )
|
||||
);
|
||||
},
|
||||
'settings.service.sanitizer' => static function ( ContainerInterface $container ) : DataSanitizer {
|
||||
'settings.service.sanitizer' => static function ( ContainerInterface $container ) : DataSanitizer {
|
||||
return new DataSanitizer();
|
||||
},
|
||||
'settings.service.data-manager' => static function ( ContainerInterface $container ) : SettingsDataManager {
|
||||
'settings.service.data-manager' => static function ( ContainerInterface $container ) : SettingsDataManager {
|
||||
return new SettingsDataManager(
|
||||
$container->get( 'settings.data.definition.methods' ),
|
||||
$container->get( 'settings.data.onboarding' ),
|
||||
|
@ -331,7 +332,7 @@ return array(
|
|||
$container->get( 'settings.data.todos' ),
|
||||
);
|
||||
},
|
||||
'settings.ajax.switch_ui' => static function ( ContainerInterface $container ) : SwitchSettingsUiEndpoint {
|
||||
'settings.ajax.switch_ui' => static function ( ContainerInterface $container ) : SwitchSettingsUiEndpoint {
|
||||
return new SwitchSettingsUiEndpoint(
|
||||
$container->get( 'woocommerce.logger.woocommerce' ),
|
||||
$container->get( 'button.request-data' ),
|
||||
|
@ -339,7 +340,7 @@ return array(
|
|||
$container->get( 'api.merchant_id' ) !== ''
|
||||
);
|
||||
},
|
||||
'settings.rest.todos' => static function ( ContainerInterface $container ) : TodosRestEndpoint {
|
||||
'settings.rest.todos' => static function ( ContainerInterface $container ) : TodosRestEndpoint {
|
||||
return new TodosRestEndpoint(
|
||||
$container->get( 'settings.data.todos' ),
|
||||
$container->get( 'settings.data.definition.todos' ),
|
||||
|
@ -347,22 +348,25 @@ return array(
|
|||
$container->get( 'settings.service.todos_sorting' )
|
||||
);
|
||||
},
|
||||
'settings.data.todos' => static function ( ContainerInterface $container ) : TodosModel {
|
||||
'settings.data.todos' => static function ( ContainerInterface $container ) : TodosModel {
|
||||
return new TodosModel();
|
||||
},
|
||||
'settings.data.definition.todos' => static function ( ContainerInterface $container ) : TodosDefinition {
|
||||
'settings.data.definition.todos' => static function ( ContainerInterface $container ) : TodosDefinition {
|
||||
return new TodosDefinition(
|
||||
$container->get( 'settings.service.todos_eligibilities' ),
|
||||
$container->get( 'settings.data.general' ),
|
||||
$container->get( 'wc-subscriptions.helper' )
|
||||
$container->get( 'settings.data.general' )
|
||||
);
|
||||
},
|
||||
'settings.data.definition.methods' => static function ( ContainerInterface $container ) : PaymentMethodsDefinition {
|
||||
'settings.data.definition.methods' => static function ( ContainerInterface $container ) : PaymentMethodsDefinition {
|
||||
return new PaymentMethodsDefinition(
|
||||
$container->get( 'settings.data.payment' ),
|
||||
$container->get( 'settings.data.definition.method_dependencies' )
|
||||
);
|
||||
},
|
||||
'settings.service.pay_later_status' => static function ( ContainerInterface $container ) : array {
|
||||
'settings.data.definition.method_dependencies' => static function ( ContainerInterface $container ) : PaymentMethodsDependenciesDefinition {
|
||||
return new PaymentMethodsDependenciesDefinition();
|
||||
},
|
||||
'settings.service.pay_later_status' => static function ( ContainerInterface $container ) : array {
|
||||
$pay_later_endpoint = $container->get( 'settings.rest.pay_later_messaging' );
|
||||
$pay_later_settings = $pay_later_endpoint->get_details()->get_data();
|
||||
|
||||
|
@ -383,7 +387,7 @@ return array(
|
|||
'is_enabled_for_any_location' => $is_pay_later_messaging_enabled_for_any_location,
|
||||
);
|
||||
},
|
||||
'settings.service.button_locations' => static function ( ContainerInterface $container ) : array {
|
||||
'settings.service.button_locations' => static function ( ContainerInterface $container ) : array {
|
||||
$styling_endpoint = $container->get( 'settings.rest.styling' );
|
||||
$styling_data = $styling_endpoint->get_details()->get_data()['data'];
|
||||
|
||||
|
@ -393,7 +397,7 @@ return array(
|
|||
'product_enabled' => $styling_data['product']->enabled ?? false,
|
||||
);
|
||||
},
|
||||
'settings.service.gateways_status' => static function ( ContainerInterface $container ) : array {
|
||||
'settings.service.gateways_status' => static function ( ContainerInterface $container ) : array {
|
||||
$payment_endpoint = $container->get( 'settings.rest.payment' );
|
||||
$settings = $payment_endpoint->get_details()->get_data();
|
||||
|
||||
|
@ -404,7 +408,7 @@ return array(
|
|||
'card-button' => $settings['data']['ppcp-card-button-gateway']['enabled'] ?? false,
|
||||
);
|
||||
},
|
||||
'settings.service.merchant_capabilities' => static function ( ContainerInterface $container ) : array {
|
||||
'settings.service.merchant_capabilities' => static function ( ContainerInterface $container ) : array {
|
||||
$features = apply_filters(
|
||||
'woocommerce_paypal_payments_rest_common_merchant_features',
|
||||
array()
|
||||
|
@ -420,7 +424,7 @@ return array(
|
|||
);
|
||||
},
|
||||
|
||||
'settings.service.todos_eligibilities' => static function ( ContainerInterface $container ) : TodosEligibilityService {
|
||||
'settings.service.todos_eligibilities' => static function ( ContainerInterface $container ) : TodosEligibilityService {
|
||||
$pay_later_service = $container->get( 'settings.service.pay_later_status' );
|
||||
$pay_later_statuses = $pay_later_service['statuses'];
|
||||
$is_pay_later_messaging_enabled_for_any_location = $pay_later_service['is_enabled_for_any_location'];
|
||||
|
@ -439,7 +443,6 @@ return array(
|
|||
* 3. $gateways, $pay_later_statuses, $button_locations - Plugin settings (enabled/disabled status).
|
||||
*
|
||||
* @param bool $is_fastlane_eligible - Show if merchant is eligible (ACDC) but hasn't enabled Fastlane gateway.
|
||||
* @param bool $is_card_payment_eligible - Show if merchant is eligible (ACDC) but hasn't enabled card button gateway.
|
||||
* @param bool $is_pay_later_messaging_eligible - Show if Pay Later messaging is enabled for at least one location.
|
||||
* @param bool $is_pay_later_messaging_product_eligible - Show if Pay Later is not enabled anywhere and specifically not on product page.
|
||||
* @param bool $is_pay_later_messaging_cart_eligible - Show if Pay Later is not enabled anywhere and specifically not on cart.
|
||||
|
@ -457,7 +460,6 @@ return array(
|
|||
*/
|
||||
return new TodosEligibilityService(
|
||||
$container->get( 'axo.eligible' ) && $capabilities['acdc'] && ! $gateways['axo'], // Enable Fastlane.
|
||||
$capabilities['acdc'] && ! $gateways['card-button'], // Enable Credit and Debit Cards on your checkout.
|
||||
$is_pay_later_messaging_enabled_for_any_location, // Enable Pay Later messaging.
|
||||
! $is_pay_later_messaging_enabled_for_any_location && ! $pay_later_statuses['product'], // Add Pay Later messaging (Product page).
|
||||
! $is_pay_later_messaging_enabled_for_any_location && ! $pay_later_statuses['cart'], // Add Pay Later messaging (Cart).
|
||||
|
@ -477,7 +479,7 @@ return array(
|
|||
$container->get( 'googlepay.eligible' ) && $capabilities['google_pay'] && ! $gateways['google_pay'],
|
||||
);
|
||||
},
|
||||
'settings.service.todos_sorting' => static function ( ContainerInterface $container ) : TodosSortingAndFilteringService {
|
||||
'settings.service.todos_sorting' => static function ( ContainerInterface $container ) : TodosSortingAndFilteringService {
|
||||
return new TodosSortingAndFilteringService(
|
||||
$container->get( 'settings.data.todos' )
|
||||
);
|
||||
|
|
|
@ -58,7 +58,7 @@ abstract class AbstractDataModel {
|
|||
*/
|
||||
public function load() : void {
|
||||
$saved_data = get_option( static::OPTION_KEY, array() );
|
||||
$filtered_data = array_intersect_key( $saved_data, $this->data );
|
||||
$filtered_data = array_intersect_key( (array) $saved_data, $this->data );
|
||||
$this->data = array_merge( $this->data, $filtered_data );
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<?php
|
||||
/**
|
||||
* PayPal Commerce Todos Definitions
|
||||
* Payment Methods Definitions
|
||||
*
|
||||
* @package WooCommerce\PayPalCommerce\Settings\Data\Definition
|
||||
*/
|
||||
|
@ -40,6 +40,13 @@ class PaymentMethodsDefinition {
|
|||
*/
|
||||
private PaymentSettings $settings;
|
||||
|
||||
/**
|
||||
* Payment method dependencies definition.
|
||||
*
|
||||
* @var PaymentMethodsDependenciesDefinition
|
||||
*/
|
||||
private PaymentMethodsDependenciesDefinition $dependencies_definition;
|
||||
|
||||
/**
|
||||
* List of WooCommerce payment gateways.
|
||||
*
|
||||
|
@ -50,10 +57,15 @@ class PaymentMethodsDefinition {
|
|||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param PaymentSettings $settings Payment methods data model.
|
||||
* @param PaymentSettings $settings Payment methods data model.
|
||||
* @param PaymentMethodsDependenciesDefinition $dependencies_definition Payment dependencies definition.
|
||||
*/
|
||||
public function __construct( PaymentSettings $settings ) {
|
||||
$this->settings = $settings;
|
||||
public function __construct(
|
||||
PaymentSettings $settings,
|
||||
PaymentMethodsDependenciesDefinition $dependencies_definition
|
||||
) {
|
||||
$this->settings = $settings;
|
||||
$this->dependencies_definition = $dependencies_definition;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -73,15 +85,30 @@ class PaymentMethodsDefinition {
|
|||
|
||||
$result = array();
|
||||
foreach ( $all_methods as $method ) {
|
||||
$result[ $method['id'] ] = $this->build_method_definition(
|
||||
$method['id'],
|
||||
$method_id = $method['id'];
|
||||
|
||||
// Add dependency info if applicable.
|
||||
$depends_on = $this->dependencies_definition->get_parent_methods( $method_id );
|
||||
if ( ! empty( $depends_on ) ) {
|
||||
$method['depends_on'] = $depends_on;
|
||||
}
|
||||
|
||||
$result[ $method_id ] = $this->build_method_definition(
|
||||
$method_id,
|
||||
$method['title'],
|
||||
$method['description'],
|
||||
$method['icon'],
|
||||
$method['fields'] ?? array()
|
||||
$method['fields'] ?? array(),
|
||||
$depends_on
|
||||
);
|
||||
}
|
||||
|
||||
// Add dependency maps to metadata.
|
||||
$result['__meta'] = array(
|
||||
'dependencies' => $this->dependencies_definition->get_dependencies(),
|
||||
'dependents' => $this->dependencies_definition->get_dependents_map(),
|
||||
);
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
@ -95,14 +122,15 @@ class PaymentMethodsDefinition {
|
|||
* @param string $icon Admin-side icon of the payment method.
|
||||
* @param array|false $fields Optional. Additional fields to display in the edit modal.
|
||||
* Setting this to false omits all fields.
|
||||
* @param array $depends_on Optional. IDs of payment methods that this depends on.
|
||||
* @return array Payment method definition.
|
||||
*/
|
||||
private function build_method_definition(
|
||||
string $gateway_id,
|
||||
string $title,
|
||||
string $description,
|
||||
string $icon,
|
||||
$fields = array()
|
||||
string $icon, $fields = array(),
|
||||
array $depends_on = array()
|
||||
) : array {
|
||||
$gateway = $this->wc_gateways[ $gateway_id ] ?? null;
|
||||
|
||||
|
@ -119,6 +147,11 @@ class PaymentMethodsDefinition {
|
|||
'itemDescription' => $description,
|
||||
);
|
||||
|
||||
// Add dependency information if provided - ensure it's included directly in the config.
|
||||
if ( ! empty( $depends_on ) ) {
|
||||
$config['depends_on'] = $depends_on;
|
||||
}
|
||||
|
||||
if ( is_array( $fields ) ) {
|
||||
$config['fields'] = array_merge(
|
||||
array(
|
||||
|
|
|
@ -0,0 +1,111 @@
|
|||
<?php
|
||||
/**
|
||||
* Payment Methods Dependencies Definition
|
||||
*
|
||||
* @package WooCommerce\PayPalCommerce\Settings\Data\Definition
|
||||
*/
|
||||
|
||||
declare( strict_types = 1 );
|
||||
|
||||
namespace WooCommerce\PayPalCommerce\Settings\Data\Definition;
|
||||
|
||||
use WooCommerce\PayPalCommerce\Applepay\ApplePayGateway;
|
||||
use WooCommerce\PayPalCommerce\Axo\Gateway\AxoGateway;
|
||||
use WooCommerce\PayPalCommerce\Googlepay\GooglePayGateway;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Gateway\CardButtonGateway;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Gateway\CreditCardGateway;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayPalGateway;
|
||||
use WooCommerce\PayPalCommerce\LocalAlternativePaymentMethods\BancontactGateway;
|
||||
use WooCommerce\PayPalCommerce\LocalAlternativePaymentMethods\BlikGateway;
|
||||
use WooCommerce\PayPalCommerce\LocalAlternativePaymentMethods\EPSGateway;
|
||||
use WooCommerce\PayPalCommerce\LocalAlternativePaymentMethods\IDealGateway;
|
||||
use WooCommerce\PayPalCommerce\LocalAlternativePaymentMethods\MultibancoGateway;
|
||||
use WooCommerce\PayPalCommerce\LocalAlternativePaymentMethods\MyBankGateway;
|
||||
use WooCommerce\PayPalCommerce\LocalAlternativePaymentMethods\P24Gateway;
|
||||
use WooCommerce\PayPalCommerce\LocalAlternativePaymentMethods\TrustlyGateway;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Gateway\OXXO\OXXO;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayUponInvoice\PayUponInvoiceGateway;
|
||||
|
||||
/**
|
||||
* Class PaymentMethodsDependenciesDefinition
|
||||
*
|
||||
* Defines dependency relationships between payment methods.
|
||||
*/
|
||||
class PaymentMethodsDependenciesDefinition {
|
||||
|
||||
/**
|
||||
* Get all payment method dependencies
|
||||
*
|
||||
* Maps dependent method ID => array of parent method IDs.
|
||||
* A dependent method is disabled if ANY of its required parents is disabled.
|
||||
*
|
||||
* @return array The dependency relationships between payment methods
|
||||
*/
|
||||
public function get_dependencies(): array {
|
||||
$dependencies = array(
|
||||
CardButtonGateway::ID => array( PayPalGateway::ID ),
|
||||
CreditCardGateway::ID => array( PayPalGateway::ID ),
|
||||
AxoGateway::ID => array( PayPalGateway::ID, CreditCardGateway::ID ),
|
||||
ApplePayGateway::ID => array( PayPalGateway::ID, CreditCardGateway::ID ),
|
||||
GooglePayGateway::ID => array( PayPalGateway::ID, CreditCardGateway::ID ),
|
||||
BancontactGateway::ID => array( PayPalGateway::ID ),
|
||||
BlikGateway::ID => array( PayPalGateway::ID ),
|
||||
EPSGateway::ID => array( PayPalGateway::ID ),
|
||||
IDealGateway::ID => array( PayPalGateway::ID ),
|
||||
MultibancoGateway::ID => array( PayPalGateway::ID ),
|
||||
MyBankGateway::ID => array( PayPalGateway::ID ),
|
||||
P24Gateway::ID => array( PayPalGateway::ID ),
|
||||
TrustlyGateway::ID => array( PayPalGateway::ID ),
|
||||
PayUponInvoiceGateway::ID => array( PayPalGateway::ID ),
|
||||
OXXO::ID => array( PayPalGateway::ID ),
|
||||
'venmo' => array( PayPalGateway::ID ),
|
||||
'pay-later' => array( PayPalGateway::ID ),
|
||||
);
|
||||
|
||||
return apply_filters(
|
||||
'woocommerce_paypal_payments_payment_method_dependencies',
|
||||
$dependencies
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a mapping from parent methods to their dependent methods
|
||||
*
|
||||
* @return array Parent-to-child dependency map
|
||||
*/
|
||||
public function get_dependents_map(): array {
|
||||
$result = array();
|
||||
$dependencies = $this->get_dependencies();
|
||||
|
||||
foreach ( $dependencies as $child_id => $parent_ids ) {
|
||||
foreach ( $parent_ids as $parent_id ) {
|
||||
if ( ! isset( $result[ $parent_id ] ) ) {
|
||||
$result[ $parent_id ] = array();
|
||||
}
|
||||
$result[ $parent_id ][] = $child_id;
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all parent methods that a method depends on
|
||||
*
|
||||
* @param string $method_id Method ID to check.
|
||||
* @return array Array of parent method IDs
|
||||
*/
|
||||
public function get_parent_methods( string $method_id ): array {
|
||||
return $this->get_dependencies()[ $method_id ] ?? array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get methods that depend on a parent method
|
||||
*
|
||||
* @param string $parent_id Parent method ID.
|
||||
* @return array Array of dependent method IDs
|
||||
*/
|
||||
public function get_dependent_methods( string $parent_id ): array {
|
||||
return $this->get_dependents_map()[ $parent_id ] ?? array();
|
||||
}
|
||||
}
|
|
@ -11,7 +11,6 @@ namespace WooCommerce\PayPalCommerce\Settings\Data\Definition;
|
|||
|
||||
use WooCommerce\PayPalCommerce\Settings\Service\TodosEligibilityService;
|
||||
use WooCommerce\PayPalCommerce\Settings\Data\GeneralSettings;
|
||||
use WooCommerce\PayPalCommerce\WcSubscriptions\Helper\SubscriptionHelper;
|
||||
|
||||
/**
|
||||
* Class TodosDefinition
|
||||
|
@ -35,28 +34,18 @@ class TodosDefinition {
|
|||
*/
|
||||
protected GeneralSettings $settings;
|
||||
|
||||
/**
|
||||
* The subscription helper.
|
||||
*
|
||||
* @var SubscriptionHelper
|
||||
*/
|
||||
protected SubscriptionHelper $subscription_helper;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param TodosEligibilityService $eligibilities The todos eligibility service.
|
||||
* @param GeneralSettings $settings The general settings service.
|
||||
* @param SubscriptionHelper $subscription_helper The subscription helper.
|
||||
*/
|
||||
public function __construct(
|
||||
TodosEligibilityService $eligibilities,
|
||||
GeneralSettings $settings,
|
||||
SubscriptionHelper $subscription_helper
|
||||
GeneralSettings $settings
|
||||
) {
|
||||
$this->eligibilities = $eligibilities;
|
||||
$this->settings = $settings;
|
||||
$this->subscription_helper = $subscription_helper;
|
||||
$this->eligibilities = $eligibilities;
|
||||
$this->settings = $settings;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -80,18 +69,6 @@ class TodosDefinition {
|
|||
),
|
||||
'priority' => 1,
|
||||
),
|
||||
'enable_credit_debit_cards' => array(
|
||||
'title' => __( 'Enable Credit and Debit Cards on your checkout', 'woocommerce-paypal-payments' ),
|
||||
'description' => __( 'Credit and Debit Cards is now available for Blocks checkout pages', 'woocommerce-paypal-payments' ),
|
||||
'isEligible' => $eligibility_checks['enable_credit_debit_cards'],
|
||||
'action' => array(
|
||||
'type' => 'tab',
|
||||
'tab' => 'payment_methods',
|
||||
'section' => 'ppcp-card-button-gateway',
|
||||
'highlight' => 'ppcp-card-button-gateway',
|
||||
),
|
||||
'priority' => 2,
|
||||
),
|
||||
'enable_pay_later_messaging' => array(
|
||||
'title' => __( 'Enable Pay Later messaging', 'woocommerce-paypal-payments' ),
|
||||
'description' => __( 'Show Pay Later messaging to boost conversion rate and increase cart size', 'woocommerce-paypal-payments' ),
|
||||
|
@ -138,9 +115,7 @@ class TodosDefinition {
|
|||
'isEligible' => $eligibility_checks['configure_paypal_subscription'],
|
||||
'action' => array(
|
||||
'type' => 'external',
|
||||
'url' => $this->subscription_helper->has_subscription_products()
|
||||
? admin_url( 'edit.php?post_type=product&product_type=subscription' ) // If subscription products exist, go to the subscriptions products archive page.
|
||||
: admin_url( 'post-new.php?post_type=product' ), // If there are no subscriptions products, go to create one.
|
||||
'url' => 'https://woocommerce.com/document/woocommerce-paypal-payments/#paypal-subscriptions',
|
||||
'completeOnClick' => true,
|
||||
),
|
||||
'priority' => 5,
|
||||
|
|
|
@ -150,7 +150,17 @@ class PaymentRestEndpoint extends RestEndpoint {
|
|||
$gateway_settings = array();
|
||||
$all_methods = $this->gateways();
|
||||
|
||||
// First extract __meta if present.
|
||||
if ( isset( $all_methods['__meta'] ) ) {
|
||||
$gateway_settings['__meta'] = $all_methods['__meta'];
|
||||
}
|
||||
|
||||
foreach ( $all_methods as $key => $method ) {
|
||||
// Skip the __meta key as we've already handled it.
|
||||
if ( $key === '__meta' ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$gateway_settings[ $key ] = array(
|
||||
'id' => $method['id'],
|
||||
'title' => $method['title'],
|
||||
|
@ -164,6 +174,11 @@ class PaymentRestEndpoint extends RestEndpoint {
|
|||
if ( isset( $method['fields'] ) ) {
|
||||
$gateway_settings[ $key ]['fields'] = $method['fields'];
|
||||
}
|
||||
|
||||
// Preserve dependency information.
|
||||
if ( isset( $method['depends_on'] ) ) {
|
||||
$gateway_settings[ $key ]['depends_on'] = $method['depends_on'];
|
||||
}
|
||||
}
|
||||
|
||||
$gateway_settings['paypalShowLogo'] = $this->settings->get_paypal_show_logo();
|
||||
|
|
|
@ -225,10 +225,11 @@ class SettingsDataManager {
|
|||
if ( $flags->use_card_payments ) {
|
||||
// Enable ACDC for business sellers.
|
||||
$this->payment_methods->toggle_method_state( CreditCardGateway::ID, true );
|
||||
}
|
||||
|
||||
$this->payment_methods->toggle_method_state( ApplePayGateway::ID, true );
|
||||
$this->payment_methods->toggle_method_state( GooglePayGateway::ID, true );
|
||||
// Apple Pay and Google Pay depend on the ACDC gateway.
|
||||
$this->payment_methods->toggle_method_state( ApplePayGateway::ID, true );
|
||||
$this->payment_methods->toggle_method_state( GooglePayGateway::ID, true );
|
||||
}
|
||||
|
||||
// Enable all APM methods.
|
||||
foreach ( $methods_apm as $method ) {
|
||||
|
|
|
@ -24,13 +24,6 @@ class TodosEligibilityService {
|
|||
*/
|
||||
private bool $is_fastlane_eligible;
|
||||
|
||||
/**
|
||||
* Whether card payments are eligible.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
private bool $is_card_payment_eligible;
|
||||
|
||||
/**
|
||||
* Whether Pay Later messaging is eligible.
|
||||
*
|
||||
|
@ -133,7 +126,6 @@ class TodosEligibilityService {
|
|||
* Constructor.
|
||||
*
|
||||
* @param bool $is_fastlane_eligible Whether Fastlane is eligible.
|
||||
* @param bool $is_card_payment_eligible Whether card payments are eligible.
|
||||
* @param bool $is_pay_later_messaging_eligible Whether Pay Later messaging is eligible.
|
||||
* @param bool $is_pay_later_messaging_product_eligible Whether Pay Later messaging for product page is eligible.
|
||||
* @param bool $is_pay_later_messaging_cart_eligible Whether Pay Later messaging for cart is eligible.
|
||||
|
@ -151,7 +143,6 @@ class TodosEligibilityService {
|
|||
*/
|
||||
public function __construct(
|
||||
bool $is_fastlane_eligible,
|
||||
bool $is_card_payment_eligible,
|
||||
bool $is_pay_later_messaging_eligible,
|
||||
bool $is_pay_later_messaging_product_eligible,
|
||||
bool $is_pay_later_messaging_cart_eligible,
|
||||
|
@ -168,7 +159,6 @@ class TodosEligibilityService {
|
|||
bool $is_enable_google_pay_eligible
|
||||
) {
|
||||
$this->is_fastlane_eligible = $is_fastlane_eligible;
|
||||
$this->is_card_payment_eligible = $is_card_payment_eligible;
|
||||
$this->is_pay_later_messaging_eligible = $is_pay_later_messaging_eligible;
|
||||
$this->is_pay_later_messaging_product_eligible = $is_pay_later_messaging_product_eligible;
|
||||
$this->is_pay_later_messaging_cart_eligible = $is_pay_later_messaging_cart_eligible;
|
||||
|
@ -193,7 +183,6 @@ class TodosEligibilityService {
|
|||
public function get_eligibility_checks(): array {
|
||||
return array(
|
||||
'enable_fastlane' => fn() => $this->is_fastlane_eligible,
|
||||
'enable_credit_debit_cards' => fn() => $this->is_card_payment_eligible,
|
||||
'enable_pay_later_messaging' => fn() => $this->is_pay_later_messaging_eligible,
|
||||
'add_pay_later_messaging_product_page' => fn() => $this->is_pay_later_messaging_product_eligible,
|
||||
'add_pay_later_messaging_cart' => fn() => $this->is_pay_later_messaging_cart_eligible,
|
||||
|
|
|
@ -342,6 +342,12 @@ class SettingsModule implements ServiceModule, ExecutableModule {
|
|||
$dcc_applies = $container->get( 'api.helpers.dccapplies' );
|
||||
assert( $dcc_applies instanceof DCCApplies );
|
||||
|
||||
$general_settings = $container->get( 'settings.data.general' );
|
||||
assert( $general_settings instanceof GeneralSettings );
|
||||
|
||||
$merchant_data = $general_settings->get_merchant_data();
|
||||
$merchant_country = $merchant_data->merchant_country;
|
||||
|
||||
// Unset BCDC if merchant is eligible for ACDC and country is eligible for card fields.
|
||||
$card_fields_eligible = $container->get( 'card-fields.eligible' );
|
||||
if ( $dcc_product_status->is_active() && $card_fields_eligible ) {
|
||||
|
@ -368,6 +374,16 @@ class SettingsModule implements ServiceModule, ExecutableModule {
|
|||
unset( $payment_methods['ppcp-axo-gateway'] );
|
||||
}
|
||||
|
||||
// Unset OXXO if merchant country is not Mexico.
|
||||
if ( 'MX' !== $merchant_country ) {
|
||||
unset( $payment_methods[ OXXO::ID ] );
|
||||
}
|
||||
|
||||
// Unset Pay Unon Invoice if merchant country is not Germany.
|
||||
if ( 'DE' !== $merchant_country ) {
|
||||
unset( $payment_methods[ PayUponInvoiceGateway::ID ] );
|
||||
}
|
||||
|
||||
// For non-ACDC regions unset ACDC, local APMs and set BCDC.
|
||||
if ( ! $dcc_applies ) {
|
||||
unset( $payment_methods[ CreditCardGateway::ID ] );
|
||||
|
|
|
@ -159,7 +159,7 @@ class Settings implements ContainerInterface {
|
|||
if ( $this->settings ) {
|
||||
return false;
|
||||
}
|
||||
$this->settings = get_option( self::KEY, array() );
|
||||
$this->settings = (array) get_option( self::KEY, array() );
|
||||
|
||||
$defaults = array(
|
||||
'title' => __( 'PayPal', 'woocommerce-paypal-payments' ),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue