Skip to content

Commit

Permalink
fix: action.reject for applepay and googlepay
Browse files Browse the repository at this point in the history
  • Loading branch information
ribeiroguilherme committed Feb 26, 2024
1 parent 9bd295b commit 34d8420
Show file tree
Hide file tree
Showing 5 changed files with 110 additions and 10 deletions.
41 changes: 41 additions & 0 deletions packages/lib/src/components/ApplePay/ApplePay.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,47 @@ describe('ApplePay', () => {

expect(onPaymentFailedMock).toHaveBeenCalledTimes(1);
});

test('should pass an empty error to ApplePay if action.reject is used without errors being passed to it', async () => {
const onPaymentFailedMock = jest.fn();
const event = mock<ApplePayJS.ApplePayPaymentAuthorizedEvent>({
payment: {
token: {
paymentData: 'payment-data'
}
}
});

const applepay = new ApplePay(global.core, {
amount: { currency: 'EUR', value: 2000 },
onPaymentFailed: onPaymentFailedMock,
onSubmit(state, component, actions) {
actions.reject();
}
});

applepay.submit();

// Session initialized
await new Promise(process.nextTick);
expect(jest.spyOn(ApplePayService.prototype, 'begin')).toHaveBeenCalledTimes(1);

// Trigger ApplePayService onPaymentAuthorized property
// @ts-ignore ApplePayService is mocked
const onPaymentAuthorized = ApplePayService.mock.calls[0][1].onPaymentAuthorized;
const resolveMock = jest.fn();
const rejectMock = jest.fn();
onPaymentAuthorized(resolveMock, rejectMock, event);

await new Promise(process.nextTick);
expect(rejectMock).toHaveBeenCalledWith({
errors: undefined,
status: 0
});

expect(onPaymentFailedMock).toHaveBeenCalledTimes(1);
expect(onPaymentFailedMock).toHaveBeenCalledWith({ error: { applePayError: undefined } }, applepay);
});
});
describe('onOrderTrackingRequest()', () => {
test('should collect order details and pass it to Apple', async () => {
Expand Down
13 changes: 10 additions & 3 deletions packages/lib/src/components/ApplePay/ApplePay.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@ import { resolveSupportedVersion, mapBrands, formatApplePayContactToAdyenAddress
import AdyenCheckoutError from '../../core/Errors/AdyenCheckoutError';
import { TxVariants } from '../tx-variants';
import { sanitizeResponse, verifyPaymentDidNotFail } from '../internal/UIElement/utils';
import { ANALYTICS_INSTANT_PAYMENT_BUTTON, ANALYTICS_SELECTED_STR } from '../../core/Analytics/constants';
import type { ApplePayConfiguration, ApplePayElementData, ApplePayPaymentOrderDetails, ApplePaySessionRequest } from './types';
import type { ICore } from '../../core/types';
import type { PaymentResponseData, RawPaymentResponse } from '../../types/global-types';
import { ANALYTICS_INSTANT_PAYMENT_BUTTON, ANALYTICS_SELECTED_STR } from '../../core/Analytics/constants';

const latestSupportedVersion = 14;

Expand Down Expand Up @@ -122,15 +122,22 @@ class ApplePayElement extends UIElement<ApplePayConfiguration> {
.then(paymentResponse => {
this.handleResponse(paymentResponse);
})
.catch((paymentResponse: RawPaymentResponse) => {
.catch((paymentResponse?: RawPaymentResponse) => {
const errors = paymentResponse?.error?.applePayError;

reject({
status: ApplePaySession.STATUS_FAILURE,
errors: errors ? (Array.isArray(errors) ? errors : [errors]) : undefined
});

this.handleFailedResult(paymentResponse);
const responseWithError: RawPaymentResponse = {
...paymentResponse,
error: {
applePayError: errors
}
};

this.handleFailedResult(responseWithError);
});
}
});
Expand Down
47 changes: 46 additions & 1 deletion packages/lib/src/components/GooglePay/GooglePay.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,52 @@ describe('GooglePay', () => {
transactionState: 'ERROR'
});

expect(onPaymentFailedMock).toHaveBeenCalledWith({ resultCode: 'Refused', error: { googlePayError: 'Insufficient funds' } }, gpay);
expect(onPaymentFailedMock).toHaveBeenCalledWith(
{
resultCode: 'Refused',
error: {
googlePayError: {
intent: 'PAYMENT_AUTHORIZATION',
message: 'Insufficient funds',
reason: 'OTHER_ERROR'
}
}
},
gpay
);
});

test('should pass error to GooglePay when action.reject is called without parameters', async () => {
const onSubmitMock = jest.fn().mockImplementation((data, component, actions) => {
actions.reject();
});
const onPaymentFailedMock = jest.fn();

const gpay = new GooglePay(global.core, {
i18n: global.i18n,
onSubmit: onSubmitMock,
onPaymentFailed: onPaymentFailedMock
});

// @ts-ignore GooglePayService is mocked
const onPaymentAuthorized = GooglePayService.mock.calls[0][0].paymentDataCallbacks.onPaymentAuthorized;
const promise = onPaymentAuthorized(googlePaymentData);

await new Promise(process.nextTick);

expect(promise).resolves.toEqual({
error: {
intent: 'PAYMENT_AUTHORIZATION',
message: 'Payment failed',
reason: 'OTHER_ERROR'
},
transactionState: 'ERROR'
});

expect(onPaymentFailedMock).toHaveBeenCalledWith(
{ error: { googlePayError: { intent: 'PAYMENT_AUTHORIZATION', message: 'Payment failed', reason: 'OTHER_ERROR' } } },
gpay
);
});
});

Expand Down
17 changes: 12 additions & 5 deletions packages/lib/src/components/GooglePay/GooglePay.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ import collectBrowserInfo from '../../utils/browserInfo';
import AdyenCheckoutError from '../../core/Errors/AdyenCheckoutError';
import { TxVariants } from '../tx-variants';
import { sanitizeResponse, verifyPaymentDidNotFail } from '../internal/UIElement/utils';
import { ANALYTICS_INSTANT_PAYMENT_BUTTON, ANALYTICS_SELECTED_STR } from '../../core/Analytics/constants';
import type { AddressData, PaymentResponseData, RawPaymentResponse } from '../../types/global-types';
import type { GooglePayConfiguration } from './types';
import { ICore } from '../../core/types';
import { ANALYTICS_INSTANT_PAYMENT_BUTTON, ANALYTICS_SELECTED_STR } from '../../core/Analytics/constants';
import type { ICore } from '../../core/types';

class GooglePay extends UIElement<GooglePayConfiguration> {
public static type = TxVariants.googlepay;
Expand Down Expand Up @@ -113,10 +113,10 @@ class GooglePay extends UIElement<GooglePayConfiguration> {
.then(paymentResponse => {
this.handleResponse(paymentResponse);
})
.catch((paymentResponse: RawPaymentResponse) => {
.catch((paymentResponse?: RawPaymentResponse) => {
this.setElementStatus('ready');

const googlePayError = paymentResponse.error?.googlePayError;
const googlePayError = paymentResponse?.error?.googlePayError;
const fallbackMessage = this.props.i18n.get('error.subtitle.payment');

const error: google.payments.api.PaymentDataError =
Expand All @@ -137,7 +137,14 @@ class GooglePay extends UIElement<GooglePayConfiguration> {
error
});

this.handleFailedResult(paymentResponse);
const responseWithError = {
...paymentResponse,
error: {
googlePayError: error
}
};

this.handleFailedResult(responseWithError);
});
});
};
Expand Down
2 changes: 1 addition & 1 deletion packages/lib/src/core/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ export interface CoreConfiguration {
element: UIElement,
actions: {
resolve: (response: CheckoutAdvancedFlowResponse) => void;
reject: () => void;
reject: (error?: Pick<CheckoutAdvancedFlowResponse, 'error'>) => void;
}
): void;

Expand Down

0 comments on commit 34d8420

Please sign in to comment.