Merge branch 'trunk' into PCP-1393-update-to-vault-v-3

This commit is contained in:
Emili Castells Guasch 2023-11-03 11:18:55 +01:00
commit 9aef764ba8
10 changed files with 243 additions and 53 deletions

View file

@ -48,8 +48,8 @@ class ApiModule implements ModuleInterface {
'ppcp_create_order_request_body_data', 'ppcp_create_order_request_body_data',
function( array $data ) use ( $c ) { function( array $data ) use ( $c ) {
foreach ( $data['purchase_units'] as $purchase_unit_index => $purchase_unit ) { foreach ( ( $data['purchase_units'] ?? array() ) as $purchase_unit_index => $purchase_unit ) {
foreach ( $purchase_unit['items'] as $item_index => $item ) { foreach ( ( $purchase_unit['items'] ?? array() ) as $item_index => $item ) {
$data['purchase_units'][ $purchase_unit_index ]['items'][ $item_index ]['name'] = $data['purchase_units'][ $purchase_unit_index ]['items'][ $item_index ]['name'] =
apply_filters( 'woocommerce_paypal_payments_cart_line_item_name', $item['name'], $item['cart_item_key'] ?? null ); apply_filters( 'woocommerce_paypal_payments_cart_line_item_name', $item['name'], $item['cart_item_key'] ?? null );
} }

View file

@ -102,7 +102,7 @@ class OrderTransient {
$transient = array(); $transient = array();
} }
if ( ! is_array( $transient['notes'] ) ) { if ( ! is_array( $transient['notes'] ?? null ) ) {
$transient['notes'] = array(); $transient['notes'] = array();
} }

View file

@ -130,6 +130,24 @@ return array(
return apply_filters( return apply_filters(
'woocommerce_paypal_payments_applepay_supported_country_currency_matrix', 'woocommerce_paypal_payments_applepay_supported_country_currency_matrix',
array( array(
'CA' => array(
'AUD',
'CAD',
'CHF',
'CZK',
'DKK',
'EUR',
'GBP',
'HKD',
'HUF',
'JPY',
'NOK',
'NZD',
'PLN',
'SEK',
'SGD',
'USD',
),
'GB' => array( 'GB' => array(
'AUD', 'AUD',
'CAD', 'CAD',
@ -148,6 +166,24 @@ return array(
'SGD', 'SGD',
'USD', 'USD',
), ),
'IT' => array(
'AUD',
'CAD',
'CHF',
'CZK',
'DKK',
'EUR',
'GBP',
'HKD',
'HUF',
'JPY',
'NOK',
'NZD',
'PLN',
'SEK',
'SGD',
'USD',
),
'US' => array( 'US' => array(
'AUD', 'AUD',
'CAD', 'CAD',
@ -156,24 +192,6 @@ return array(
'JPY', 'JPY',
'USD', 'USD',
), ),
'CA' => array(
'AUD',
'CAD',
'CHF',
'CZK',
'DKK',
'EUR',
'GBP',
'HKD',
'HUF',
'JPY',
'NOK',
'NZD',
'PLN',
'SEK',
'SGD',
'USD',
),
) )
); );
}, },

View file

@ -84,11 +84,12 @@ class ApplepayModule implements ModuleInterface {
return; return;
} }
$module->load_assets( $c, $apple_payment_method ); if ( $apple_payment_method->is_enabled() ) {
$module->handle_validation_file( $c ); $module->load_assets( $c, $apple_payment_method );
$module->render_buttons( $c, $apple_payment_method ); $module->handle_validation_file( $c, $apple_payment_method );
$module->render_buttons( $c, $apple_payment_method );
$apple_payment_method->bootstrap_ajax_request(); $apple_payment_method->bootstrap_ajax_request();
}
}, },
1 1
); );
@ -215,9 +216,13 @@ class ApplepayModule implements ModuleInterface {
* Handles the validation file. * Handles the validation file.
* *
* @param ContainerInterface $c The container. * @param ContainerInterface $c The container.
* @param ApplePayButton $button The button.
* @return void * @return void
*/ */
public function handle_validation_file( ContainerInterface $c ): void { public function handle_validation_file( ContainerInterface $c, ApplePayButton $button ): void {
if ( ! $button->is_enabled() ) {
return;
}
$env = $c->get( 'onboarding.environment' ); $env = $c->get( 'onboarding.environment' );
assert( $env instanceof Environment ); assert( $env instanceof Environment );
$is_sandobx = $env->current_environment_is( Environment::SANDBOX ); $is_sandobx = $env->current_environment_is( Environment::SANDBOX );

View file

@ -395,14 +395,16 @@ class SmartButton implements SmartButtonInterface {
return false; return false;
} }
$get_hook = function ( string $location ): ?array { $default_pay_order_hook = 'woocommerce_pay_order_before_submit';
$get_hook = function ( string $location ) use ( $default_pay_order_hook ): ?array {
switch ( $location ) { switch ( $location ) {
case 'checkout': case 'checkout':
return $this->messages_renderer_hook( $location, 'woocommerce_review_order_before_payment', 10 ); return $this->messages_renderer_hook( $location, 'woocommerce_review_order_before_payment', 10 );
case 'cart': case 'cart':
return $this->messages_renderer_hook( $location, $this->proceed_to_checkout_button_renderer_hook(), 19 ); return $this->messages_renderer_hook( $location, $this->proceed_to_checkout_button_renderer_hook(), 19 );
case 'pay-now': case 'pay-now':
return $this->messages_renderer_hook( 'pay_order', 'woocommerce_pay_order_before_submit', 10 ); return $this->messages_renderer_hook( $location, $default_pay_order_hook, 10 );
case 'product': case 'product':
return $this->messages_renderer_hook( $location, $this->single_product_renderer_hook(), 30 ); return $this->messages_renderer_hook( $location, $this->single_product_renderer_hook(), 30 );
case 'shop': case 'shop':
@ -425,6 +427,28 @@ class SmartButton implements SmartButtonInterface {
$hook['priority'] $hook['priority']
); );
// Looks like there are no hooks like woocommerce_review_order_before_payment on the pay for order page, so have to move using JS.
if ( $location === 'pay-now' && $hook['name'] === $default_pay_order_hook &&
/**
* The filter returning true if Pay Later messages should be displayed before payment methods
* on the pay for order page, like in checkout.
*/
apply_filters(
'woocommerce_paypal_payments_put_pay_order_messages_before_payment_methods',
true
)
) {
add_action(
'ppcp_after_pay_order_message_wrapper',
function () {
echo '
<script>
document.querySelector("#payment").before(document.querySelector("#ppcp-messages"))
</script>';
}
);
}
return true; return true;
} }
@ -681,11 +705,12 @@ class SmartButton implements SmartButtonInterface {
/** /**
* Renders the HTML for the credit messaging. * Renders the HTML for the credit messaging.
*/ */
public function message_renderer() { public function message_renderer(): void {
$product = wc_get_product(); $product = wc_get_product();
$location = $this->location(); $location = $this->location();
$location_hook = $this->location_to_hook( $location );
if ( if (
$location === 'product' && is_a( $product, WC_Product::class ) $location === 'product' && is_a( $product, WC_Product::class )
@ -697,7 +722,17 @@ class SmartButton implements SmartButtonInterface {
return; return;
} }
/**
* A hook executed before rendering of the PCP Pay Later messages wrapper.
*/
do_action( "ppcp_before_{$location_hook}_message_wrapper" );
echo '<div id="ppcp-messages" data-partner-attribution-id="Woo_PPCP"></div>'; echo '<div id="ppcp-messages" data-partner-attribution-id="Woo_PPCP"></div>';
/**
* A hook executed after rendering of the PCP Pay Later messages wrapper.
*/
do_action( "ppcp_after_{$location_hook}_message_wrapper" );
} }
/** /**
@ -1204,6 +1239,13 @@ class SmartButton implements SmartButtonInterface {
$params['enable-funding'] = implode( ',', array_unique( $enable_funding ) ); $params['enable-funding'] = implode( ',', array_unique( $enable_funding ) );
} }
$locale = $this->settings->has( 'smart_button_language' ) ? $this->settings->get( 'smart_button_language' ) : '';
$locale = (string) apply_filters( 'woocommerce_paypal_payments_smart_buttons_locale', $locale );
if ( $locale ) {
$params['locale'] = $locale;
}
return $params; return $params;
} }
@ -1400,18 +1442,20 @@ class SmartButton implements SmartButtonInterface {
* @return array An array with 'name' and 'priority' keys. * @return array An array with 'name' and 'priority' keys.
*/ */
private function messages_renderer_hook( string $location, string $default_hook, int $default_priority ): array { private function messages_renderer_hook( string $location, string $default_hook, int $default_priority ): array {
$location_hook = $this->location_to_hook( $location );
/** /**
* The filter returning the action name that will be used for rendering Pay Later messages. * The filter returning the action name that will be used for rendering Pay Later messages.
*/ */
$hook = (string) apply_filters( $hook = (string) apply_filters(
"woocommerce_paypal_payments_${location}_messages_renderer_hook", "woocommerce_paypal_payments_${location_hook}_messages_renderer_hook",
$default_hook $default_hook
); );
/** /**
* The filter returning the action priority that will be used for rendering Pay Later messages. * The filter returning the action priority that will be used for rendering Pay Later messages.
*/ */
$priority = (int) apply_filters( $priority = (int) apply_filters(
"woocommerce_paypal_payments_${location}_messages_renderer_priority", "woocommerce_paypal_payments_${location_hook}_messages_renderer_priority",
$default_priority $default_priority
); );
return array( return array(
@ -1725,4 +1769,18 @@ class SmartButton implements SmartButtonInterface {
} }
/**
* Converts the location name into the name used in hooks.
*
* @param string $location The location.
* @return string
*/
private function location_to_hook( string $location ): string {
switch ( $location ) {
case 'pay-now':
return 'pay_order';
default:
return $location;
}
}
} }

View file

@ -34,6 +34,28 @@ trait ContextTrait {
return false; return false;
} }
/**
* Checks WC is_cart() + WC cart ajax requests.
*/
private function is_cart(): bool {
if ( is_cart() ) {
return true;
}
/**
* The filter returning whether to detect WC cart ajax requests.
*/
if ( apply_filters( 'ppcp_check_ajax_cart', true ) ) {
// phpcs:ignore WordPress.Security
$wc_ajax = $_GET['wc-ajax'] ?? '';
if ( in_array( $wc_ajax, array( 'update_shipping_method' ), true ) ) {
return true;
}
}
return false;
}
/** /**
* The current context. * The current context.
* *
@ -56,7 +78,7 @@ trait ContextTrait {
return 'cart-block'; return 'cart-block';
} }
if ( is_cart() ) { if ( $this->is_cart() ) {
return 'cart'; return 'cart';
} }

View file

@ -90,6 +90,24 @@ return array(
return apply_filters( return apply_filters(
'woocommerce_paypal_payments_googlepay_supported_country_currency_matrix', 'woocommerce_paypal_payments_googlepay_supported_country_currency_matrix',
array( array(
'CA' => array(
'AUD',
'CAD',
'CHF',
'CZK',
'DKK',
'EUR',
'GBP',
'HKD',
'HUF',
'JPY',
'NOK',
'NZD',
'PLN',
'SEK',
'SGD',
'USD',
),
'GB' => array( 'GB' => array(
'AUD', 'AUD',
'CAD', 'CAD',
@ -108,6 +126,24 @@ return array(
'SGD', 'SGD',
'USD', 'USD',
), ),
'IT' => array(
'AUD',
'CAD',
'CHF',
'CZK',
'DKK',
'EUR',
'GBP',
'HKD',
'HUF',
'JPY',
'NOK',
'NZD',
'PLN',
'SEK',
'SGD',
'USD',
),
'US' => array( 'US' => array(
'AUD', 'AUD',
'CAD', 'CAD',
@ -116,24 +152,6 @@ return array(
'JPY', 'JPY',
'USD', 'USD',
), ),
'CA' => array(
'AUD',
'CAD',
'CHF',
'CZK',
'DKK',
'EUR',
'GBP',
'HKD',
'HUF',
'JPY',
'NOK',
'NZD',
'PLN',
'SEK',
'SGD',
'USD',
),
) )
); );
}, },

View file

@ -115,7 +115,7 @@ document.addEventListener(
'currency': PayPalCommerceGatewaySettings.currency, 'currency': PayPalCommerceGatewaySettings.currency,
'integration-date': PayPalCommerceGatewaySettings.integration_date, 'integration-date': PayPalCommerceGatewaySettings.integration_date,
'components': PayPalCommerceGatewaySettings.components, 'components': PayPalCommerceGatewaySettings.components,
'enable-funding': ['venmo', 'paylater'], 'enable-funding': ['venmo', 'paylater']
}; };
if (PayPalCommerceGatewaySettings.environment === 'sandbox') { if (PayPalCommerceGatewaySettings.environment === 'sandbox') {
@ -134,6 +134,11 @@ document.addEventListener(
settings['disable-funding'] = disabledSources; settings['disable-funding'] = disabledSources;
} }
const smartButtonLocale = document.getElementById('ppcp-smart_button_language');
if (smartButtonLocale?.length > 0 && smartButtonLocale?.value !== '') {
settings['locale'] = smartButtonLocale.value;
}
return settings; return settings;
} }

View file

@ -1422,4 +1422,52 @@ return array(
return new DisplayManager( $settings ); return new DisplayManager( $settings );
} }
), ),
'wcgateway.wp-paypal-locales-map' => static function( ContainerInterface $container ): array {
return apply_filters(
'woocommerce_paypal_payments_button_locales',
array(
'' => __( 'Browser language', 'woocommerce-paypal-payments' ),
'ar_DZ' => __( 'Arabic (Algeria)', 'woocommerce-paypal-payments' ),
'ar_BH' => __( 'Arabic (Bahrain)', 'woocommerce-paypal-payments' ),
'ar_EG' => __( 'Arabic (Egypt)', 'woocommerce-paypal-payments' ),
'ar_JO' => __( 'Arabic (Jordan)', 'woocommerce-paypal-payments' ),
'ar_KW' => __( 'Arabic (Kuwait)', 'woocommerce-paypal-payments' ),
'ar_MA' => __( 'Arabic (Morocco)', 'woocommerce-paypal-payments' ),
'ar_SA' => __( 'Arabic (Saudi Arabia)', 'woocommerce-paypal-payments' ),
'cs_CZ' => __( 'Czech', 'woocommerce-paypal-payments' ),
'zh_CN' => __( 'Chinese (Simplified)', 'woocommerce-paypal-payments' ),
'zh_HK' => __( 'Chinese (Hong Kong)', 'woocommerce-paypal-payments' ),
'zh_TW' => __( 'Chinese (Traditional)', 'woocommerce-paypal-payments' ),
'da_DK' => __( 'Danish', 'woocommerce-paypal-payments' ),
'nl_NL' => __( 'Dutch', 'woocommerce-paypal-payments' ),
'en_AU' => __( 'English (Australia)', 'woocommerce-paypal-payments' ),
'en_GB' => __( 'English (United Kingdom)', 'woocommerce-paypal-payments' ),
'en_US' => __( 'English (United States)', 'woocommerce-paypal-payments' ),
'fi_FI' => __( 'Finnish', 'woocommerce-paypal-payments' ),
'fr_CA' => __( 'French (Canada)', 'woocommerce-paypal-payments' ),
'fr_FR' => __( 'French (France)', 'woocommerce-paypal-payments' ),
'de_DE' => __( 'German (Germany)', 'woocommerce-paypal-payments' ),
'de_CH' => __( 'German (Switzerland)', 'woocommerce-paypal-payments' ),
'de_AT' => __( 'German (Austria)', 'woocommerce-paypal-payments' ),
'de_LU' => __( 'German (Luxembourg)', 'woocommerce-paypal-payments' ),
'el_GR' => __( 'Greek', 'woocommerce-paypal-payments' ),
'he_IL' => __( 'Hebrew', 'woocommerce-paypal-payments' ),
'hu_HU' => __( 'Hungarian', 'woocommerce-paypal-payments' ),
'id_ID' => __( 'Indonesian', 'woocommerce-paypal-payments' ),
'it_IT' => __( 'Italian', 'woocommerce-paypal-payments' ),
'ja_JP' => __( 'Japanese', 'woocommerce-paypal-payments' ),
'ko_KR' => __( 'Korean', 'woocommerce-paypal-payments' ),
'no_NO' => __( 'Norwegian', 'woocommerce-paypal-payments' ),
'es_ES' => __( 'Spanish (Spain)', 'woocommerce-paypal-payments' ),
'es_MX' => __( 'Spanish (Mexico)', 'woocommerce-paypal-payments' ),
'pl_PL' => __( 'Polish', 'woocommerce-paypal-payments' ),
'pt_BR' => __( 'Portuguese (Brazil)', 'woocommerce-paypal-payments' ),
'pt_PT' => __( 'Portuguese (Portugal)', 'woocommerce-paypal-payments' ),
'ru_RU' => __( 'Russian', 'woocommerce-paypal-payments' ),
'sk_SK' => __( 'Slovak', 'woocommerce-paypal-payments' ),
'sv_SE' => __( 'Swedish', 'woocommerce-paypal-payments' ),
'th_TH' => __( 'Thai', 'woocommerce-paypal-payments' ),
)
);
},
); );

View file

@ -71,6 +71,22 @@ return function ( ContainerInterface $container, array $fields ): array {
'requirements' => array(), 'requirements' => array(),
'gateway' => 'paypal', 'gateway' => 'paypal',
), ),
'smart_button_language' => array(
'title' => __( 'Smart Button Language', 'woocommerce-paypal-payments' ),
'type' => 'select',
'desc_tip' => true,
'description' => __(
'The language and region used for the displayed PayPal Smart Buttons. The default value is the current language and region setting in a browser.',
'woocommerce-paypal-payments'
),
'class' => array(),
'input_class' => array( 'wc-enhanced-select' ),
'default' => 'en',
'options' => $container->get( 'wcgateway.wp-paypal-locales-map' ),
'screens' => array( State::STATE_ONBOARDED ),
'gateway' => 'paypal',
'requirements' => array(),
),
'smart_button_enable_styling_per_location' => array( 'smart_button_enable_styling_per_location' => array(
'title' => __( 'Customize Smart Buttons Per Location', 'woocommerce-paypal-payments' ), 'title' => __( 'Customize Smart Buttons Per Location', 'woocommerce-paypal-payments' ),
'type' => 'checkbox', 'type' => 'checkbox',