Skip to content

Commit 8f64c56

Browse files
authored
Merge pull request #3114 from bigcommerce/feat/afterpay_script_https
fix(payment): PI-4789 added https to afterpay script loading
2 parents cec8c8f + 6fc186d commit 8f64c56

File tree

4 files changed

+123
-10
lines changed

4 files changed

+123
-10
lines changed

packages/afterpay-integration/src/afterpay-payment-strategy.spec.ts

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import {
1414
} from '@bigcommerce/checkout-sdk/payment-integration-api';
1515
import {
1616
getCart,
17+
getConfig,
1718
getErrorPaymentResponseBody,
1819
getOrderRequestBody,
1920
getResponse,
@@ -30,6 +31,8 @@ describe('AfterpayPaymentStrategy', () => {
3031
let paymentMethod: PaymentMethod;
3132
let scriptLoader: AfterpayScriptLoader;
3233
let strategy: AfterpayPaymentStrategy;
34+
const storeConfig = getConfig().storeConfig;
35+
const withHttpsExperimentName = 'PI-4789.afterpay_script_use_https';
3336

3437
const afterpaySdk = {
3538
initialize: jest.fn(),
@@ -66,6 +69,17 @@ describe('AfterpayPaymentStrategy', () => {
6669
jest.spyOn(paymentIntegrationService.getState(), 'getPaymentMethod').mockReturnValue(
6770
paymentMethod,
6871
);
72+
73+
jest.spyOn(paymentIntegrationService.getState(), 'getStoreConfigOrThrow').mockReturnValue({
74+
...storeConfig,
75+
checkoutSettings: {
76+
...storeConfig.checkoutSettings,
77+
features: {
78+
...storeConfig.checkoutSettings.features,
79+
[withHttpsExperimentName]: true,
80+
},
81+
},
82+
});
6983
});
7084

7185
afterEach(() => {
@@ -92,7 +106,30 @@ describe('AfterpayPaymentStrategy', () => {
92106
gatewayId: paymentMethod.gateway,
93107
});
94108

95-
expect(scriptLoader.load).toHaveBeenCalledWith(paymentMethod, 'US');
109+
expect(scriptLoader.load).toHaveBeenCalledWith(paymentMethod, 'US', true);
110+
});
111+
112+
it('loads script when initializing strategy with NO https', async () => {
113+
jest.spyOn(
114+
paymentIntegrationService.getState(),
115+
'getStoreConfigOrThrow',
116+
).mockReturnValue({
117+
...storeConfig,
118+
checkoutSettings: {
119+
...storeConfig.checkoutSettings,
120+
features: {
121+
...storeConfig.checkoutSettings.features,
122+
[withHttpsExperimentName]: false,
123+
},
124+
},
125+
});
126+
127+
await strategy.initialize({
128+
methodId: paymentMethod.id,
129+
gatewayId: paymentMethod.gateway,
130+
});
131+
132+
expect(scriptLoader.load).toHaveBeenCalledWith(paymentMethod, 'US', false);
96133
});
97134

98135
it('loads script when initializing strategy with NZD', async () => {
@@ -106,7 +143,7 @@ describe('AfterpayPaymentStrategy', () => {
106143
gatewayId: paymentMethod.gateway,
107144
});
108145

109-
expect(scriptLoader.load).toHaveBeenCalledWith(paymentMethod, 'NZ');
146+
expect(scriptLoader.load).toHaveBeenCalledWith(paymentMethod, 'NZ', true);
110147
});
111148
});
112149

packages/afterpay-integration/src/afterpay-payment-strategy.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import {
1717
RequestError,
1818
RequestOptions,
1919
} from '@bigcommerce/checkout-sdk/payment-integration-api';
20+
import { isExperimentEnabled } from '@bigcommerce/checkout-sdk/utility';
2021

2122
import AfterpayScriptLoader from './afterpay-script-loader';
2223
import AfterpaySdk from './afterpay-sdk';
@@ -34,12 +35,19 @@ export default class AfterpayPaymentStrategy implements PaymentStrategy {
3435
const paymentMethod = state.getPaymentMethod(options.methodId, options.gatewayId);
3536
const currencyCode = state.getCart()?.currency.code || '';
3637
const countryCode = this._mapCurrencyToISO2(currencyCode);
38+
const features = state.getStoreConfigOrThrow().checkoutSettings.features;
39+
const withHttpsExperimentName = 'PI-4789.afterpay_script_use_https';
40+
const withHttps = isExperimentEnabled(features, withHttpsExperimentName, false);
3741

3842
if (!paymentMethod) {
3943
throw new MissingDataError(MissingDataErrorType.MissingPaymentMethod);
4044
}
4145

42-
this._afterpaySdk = await this._afterpayScriptLoader.load(paymentMethod, countryCode);
46+
this._afterpaySdk = await this._afterpayScriptLoader.load(
47+
paymentMethod,
48+
countryCode,
49+
withHttps,
50+
);
4351
}
4452

4553
deinitialize(): Promise<void> {

packages/afterpay-integration/src/afterpay-script-loader.spec.ts

Lines changed: 56 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ describe('AfterpayScriptLoader', () => {
2828
'//portal.afterpay.com/afterpay-async.js',
2929
);
3030

31-
await afterpayScriptLoader.load(method, 'NZ');
31+
await afterpayScriptLoader.load(method, 'NZ', false);
3232

3333
expect(scriptLoader.loadScript).toHaveBeenCalledWith(
3434
'//portal.afterpay.com/afterpay-async.js',
@@ -38,7 +38,7 @@ describe('AfterpayScriptLoader', () => {
3838
it('loads sandbox widget script if in test mode for AU & NZ', async () => {
3939
const method = merge({}, getAfterpay(), { config: { testMode: true } });
4040

41-
await afterpayScriptLoader.load(method, 'AU');
41+
await afterpayScriptLoader.load(method, 'AU', false);
4242

4343
expect(scriptLoader.loadScript).toHaveBeenCalledWith(
4444
'//portal.sandbox.afterpay.com/afterpay.js',
@@ -54,7 +54,7 @@ describe('AfterpayScriptLoader', () => {
5454
it('loads widget script for US', async () => {
5555
const method = getAfterpay();
5656

57-
await afterpayScriptLoader.load(method, 'US');
57+
await afterpayScriptLoader.load(method, 'US', false);
5858

5959
expect(scriptLoader.loadScript).toHaveBeenCalledWith(
6060
'//portal.afterpay.com/afterpay-async.js',
@@ -64,10 +64,62 @@ describe('AfterpayScriptLoader', () => {
6464
it('loads sandbox widget script if in test mode for US', async () => {
6565
const method = merge({}, getAfterpay(), { config: { testMode: true } });
6666

67-
await afterpayScriptLoader.load(method, 'US');
67+
await afterpayScriptLoader.load(method, 'US', false);
6868

6969
expect(scriptLoader.loadScript).toHaveBeenCalledWith(
7070
'//portal.sandbox.afterpay.com/afterpay.js',
7171
);
7272
});
73+
74+
it('loads widget script with HTTPS for AU & NZ', async () => {
75+
const method = getAfterpay();
76+
77+
await afterpayScriptLoader.load(method, 'AU', true);
78+
79+
expect(scriptLoader.loadScript).toHaveBeenCalledWith(
80+
'https://portal.afterpay.com/afterpay-async.js',
81+
);
82+
83+
await afterpayScriptLoader.load(method, 'NZ');
84+
85+
expect(scriptLoader.loadScript).toHaveBeenCalledWith(
86+
'https://portal.afterpay.com/afterpay-async.js',
87+
);
88+
});
89+
90+
it('loads sandbox widget script with HTTPS if in test mode for AU & NZ', async () => {
91+
const method = merge({}, getAfterpay(), { config: { testMode: true } });
92+
93+
await afterpayScriptLoader.load(method, 'AU', true);
94+
95+
expect(scriptLoader.loadScript).toHaveBeenCalledWith(
96+
'https://portal.sandbox.afterpay.com/afterpay.js',
97+
);
98+
99+
await afterpayScriptLoader.load(method, 'NZ');
100+
101+
expect(scriptLoader.loadScript).toHaveBeenCalledWith(
102+
'https://portal.sandbox.afterpay.com/afterpay.js',
103+
);
104+
});
105+
106+
it('loads widget script with HTTPS for US', async () => {
107+
const method = getAfterpay();
108+
109+
await afterpayScriptLoader.load(method, 'US', true);
110+
111+
expect(scriptLoader.loadScript).toHaveBeenCalledWith(
112+
'https://portal.afterpay.com/afterpay-async.js',
113+
);
114+
});
115+
116+
it('loads sandbox widget script with HTTPS if in test mode for US', async () => {
117+
const method = merge({}, getAfterpay(), { config: { testMode: true } });
118+
119+
await afterpayScriptLoader.load(method, 'US', true);
120+
121+
expect(scriptLoader.loadScript).toHaveBeenCalledWith(
122+
'https://portal.sandbox.afterpay.com/afterpay.js',
123+
);
124+
});
73125
});

packages/afterpay-integration/src/afterpay-script-loader.ts

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,15 @@ import isAfterpayWindow from './is-afterpay-window';
1111
enum SCRIPTS_DEFAULT {
1212
PROD = '//portal.afterpay.com/afterpay-async.js',
1313
SANDBOX = '//portal.sandbox.afterpay.com/afterpay.js',
14+
HTTPS_PROD = 'https://portal.afterpay.com/afterpay-async.js',
15+
HTTPS_SANDBOX = 'https://portal.sandbox.afterpay.com/afterpay.js',
1416
}
1517

1618
enum SCRIPTS_US {
1719
PROD = '//portal.afterpay.com/afterpay-async.js',
1820
SANDBOX = '//portal.sandbox.afterpay.com/afterpay.js',
21+
HTTPS_PROD = 'https://portal.afterpay.com/afterpay-async.js',
22+
HTTPS_SANDBOX = 'https://portal.sandbox.afterpay.com/afterpay.js',
1923
}
2024

2125
/** Class responsible for loading the Afterpay SDK */
@@ -27,9 +31,13 @@ export default class AfterpayScriptLoader {
2731
*
2832
* @param {PaymentMethod} method the payment method data
2933
*/
30-
async load(method: PaymentMethod, countryCode: string): Promise<AfterpaySdk> {
34+
async load(
35+
method: PaymentMethod,
36+
countryCode: string,
37+
withHttps = false,
38+
): Promise<AfterpaySdk> {
3139
const testMode = method.config.testMode || false;
32-
const scriptURI = this._getScriptURI(countryCode, testMode);
40+
const scriptURI = this._getScriptURI(countryCode, testMode, withHttps);
3341

3442
return this._scriptLoader.loadScript(scriptURI).then(() => {
3543
if (!isAfterpayWindow(window)) {
@@ -40,11 +48,19 @@ export default class AfterpayScriptLoader {
4048
});
4149
}
4250

43-
private _getScriptURI(countryCode: string, testMode: boolean): string {
51+
private _getScriptURI(countryCode: string, testMode: boolean, withHttps = false): string {
4452
if (countryCode === 'US') {
53+
if (withHttps) {
54+
return testMode ? SCRIPTS_US.HTTPS_SANDBOX : SCRIPTS_US.HTTPS_PROD;
55+
}
56+
4557
return testMode ? SCRIPTS_US.SANDBOX : SCRIPTS_US.PROD;
4658
}
4759

60+
if (withHttps) {
61+
return testMode ? SCRIPTS_DEFAULT.HTTPS_SANDBOX : SCRIPTS_DEFAULT.HTTPS_PROD;
62+
}
63+
4864
return testMode ? SCRIPTS_DEFAULT.SANDBOX : SCRIPTS_DEFAULT.PROD;
4965
}
5066
}

0 commit comments

Comments
 (0)