diff --git a/package-lock.json b/package-lock.json
index dbcd18329a..d99f92aa67 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -838,9 +838,9 @@
"integrity": "sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg=="
},
"regenerator-runtime": {
- "version": "0.13.6",
- "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.6.tgz",
- "integrity": "sha512-GmwlGiazQEbOwQWDdbbaP10i15pGtScYWLbMZuu+RKRz0cZ+g8IUONazBnaZqe7j1670IV1HgE4/8iy7CQPf4Q=="
+ "version": "0.13.7",
+ "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz",
+ "integrity": "sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew=="
}
}
},
@@ -1609,9 +1609,9 @@
}
},
"@bigcommerce/checkout-sdk": {
- "version": "1.83.0",
- "resolved": "https://registry.npmjs.org/@bigcommerce/checkout-sdk/-/checkout-sdk-1.83.0.tgz",
- "integrity": "sha512-RqTn3hjP1lhSdpovhwrrCajpSbIzmzK7MzMPRsYAE2mPVaPuoJ1DrtUY2DqQXQuddZIHjGK4CpYRtF6TXljSng==",
+ "version": "1.84.0",
+ "resolved": "https://registry.npmjs.org/@bigcommerce/checkout-sdk/-/checkout-sdk-1.84.0.tgz",
+ "integrity": "sha512-hACODL85dGx/Az3eNqYJzBtDpfFTHuItMP/LHeaUVMvt+Z5QIuFEJVbBuFgE/p+A8C8xw+qnKgAKu8lYJzv/pQ==",
"requires": {
"@babel/polyfill": "^7.4.4",
"@bigcommerce/bigpay-client": "^5.9.0",
@@ -1806,7 +1806,7 @@
"query-string": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/query-string/-/query-string-5.1.1.tgz",
- "integrity": "sha1-p4wBK3HBfgXy4/ojGd0zBoLvs8s=",
+ "integrity": "sha512-gjWOsm2SoGlgLEdAGt7a6slVOk9mGiXmPFMqrEhLQ68rhQuBnpfs3+EmlvqKyxnCo9/PPlF+9MtY02S1aFg+Jw==",
"requires": {
"decode-uri-component": "^0.2.0",
"object-assign": "^4.1.0",
@@ -2263,7 +2263,7 @@
"@types/color-name": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz",
- "integrity": "sha1-HBJhu+qhCoBVu8XYq4S3sq/IRqA="
+ "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ=="
},
"@types/credit-card-type": {
"version": "7.0.0",
@@ -12146,7 +12146,7 @@
"lodash.merge": {
"version": "4.6.2",
"resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
- "integrity": "sha1-VYqlO0O2YeGSWgr9+japoQhf5Xo="
+ "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ=="
},
"lodash.sortby": {
"version": "4.7.0",
diff --git a/package.json b/package.json
index 69abafec19..ba013f3440 100644
--- a/package.json
+++ b/package.json
@@ -23,7 +23,7 @@
},
"homepage": "https://github.com/bigcommerce/checkout-js#readme",
"dependencies": {
- "@bigcommerce/checkout-sdk": "^1.83.0",
+ "@bigcommerce/checkout-sdk": "^1.84.0",
"@bigcommerce/citadel": "^2.15.1",
"@bigcommerce/form-poster": "^1.2.2",
"@bigcommerce/memoize": "^1.0.0",
diff --git a/src/app/payment/Payment.tsx b/src/app/payment/Payment.tsx
index daac057863..75258cde0a 100644
--- a/src/app/payment/Payment.tsx
+++ b/src/app/payment/Payment.tsx
@@ -247,8 +247,9 @@ class Payment extends Component;
}
- if (method.id === PaymentMethodId.StripeV3) {
+ if (method.gateway === PaymentMethodId.StripeV3) {
return ;
}
diff --git a/src/app/payment/paymentMethod/StripePaymentMethod.spec.tsx b/src/app/payment/paymentMethod/StripePaymentMethod.spec.tsx
index 7da058dffd..aad8d3977d 100644
--- a/src/app/payment/paymentMethod/StripePaymentMethod.spec.tsx
+++ b/src/app/payment/paymentMethod/StripePaymentMethod.spec.tsx
@@ -7,21 +7,11 @@ import React, { FunctionComponent } from 'react';
import { CheckoutProvider } from '../../checkout';
import { getStoreConfig } from '../../config/config.mock';
import { createLocaleContext, LocaleContext, LocaleContextType } from '../../locale';
-import { getCreditCardInputStyles } from '../creditCard';
import { getPaymentMethod } from '../payment-methods.mock';
import HostedWidgetPaymentMethod, { HostedWidgetPaymentMethodProps } from './HostedWidgetPaymentMethod';
import { default as PaymentMethodComponent, PaymentMethodProps } from './PaymentMethod';
-jest.mock('../creditCard', () => ({
- ...jest.requireActual('../creditCard'),
- getCreditCardInputStyles: jest.fn, Parameters>(
- (_containerId, _fieldType) => {
- return Promise.resolve({ color: 'rgb(255, 0, 0)', fontWeight: '500', fontFamily: 'Montserrat, Arial, Helvetica, sans-serif', fontSize: '14px', fontSmoothing: 'auto'});
- }
- ),
-}));
-
describe('when using Stripe payment', () => {
let method: PaymentMethod;
let checkoutService: CheckoutService;
@@ -39,7 +29,6 @@ describe('when using Stripe payment', () => {
checkoutService = createCheckoutService();
checkoutState = checkoutService.getState();
localeContext = createLocaleContext(getStoreConfig());
- method = { ...getPaymentMethod(), id: 'stripev3' };
jest.spyOn(checkoutState.data, 'getConfig')
.mockReturnValue(getStoreConfig());
@@ -64,61 +53,134 @@ describe('when using Stripe payment', () => {
);
});
- it('renders as hosted widget method', () => {
- const container = mount();
- const component: ReactWrapper = container.find(HostedWidgetPaymentMethod);
-
- expect(component.props())
- .toEqual(expect.objectContaining({
- containerId: 'stripe-card-field',
- deinitializePayment: expect.any(Function),
- initializePayment: expect.any(Function),
- additionalContainerClassName: 'optimizedCheckout-form-input',
- method,
- }));
- });
+ describe('when using card component', () => {
+ beforeEach(() => {
+ method = { ...getPaymentMethod(), id: 'card', gateway: 'stripev3', method: 'card'};
+ });
+
+ it('renders as hosted widget method', () => {
+ const container = mount();
+ const component: ReactWrapper = container.find(HostedWidgetPaymentMethod);
+
+ expect(component.props())
+ .toEqual(expect.objectContaining({
+ containerId: `stripe-card-component-field`,
+ deinitializePayment: expect.any(Function),
+ initializePayment: expect.any(Function),
+ additionalContainerClassName: 'optimizedCheckout-form-input widget--stripev3',
+ method,
+ }));
+ });
+
+ it('initializes method with required config', () => {
+ const container = mount();
+ const component: ReactWrapper = container.find(HostedWidgetPaymentMethod);
- it('initializes method with required config', async () => {
- const container = mount();
- const component: ReactWrapper = container.find(HostedWidgetPaymentMethod);
+ component.prop('initializePayment')({
+ methodId: method.id,
+ gatewayId: method.gateway,
+ });
+
+ expect(checkoutService.initializePayment)
+ .toHaveBeenCalledWith(expect.objectContaining({
+ methodId: method.id,
+ stripev3: {
+ containerId: 'stripe-card-component-field',
+ options: {
+ classes: {
+ base: 'form-input optimizedCheckout-form-input',
+ },
+ },
+ },
+ }));
+ });
+ });
- component.prop('initializePayment')({
- methodId: method.id,
- gatewayId: method.gateway,
+ describe('when using ideal component', () => {
+ beforeEach(() => {
+ method = { ...getPaymentMethod(), id: 'idealBank', gateway: 'stripev3', method: 'idealBank'};
});
- expect(getCreditCardInputStyles)
- .toHaveBeenCalledWith('stripe-card-field', ['color', 'fontFamily', 'fontWeight', 'fontSmoothing']);
+ it('renders as hosted widget method', () => {
+ const container = mount();
+ const component: ReactWrapper = container.find(HostedWidgetPaymentMethod);
+
+ expect(component.props())
+ .toEqual(expect.objectContaining({
+ containerId: `stripe-idealBank-component-field`,
+ deinitializePayment: expect.any(Function),
+ initializePayment: expect.any(Function),
+ additionalContainerClassName: 'optimizedCheckout-form-input widget--stripev3',
+ method,
+ }));
+ });
- await new Promise(resolve => process.nextTick(resolve));
+ it('initializes method with required config', () => {
+ const container = mount();
+ const component: ReactWrapper = container.find(HostedWidgetPaymentMethod);
- expect(checkoutService.initializePayment)
- .toHaveBeenCalledWith(expect.objectContaining({
+ component.prop('initializePayment')({
methodId: method.id,
gatewayId: method.gateway,
- [method.id]: {
- containerId: 'stripe-card-field',
- style: {
- base: {
- color: 'rgb(255, 0, 0)',
- fontWeight: '500',
- fontFamily: 'Montserrat, Arial, Helvetica, sans-serif',
- fontSize: '14px',
- fontSmoothing: 'auto',
- '::placeholder': {
- color: '#E1E1E1',
- },
+ });
+
+ expect(checkoutService.initializePayment)
+ .toHaveBeenCalledWith(expect.objectContaining({
+ methodId: method.id,
+ stripev3: {
+ containerId: 'stripe-idealBank-component-field',
+ options: {
+ classes: {
+ base: 'form-input optimizedCheckout-form-input',
+ },
+ },
},
- invalid: {
- color: 'rgb(255, 0, 0)',
- fontWeight: '500',
- fontFamily: 'Montserrat, Arial, Helvetica, sans-serif',
- fontSize: '14px',
- fontSmoothing: 'auto',
- iconColor: 'rgb(255, 0, 0)',
+ })
+ );
+ });
+ });
+
+ describe('when using iban component', () => {
+ beforeEach(() => {
+ method = { ...getPaymentMethod(), id: 'iban', gateway: 'stripev3', method: 'iban'};
+ });
+
+ it('renders as hosted widget method', () => {
+ const container = mount();
+ const component: ReactWrapper = container.find(HostedWidgetPaymentMethod);
+
+ expect(component.props())
+ .toEqual(expect.objectContaining({
+ containerId: `stripe-iban-component-field`,
+ deinitializePayment: expect.any(Function),
+ initializePayment: expect.any(Function),
+ additionalContainerClassName: 'optimizedCheckout-form-input widget--stripev3',
+ method,
+ }));
+ });
+
+ it('initializes method with required config', () => {
+ const container = mount();
+ const component: ReactWrapper = container.find(HostedWidgetPaymentMethod);
+
+ component.prop('initializePayment')({
+ methodId: method.id,
+ gatewayId: method.gateway,
+ });
+
+ expect(checkoutService.initializePayment)
+ .toHaveBeenCalledWith(expect.objectContaining({
+ methodId: method.id,
+ stripev3: {
+ containerId: 'stripe-iban-component-field',
+ options: {
+ classes: {
+ base: 'form-input optimizedCheckout-form-input',
+ },
+ supportedCountries: ['SEPA'],
},
},
- },
- }));
+ }));
+ });
});
});
diff --git a/src/app/payment/paymentMethod/StripePaymentMethod.tsx b/src/app/payment/paymentMethod/StripePaymentMethod.tsx
index a87c17a840..4c753a765c 100644
--- a/src/app/payment/paymentMethod/StripePaymentMethod.tsx
+++ b/src/app/payment/paymentMethod/StripePaymentMethod.tsx
@@ -1,47 +1,65 @@
-import { PaymentInitializeOptions } from '@bigcommerce/checkout-sdk';
+import { PaymentInitializeOptions, StripeElementOptions } from '@bigcommerce/checkout-sdk';
import React, { useCallback, FunctionComponent } from 'react';
import { Omit } from 'utility-types';
-import { getCreditCardInputStyles, CreditCardInputStylesType } from '../creditCard';
-
import HostedWidgetPaymentMethod, { HostedWidgetPaymentMethodProps } from './HostedWidgetPaymentMethod';
-export type SquarePaymentMethodProps = Omit;
+export type StripePaymentMethodProps = Omit;
+
+export interface StripeOptions {
+ card: StripeElementOptions;
+ iban: StripeElementOptions;
+ idealBank: StripeElementOptions;
+}
-const StripePaymentMethod: FunctionComponent = ({
+export enum StripeV3PaymentMethodType {
+ card = 'card',
+ iban = 'iban',
+ idealBank = 'idealBank',
+}
+
+const StripePaymentMethod: FunctionComponent = ({
initializePayment,
+ method,
...rest
}) => {
+ const paymentMethodType = method.id as StripeV3PaymentMethodType;
+ const containerId = `stripe-${paymentMethodType}-component-field`;
+
const initializeStripePayment = useCallback(async (options: PaymentInitializeOptions) => {
- const creditCardInputStyles = await getCreditCardInputStyles('stripe-card-field', ['color', 'fontFamily', 'fontWeight', 'fontSmoothing']);
- const creditCardInputErrorStyles = await getCreditCardInputStyles('stripe-card-field', ['color'], CreditCardInputStylesType.Error);
+ const classes = {
+ base: 'form-input optimizedCheckout-form-input',
+ };
+
+ const stripeOptions: StripeOptions = {
+ [StripeV3PaymentMethodType.card]: {
+ classes,
+ },
+ [StripeV3PaymentMethodType.iban]: {
+ ...{ classes },
+ supportedCountries: ['SEPA'],
+ },
+ [StripeV3PaymentMethodType.idealBank]: {
+ classes,
+ },
+ };
return initializePayment({
...options,
stripev3: {
- containerId: 'stripe-card-field',
- style: {
- base: {
- ...creditCardInputStyles,
- '::placeholder': {
- color: '#E1E1E1',
- },
- },
- invalid: {
- ...creditCardInputErrorStyles,
- iconColor: creditCardInputErrorStyles.color,
- },
- },
+ containerId,
+ options: stripeOptions[paymentMethodType],
},
});
- }, [initializePayment]);
+ }, [initializePayment, containerId, paymentMethodType]);
return ;
};
diff --git a/src/scss/components/checkout/widget/_widget.scss b/src/scss/components/checkout/widget/_widget.scss
index 73ebf359a5..161def147f 100644
--- a/src/scss/components/checkout/widget/_widget.scss
+++ b/src/scss/components/checkout/widget/_widget.scss
@@ -59,6 +59,7 @@
margin-bottom: remCalc(20px);
margin-top: remCalc(20px);
+ padding: 1rem;
}
.StripeElement--focus {