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.
 	 */