Commit 257ced44c50 for woocommerce

commit 257ced44c501e42094b3e3cfeecbee5768c7cd3c
Author: Christopher Hertel <mail@christopher-hertel.de>
Date:   Fri Nov 6 00:18:16 2026 +0100

    Report whether product-delete trashed or permanently deleted a product (#70717)

    * Report whether product-delete trashed or permanently deleted

    * Add changelog entry for product-delete result status

    * Describe only the requested product in the product-delete result

    * Drop the always-true deleted field from the product-delete result

diff --git a/plugins/woocommerce/changelog/wooai-1655-trash-vs-permanent b/plugins/woocommerce/changelog/wooai-1655-trash-vs-permanent
new file mode 100644
index 00000000000..13feb0a8159
--- /dev/null
+++ b/plugins/woocommerce/changelog/wooai-1655-trash-vs-permanent
@@ -0,0 +1,4 @@
+Significance: patch
+Type: tweak
+
+Say in the product-delete ability result whether a product was moved to the trash or deleted permanently.
diff --git a/plugins/woocommerce/src/Internal/Abilities/Domain/ProductDelete.php b/plugins/woocommerce/src/Internal/Abilities/Domain/ProductDelete.php
index 76dfa59b35a..9582cc2dec8 100644
--- a/plugins/woocommerce/src/Internal/Abilities/Domain/ProductDelete.php
+++ b/plugins/woocommerce/src/Internal/Abilities/Domain/ProductDelete.php
@@ -8,6 +8,7 @@ declare( strict_types=1 );
 namespace Automattic\WooCommerce\Internal\Abilities\Domain;

 use Automattic\WooCommerce\Abilities\ActionableAbility;
+use Automattic\WooCommerce\Enums\ProductStatus;
 use Automattic\WooCommerce\Internal\Abilities\Domain\Traits\DomainAbilityHelpers;
 use Automattic\WooCommerce\Internal\Abilities\Domain\Traits\ProductAbilityTrait;

@@ -31,6 +32,11 @@ class ProductDelete extends ActionableAbility {
 	 */
 	public const ABILITY_NAME = 'woocommerce/product-delete';

+	/**
+	 * The result status of a forced delete, which leaves nothing to restore.
+	 */
+	private const STATUS_DELETED = 'deleted';
+
 	/**
 	 * ID of the product the call deletes, kept because a forced delete clears the object's ID.
 	 *
@@ -84,12 +90,12 @@ class ProductDelete extends ActionableAbility {
 		return array(
 			'label'               => __( 'Delete product', 'woocommerce' ),
 			'description'         => __(
-				'Delete, trash, or restore a product.',
+				'Move a product to the trash, or delete it permanently.',
 				'woocommerce'
 			),
 			'category'            => 'woocommerce',
 			'input_schema'        => self::build_input_schema(),
-			'output_schema'       => self::get_delete_output_schema(),
+			'output_schema'       => self::build_output_schema(),
 			'permission_callback' => array( __CLASS__, 'can_delete_product' ),
 			'meta'                => array(
 				'show_in_rest' => true,
@@ -287,8 +293,8 @@ class ProductDelete extends ActionableAbility {
 		unset( $subject );

 		return array(
-			'deleted' => true,
-			'id'      => $this->product_id,
+			'id'     => $this->product_id,
+			'status' => $this->force ? self::STATUS_DELETED : ProductStatus::TRASH,
 		);
 	}

@@ -330,4 +336,27 @@ class ProductDelete extends ActionableAbility {
 			'additionalProperties' => false,
 		);
 	}
+
+	/**
+	 * Get the output schema.
+	 *
+	 * @return array
+	 */
+	private static function build_output_schema(): array {
+		return array(
+			'type'                 => 'object',
+			'properties'           => array(
+				'id'     => array(
+					'type'        => 'integer',
+					'description' => __( 'ID of the product.', 'woocommerce' ),
+				),
+				'status' => array(
+					'type'        => 'string',
+					'enum'        => array( ProductStatus::TRASH, self::STATUS_DELETED ),
+					'description' => __( 'What happened to the product. "trash": the product was moved to the trash, and can be restored. "deleted": the product was permanently deleted, and cannot be restored.', 'woocommerce' ),
+				),
+			),
+			'additionalProperties' => false,
+		);
+	}
 }
diff --git a/plugins/woocommerce/src/Internal/Abilities/Domain/Traits/DomainAbilityHelpers.php b/plugins/woocommerce/src/Internal/Abilities/Domain/Traits/DomainAbilityHelpers.php
index 70aaabe15ba..2ac2de67c68 100644
--- a/plugins/woocommerce/src/Internal/Abilities/Domain/Traits/DomainAbilityHelpers.php
+++ b/plugins/woocommerce/src/Internal/Abilities/Domain/Traits/DomainAbilityHelpers.php
@@ -98,22 +98,6 @@ trait DomainAbilityHelpers {
 		);
 	}

