Commit d9eec7d26a7 for woocommerce
commit d9eec7d26a7fd0b81ca66fb0ce28693ed37dc1a1
Author: Jorge A. Torres <jorge.torres@automattic.com>
Date: Fri Oct 30 08:47:29 2026 -0500
Ensure consistent hash/attribute ordering when adding variations to cart (#70391)
diff --git a/plugins/woocommerce/changelog/fix-cart-id-variation-attribute-order b/plugins/woocommerce/changelog/fix-cart-id-variation-attribute-order
new file mode 100644
index 00000000000..1450a6f78ef
--- /dev/null
+++ b/plugins/woocommerce/changelog/fix-cart-id-variation-attribute-order
@@ -0,0 +1,4 @@
+Significance: patch
+Type: fix
+
+Fix a "Sold individually" product variation sometimes being allowed into the cart more than once.
diff --git a/plugins/woocommerce/includes/class-wc-cart.php b/plugins/woocommerce/includes/class-wc-cart.php
index bff0e8d4dce..e61e8d60ba4 100644
--- a/plugins/woocommerce/includes/class-wc-cart.php
+++ b/plugins/woocommerce/includes/class-wc-cart.php
@@ -1156,6 +1156,8 @@ class WC_Cart extends WC_Legacy_Cart {
}
if ( is_array( $variation ) && ! empty( $variation ) ) {
+ // Sort for consistent item identification regardless of attribute order.
+ ksort( $variation );
$variation_key = '';
foreach ( $variation as $key => $value ) {
$variation_key .= trim( $key ) . trim( $value );
diff --git a/plugins/woocommerce/tests/php/includes/class-wc-cart-test.php b/plugins/woocommerce/tests/php/includes/class-wc-cart-test.php
index 8b77a9b45df..b21257ee273 100644
--- a/plugins/woocommerce/tests/php/includes/class-wc-cart-test.php
+++ b/plugins/woocommerce/tests/php/includes/class-wc-cart-test.php
@@ -222,6 +222,30 @@ class WC_Cart_Test extends \WC_Unit_Test_Case {
$product->delete( true );
}
+ /**
+ * @testdox generate_cart_id should not depend on the order the variation attributes are listed in
+ */
+ public function test_generate_cart_id_ignores_variation_attribute_order(): void {
+ $this->assertSame(
+ WC()->cart->generate_cart_id(
+ 1,
+ 2,
+ array(
+ 'attribute_pa_size' => 'small',
+ 'attribute_pa_colour' => 'red',
+ )
+ ),
+ WC()->cart->generate_cart_id(
+ 1,
+ 2,
+ array(
+ 'attribute_pa_colour' => 'red',
+ 'attribute_pa_size' => 'small',
+ )
+ )
+ );
+ }
+
/**
* @testdox should throw a notice to the cart if an "any" attribute is empty.
*/