Commit 81002c46d8 for woocommerce

commit 81002c46d84a383c8cf5a6cfeb098d6e6f64f3fa
Author: Mayisha <33387139+Mayisha@users.noreply.github.com>
Date:   Mon Nov 24 11:33:47 2025 +0600

    PayPal Standard: Hide gateway for orders v2 for empty payee email (#62017)

    * bail if paypal is not loaded

    * hide paypal gateway for orders v2 when email is empty

    * hide paypal button from blocks page when gateway is not available

    * add tests

    * check if email is empty

    * prevent loading js sdk script and placeholder container when email is not valid

diff --git a/plugins/woocommerce/changelog/62017-fix-empty-payee-email b/plugins/woocommerce/changelog/62017-fix-empty-payee-email
new file mode 100644
index 0000000000..06c28aa2fd
--- /dev/null
+++ b/plugins/woocommerce/changelog/62017-fix-empty-payee-email
@@ -0,0 +1,4 @@
+Significance: patch
+Type: fix
+
+Hide PayPal Standard for orders v2 from the checkout page when the email is empty in the settings.
\ No newline at end of file
diff --git a/plugins/woocommerce/client/legacy/js/gateways/paypal.js b/plugins/woocommerce/client/legacy/js/gateways/paypal.js
index 660516a0bd..1abc9d93c5 100644
--- a/plugins/woocommerce/client/legacy/js/gateways/paypal.js
+++ b/plugins/woocommerce/client/legacy/js/gateways/paypal.js
@@ -11,6 +11,11 @@ jQuery(function ($) {
 			return;
 		}

+		// If PayPal is not loaded, don't try to render the buttons.
+		if ( typeof paypal === 'undefined' ) {
+			return;
+		}
+
 		applyStyles();

 		/**
diff --git a/plugins/woocommerce/includes/gateways/paypal/class-wc-gateway-paypal.php b/plugins/woocommerce/includes/gateways/paypal/class-wc-gateway-paypal.php
index 43592bac11..479a3e1562 100644
--- a/plugins/woocommerce/includes/gateways/paypal/class-wc-gateway-paypal.php
+++ b/plugins/woocommerce/includes/gateways/paypal/class-wc-gateway-paypal.php
@@ -212,7 +212,7 @@ class WC_Gateway_Paypal extends WC_Payment_Gateway {
 				add_action( 'woocommerce_before_thankyou', array( $this, 'update_addresses_in_order' ), 10 );

 				$buttons = new WC_Gateway_Paypal_Buttons( $this );
-				if ( $buttons->is_enabled() ) {
+				if ( $buttons->is_enabled() && ! $this->needs_setup() ) {
 					add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_scripts' ) );
 					add_filter( 'wp_script_attributes', array( $this, 'add_paypal_sdk_attributes' ) );

@@ -340,6 +340,20 @@ class WC_Gateway_Paypal extends WC_Payment_Gateway {
 		$transact_account_manager->do_onboarding();
 	}

+	/**
+	 * Check if the gateway is available for use.
+	 *
+	 * @return bool
+	 */
+	public function is_available() {
+		// For Orders v2, require a valid email address to be set up in the gateway settings.
+		if ( $this->should_use_orders_v2() && $this->needs_setup() ) {
+			return false;
+		}
+
+		return parent::is_available();
+	}
+
 	/**
 	 * Return whether or not this gateway still requires setup to function.
 	 *
@@ -350,7 +364,7 @@ class WC_Gateway_Paypal extends WC_Payment_Gateway {
 	 * @return bool
 	 */
 	public function needs_setup() {
-		return ! is_email( $this->email );
+		return empty( $this->email ) || ! is_email( $this->email );
 	}

 	/**
diff --git a/plugins/woocommerce/src/Blocks/Payments/Integrations/PayPal.php b/plugins/woocommerce/src/Blocks/Payments/Integrations/PayPal.php
index f61a60839d..39b6729026 100644
--- a/plugins/woocommerce/src/Blocks/Payments/Integrations/PayPal.php
+++ b/plugins/woocommerce/src/Blocks/Payments/Integrations/PayPal.php
@@ -70,6 +70,10 @@ final class PayPal extends AbstractPaymentMethodType {
 	public function get_payment_method_data() {
 		$gateway = WC_Gateway_Paypal::get_instance();

+		if ( ! $gateway->is_available() ) {
+			return [];
+		}
+
 		include_once WC_ABSPATH . 'includes/gateways/paypal/class-wc-gateway-paypal-buttons.php';
 		$buttons = new \WC_Gateway_Paypal_Buttons( $gateway );
 		$options = $buttons->get_options();
diff --git a/plugins/woocommerce/tests/php/includes/gateways/paypal/class-wc-gateway-paypal-test.php b/plugins/woocommerce/tests/php/includes/gateways/paypal/class-wc-gateway-paypal-test.php
index 873b999b89..6b04c50f38 100644
--- a/plugins/woocommerce/tests/php/includes/gateways/paypal/class-wc-gateway-paypal-test.php
+++ b/plugins/woocommerce/tests/php/includes/gateways/paypal/class-wc-gateway-paypal-test.php
@@ -223,4 +223,79 @@ class WC_Gateway_Paypal_Test extends \WC_Unit_Test_Case {
 			}
 		}
 	}
+
+	/**
+	 * Test that gateway is available when Orders v2 is disabled (legacy mode).
+	 */
+	public function test_is_available_with_legacy_mode() {
+		// Enable the gateway.
+		update_option( 'woocommerce_paypal_settings', array( 'enabled' => 'yes' ) );
+
+		// Mock Orders v2 to be disabled.
+		$mock_gateway = $this->getMockBuilder( WC_Gateway_Paypal::class )
+			->onlyMethods( array( 'should_use_orders_v2' ) )
+			->getMock();
+		$mock_gateway->method( 'should_use_orders_v2' )->willReturn( false );
+
+		$this->assertTrue( $mock_gateway->is_available() );
+	}
+
+	/**
+	 * Test that gateway availability depends on email field value when Orders v2 is enabled.
+	 *
+	 * @dataProvider gateway_availability_data_provider_for_orders_v2
+	 *
+	 * @param string|null $email The email to set for the gateway.
+	 * @param bool        $expected_available Whether the gateway should be available.
+	 */
+	public function test_is_available_with_orders_v2( ?string $email, bool $expected_available ) {
+		$new_settings = array(
+			'enabled' => 'yes',
+		);
+
+		if ( null !== $email ) {
+			$new_settings['email'] = $email;
+		} else {
+			// Remove the email field from the settings to test the case where the email field is not set.
+			$current_settings = get_option( 'woocommerce_paypal_settings', array() );
+			unset( $current_settings['email'] );
+			$new_settings = array_merge( $new_settings, $current_settings );
+		}
+
+		update_option( 'woocommerce_paypal_settings', $new_settings );
+
+		// Mock Orders v2 to be enabled.
+		$mock_gateway = $this->getMockBuilder( WC_Gateway_Paypal::class )
+			->onlyMethods( array( 'should_use_orders_v2' ) )
+			->getMock();
+		$mock_gateway->method( 'should_use_orders_v2' )->willReturn( true );
+
+		$this->assertSame( $expected_available, $mock_gateway->is_available() );
+	}
+
+	/**
+	 * Data provider for payment gateway availability tests when Orders v2 is enabled.
+	 *
+	 * @return array Test cases with email values and expected paypal gateway availability.
+	 */
+	public function gateway_availability_data_provider_for_orders_v2() {
+		return array(
+			'email field is not set' => array(
+				'email'              => null,
+				'expected_available' => false,
+			),
+			'email is empty string'  => array(
+				'email'              => '',
+				'expected_available' => false,
+			),
+			'email is invalid'       => array(
+				'email'              => 'example@',
+				'expected_available' => false,
+			),
+			'email is valid'         => array(
+				'email'              => 'merchant@example.com',
+				'expected_available' => true,
+			),
+		);
+	}
 }