Skip to content
Open
Show file tree
Hide file tree
Changes from 15 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions changelog/refactor-google-pay-apple-pay-settings-storage
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: patch
Type: update

refactor: Google Pay/Apple Pay settings storage consistency
21 changes: 19 additions & 2 deletions includes/admin/class-wc-rest-payments-settings-controller.php
Original file line number Diff line number Diff line change
Expand Up @@ -509,7 +509,7 @@ public function get_settings(): WP_REST_Response {
'account_branding_primary_color' => $this->wcpay_gateway->get_option( 'account_branding_primary_color' ),
'account_branding_secondary_color' => $this->wcpay_gateway->get_option( 'account_branding_secondary_color' ),
'account_domestic_currency' => $this->wcpay_gateway->get_option( 'account_domestic_currency' ),
'is_payment_request_enabled' => 'yes' === $this->wcpay_gateway->get_option( 'payment_request' ),
'is_payment_request_enabled' => $this->wcpay_gateway->is_payment_request_enabled(),
'is_apple_google_pay_in_payment_methods_options_enabled' => 'yes' === $this->wcpay_gateway->get_option( 'apple_google_pay_in_payment_methods_options' ),
'is_debug_log_enabled' => 'yes' === $this->wcpay_gateway->get_option( 'enable_logging' ),
'payment_request_enabled_locations' => $this->wcpay_gateway->get_option( 'payment_request_button_locations' ),
Expand Down Expand Up @@ -870,7 +870,24 @@ private function update_is_payment_request_enabled( WP_REST_Request $request ) {

$is_payment_request_enabled = $request->get_param( 'is_payment_request_enabled' );

$this->wcpay_gateway->update_option( 'payment_request', $is_payment_request_enabled ? 'yes' : 'no' );
// Update Google Pay and Apple Pay enabled settings to keep them in sync.
$google_pay_gateway = WC_Payments::get_payment_gateway_by_id( \WCPay\PaymentMethods\Configs\Definitions\GooglePayDefinition::get_id() );
$apple_pay_gateway = WC_Payments::get_payment_gateway_by_id( \WCPay\PaymentMethods\Configs\Definitions\ApplePayDefinition::get_id() );
if ( $is_payment_request_enabled ) {
if ( $google_pay_gateway ) {
$google_pay_gateway->enable();
}
if ( $apple_pay_gateway ) {
$apple_pay_gateway->enable();
}
} else {
if ( $google_pay_gateway ) {
$google_pay_gateway->disable();
}
if ( $apple_pay_gateway ) {
$apple_pay_gateway->disable();
}
}
}

/**
Expand Down
5 changes: 4 additions & 1 deletion includes/class-duplicates-detection-service.php
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,10 @@ private function search_for_payment_request_buttons() {
if ( strpos( $gateway->id, $keyword ) !== false ) {
$this->gateways_qualified_by_duplicates_detector[ $prb_payment_method ][] = $gateway->id;
break;
} elseif ( 'yes' === $gateway->get_option( 'payment_request' ) && in_array( $gateway->id, [ 'woocommerce_payments', 'stripe' ], true ) ) {
} elseif ( 'woocommerce_payments' === $gateway->id && method_exists( $gateway, 'is_payment_request_enabled' ) && $gateway->is_payment_request_enabled() ) {
$this->gateways_qualified_by_duplicates_detector[ $prb_payment_method ][] = $gateway->id;
break;
} elseif ( 'stripe' === $gateway->id && 'yes' === $gateway->get_option( 'payment_request' ) ) {
$this->gateways_qualified_by_duplicates_detector[ $prb_payment_method ][] = $gateway->id;
break;
} elseif ( 'yes' === $gateway->get_option( 'express_checkout_enabled' ) ) {
Expand Down
27 changes: 12 additions & 15 deletions includes/class-wc-payment-gateway-wcpay.php
Original file line number Diff line number Diff line change
Expand Up @@ -442,20 +442,6 @@ public function get_form_fields() {
'type' => 'title',
'description' => '',
],
'payment_request' => [
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No longer needed - the payment_request setting got deleted in favor of the enabled flag on the Google Pay/Apple Pay payment method definitions

'title' => __( 'Enable/disable', 'woocommerce-payments' ),
'label' => sprintf(
/* translators: 1) br tag 2) Stripe anchor tag 3) Apple anchor tag */
__( 'Enable payment request buttons (Apple Pay, Google Pay, and more). %1$sBy using Apple Pay, you agree to %2$s and %3$s\'s Terms of Service.', 'woocommerce-payments' ),
'<br />',
'<a href="https://stripe.com/apple-pay/legal" target="_blank">Stripe</a>',
'<a href="https://developer.apple.com/apple-pay/acceptable-use-guidelines-for-websites/" target="_blank">Apple</a>'
),
'type' => 'checkbox',
'description' => __( 'If enabled, users will be able to pay using Apple Pay, Google Pay or the Payment Request API if supported by the browser.', 'woocommerce-payments' ),
'default' => empty( get_option( 'woocommerce_woocommerce_payments_settings' ) ) ? 'yes' : 'no', // Enable by default for new installations only.
'desc_tip' => true,
],
'payment_request_button_type' => [
'title' => __( 'Button type', 'woocommerce-payments' ),
'type' => 'select',
Expand Down Expand Up @@ -957,7 +943,18 @@ public function is_saved_cards_enabled() {
* @return bool Whether the setting to show the payment request buttons is enabled or not.
*/
public function is_payment_request_enabled() {
return 'yes' === $this->get_option( 'payment_request' );
$google_pay_gateway = WC_Payments::get_payment_gateway_by_id( \WCPay\PaymentMethods\Configs\Definitions\GooglePayDefinition::get_id() );
if ( $google_pay_gateway && $google_pay_gateway->is_enabled() ) {
return true;
}

// Fallback, just in case.
$apple_pay_gateway = WC_Payments::get_payment_gateway_by_id( \WCPay\PaymentMethods\Configs\Definitions\ApplePayDefinition::get_id() );
if ( $apple_pay_gateway && $apple_pay_gateway->is_enabled() ) {
return true;
}

return false;
}

/**
Expand Down
2 changes: 1 addition & 1 deletion includes/class-wc-payments-account.php
Original file line number Diff line number Diff line change
Expand Up @@ -2726,7 +2726,7 @@ private function get_store_setup_details(): array {
'debug_log_enabled' => 'yes' === $gateway->get_option( 'enable_logging' ),

'payment_request' => [
'enabled' => 'yes' === $gateway->get_option( 'payment_request' ),
'enabled' => $gateway->is_payment_request_enabled(),
'enabled_locations' => $gateway->get_option( 'payment_request_button_locations' ),
'button_type' => $gateway->get_option( 'payment_request_button_type' ),
'button_size' => $gateway->get_option( 'payment_request_button_size' ),
Expand Down
96 changes: 55 additions & 41 deletions includes/class-wc-payments-apple-pay-registration.php
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,11 @@ class WC_Payments_Apple_Pay_Registration {
private $domain_name;

/**
* Stores Apple Pay domain verification issues.
* Option name for storing Apple Pay domain verification errors.
*
* @var string
*/
private $apple_pay_verify_notice;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the previous implementation, the error message was stored as an attribute on the class.
The problem is that the settings updates happen over AJAX. And the attribute is not persisted across page refreshes.
So the exact error message was never displayed to the merchant.

I modified the implementation to store the error message in a new wcpay_apple_pay_domain_error option, so it can be persisted across page refreshes.

const APPLE_PAY_DOMAIN_ERROR_OPTION = 'wcpay_apple_pay_domain_error';

/**
* Initialize class actions.
Expand All @@ -63,11 +63,10 @@ class WC_Payments_Apple_Pay_Registration {
* @param WC_Payment_Gateway_WCPay $gateway WooCommerce Payments gateway.
*/
public function __construct( WC_Payments_API_Client $payments_api_client, WC_Payments_Account $account, WC_Payment_Gateway_WCPay $gateway ) {
$this->domain_name = wp_parse_url( get_site_url(), PHP_URL_HOST );
$this->apple_pay_verify_notice = '';
$this->payments_api_client = $payments_api_client;
$this->account = $account;
$this->gateway = $gateway;
$this->domain_name = wp_parse_url( get_site_url(), PHP_URL_HOST );
$this->payments_api_client = $payments_api_client;
$this->account = $account;
$this->gateway = $gateway;
}

/**
Expand All @@ -88,30 +87,44 @@ public function init() {
add_action( 'admin_init', [ $this, 'verify_domain_on_domain_name_change' ] );

add_action( 'woocommerce_woocommerce_payments_admin_notices', [ $this, 'display_error_notice' ] );
add_action( 'add_option_woocommerce_woocommerce_payments_settings', [ $this, 'verify_domain_on_new_settings' ], 10, 2 );
add_action( 'update_option_woocommerce_woocommerce_payments_settings', [ $this, 'verify_domain_on_updated_settings' ], 10, 2 );

// Listen to Apple Pay gateway settings changes for domain verification.
add_action( 'add_option_woocommerce_woocommerce_payments_apple_pay_settings', [ $this, 'verify_domain_on_new_settings' ], 10, 2 );
add_action( 'update_option_woocommerce_woocommerce_payments_apple_pay_settings', [ $this, 'verify_domain_on_updated_settings' ], 10, 2 );
}

/**
* Whether the gateway and Express Checkout Buttons (prerequisites for Apple Pay) are enabled.
* Whether Apple Pay is enabled.
*
* Checks both the main gateway and the Apple Pay gateway are enabled.
*
* @return bool Whether Apple Pay required settings are enabled.
* @return bool Whether Apple Pay is enabled.
*/
private function is_enabled() {
return $this->gateway->is_enabled() && 'yes' === $this->gateway->get_option( 'payment_request' );
// Check if the main gateway is enabled.
if ( ! $this->gateway->is_enabled() ) {
return false;
}

// Check if the Apple Pay gateway is enabled.
$apple_pay_gateway = WC_Payments::get_payment_gateway_by_id( 'apple_pay' );

if ( ! $apple_pay_gateway ) {
return false;
}

return $apple_pay_gateway->is_enabled();
}

/**
* Whether the gateway and Express Checkout Buttons were enabled in previous settings.
* Whether Apple Pay was enabled in previous settings.
*
* @param array|null $prev_settings Gateway settings.
* @param array|null $prev_settings Apple Pay gateway settings.
*
* @return bool Whether Apple Pay required settings are enabled.
* @return bool Whether Apple Pay was enabled.
*/
private function was_enabled( $prev_settings ) {
$gateway_enabled = 'yes' === ( $prev_settings['enabled'] ?? 'no' );
$payment_request_enabled = 'yes' === ( $prev_settings['payment_request'] ?? 'no' );
return $gateway_enabled && $payment_request_enabled;
return 'yes' === ( $prev_settings['enabled'] ?? 'no' );
}

/**
Expand Down Expand Up @@ -153,6 +166,7 @@ public function register_domain() {
if ( isset( $registration_response['id'] ) && ( isset( $registration_response['apple_pay']['status'] ) && 'active' === $registration_response['apple_pay']['status'] ) ) {
$this->gateway->update_option( 'apple_pay_verified_domain', $this->domain_name );
$this->gateway->update_option( 'apple_pay_domain_set', 'yes' );
delete_option( self::APPLE_PAY_DOMAIN_ERROR_OPTION );

Logger::log( __( 'Your domain has been verified with Apple Pay!', 'woocommerce-payments' ) );
Tracker::track_admin(
Expand All @@ -170,11 +184,10 @@ public function register_domain() {
} catch ( API_Exception $e ) {
$error = $e->getMessage();
}
// Display error message in notice.
$this->apple_pay_verify_notice = $error;

$this->gateway->update_option( 'apple_pay_verified_domain', $this->domain_name );
$this->gateway->update_option( 'apple_pay_domain_set', 'no' );
update_option( self::APPLE_PAY_DOMAIN_ERROR_OPTION, $error );

Logger::log( 'Error registering domain with Apple: ' . $error );
Tracker::track_admin(
Expand All @@ -192,7 +205,7 @@ public function register_domain() {
*/
public function verify_domain_if_configured() {
// If Express Checkout Buttons are not enabled,
// do not attempt to register domain.
// do not attempt to register the domain.
if ( ! $this->is_enabled() ) {
return;
}
Expand Down Expand Up @@ -232,29 +245,36 @@ public function display_error_notice() {
return;
}

$empty_notice = empty( $this->apple_pay_verify_notice );
$domain_set = $this->gateway->get_option( 'apple_pay_domain_set' );
$error_notice = get_option( self::APPLE_PAY_DOMAIN_ERROR_OPTION, '' );
$empty_notice = empty( $error_notice );

// Don't display error notice if verification notice is empty and
// apple_pay_domain_set option equals to '' or 'yes'.
if ( $empty_notice && 'no' !== $domain_set ) {
return;
}

// Clear the error after retrieving it so it only displays once.
if ( ! $empty_notice ) {
delete_option( self::APPLE_PAY_DOMAIN_ERROR_OPTION );
}

/**
* Apple pay is enabled by default and domain verification initializes
* when setting screen is displayed. So if domain verification is not set,
* something went wrong so lets notify user.
*/
$allowed_html = [
$allowed_html = [
'a' => [
'href' => [],
'title' => [],
],
];
$payment_request_button_text = __( 'Express checkouts:', 'woocommerce-payments' );
$verification_failed_without_error = __( 'Apple Pay domain verification failed.', 'woocommerce-payments' );
$verification_failed_with_error = __( 'Apple Pay domain verification failed with the following error:', 'woocommerce-payments' );
$check_log_text = WC_Payments_Utils::esc_interpolated_html(
$verification_failed = $empty_notice
? __( 'Apple Pay domain verification failed.', 'woocommerce-payments' )
: __( 'Apple Pay domain verification failed with the following error:', 'woocommerce-payments' );
$check_log_text = WC_Payments_Utils::esc_interpolated_html(
/* translators: a: Link to the logs page */
__( 'Please check the <a>logs</a> for more details on this issue. Debug log must be enabled under <strong>Advanced settings</strong> to see recorded logs.', 'woocommerce-payments' ),
[
Expand All @@ -271,20 +291,14 @@ public function display_error_notice() {

?>
<div class="notice notice-error apple-pay-message">
<?php if ( $empty_notice ) : ?>
<p>
<strong><?php echo esc_html( $payment_request_button_text ); ?></strong>
<?php echo esc_html( $verification_failed_without_error ); ?>
<?php echo $learn_more_text; /* @codingStandardsIgnoreLine */ ?>
</p>
<?php else : ?>
<p>
<strong><?php echo esc_html( $payment_request_button_text ); ?></strong>
<?php echo esc_html( $verification_failed_with_error ); ?>
<?php echo $learn_more_text; /* @codingStandardsIgnoreLine */ ?>
</p>
<p><i><?php echo wp_kses( make_clickable( esc_html( $this->apple_pay_verify_notice ) ), $allowed_html ); ?></i></p>
<?php endif; ?>
<p>
<strong><?php esc_html_e( 'Express checkouts:', 'woocommerce-payments' ); ?></strong>
<?php echo esc_html( $verification_failed ); ?>
<?php echo $learn_more_text; /* @codingStandardsIgnoreLine */ ?>
</p>
<?php if ( ! $empty_notice ) : ?>
<p><i><?php echo wp_kses( make_clickable( esc_html( $error_notice ) ), $allowed_html ); ?></i></p>
<?php endif; ?>
<p><?php echo $check_log_text; /* @codingStandardsIgnoreLine */ ?></p>
</div>
<?php
Expand Down
1 change: 0 additions & 1 deletion includes/class-wc-payments-blocks-payment-method.php
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,6 @@ public function is_active() {
* @return string[] A list of script handles.
*/
public function get_payment_method_script_handles() {

if ( ( is_cart() || is_checkout() || is_product() || has_block( 'woocommerce/checkout' ) || has_block( 'woocommerce/cart' ) || is_admin() ) ) {
WC_Payments_Utils::enqueue_style(
'wc-blocks-checkout-style',
Expand Down
20 changes: 16 additions & 4 deletions includes/class-wc-payments-onboarding-service.php
Original file line number Diff line number Diff line change
Expand Up @@ -1439,11 +1439,23 @@ public function update_enabled_payment_methods_ids( $gateway, $capabilities = []
$gateway->update_is_woopay_enabled( false );
}

// Update gateway option with the Apple/Google Pay capability.
if ( ! empty( $capabilities['apple_google'] ) || ( ! empty( $capabilities['apple_pay'] ) || ! empty( $capabilities['google_pay'] ) ) ) {
$gateway->update_option( 'payment_request', 'yes' );
// Update Apple/Google Pay gateway enabled state.
$google_pay_gateway = WC_Payments::get_payment_gateway_by_id( \WCPay\PaymentMethods\Configs\Definitions\GooglePayDefinition::get_id() );
$apple_pay_gateway = WC_Payments::get_payment_gateway_by_id( \WCPay\PaymentMethods\Configs\Definitions\ApplePayDefinition::get_id() );
if ( ! empty( $capabilities['apple_google'] ) || ! empty( $capabilities['apple_pay'] ) ) {
if ( $apple_pay_gateway ) {
$apple_pay_gateway->enable();
}
if ( $google_pay_gateway ) {
$google_pay_gateway->enable();
}
} else {
$gateway->update_option( 'payment_request', 'no' );
if ( $apple_pay_gateway ) {
$apple_pay_gateway->disable();
}
if ( $google_pay_gateway ) {
$google_pay_gateway->disable();
}
}
}

Expand Down
2 changes: 1 addition & 1 deletion includes/class-wc-payments-status.php
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,7 @@ public function render_status_report_section() {
<td class="help"><?php echo wc_help_tip( esc_html__( 'Whether the store has Payment Request enabled or not.', 'woocommerce-payments' ) ); /* phpcs:ignore WordPress.XSS.EscapeOutput.OutputNotEscaped, WordPress.Security.EscapeOutput.OutputNotEscaped */ ?></td>
<td>
<?php
$payment_request_enabled = 'yes' === $this->gateway->get_option( 'payment_request' );
$payment_request_enabled = $this->gateway->is_payment_request_enabled();
$payment_request_enabled_locations = $this->gateway->get_option( 'payment_request_button_locations', [] );
$payment_request_enabled_locations = empty( $payment_request_enabled_locations ) ? 'no locations enabled' : implode( ',', $payment_request_enabled_locations );
echo esc_html( $payment_request_enabled ? __( 'Enabled', 'woocommerce-payments' ) . ' (' . $payment_request_enabled_locations . ')' : __( 'Disabled', 'woocommerce-payments' ) );
Expand Down
2 changes: 2 additions & 0 deletions includes/class-wc-payments.php
Original file line number Diff line number Diff line change
Expand Up @@ -705,6 +705,7 @@ function () {
require_once __DIR__ . '/migrations/class-erase-bnpl-announcement-meta.php';
require_once __DIR__ . '/migrations/class-erase-deprecated-flags-and-options.php';
require_once __DIR__ . '/migrations/class-manual-capture-payment-method-settings-update.php';
require_once __DIR__ . '/migrations/class-migrate-payment-request-to-express-checkout-enabled.php';
add_action( 'woocommerce_woocommerce_payments_updated', [ new Allowed_Payment_Request_Button_Types_Update( self::get_gateway() ), 'maybe_migrate' ] );
add_action( 'woocommerce_woocommerce_payments_updated', [ new \WCPay\Migrations\Allowed_Payment_Request_Button_Sizes_Update( self::get_gateway() ), 'maybe_migrate' ] );
add_action( 'woocommerce_woocommerce_payments_updated', [ new \WCPay\Migrations\Update_Service_Data_From_Server( self::get_account_service() ), 'maybe_migrate' ] );
Expand All @@ -717,6 +718,7 @@ function () {
add_action( 'woocommerce_woocommerce_payments_updated', [ new \WCPay\Migrations\Erase_Bnpl_Announcement_Meta(), 'maybe_migrate' ] );
add_action( 'woocommerce_woocommerce_payments_updated', [ new \WCPay\Migrations\Erase_Deprecated_Flags_And_Options(), 'maybe_migrate' ] );
add_action( 'woocommerce_woocommerce_payments_updated', [ new \WCPay\Migrations\Manual_Capture_Payment_Method_Settings_Update( self::get_gateway(), self::get_payment_gateway_map() ), 'maybe_migrate' ] );
add_action( 'woocommerce_woocommerce_payments_updated', [ new \WCPay\Migrations\Migrate_Payment_Request_To_Express_Checkout_Enabled(), 'maybe_migrate' ] );

include_once WCPAY_ABSPATH . '/includes/class-wc-payments-explicit-price-formatter.php';
WC_Payments_Explicit_Price_Formatter::init();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ public function init() {
$this->express_checkout_button_handler->init();

$is_woopay_enabled = WC_Payments_Features::is_woopay_enabled();
$is_payment_request_enabled = 'yes' === $this->gateway->get_option( 'payment_request' );
$is_payment_request_enabled = $this->gateway->is_payment_request_enabled();

if ( $is_woopay_enabled ) {
add_action( 'wc_ajax_wcpay_add_to_cart', [ $this->express_checkout_ajax_handler, 'ajax_add_to_cart' ] );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,8 @@ public function init() {
return;
}

// Checks if Payment Request is enabled.
if ( 'yes' !== $this->gateway->get_option( 'payment_request' ) ) {
// Checks if Google Pay or Apple Pay are enabled.
if ( ! $this->gateway->is_payment_request_enabled() ) {
return;
}

Expand Down
Loading
Loading