Commit 7f77d4be91 for woocommerce

commit 7f77d4be91496206d119adaf9ae15e987b661196
Author: Raluca Stan <ralucastn@gmail.com>
Date:   Fri Dec 12 15:06:49 2025 +0100

    Store API: Orders endpoint returns an empty array for the `variation` field on simple products (#62162)

    * Order endpoint: Protect against parsing non-string attribute values

    Ensures that attribute values are strings before attempting taxonomy lookups.

    This prevents errors when a simple product's custom attribute has the same slug as a global attribute, which can result in a WC_Product_Attribute object being passed instead of a string.

    Addresses: wooplug-5907-uncaught-error-object-of-class-wc_product_attribute-could

    * Add tests and changelog

    * Revert "Order endpoint: Protect against parsing non-string attribute values"

    This reverts commit 740c4d5db83cb3801846a07b66e93b50aee5b6a7.

    * Undo test

    * Keep variation an empty array for order items that are simple products

    * Use instanceof WC_Product_Variation which PHPStan understands for type narrowing

    * Call $product->get_attributes to keep current behaviour

    * Update changelog

diff --git a/plugins/woocommerce/changelog/wooplug-5907-uncaught-error-object-of-class-wc_product_attribute-could b/plugins/woocommerce/changelog/wooplug-5907-uncaught-error-object-of-class-wc_product_attribute-could
new file mode 100644
index 0000000000..a7b43cd20f
--- /dev/null
+++ b/plugins/woocommerce/changelog/wooplug-5907-uncaught-error-object-of-class-wc_product_attribute-could
@@ -0,0 +1,4 @@
+Significance: patch
+Type: fix
+
+Fix: Store API: Orders endpoint now returns an empty array for the `variation` field on simple products, matching cart endpoint behavior.
diff --git a/plugins/woocommerce/src/StoreApi/Schemas/V1/OrderItemSchema.php b/plugins/woocommerce/src/StoreApi/Schemas/V1/OrderItemSchema.php
index 375c7f7610..03cef4899b 100644
--- a/plugins/woocommerce/src/StoreApi/Schemas/V1/OrderItemSchema.php
+++ b/plugins/woocommerce/src/StoreApi/Schemas/V1/OrderItemSchema.php
@@ -72,7 +72,11 @@ class OrderItemSchema extends ItemSchema {
 			$product_properties['prices']             = $this->prepare_product_price_response( $product, get_option( 'woocommerce_tax_display_cart' ) );
 			$product_properties['sold_individually']  = $product->is_sold_individually();
 			$product_properties['images']             = $this->get_images( $product );
-			$product_properties['variation']          = $this->format_variation_data( $product->get_attributes(), $product );
+			// Only include variation data for product variations, not simple products.
+			// This is consistent with the cart endpoint behavior.
+			if ( $product instanceof \WC_Product_Variation ) {
+				$product_properties['variation'] = $this->format_variation_data( $product->get_attributes(), $product );
+			}
 		}

 		return [
diff --git a/plugins/woocommerce/tests/php/src/Blocks/StoreApi/Schemas/OrderItemSchemaTest.php b/plugins/woocommerce/tests/php/src/Blocks/StoreApi/Schemas/OrderItemSchemaTest.php
index ec04cbff33..21bd272146 100644
--- a/plugins/woocommerce/tests/php/src/Blocks/StoreApi/Schemas/OrderItemSchemaTest.php
+++ b/plugins/woocommerce/tests/php/src/Blocks/StoreApi/Schemas/OrderItemSchemaTest.php
@@ -159,4 +159,85 @@ class OrderItemSchemaTest extends TestCase {
 		$this->assertEquals( $item->get_name(), $result['name'] );
 		$this->assertEquals( $item->get_quantity(), $result['quantity'] );
 	}
+
+	/**
+	 * Test that simple products return empty variation array.
+	 *
+	 * Simple products don't have variations, so the variation field should be empty.
+	 * This is consistent with the cart endpoint behavior.
+	 */
+	public function test_get_item_response_simple_product_has_empty_variation(): void {
+		// Arrange - Create a simple product with attributes.
+		$product = \WC_Helper_Product::create_simple_product();
+		$product->set_attributes(
+			array(
+				'size' => new \WC_Product_Attribute(
+					array(
+						'name'    => 'size',
+						'options' => array( 'Small', 'Medium' ),
+					)
+				),
+			)
+		);
+		$product->save();
+
+		// Create an order with this product.
+		$order = new \WC_Order();
+		$order->add_product( $product, 1 );
+		$order->save();
+
+		$items = $order->get_items();
+		$item  = reset( $items );
+
+		// Act - Get item response.
+		$result = $this->sut->get_item_response( $item );
+
+		// Assert - variation should be empty for simple products.
+		$this->assertArrayHasKey( 'variation', $result );
+		$this->assertIsArray( $result['variation'] );
+		$this->assertEmpty( $result['variation'] );
+
+		// Cleanup.
+		$order->delete( true );
+		$product->delete( true );
+	}
+
+	/**
+	 * Test that product variations return variation attributes.
+	 *
+	 * Product variations should have their selected variation attributes
+	 * included in the response.
+	 */
+	public function test_get_item_response_variation_product_has_variation_data(): void {
+		// Arrange - Create a variable product with variations.
+		$variable_product = \WC_Helper_Product::create_variation_product();
+		$variations       = $variable_product->get_children();
+		$variation        = wc_get_product( $variations[0] );
+
+		// Create an order with the variation.
+		$order = new \WC_Order();
+		$order->add_product( $variation, 1 );
+		$order->save();
+
+		$items = $order->get_items();
+		$item  = reset( $items );
+
+		// Act - Get item response.
+		$result = $this->sut->get_item_response( $item );
+
+		// Assert - variation should contain the variation attributes.
+		$this->assertArrayHasKey( 'variation', $result );
+		$this->assertIsArray( $result['variation'] );
+		$this->assertNotEmpty( $result['variation'] );
+
+		// Verify structure of variation data.
+		$first_variation = $result['variation'][0];
+		$this->assertArrayHasKey( 'raw_attribute', $first_variation );
+		$this->assertArrayHasKey( 'attribute', $first_variation );
+		$this->assertArrayHasKey( 'value', $first_variation );
+
+		// Cleanup.
+		$order->delete( true );
+		$variable_product->delete( true );
+	}
 }