Commit 3cace7de85 for woocommerce

commit 3cace7de854d11fb6594619f020e03abb154e8ba
Author: Herman <KokkieH@users.noreply.github.com>
Date:   Wed Jan 21 07:36:37 2026 +0200

    Add notice when connected store is deleted from WCCOM (#62864)

    * Fetch helper connection info before calling get_subscriptions()

    - get_subscriptions() calls wp_send_json() which terminates execution, so we never get to the step where we try to fetch helper connection info and set the transient used for url mismatch notice

    * Store in transient if site connection has maybe been deleted on WCCOM

    * Display notice on My Subscriptions if transient set for maybe deleted site

    * Add changefile(s) from automation for the following project(s): woocommerce, woocommerce/client/admin

    ---------

    Co-authored-by: woocommercebot <woocommercebot@users.noreply.github.com>

diff --git a/plugins/woocommerce/changelog/62864-add-WCCOM-1903-notice-when-connected-store-deleted b/plugins/woocommerce/changelog/62864-add-WCCOM-1903-notice-when-connected-store-deleted
new file mode 100644
index 0000000000..060c4a0197
--- /dev/null
+++ b/plugins/woocommerce/changelog/62864-add-WCCOM-1903-notice-when-connected-store-deleted
@@ -0,0 +1,4 @@
+Significance: minor
+Type: enhancement
+
+Display a notice if Helper response from WooCommerce.com indicates the connection might have been removed on that end.
\ No newline at end of file
diff --git a/plugins/woocommerce/client/admin/client/marketplace/components/my-subscriptions/my-subscriptions.tsx b/plugins/woocommerce/client/admin/client/marketplace/components/my-subscriptions/my-subscriptions.tsx
index f3ff924a16..1784fe082b 100644
--- a/plugins/woocommerce/client/admin/client/marketplace/components/my-subscriptions/my-subscriptions.tsx
+++ b/plugins/woocommerce/client/admin/client/marketplace/components/my-subscriptions/my-subscriptions.tsx
@@ -159,6 +159,15 @@ export default function MySubscriptions(): JSX.Element {
 					</Notice>
 				) }

+			{ wccomSettings?.maybe_deleted_connection && (
+				<Notice
+					id={ 'woo-deleted-connection-notice' }
+					description={ wccomSettings?.maybe_deleted_connection }
+					isDismissible={ false }
+					variant="error"
+				/>
+			) }
+
 			<div className="woocommerce-marketplace__my-subscriptions">
 				<InstallModal />
 				<section className="woocommerce-marketplace__my-subscriptions__notices">
diff --git a/plugins/woocommerce/includes/admin/helper/class-wc-helper-admin.php b/plugins/woocommerce/includes/admin/helper/class-wc-helper-admin.php
index 5b10749d4d..30e07aa8c7 100644
--- a/plugins/woocommerce/includes/admin/helper/class-wc-helper-admin.php
+++ b/plugins/woocommerce/includes/admin/helper/class-wc-helper-admin.php
@@ -106,6 +106,7 @@ class WC_Helper_Admin {
 				$settings['wccomHelper']['subscription_missing_notice']  = PluginsHelper::get_missing_subscription_notice();
 				$settings['wccomHelper']['connection_url_notice']        = WC_Woo_Helper_Connection::get_connection_url_notice();
 				$settings['wccomHelper']['has_host_plan_orders']         = WC_Woo_Helper_Connection::has_host_plan_orders();
+				$settings['wccomHelper']['maybe_deleted_connection']     = WC_Woo_Helper_Connection::get_deleted_connection_notice();
 			} else {
 				$settings['wccomHelper']['disconnected_notice'] = PluginsHelper::get_wccom_disconnected_notice();
 			}
