Skip to content

Commit d0a08eb

Browse files
author
Anne Mirasol
authored
Hide express checkout if no product variation selected (#4133)
* Hide ECE buttons when product variation selection is needed * Add changelog and readme entries * Add e2e tests
1 parent 6e7e04c commit d0a08eb

File tree

4 files changed

+70
-3
lines changed

4 files changed

+70
-3
lines changed

changelog.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
* Fix - Hide Amazon Pay in settings when legacy checkout is enabled.
3232
* Fix - Fix subscription renewal issues for Amazon Pay.
3333
* Tweak - SPE: Remove radio buttons
34+
* Update - Hide express checkout buttons when no product variation is selected.
3435

3536
= 9.3.1 - 2025-03-14 =
3637
* Fix - Temporarily disables the subscriptions detached notice feature due to long loading times on stores with many subscriptions.

client/entrypoints/express-checkout/index.js

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,24 @@ jQuery( function ( $ ) {
181181
return shippingAddressChangeHandler( api, event, elements );
182182
};
183183

184+
// Check if the product is waiting for a variation to be selected.
185+
const isVariationSelectionNeeded = () => {
186+
// This check only makes sense on the product page.
187+
const isProductPage = getExpressCheckoutData( 'is_product_page' );
188+
if ( ! isProductPage ) {
189+
return false;
190+
}
191+
192+
const isVariationProduct = document.querySelector(
193+
'.single_variation_wrap'
194+
);
195+
const variationId = document.querySelector(
196+
'input[name="variation_id"]'
197+
)?.value;
198+
const variationSelected = variationId && variationId !== '0';
199+
return isVariationProduct && ! variationSelected;
200+
};
201+
184202
const wcStripeECE = {
185203
createButton: ( elements, options ) =>
186204
elements.create( 'expressCheckout', options ),
@@ -418,6 +436,7 @@ jQuery( function ( $ ) {
418436
onReadyHandler( onReadyParams );
419437

420438
if (
439+
! isVariationSelectionNeeded() &&
421440
onReadyParams.availablePaymentMethods &&
422441
Object.values(
423442
onReadyParams.availablePaymentMethods
@@ -707,6 +726,11 @@ jQuery( function ( $ ) {
707726
$( document.body )
708727
.off( 'woocommerce_variation_has_changed' )
709728
.on( 'woocommerce_variation_has_changed', () => {
729+
if ( isVariationSelectionNeeded() ) {
730+
wcStripeECE.hide();
731+
return;
732+
}
733+
710734
wcStripeECE.blockExpressCheckoutButton();
711735

712736
$.when( wcStripeECE.getSelectedProductData() )
@@ -737,6 +761,7 @@ jQuery( function ( $ ) {
737761
response
738762
);
739763
}
764+
740765
wcStripeECE.show();
741766
}
742767
} )
@@ -748,6 +773,14 @@ jQuery( function ( $ ) {
748773
} );
749774
} );
750775

776+
$( document.body )
777+
.off( 'woocommerce_update_variation_values' )
778+
.on( 'woocommerce_update_variation_values', () => {
779+
if ( isVariationSelectionNeeded() ) {
780+
wcStripeECE.hide();
781+
}
782+
} );
783+
751784
$( '.quantity' )
752785
.off( 'input', '.qty' )
753786
.on(

readme.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,5 +141,6 @@ If you get stuck, you can ask for help in the [Plugin Forum](https://wordpress.o
141141
* Fix - Hide Amazon Pay in settings when legacy checkout is enabled.
142142
* Fix - Fix subscription renewal issues for Amazon Pay.
143143
* Tweak - SPE: Remove radio buttons
144+
* Update - Hide express checkout buttons when no product variation is selected.
144145

145146
[See changelog for all versions](https://raw.githubusercontent.com/woocommerce/woocommerce-gateway-stripe/trunk/changelog.txt).

tests/e2e/tests/express-checkout/express-checkout.spec.js

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,7 @@ const addProductToCart = async ( page, productSlug = 'beanie' ) => {
1616
).toBeVisible();
1717
};
1818

19-
const testLink = async ( page, navigateTo, isBlockPage = false ) => {
20-
await page.goto( navigateTo );
21-
19+
const getLinkButton = async ( page, isBlockPage = false ) => {
2220
let frameLocator;
2321
if ( isBlockPage ) {
2422
frameLocator = await page.frameLocator(
@@ -32,6 +30,14 @@ const testLink = async ( page, navigateTo, isBlockPage = false ) => {
3230
const linkButton = await frameLocator.getByRole( 'button', {
3331
name: 'Pay with Link',
3432
} );
33+
34+
return linkButton;
35+
};
36+
37+
const testLink = async ( page, navigateTo, isBlockPage = false ) => {
38+
await page.goto( navigateTo );
39+
40+
const linkButton = await getLinkButton( page, isBlockPage );
3541
await expect( linkButton ).toBeEnabled();
3642

3743
const context = await page.context();
@@ -74,3 +80,29 @@ test.describe( 'customer can use Link express checkout', () => {
7480
await testLink( page, '/checkout', true );
7581
} );
7682
} );
83+
84+
test.describe( 'express checkout and variable products', () => {
85+
test( 'is hidden when no product variation is selected', async ( {
86+
page,
87+
} ) => {
88+
await page.goto( '/product/hoodie' );
89+
90+
// We want to wait for the express checkout element to be loaded,
91+
// before asserting that it is hidden. Immedidately asserting that it is hidden
92+
// might cause the test to pass only because the element is not yet loaded.
93+
const linkContainer = page.locator(
94+
'#wc-stripe-express-checkout-element-link iframe[name^="__privateStripeFrame"]'
95+
);
96+
await expect( linkContainer ).toHaveCount( 1 );
97+
await expect( linkContainer ).toBeHidden();
98+
} );
99+
100+
test( 'is visible when a product variation is selected', async ( {
101+
page,
102+
} ) => {
103+
await page.goto( '/product/hoodie' );
104+
await page.getByLabel( 'Logo', { exact: true } ).selectOption( 'Yes' );
105+
const linkButton = await getLinkButton( page );
106+
await expect( linkButton ).toBeVisible();
107+
} );
108+
} );

0 commit comments

Comments
 (0)