Commit 99d6aeb02d7 for woocommerce

commit 99d6aeb02d7882365c41ab08ec2f80f103476fc6
Author: Daniel Mallory <daniel.mallory@automattic.com>
Date:   Fri Sep 11 20:34:05 2026 +0100

    Fix product attribute Term ID sorting (#68517)

    * fix: honor product attribute term ID ordering

    * docs: add attribute term ordering changelog

diff --git a/plugins/woocommerce/changelog/fix-45521-attribute-term-id-order b/plugins/woocommerce/changelog/fix-45521-attribute-term-id-order
new file mode 100644
index 00000000000..4551566b2bd
--- /dev/null
+++ b/plugins/woocommerce/changelog/fix-45521-attribute-term-id-order
@@ -0,0 +1,4 @@
+Significance: patch
+Type: fix
+
+Honor the Term ID sort order for product attribute terms and variation dropdowns.
diff --git a/plugins/woocommerce/includes/wc-term-functions.php b/plugins/woocommerce/includes/wc-term-functions.php
index f74c91954ed..4c70a4c2bc9 100644
--- a/plugins/woocommerce/includes/wc-term-functions.php
+++ b/plugins/woocommerce/includes/wc-term-functions.php
@@ -37,6 +37,9 @@ function wc_change_get_terms_defaults( $defaults, $taxonomies ) {
 	// Change defaults. Invalid values will be changed later @see wc_change_pre_get_terms.
 	// These are in place so we know if a specific order was requested.
 	switch ( $orderby ) {
+		case 'id':
+			$defaults['orderby'] = 'term_id';
+			break;
 		case 'menu_order':
 		case 'name_num':
 		case 'parent':
diff --git a/plugins/woocommerce/tests/php/includes/wc-term-functions-tests.php b/plugins/woocommerce/tests/php/includes/wc-term-functions-tests.php
index 7246e21fcb9..abe374c4436 100644
--- a/plugins/woocommerce/tests/php/includes/wc-term-functions-tests.php
+++ b/plugins/woocommerce/tests/php/includes/wc-term-functions-tests.php
@@ -86,6 +86,35 @@ class WC_Term_Functions_Tests extends \WC_Unit_Test_Case {
 		parent::tearDown();
 	}

+	/**
+	 * @testdox Should honor the attribute's Term ID default without overriding explicit query ordering.
+	 */
+	public function test_attribute_term_id_ordering(): void {
+		global $wc_product_attributes;
+
+		$original_attributes = $wc_product_attributes;
+		$attribute           = WC_Helper_Product::create_attribute( 'id_sort_test', array( 'Zebra', 'Apple', 'Mango' ) );
+		$taxonomy            = $attribute['attribute_taxonomy'];
+		try {
+			wc_update_attribute( $attribute['attribute_id'], array( 'order_by' => 'id' ) );
+			$product_id = $this->products['product1']->get_id();
+			wp_set_object_terms( $product_id, $attribute['term_ids'], $taxonomy );
+
+			$args = array(
+				'taxonomy'   => $taxonomy,
+				'hide_empty' => false,
+				'fields'     => 'names',
+			);
+			$this->assertSame( array( 'Zebra', 'Apple', 'Mango' ), get_terms( $args ), 'Default queries should honor the saved Term ID setting.' );
+			$this->assertSame( array( 'Zebra', 'Apple', 'Mango' ), wc_get_product_terms( $product_id, $taxonomy, array( 'fields' => 'names' ) ), 'Product term queries should use the same default ordering.' );
+			$this->assertSame( array( 'Apple', 'Mango', 'Zebra' ), get_terms( array_merge( $args, array( 'orderby' => 'name' ) ) ), 'An explicit ordering should override the attribute default.' );
+			$this->assertSame( array( 'Mango', 'Apple', 'Zebra' ), get_terms( array_merge( $args, array( 'order' => 'DESC' ) ) ), 'Descending order should use term IDs too.' );
+		} finally {
+			unregister_taxonomy( $taxonomy );
+			$wc_product_attributes = $original_attributes;
+		}
+	}
+
 	/**
 	 * @testdox Term product counts with default settings.
 	 */