diff --git a/packages/braintree-integration/src/braintree-fastlane/braintree-fastlane-utils.spec.ts b/packages/braintree-integration/src/braintree-fastlane/braintree-fastlane-utils.spec.ts index e92085860c..d5b8993fe3 100644 --- a/packages/braintree-integration/src/braintree-fastlane/braintree-fastlane-utils.spec.ts +++ b/packages/braintree-integration/src/braintree-fastlane/braintree-fastlane-utils.spec.ts @@ -519,6 +519,31 @@ describe('BraintreeFastlaneUtils', () => { ); }); + it('does not authenticate customer if profileData is undefined', async () => { + jest.spyOn( + braintreeFastlaneMock.identity, + 'triggerAuthenticationFlow', + ).mockResolvedValue({ + authenticationState: BraintreeFastlaneAuthenticationState.FAILED, + profileData: undefined, + }); + + const updatePaymentProviderCustomerPayload = { + authenticationState: BraintreeFastlaneAuthenticationState.FAILED, + addresses: [], + instruments: [], + }; + + await subject.initializeBraintreeFastlaneOrThrow(methodId, undefined); + await subject.runPayPalAuthenticationFlowOrThrow(); + + expect(CookieStorage.remove).toHaveBeenCalledWith('bc-fastlane-sessionId'); + expect(braintreeFastlaneMock.identity.triggerAuthenticationFlow).toHaveBeenCalled(); + expect(paymentIntegrationService.updatePaymentProviderCustomer).toHaveBeenCalledWith( + updatePaymentProviderCustomerPayload, + ); + }); + it('preselects billing address with first paypal fastlane billing address', async () => { await subject.initializeBraintreeFastlaneOrThrow(methodId, undefined); await subject.runPayPalAuthenticationFlowOrThrow(); diff --git a/packages/braintree-integration/src/braintree-fastlane/braintree-fastlane-utils.ts b/packages/braintree-integration/src/braintree-fastlane/braintree-fastlane-utils.ts index 3ea8a3089d..b0bfef283c 100644 --- a/packages/braintree-integration/src/braintree-fastlane/braintree-fastlane-utils.ts +++ b/packages/braintree-integration/src/braintree-fastlane/braintree-fastlane-utils.ts @@ -130,7 +130,10 @@ export default class BraintreeFastlaneUtils { const phoneNumber = profileData?.shippingAddress?.phoneNumber || ''; - if (authenticationState === BraintreeFastlaneAuthenticationState.CANCELED) { + if ( + authenticationState === BraintreeFastlaneAuthenticationState.CANCELED || + !profileData + ) { await this.paymentIntegrationService.updatePaymentProviderCustomer({ authenticationState, addresses: [], diff --git a/packages/braintree-utils/src/types.ts b/packages/braintree-utils/src/types.ts index 6b1f21b88b..b9e4540e31 100644 --- a/packages/braintree-utils/src/types.ts +++ b/packages/braintree-utils/src/types.ts @@ -515,13 +515,13 @@ export interface BraintreeFastlaneStylesOption { export enum BraintreeFastlaneAuthenticationState { SUCCEEDED = 'succeeded', FAILED = 'failed', - CANCELED = 'cancelled', + CANCELED = 'canceled', UNRECOGNIZED = 'unrecognized', } export interface BraintreeFastlaneAuthenticationCustomerResult { authenticationState: BraintreeFastlaneAuthenticationState; - profileData: BraintreeFastlaneProfileData; + profileData?: BraintreeFastlaneProfileData; } export interface BraintreeFastlaneProfileData { diff --git a/packages/core/src/shipping/strategies/braintree/braintree-fastlane-shipping-strategy.spec.ts b/packages/core/src/shipping/strategies/braintree/braintree-fastlane-shipping-strategy.spec.ts index 866f3990a3..124357f3cd 100644 --- a/packages/core/src/shipping/strategies/braintree/braintree-fastlane-shipping-strategy.spec.ts +++ b/packages/core/src/shipping/strategies/braintree/braintree-fastlane-shipping-strategy.spec.ts @@ -460,6 +460,42 @@ describe('BraintreeFastlaneShippingStrategy', () => { }); }); + it('update payment provider customer with empty addresses if profileData is undefined', async () => { + const updatePaymentProviderCustomerMock = jest.fn(); + + const lookupCustomerByEmailMock = () => ({ customerContextId: 'asd' }); + const triggerAuthenticationFlowMock = jest.fn().mockImplementation(() => ({ + authenticationState: BraintreeFastlaneAuthenticationState.FAILED, + profileData: undefined, + })); + + jest.spyOn(braintreeIntegrationServiceMock, 'getBraintreeFastlane').mockImplementation( + () => ({ + identity: { + lookupCustomerByEmail: lookupCustomerByEmailMock, + triggerAuthenticationFlow: triggerAuthenticationFlowMock, + }, + }), + ); + + jest.spyOn( + paymentProviderCustomerActionCreator, + 'updatePaymentProviderCustomer', + ).mockImplementation(updatePaymentProviderCustomerMock); + + const strategy = createStrategy(); + + await strategy.initialize(defaultOptions); + + expect(triggerAuthenticationFlowMock).toHaveBeenCalled(); + expect(CookieStorage.remove).toHaveBeenCalledWith('bc-fastlane-sessionId'); + expect(updatePaymentProviderCustomerMock).toHaveBeenCalledWith({ + authenticationState: BraintreeFastlaneAuthenticationState.FAILED, + addresses: [], + instruments: [], + }); + }); + it('update billing address for digital product', async () => { const updatePaymentProviderCustomerMock = jest.fn(); const updateBillingAddressMock = jest.fn(); diff --git a/packages/core/src/shipping/strategies/braintree/braintree-fastlane-shipping-strategy.ts b/packages/core/src/shipping/strategies/braintree/braintree-fastlane-shipping-strategy.ts index 35d54d7d58..6426d58bc4 100644 --- a/packages/core/src/shipping/strategies/braintree/braintree-fastlane-shipping-strategy.ts +++ b/packages/core/src/shipping/strategies/braintree/braintree-fastlane-shipping-strategy.ts @@ -185,7 +185,7 @@ export default class BraintreeFastlaneShippingStrategy implements ShippingStrate customerContextId, ); - if (authenticationState === BraintreeFastlaneAuthenticationState.CANCELED) { + if (authenticationState === BraintreeFastlaneAuthenticationState.CANCELED || !profileData) { await this._store.dispatch( this._paymentProviderCustomerActionCreator.updatePaymentProviderCustomer({ authenticationState,