Commit 635094bd0c for woocommerce

commit 635094bd0c0ade3f2a7744e5557348eb1657e04b
Author: Eric Binnion <ericbinnion@gmail.com>
Date:   Tue Feb 17 18:12:57 2026 -0600

    Always show payment method radio in checkout (#63351)

    * Always show payment method radio in checkout

    * Add changelog

    * Refactor payment method test helpers

diff --git a/plugins/woocommerce/changelog/update-pay-506-always-show-payment-radio b/plugins/woocommerce/changelog/update-pay-506-always-show-payment-radio
new file mode 100644
index 0000000000..cab78e8f64
--- /dev/null
+++ b/plugins/woocommerce/changelog/update-pay-506-always-show-payment-radio
@@ -0,0 +1,4 @@
+Significance: patch
+Type: fix
+
+Always show radio for payment methods on checkout.
diff --git a/plugins/woocommerce/client/blocks/assets/js/blocks/cart-checkout-shared/payment-methods/payment-method-options.js b/plugins/woocommerce/client/blocks/assets/js/blocks/cart-checkout-shared/payment-methods/payment-method-options.js
index 9e8bdbcd7c..dc21356423 100644
--- a/plugins/woocommerce/client/blocks/assets/js/blocks/cart-checkout-shared/payment-methods/payment-method-options.js
+++ b/plugins/woocommerce/client/blocks/assets/js/blocks/cart-checkout-shared/payment-methods/payment-method-options.js
@@ -7,7 +7,6 @@ import {
 } from '@woocommerce/base-context/hooks';
 import { cloneElement, useCallback } from '@wordpress/element';
 import { useEditorContext } from '@woocommerce/base-context';
-import clsx from 'clsx';
 import { RadioControlAccordion } from '@woocommerce/blocks-components';
 import { useDispatch, useSelect } from '@wordpress/data';
 import { getPaymentMethods } from '@woocommerce/blocks-registry';
@@ -29,7 +28,6 @@ const PaymentMethodOptions = () => {
 		activeSavedToken,
 		activePaymentMethod,
 		isExpressPaymentMethodActive,
-		savedPaymentMethods,
 		availablePaymentMethods,
 	} = useSelect( ( select ) => {
 		const store = select( paymentStore );
@@ -37,7 +35,6 @@ const PaymentMethodOptions = () => {
 			activeSavedToken: store.getActiveSavedToken(),
 			activePaymentMethod: store.getActivePaymentMethod(),
 			isExpressPaymentMethodActive: store.isExpressPaymentMethodActive(),
-			savedPaymentMethods: store.getSavedPaymentMethods(),
 			availablePaymentMethods: store.getAvailablePaymentMethods(),
 		};
 	} );
@@ -86,18 +83,10 @@ const PaymentMethodOptions = () => {
 		]
 	);

-	const isSinglePaymentMethod =
-		Object.keys( savedPaymentMethods ).length === 0 &&
-		Object.keys( availablePaymentMethods ).length === 1;
-
-	const singleOptionClass = clsx( {
-		'disable-radio-control': isSinglePaymentMethod,
-	} );
 	return isExpressPaymentMethodActive ? null : (
 		<RadioControlAccordion
 			highlightChecked={ true }
 			id={ 'wc-payment-method-options' }
-			className={ singleOptionClass }
 			selected={ activeSavedToken ? null : activePaymentMethod }
 			onChange={ onChange }
 			options={ options }
diff --git a/plugins/woocommerce/client/blocks/assets/js/blocks/cart-checkout-shared/payment-methods/style.scss b/plugins/woocommerce/client/blocks/assets/js/blocks/cart-checkout-shared/payment-methods/style.scss
index 2700de7600..7764e8ad06 100644
--- a/plugins/woocommerce/client/blocks/assets/js/blocks/cart-checkout-shared/payment-methods/style.scss
+++ b/plugins/woocommerce/client/blocks/assets/js/blocks/cart-checkout-shared/payment-methods/style.scss
@@ -46,16 +46,6 @@
 		}
 	}

