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 );
+ }
}