Skip to content

Commit

Permalink
Switch to proper input element when using Stripe Link autofill (#8017)
Browse files Browse the repository at this point in the history
Co-authored-by: Timur Karimov <[email protected]>
Co-authored-by: Guilherme Pressutto <[email protected]>
  • Loading branch information
3 people authored and Jinksi committed Jan 30, 2024
1 parent 515c001 commit 12cbfce
Show file tree
Hide file tree
Showing 6 changed files with 78 additions and 1 deletion.
4 changes: 4 additions & 0 deletions changelog/align-stripe-link-behavior
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: minor
Type: add

Select the proper payment element when using saved Stripe Link tokens or choosing to use Stripe Link for new email.
5 changes: 5 additions & 0 deletions client/checkout/blocks/saved-token-handler.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import { useEffect } from 'react';
import { usePaymentCompleteHandler } from './hooks';
import { useSelect } from '@wordpress/data';
import { removeLinkButton } from '../stripe-link';

export const SavedTokenHandler = ( {
api,
Expand Down Expand Up @@ -46,5 +47,9 @@ export const SavedTokenHandler = ( {
false // No need to save a payment that has already been saved.
);

// Once saved token component is loaded, Stripe Link button should be removed,
// because payment elements are not used then and there's no element to attach the button to.
removeLinkButton();

return <></>;
};
5 changes: 4 additions & 1 deletion client/checkout/classic/payment-processing.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@ import {
getUpeSettings,
isLinkEnabled,
} from 'wcpay/checkout/utils/upe';
import enableStripeLinkPaymentMethod from 'wcpay/checkout/stripe-link';
import enableStripeLinkPaymentMethod, {
switchToNewPaymentTokenElement,
} from 'wcpay/checkout/stripe-link';
import {
SHORTCODE_SHIPPING_ADDRESS_FIELDS,
SHORTCODE_BILLING_ADDRESS_FIELDS,
Expand Down Expand Up @@ -347,6 +349,7 @@ export function maybeEnableStripeLink( api ) {
event.preventDefault();
// Trigger modal.
linkAutofill.launch( { email: billingEmailInput.value } );
switchToNewPaymentTokenElement();
} );
},
} );
Expand Down
25 changes: 25 additions & 0 deletions client/checkout/stripe-link/index.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,27 @@
/**
* Internal dependencies
*/
import { dispatchChangeEventFor } from '../utils/upe';

export const switchToNewPaymentTokenElement = () => {
const newPaymentTokenElement = document.getElementById(
'wc-woocommerce_payments-payment-token-new'
);
if ( newPaymentTokenElement && ! newPaymentTokenElement.checked ) {
newPaymentTokenElement.checked = true;
dispatchChangeEventFor( newPaymentTokenElement );
}
};

export const removeLinkButton = () => {
const stripeLinkButton = document.querySelector(
'.wcpay-stripelink-modal-trigger'
);
if ( stripeLinkButton ) {
stripeLinkButton.remove();
}
};

const transformStripeLinkAddress = ( address ) => {
// when clicking "use another address" or "use another payment method", the returned value for shipping/billing might be `null`.
if ( ! address ) return null;
Expand Down Expand Up @@ -40,6 +64,7 @@ const enableStripeLinkPaymentMethod = ( options ) => {
transformStripeLinkAddress( billingAddress ),
transformStripeLinkAddress( shippingAddress )
);
switchToNewPaymentTokenElement();
} );
};

Expand Down
35 changes: 35 additions & 0 deletions client/checkout/utils/test/upe.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
blocksShowLinkButtonHandler,
getSelectedUPEGatewayPaymentMethod,
isUsingSavedPaymentMethod,
dispatchChangeEventFor,
} from '../upe';
import { getPaymentMethodsConstants } from '../../constants';
import { getUPEConfig } from 'wcpay/utils/checkout';
Expand Down Expand Up @@ -533,3 +534,37 @@ describe( 'isUsingSavedPaymentMethod', () => {
expect( isUsingSavedPaymentMethod( paymentMethodType ) ).toBe( false );
} );
} );

describe( 'dispatching change event for element', () => {
it( 'should dispatch a change event with bubbling', () => {
const mockElement = document.createElement( 'input' );
jest.spyOn( mockElement, 'dispatchEvent' );

dispatchChangeEventFor( mockElement );

expect( mockElement.dispatchEvent ).toHaveBeenCalledWith(
expect.objectContaining( {
type: 'change',
bubbles: true,
} )
);
} );

it( 'should throw an error when called with an invalid element', () => {
expect( () => {
dispatchChangeEventFor( null );
} ).toThrow();

expect( () => {
dispatchChangeEventFor( undefined );
} ).toThrow();

expect( () => {
dispatchChangeEventFor( {} );
} ).toThrow();

expect( () => {
dispatchChangeEventFor( 'not-an-element' );
} ).toThrow();
} );
} );
5 changes: 5 additions & 0 deletions client/checkout/utils/upe.js
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,11 @@ export function isUsingSavedPaymentMethod( paymentMethodType ) {
);
}

export function dispatchChangeEventFor( element ) {
const event = new Event( 'change', { bubbles: true } );
element.dispatchEvent( event );
}

/**
*
* Custom React hook that provides customer data and related functions for managing customer information.
Expand Down

0 comments on commit 12cbfce

Please sign in to comment.