-	.wc-block-components-radio-control.disable-radio-control {
-		.wc-block-components-radio-control__option {
-			padding-left: $gap;
-		}
-
-		.wc-block-components-radio-control__input {
-			display: none;
-		}
-	}
-
 	.wc-block-components-checkout-step__description-payments-aligned {
 		@include font-small-locked;
 		margin: 0;
diff --git a/plugins/woocommerce/client/blocks/assets/js/blocks/cart-checkout-shared/payment-methods/test/payment-methods.js b/plugins/woocommerce/client/blocks/assets/js/blocks/cart-checkout-shared/payment-methods/test/payment-methods.js
index de7b73ec95..fd0bb1883e 100644
--- a/plugins/woocommerce/client/blocks/assets/js/blocks/cart-checkout-shared/payment-methods/test/payment-methods.js
+++ b/plugins/woocommerce/client/blocks/assets/js/blocks/cart-checkout-shared/payment-methods/test/payment-methods.js
@@ -37,9 +37,12 @@ jest.mock( '@woocommerce/blocks-components', () => {
 	return {
 		__esModule: true,
 		...originalModule,
-		RadioControlAccordion: ( { onChange } ) => (
+		RadioControlAccordion: ( { onChange, className = '' } ) => (
 			<>
 				<span>Payment method options</span>
+				<span data-testid="payment-method-options-class-name">
+					{ className }
+				</span>
 				<button onClick={ () => onChange( 'credit-card' ) }>
 					Select new payment
 				</button>
@@ -80,8 +83,8 @@ jest.mock( '@wordpress/data', () => {
 	};
 } );

-const registerMockPaymentMethods = () => {
-	[ 'cod', 'credit-card' ].forEach( ( name ) => {
+const registerMockPaymentMethodsByName = ( names ) => {
+	names.forEach( ( name ) => {
 		registerPaymentMethod( {
 			name,
 			label: name,
@@ -100,6 +103,10 @@ const registerMockPaymentMethods = () => {
 	dispatch( paymentStore ).__internalUpdateAvailablePaymentMethods();
 };

+const registerMockPaymentMethods = () => {
+	registerMockPaymentMethodsByName( [ 'cod', 'credit-card' ] );
+};
+
 const registerMockExpressPaymentMethods = () => {
 	registerExpressPaymentMethod( {
 		name: 'dummy-express',
@@ -111,12 +118,24 @@ const registerMockExpressPaymentMethods = () => {
 	dispatch( paymentStore ).__internalUpdateAvailablePaymentMethods();
 };

-const resetMockPaymentMethods = () => {
-	[ 'cod', 'credit-card' ].forEach( ( name ) => {
+const registerMockSinglePaymentMethod = () => {
+	registerMockPaymentMethodsByName( [ 'cod' ] );
+};
+
+const resetMockPaymentMethodsByName = ( names ) => {
+	names.forEach( ( name ) => {
 		__experimentalDeRegisterPaymentMethod( name );
 	} );
 };

+const resetMockPaymentMethods = () => {
+	resetMockPaymentMethodsByName( [ 'cod', 'credit-card' ] );
+};
+
+const resetMockSinglePaymentMethod = () => {
+	resetMockPaymentMethodsByName( [ 'cod' ] );
+};
+
 const resetMockExpressPaymentMethods = () => {
 	[ 'dummy-express' ].forEach( ( name ) => {
 		__experimentalDeRegisterExpressPaymentMethod( name );
@@ -264,4 +283,36 @@ describe( 'PaymentMethods', () => {

 		act( () => resetMockPaymentMethods() );
 	} );
+
+	test( 'should not apply single-method radio disable class when only one payment method is available', async () => {
+		act( () => {
+			registerMockSinglePaymentMethod();
+		} );
+
+		wpDataFunctions.dispatch( CART_STORE_KEY ).receiveCart( {
+			...previewCart,
+			payment_methods: [ 'cod' ],
+		} );
+
+		await waitFor( () => {
+			expect(
+				wpDataFunctions.select( paymentStore ).getActivePaymentMethod()
+			).toBe( 'cod' );
+		} );
+
+		render( <PaymentMethods /> );
+
+		await waitFor( () => {
+			const paymentMethodOptions = screen.queryByText(
+				/Payment method options/
+			);
+			expect( paymentMethodOptions ).not.toBeNull();
+		} );
+
+		expect(
+			screen.getByTestId( 'payment-method-options-class-name' )
+		).not.toHaveTextContent( /disable-radio-control/ );
+
+		act( () => resetMockSinglePaymentMethod() );
+	} );
 } );