diff --git a/plugins/woocommerce/includes/admin/helper/class-wc-helper-subscriptions-api.php b/plugins/woocommerce/includes/admin/helper/class-wc-helper-subscriptions-api.php
index 2bebbd6392..186ad4bab9 100644
--- a/plugins/woocommerce/includes/admin/helper/class-wc-helper-subscriptions-api.php
+++ b/plugins/woocommerce/includes/admin/helper/class-wc-helper-subscriptions-api.php
@@ -162,6 +162,7 @@ class WC_Helper_Subscriptions_API {
 			WC_Helper::refresh_helper_subscriptions();
 			WC_Helper::get_subscriptions();
 			WC_Helper::get_product_usage_notice_rules();
+			WC_Helper::fetch_helper_connection_info();
 			self::get_subscriptions();
 		} catch ( Exception $e ) {
 			wp_send_json_error(
@@ -171,8 +172,6 @@ class WC_Helper_Subscriptions_API {
 				400
 			);
 		}
-
-		WC_Helper::fetch_helper_connection_info();
 	}

 	/**
diff --git a/plugins/woocommerce/includes/admin/helper/class-wc-helper.php b/plugins/woocommerce/includes/admin/helper/class-wc-helper.php
index bfe067c366..5d2d57dd76 100644
--- a/plugins/woocommerce/includes/admin/helper/class-wc-helper.php
+++ b/plugins/woocommerce/includes/admin/helper/class-wc-helper.php
@@ -1801,6 +1801,9 @@ class WC_Helper {
 	public static function fetch_helper_connection_info() {
 		$data = self::get_cached_connection_data();
 		if ( false !== $data ) {
+			if ( ! empty( $data['maybe_deleted_connection'] ) ) {
+				return new WP_Error( 'deleted_connection', 'Connection may have been deleted' );
+			}
 			return $data;
 		}

@@ -1812,8 +1815,15 @@ class WC_Helper {
 			)
 		);

-		$status = wp_remote_retrieve_response_code( $request );
+		$status          = wp_remote_retrieve_response_code( $request );
+		$body            = json_decode( wp_remote_retrieve_body( $request ), true );
+		$connection_data = is_array( $body ) ? $body : array();
+		$message         = $connection_data['message'] ?? '';
+
 		if ( 200 !== $status ) {
+			if ( 'Connected site not found.' === $message || 'Invalid access token' === $message ) {
+				set_transient( self::CACHE_KEY_CONNECTION_DATA, array( 'maybe_deleted_connection' => true ), 1 * HOUR_IN_SECONDS );
+			}
 			return new WP_Error(
 				'invalid_response',
 				'Invalid response from WooCommerce.com',
@@ -1821,8 +1831,6 @@ class WC_Helper {
 			);
 		}

-		$connection_data = json_decode( wp_remote_retrieve_body( $request ), true );
-
 		$url = $connection_data['url'] ?? '';

 		if ( ! empty( $url ) ) {
@@ -2517,7 +2525,7 @@ class WC_Helper {
 	 * Flush connection data cache.
 	 */
 	public static function flush_connection_data_cache() {
-		delete_transient( '_woocommerce_helper_connection_data' );
+		delete_transient( self::CACHE_KEY_CONNECTION_DATA );
 	}

 	/**
diff --git a/plugins/woocommerce/includes/admin/helper/class-wc-woo-helper-connection.php b/plugins/woocommerce/includes/admin/helper/class-wc-woo-helper-connection.php
index 21aafda24e..cb43066e66 100644
--- a/plugins/woocommerce/includes/admin/helper/class-wc-woo-helper-connection.php
+++ b/plugins/woocommerce/includes/admin/helper/class-wc-woo-helper-connection.php
@@ -19,19 +19,20 @@ if ( ! defined( 'ABSPATH' ) ) {
  */
 class WC_Woo_Helper_Connection {
 	/**
-	 * Check if the Woo Update Manager plugin is active.
+	 * Get the notice for the connection URL mismatch.
 	 *
-	 * @return bool
+	 * @return string The notice for the connection URL mismatch.
 	 */
 	public static function get_connection_url_notice(): string {
 		$connection_data = WC_Helper::get_cached_connection_data();
-		if ( false === $connection_data || false === $connection_data['alert_url_mismatch'] ) {
+		if ( false === $connection_data || ! empty( $connection_data['maybe_deleted_connection'] ) || false === ( $connection_data['alert_url_mismatch'] ?? false ) ) {
 			return '';
 		}

 		$auth     = WC_Helper_Options::get( 'auth' );
-		$url      = rtrim( $auth['url'], '/' );
-		$home_url = rtrim( home_url(), '/' );
+		$url_raw  = is_array( $auth ) ? ( $auth['url'] ?? '' ) : '';
+		$url      = esc_html( rtrim( $url_raw, '/' ) );
+		$home_url = esc_html( rtrim( home_url(), '/' ) );
 		if ( empty( $url ) || $home_url === $url ) {
 			return '';
 		}
@@ -44,6 +45,28 @@ class WC_Woo_Helper_Connection {
 		);
 	}

+	/**
+	 * Get the notice for a deleted connection on WCCOM
+	 *
+	 * @return string The notice for a deleted connection on WCCOM.
+	 *
+	 * @since 10.6.0
+	 */
+	public static function get_deleted_connection_notice(): string {
+		$connection_data = WC_Helper::get_cached_connection_data();
+		if ( false === $connection_data || empty( $connection_data['maybe_deleted_connection'] ) ) {
+			return '';
+		}
+
+		$home_url = esc_html( rtrim( home_url(), '/' ) );
+
+		return sprintf(
+		/* translators: 1: home URL */
+			__( 'There is no connection for <b>%1$s</b> on WooCommerce.com. The connection may have been deleted. To fix this, please reconnect your site to <b>WooCommerce.com</b> to ensure everything works correctly.', 'woocommerce' ),
+			$home_url
+		);
+	}
+
 	/**
 	 * Check if the site has and linked host-plan orders.
 	 *
diff --git a/plugins/woocommerce/phpstan-baseline.neon b/plugins/woocommerce/phpstan-baseline.neon
index 0914682a92..58ae1f7b27 100644
--- a/plugins/woocommerce/phpstan-baseline.neon
+++ b/plugins/woocommerce/phpstan-baseline.neon
@@ -5334,18 +5334,6 @@ parameters:
 			count: 8
 			path: includes/admin/helper/class-wc-product-usage-notice.php

-		-
-			message: '#^Cannot access offset ''alert_url_mismatch'' on array\|true\.$#'
-			identifier: offsetAccess.nonOffsetAccessible
-			count: 1
-			path: includes/admin/helper/class-wc-woo-helper-connection.php
-
-		-
-			message: '#^PHPDoc tag @return with type bool is incompatible with native type string\.$#'
-			identifier: return.phpDocType
-			count: 1
-			path: includes/admin/helper/class-wc-woo-helper-connection.php
-
 		-
 			message: '#^PHPDoc tag @return with type int is incompatible with native type string\.$#'
 			identifier: return.phpDocType