Commit 0b34aab6178 for woocommerce

commit 0b34aab61784732e1ea2c86f3725b11affeecea6
Author: Justin P <228780+layoutd@users.noreply.github.com>
Date:   Tue Aug 18 10:42:32 2026 +0200

    Preserve checkout attribution inputs during deduplication (#67711)

    * Preserve checkout attribution inputs during deduplication

    * Add changelog entry for order attribution deduplication fix

    * Add checkout form precedence regression coverage

    * Fix order attribution deduplication per form

    * Add changefile(s) from automation for the following project(s): woocommerce

    ---------

    Co-authored-by: woocommercebot <woocommercebot@users.noreply.github.com>

diff --git a/plugins/woocommerce/changelog/67711-fix-order-attribution-form-dedup b/plugins/woocommerce/changelog/67711-fix-order-attribution-form-dedup
new file mode 100644
index 00000000000..2d18b94784e
--- /dev/null
+++ b/plugins/woocommerce/changelog/67711-fix-order-attribution-form-dedup
@@ -0,0 +1,5 @@
+Significance: patch
+Type: fix
+Comment: Select if this PR needs a generated summary for release notes:  - [ ] **Feature Highlight** - For user-facing features (what changed, user impact) - [ ] **Developer Advisory** - For developer-facing changes (what changed, how to detect, actions needed)  <details> <summary>When to use each?</summary>  **Feature Highlight**: New features, UI changes, or improvements that merchants/store owners will notice. - Example: "New bulk editing for products", "Improved checkout performance"  **Developer Advisory**: Breaking changes, deprecations, or changes that affect themes/plugins/extensions. - Example: "Hook signature change", "Deprecated filter", "REST API field removed"  An AI will analyze your PR and post a draft comment for you to review and edit.
+
+
diff --git a/plugins/woocommerce/changelog/fix-order-attribution-form-dedup b/plugins/woocommerce/changelog/fix-order-attribution-form-dedup
new file mode 100644
index 00000000000..cc10b2ca22d
--- /dev/null
+++ b/plugins/woocommerce/changelog/fix-order-attribution-form-dedup
@@ -0,0 +1,4 @@
+Significance: patch
+Type: fix
+
+Preserve classic checkout order attribution when duplicate input groups exist outside the checkout form.
diff --git a/plugins/woocommerce/client/legacy/js/frontend/order-attribution.js b/plugins/woocommerce/client/legacy/js/frontend/order-attribution.js
index c409b0599ef..d307803d559 100644
--- a/plugins/woocommerce/client/legacy/js/frontend/order-attribution.js
+++ b/plugins/woocommerce/client/legacy/js/frontend/order-attribution.js
@@ -28,13 +28,19 @@
 	}

 	/**
-	 * Remove duplicate `<wc-order-attribution-inputs>` elements, leaving only the first one,
-	 * to prevent sending the same data multiple times.
+	 * Remove duplicate `<wc-order-attribution-inputs>` elements within each owning form to prevent
+	 * sending the same data multiple times. Treat groups without an enclosing form as document-owned.
 	 */
 	function removeDuplicateInputGroups() {
-		document.querySelectorAll( 'wc-order-attribution-inputs' ).forEach( ( group, index ) => {
-			if ( index > 0 ) {
+		const owners = new Set();
+
+		document.querySelectorAll( 'wc-order-attribution-inputs' ).forEach( ( group ) => {
+			const owner = group.closest( 'form' ) || document;
+
+			if ( owners.has( owner ) ) {
 				group.remove();
+			} else {
+				owners.add( owner );
 			}
 		} );
 	}
diff --git a/plugins/woocommerce/client/legacy/js/frontend/test/order-attribution.js b/plugins/woocommerce/client/legacy/js/frontend/test/order-attribution.js
new file mode 100644
index 00000000000..3c4c4834b66
--- /dev/null
+++ b/plugins/woocommerce/client/legacy/js/frontend/test/order-attribution.js
@@ -0,0 +1,96 @@
+/**
+ * @jest-environment jest-fixed-jsdom
+ */
+
+describe( 'Order attribution input deduplication', () => {
+	beforeAll( () => {
+		window.wc_order_attribution = {
+			fields: {
+				source_type: 'current.typ',
+			},
+			params: {
+				allowTracking: false,
+				prefix: 'wc_order_attribution_',
+			},
+		};
+
+		require( '../order-attribution' );
+	} );
+
+	beforeEach( () => {
+		document.body.innerHTML = '';
+	} );
+
+	afterAll( () => {
+		delete window.wc_order_attribution;
+	} );
+
+	test( 'keeps checkout attribution when an out-of-form group appears first', () => {
+		document.body.innerHTML = `
+			<wc-order-attribution-inputs id="outside-form"></wc-order-attribution-inputs>
+			<form name="checkout">
+				<wc-order-attribution-inputs id="checkout-first"></wc-order-attribution-inputs>
+				<wc-order-attribution-inputs id="checkout-second"></wc-order-attribution-inputs>
+			</form>
+		`;
+
+		window.wc_order_attribution.setOrderTracking( false );
+
+		expect(
+			document.querySelectorAll( 'wc-order-attribution-inputs' )
+		).toHaveLength( 2 );
+		expect( document.getElementById( 'checkout-first' ) ).not.toBeNull();
+		expect( document.getElementById( 'outside-form' ) ).not.toBeNull();
+		expect( document.getElementById( 'checkout-second' ) ).toBeNull();
+		expect(
+			document.querySelector( 'form[name="checkout"]' ).elements.namedItem(
+				'wc_order_attribution_source_type'
+			)
+		).not.toBeNull();
+	} );
+
+	test( 'keeps one group in each form', () => {
+		document.body.innerHTML = `
+			<form name="register">
+				<wc-order-attribution-inputs id="register-first"></wc-order-attribution-inputs>
+				<wc-order-attribution-inputs id="register-second"></wc-order-attribution-inputs>
+			</form>
+			<form name="checkout">
+				<wc-order-attribution-inputs id="checkout-first"></wc-order-attribution-inputs>
+				<wc-order-attribution-inputs id="checkout-second"></wc-order-attribution-inputs>
+			</form>
+		`;
+
+		window.wc_order_attribution.setOrderTracking( false );
+
+		expect(
+			document.querySelectorAll( 'wc-order-attribution-inputs' )
+		).toHaveLength( 2 );
+		expect( document.getElementById( 'register-first' ) ).not.toBeNull();
+		expect( document.getElementById( 'register-second' ) ).toBeNull();
+		expect( document.getElementById( 'checkout-first' ) ).not.toBeNull();
+		expect( document.getElementById( 'checkout-second' ) ).toBeNull();
+		expect(
+			document.querySelector( 'form[name="register"]' ).elements.namedItem(
+				'wc_order_attribution_source_type'
+			)
+		).not.toBeNull();
+		expect(
+			document.querySelector( 'form[name="checkout"]' ).elements.namedItem(
+				'wc_order_attribution_source_type'
+			)
+		).not.toBeNull();
+	} );
+
+	test( 'keeps the first document-owned group', () => {
+		document.body.innerHTML = `
+			<wc-order-attribution-inputs id="first"></wc-order-attribution-inputs>
+			<wc-order-attribution-inputs id="second"></wc-order-attribution-inputs>
+		`;
+
+		window.wc_order_attribution.setOrderTracking( false );
+
+		expect( document.getElementById( 'first' ) ).not.toBeNull();
+		expect( document.getElementById( 'second' ) ).toBeNull();
+	} );
+} );