-	/**
-	 * Get a delete output schema.
-	 *
-	 * @return array
-	 */
-	protected static function get_delete_output_schema(): array {
-		return array(
-			'type'                 => 'object',
-			'properties'           => array(
-				'deleted' => array( 'type' => 'boolean' ),
-				'id'      => array( 'type' => 'integer' ),
-			),
-			'additionalProperties' => false,
-		);
-	}
-
 	/**
 	 * Get an ID value from ability input.
 	 *
diff --git a/plugins/woocommerce/tests/php/src/Internal/Abilities/AbilitiesLoaderTest.php b/plugins/woocommerce/tests/php/src/Internal/Abilities/AbilitiesLoaderTest.php
index 0c846de9aaf..a76dd2d999d 100644
--- a/plugins/woocommerce/tests/php/src/Internal/Abilities/AbilitiesLoaderTest.php
+++ b/plugins/woocommerce/tests/php/src/Internal/Abilities/AbilitiesLoaderTest.php
@@ -3900,8 +3900,8 @@ class AbilitiesLoaderTest extends \WC_Unit_Test_Case {
 		);

 		$this->assertNotWPError( $result );
-		$this->assertTrue( $result['deleted'] );
 		$this->assertSame( $product->get_id(), $result['id'] );
+		$this->assertSame( 'deleted', $result['status'] );
 		$this->assertNull( get_post( $product->get_id() ) );
 	}

@@ -3919,7 +3919,7 @@ class AbilitiesLoaderTest extends \WC_Unit_Test_Case {
 		);

 		$this->assertNotWPError( $result );
-		$this->assertTrue( $result['deleted'] );
+		$this->assertSame( 'deleted', $result['status'] );
 		$this->assertNull( get_post( $variation_id ) );
 	}

@@ -3937,7 +3937,7 @@ class AbilitiesLoaderTest extends \WC_Unit_Test_Case {
 		);

 		$this->assertNotWPError( $result );
-		$this->assertTrue( $result['deleted'] );
+		$this->assertSame( 'trash', $result['status'] );
 		$this->assertSame( 'trash', get_post_status( $product->get_id() ) );
 	}

diff --git a/plugins/woocommerce/tests/php/src/Internal/AbilitiesApi/ExtensibleAbilitiesTest.php b/plugins/woocommerce/tests/php/src/Internal/AbilitiesApi/ExtensibleAbilitiesTest.php
index ef24c44d244..9e9c6704053 100644
--- a/plugins/woocommerce/tests/php/src/Internal/AbilitiesApi/ExtensibleAbilitiesTest.php
+++ b/plugins/woocommerce/tests/php/src/Internal/AbilitiesApi/ExtensibleAbilitiesTest.php
@@ -2958,7 +2958,7 @@ class ExtensibleAbilitiesTest extends \WC_REST_Unit_Test_Case {
 		$this->assertSame( 400, $refused->get_status() );
 		$this->assertStringEndsWith( 'test_keep', $refused->get_data()['code'] );
 		$this->assertInstanceOf( \WC_Product::class, wc_get_product( $kept->get_id() ) );
-		$this->assertTrue( $deleted['deleted'] );
+		$this->assertSame( 'deleted', $deleted['status'] );
 		$this->assertFalse( wc_get_product( $created['product']['id'] ) );
 		$this->assertNull( get_post( $created['product']['variation_ids'][0] ), 'The variations go with the parent.' );
 	}
@@ -3080,7 +3080,7 @@ class ExtensibleAbilitiesTest extends \WC_REST_Unit_Test_Case {
 		$this->assertSame( 400, $refused->get_status() );
 		$this->assertSame( 'Keep it.', $refused->get_data()['message'] );
 		$this->assertInstanceOf( \WC_Product_Variable::class, $after );
-		$this->assertTrue( $deleted['deleted'] );
+		$this->assertSame( 'deleted', $deleted['status'] );
 		foreach ( $created['product']['variation_ids'] as $variation_id ) {
 			$this->assertSame( array( 'woocommerce/product-delete', true ), $seen[ $variation_id ] );
 		}