mirror of
https://github.com/jlengrand/adyen-web.git
synced 2026-03-10 08:01:22 +00:00
Adding support for Custom URLs (#2262)
* feat: supporting custom urls * fix: reverting safety checks * feat: using url when resolving * feat: changeset + change in the environments + test
This commit is contained in:
committed by
GitHub
parent
ea00111f75
commit
1532d705f4
5
.changeset/soft-clouds-knock.md
Normal file
5
.changeset/soft-clouds-knock.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@adyen/adyen-web': minor
|
||||
---
|
||||
|
||||
Added environmentUrls parameter to Core, which allows PBL to use custom URLs for the API and assets
|
||||
@@ -12,7 +12,7 @@ describe('Dropin', () => {
|
||||
let dropin: DropinElement;
|
||||
|
||||
beforeEach(async () => {
|
||||
const checkout = await AdyenCheckout({ analytics: { enabled: false } });
|
||||
const checkout = await AdyenCheckout({ environment: 'test', clientKey: 'test_123456', analytics: { enabled: false } });
|
||||
dropin = checkout.create('dropin');
|
||||
});
|
||||
|
||||
@@ -65,7 +65,7 @@ describe('Dropin', () => {
|
||||
});
|
||||
|
||||
test('should handle new challenge action', async () => {
|
||||
const checkout = await AdyenCheckout({ analytics: { enabled: false } });
|
||||
const checkout = await AdyenCheckout({ environment: 'test', clientKey: 'test_123456', analytics: { enabled: false } });
|
||||
|
||||
const dropin = checkout.create('dropin');
|
||||
|
||||
@@ -77,7 +77,11 @@ describe('Dropin', () => {
|
||||
});
|
||||
|
||||
test('new challenge action gets challengeWindowSize from paymentMethodsConfiguration', async () => {
|
||||
const checkout = await AdyenCheckout({ paymentMethodsConfiguration: { threeDS2: { challengeWindowSize: '02' } } });
|
||||
const checkout = await AdyenCheckout({
|
||||
environment: 'test',
|
||||
clientKey: 'test_123456',
|
||||
paymentMethodsConfiguration: { threeDS2: { challengeWindowSize: '02' } }
|
||||
});
|
||||
|
||||
const dropin = checkout.create('dropin');
|
||||
|
||||
@@ -87,7 +91,12 @@ describe('Dropin', () => {
|
||||
});
|
||||
|
||||
test('new challenge action gets challengeWindowSize from handleAction config', async () => {
|
||||
const checkout = await AdyenCheckout({ analytics: { enabled: false }, challengeWindowSize: '04' });
|
||||
const checkout = await AdyenCheckout({
|
||||
environment: 'test',
|
||||
clientKey: 'test_123456',
|
||||
analytics: { enabled: false },
|
||||
challengeWindowSize: '04'
|
||||
});
|
||||
|
||||
const dropin = checkout.create('dropin');
|
||||
mount(dropin.render());
|
||||
@@ -103,6 +112,8 @@ describe('Dropin', () => {
|
||||
describe('Instant Payments feature', () => {
|
||||
test('formatProps formats instantPaymentTypes removing duplicates and invalid values', async () => {
|
||||
const checkout = await AdyenCheckout({
|
||||
environment: 'test',
|
||||
clientKey: 'test_123456',
|
||||
analytics: { enabled: false }
|
||||
});
|
||||
const dropin = checkout.create('dropin', { instantPaymentTypes: ['alipay', 'paywithgoogle', 'paywithgoogle', 'paypal'] });
|
||||
@@ -112,6 +123,8 @@ describe('Dropin', () => {
|
||||
|
||||
test('formatProps filter out instantPaymentMethods from paymentMethods list ', async () => {
|
||||
const checkout = await AdyenCheckout({
|
||||
environment: 'test',
|
||||
clientKey: 'test_123456',
|
||||
analytics: { enabled: false },
|
||||
paymentMethodsResponse: {
|
||||
paymentMethods: [
|
||||
@@ -135,6 +148,8 @@ describe('Dropin', () => {
|
||||
];
|
||||
|
||||
const checkout = await AdyenCheckout({
|
||||
environment: 'test',
|
||||
clientKey: 'test_123456',
|
||||
analytics: { enabled: false },
|
||||
paymentMethodsResponse: {
|
||||
paymentMethods
|
||||
@@ -153,6 +168,8 @@ describe('Dropin', () => {
|
||||
beforeEach(async () => {
|
||||
const paymentMethods = [{ name: 'AliPay', type: 'alipay' }];
|
||||
const checkout = await AdyenCheckout({
|
||||
environment: 'test',
|
||||
clientKey: 'test_123456',
|
||||
analytics: { enabled: false },
|
||||
paymentMethodsResponse: {
|
||||
paymentMethods
|
||||
|
||||
@@ -137,7 +137,7 @@ describe('UIElement', () => {
|
||||
type: 'threeDS2'
|
||||
};
|
||||
|
||||
const checkout = await AdyenCheckout({ analytics: { enabled: false } });
|
||||
const checkout = await AdyenCheckout({ environment: 'test', clientKey: 'test_123456', analytics: { enabled: false } });
|
||||
const comp = checkout.create('card').mount('body');
|
||||
|
||||
const pa = comp.handleAction(fingerprintAction);
|
||||
@@ -151,6 +151,8 @@ describe('UIElement', () => {
|
||||
|
||||
test('should handle new challenge action', async () => {
|
||||
const checkout = await AdyenCheckout({
|
||||
environment: 'test',
|
||||
clientKey: 'test_123456',
|
||||
analytics: { enabled: false },
|
||||
paymentMethodsConfiguration: {
|
||||
threeDS2: { challengeWindowSize: '02' }
|
||||
|
||||
@@ -1,16 +1,47 @@
|
||||
import { resolveEnvironment } from './Environment';
|
||||
import { resolveCDNEnvironment, resolveEnvironment } from './Environment';
|
||||
|
||||
describe('Environment', () => {
|
||||
test('resolves set environments', () => {
|
||||
describe('Resolving API environment', () => {
|
||||
test('should return the proper URL according to the environment type', () => {
|
||||
expect(resolveEnvironment('test')).toBe('https://checkoutshopper-test.adyen.com/checkoutshopper/');
|
||||
expect(resolveEnvironment('TEST')).toBe('https://checkoutshopper-test.adyen.com/checkoutshopper/');
|
||||
expect(resolveEnvironment('live')).toBe('https://checkoutshopper-live.adyen.com/checkoutshopper/');
|
||||
expect(resolveEnvironment('LIVE')).toBe('https://checkoutshopper-live.adyen.com/checkoutshopper/');
|
||||
});
|
||||
|
||||
test('resolves a URL environment', () => {
|
||||
expect(resolveEnvironment('https://example.com/')).toBe('https://example.com/');
|
||||
test('should return environmentUrl if provided', () => {
|
||||
expect(resolveEnvironment('devl', 'http://localhost:8080/checkoutshopper/')).toBe('http://localhost:8080/checkoutshopper/');
|
||||
expect(resolveEnvironment('test', 'https://checkout-zeta.com/checkoutshopper/')).toBe('https://checkout-zeta.com/checkoutshopper/');
|
||||
});
|
||||
|
||||
test('resolves to the live environment as a fallback', () => {
|
||||
test('should return the live environment URL if environment type is not valid', () => {
|
||||
expect(resolveEnvironment('invalid-environment')).toBe('https://checkoutshopper-live.adyen.com/checkoutshopper/');
|
||||
});
|
||||
|
||||
test('should return the live environment URL if environment type is not provided', () => {
|
||||
// @ts-ignore It can happen that 'environment' property is not be passed by the merchant
|
||||
expect(resolveEnvironment()).toBe('https://checkoutshopper-live.adyen.com/checkoutshopper/');
|
||||
});
|
||||
});
|
||||
|
||||
describe('Resolving CDN Environment', () => {
|
||||
test('should return the proper URL according to the environment type', () => {
|
||||
expect(resolveCDNEnvironment('beta')).toBe('https://cdf6519016.cdn.adyen.com/checkoutshopper/');
|
||||
expect(resolveCDNEnvironment('BETA')).toBe('https://cdf6519016.cdn.adyen.com/checkoutshopper/');
|
||||
expect(resolveCDNEnvironment('live')).toBe('https://checkoutshopper-live.adyen.com/checkoutshopper/');
|
||||
expect(resolveCDNEnvironment('LIVE')).toBe('https://checkoutshopper-live.adyen.com/checkoutshopper/');
|
||||
});
|
||||
|
||||
test('should return environmentUrl if provided', () => {
|
||||
expect(resolveCDNEnvironment('devl', 'http://localhost:8080/checkoutshopper/')).toBe('http://localhost:8080/checkoutshopper/');
|
||||
expect(resolveCDNEnvironment('beta', 'https://testing-beta-cdn.com/')).toBe('https://testing-beta-cdn.com/');
|
||||
});
|
||||
|
||||
test('should return the live environment URL if environment type is not valid', () => {
|
||||
expect(resolveCDNEnvironment('invalid-environment')).toBe('https://checkoutshopper-live.adyen.com/checkoutshopper/');
|
||||
});
|
||||
|
||||
test('should return the live environment URL if environment type is not provided', () => {
|
||||
// @ts-ignore It can happen that 'environment' property is not be passed by the merchant
|
||||
expect(resolveCDNEnvironment()).toBe('https://checkoutshopper-live.adyen.com/checkoutshopper/');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
export const FALLBACK_CONTEXT = 'https://checkoutshopper-live.adyen.com/checkoutshopper/';
|
||||
export const resolveEnvironment = (env = '', environmentUrl?: string): string => {
|
||||
if (environmentUrl) {
|
||||
return environmentUrl;
|
||||
}
|
||||
|
||||
export const resolveEnvironment = (env: string = FALLBACK_CONTEXT): string => {
|
||||
const environments = {
|
||||
test: 'https://checkoutshopper-test.adyen.com/checkoutshopper/',
|
||||
live: 'https://checkoutshopper-live.adyen.com/checkoutshopper/',
|
||||
@@ -10,12 +13,15 @@ export const resolveEnvironment = (env: string = FALLBACK_CONTEXT): string => {
|
||||
'live-in': 'https://checkoutshopper-live-in.adyen.com/checkoutshopper/'
|
||||
};
|
||||
|
||||
return environments[env] || environments[env.toLowerCase()] || env;
|
||||
return environments[env.toLowerCase()] || FALLBACK_CONTEXT;
|
||||
};
|
||||
|
||||
export const FALLBACK_CDN_CONTEXT = 'https://checkoutshopper-live.adyen.com/checkoutshopper/';
|
||||
export const resolveCDNEnvironment = (env = '', environmentUrl?: string) => {
|
||||
if (environmentUrl) {
|
||||
return environmentUrl;
|
||||
}
|
||||
|
||||
export const resolveCDNEnvironment = (env: string = FALLBACK_CDN_CONTEXT) => {
|
||||
const environments = {
|
||||
beta: 'https://cdf6519016.cdn.adyen.com/checkoutshopper/',
|
||||
test: 'https://checkoutshopper-test.adyen.com/checkoutshopper/',
|
||||
@@ -26,5 +32,5 @@ export const resolveCDNEnvironment = (env: string = FALLBACK_CDN_CONTEXT) => {
|
||||
'live-in': 'https://checkoutshopper-live-in.adyen.com/checkoutshopper/'
|
||||
};
|
||||
|
||||
return environments[env] || environments[env.toLowerCase()] || env;
|
||||
return environments[env.toLowerCase()] || FALLBACK_CDN_CONTEXT;
|
||||
};
|
||||
|
||||
@@ -73,8 +73,8 @@ const checkoutConfig = {
|
||||
value: 19000
|
||||
},
|
||||
shopperLocale: 'en-US',
|
||||
clientKey: 'test_F7_FEKJHF',
|
||||
environment: 'test',
|
||||
clientKey: 'test_F7_FEKJHF',
|
||||
paymentMethodsResponse,
|
||||
paymentMethodsConfiguration: paymentMethodsConfiguration as PaymentMethodsConfiguration
|
||||
};
|
||||
@@ -420,7 +420,7 @@ describe('Trying to add a "scheme" property to the paymentMethodsConfiguration t
|
||||
};
|
||||
|
||||
test('Trying to create a card component with a paymentMethodsConfiguration with a "scheme" property shows a warning in the console ', () => {
|
||||
new AdyenCheckout({ paymentMethodsConfiguration });
|
||||
new AdyenCheckout({ environment: 'test', clientKey: 'test_123456', paymentMethodsConfiguration });
|
||||
// expect warning in console
|
||||
expect(console.warn).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
@@ -30,14 +30,14 @@ beforeEach(() => {
|
||||
|
||||
describe('Core', () => {
|
||||
test('should default to the FALLBACK_LOCALE', async () => {
|
||||
const checkout = new AdyenCheckout({});
|
||||
const checkout = new AdyenCheckout({ environment: 'test', clientKey: 'test_123456' });
|
||||
await checkout.initialize();
|
||||
|
||||
expect(checkout.modules.i18n.locale).toBe('en-US');
|
||||
});
|
||||
|
||||
test('should create the modules when initializing on Advanced Flow', async () => {
|
||||
const checkout = new AdyenCheckout({});
|
||||
const checkout = new AdyenCheckout({ environment: 'test', clientKey: 'test_123456' });
|
||||
await checkout.initialize();
|
||||
|
||||
expect(Object.keys(checkout.modules).length).toBeGreaterThan(1);
|
||||
@@ -45,9 +45,9 @@ describe('Core', () => {
|
||||
|
||||
test('should create the modules when initializing on Sesssions flow', async () => {
|
||||
const checkout = new AdyenCheckout({
|
||||
session: { id: 'session-id', sessionData: 'sesssion-data' },
|
||||
environment: 'test',
|
||||
clientKey: 'xxxx'
|
||||
clientKey: 'test_123456',
|
||||
session: { id: 'session-id', sessionData: 'sesssion-data' }
|
||||
});
|
||||
|
||||
await checkout.initialize();
|
||||
@@ -56,7 +56,7 @@ describe('Core', () => {
|
||||
});
|
||||
|
||||
test('should set a custom locale', async () => {
|
||||
const checkout = new AdyenCheckout({ locale: 'es-ES' });
|
||||
const checkout = new AdyenCheckout({ environment: 'test', clientKey: 'test_123456', locale: 'es-ES' });
|
||||
await checkout.initialize();
|
||||
|
||||
expect(checkout.modules.i18n.locale).toBe('es-ES');
|
||||
@@ -64,7 +64,7 @@ describe('Core', () => {
|
||||
|
||||
describe('create', () => {
|
||||
test('should create a component if it exists', async () => {
|
||||
const checkout = new AdyenCheckout({});
|
||||
const checkout = new AdyenCheckout({ environment: 'test', clientKey: 'test_123456' });
|
||||
await checkout.initialize();
|
||||
|
||||
expect(checkout.create('dropin')).toBeTruthy();
|
||||
@@ -77,7 +77,7 @@ describe('Core', () => {
|
||||
const onSubmitMockComponent = jest.fn().mockName('onSubmitMockComponent');
|
||||
|
||||
test('component props receive global props if not defined elsewhere', async () => {
|
||||
const checkout = new AdyenCheckout({ onSubmit: onSubmitMockGlobal });
|
||||
const checkout = new AdyenCheckout({ environment: 'test', clientKey: 'test_123456', onSubmit: onSubmitMockGlobal });
|
||||
await checkout.initialize();
|
||||
const component = checkout.create('card');
|
||||
|
||||
@@ -85,7 +85,7 @@ describe('Core', () => {
|
||||
});
|
||||
|
||||
test('component props take precedence over global props', async () => {
|
||||
const checkout = new AdyenCheckout({ onSubmit: onSubmitMockGlobal });
|
||||
const checkout = new AdyenCheckout({ environment: 'test', clientKey: 'test_123456', onSubmit: onSubmitMockGlobal });
|
||||
await checkout.initialize();
|
||||
const component = checkout.create('card', { onSubmit: onSubmitMockComponent });
|
||||
|
||||
@@ -94,6 +94,8 @@ describe('Core', () => {
|
||||
|
||||
test('paymentMethodsConfiguration props take precedence over global props', async () => {
|
||||
const checkout = new AdyenCheckout({
|
||||
environment: 'test',
|
||||
clientKey: 'test_123456',
|
||||
onSubmit: onSubmitMockGlobal,
|
||||
paymentMethodsConfiguration: { card: { onSubmit: onSubmitMockPMConfig } }
|
||||
});
|
||||
@@ -105,6 +107,8 @@ describe('Core', () => {
|
||||
|
||||
test('component props take precedence over paymentMethodsConfiguration props', async () => {
|
||||
const checkout = new AdyenCheckout({
|
||||
environment: 'test',
|
||||
clientKey: 'test_123456',
|
||||
paymentMethodsConfiguration: { card: { onSubmit: onSubmitMockPMConfig } }
|
||||
});
|
||||
await checkout.initialize();
|
||||
@@ -117,7 +121,10 @@ describe('Core', () => {
|
||||
|
||||
describe('createFromAction', () => {
|
||||
test('should create a component from an action object', async () => {
|
||||
const checkout = new AdyenCheckout({});
|
||||
const checkout = new AdyenCheckout({
|
||||
environment: 'test',
|
||||
clientKey: 'test_123456'
|
||||
});
|
||||
await checkout.initialize();
|
||||
|
||||
const paymentAction = checkout.createFromAction({
|
||||
@@ -131,7 +138,11 @@ describe('Core', () => {
|
||||
});
|
||||
|
||||
test('should handle new fingerprint action', async () => {
|
||||
const checkout = new AdyenCheckout({ paymentMethodsConfiguration: { threeDS2: { challengeWindowSize: '04' } } });
|
||||
const checkout = new AdyenCheckout({
|
||||
environment: 'test',
|
||||
clientKey: 'test_123456',
|
||||
paymentMethodsConfiguration: { threeDS2: { challengeWindowSize: '04' } }
|
||||
});
|
||||
await checkout.initialize();
|
||||
|
||||
const fingerprintAction = {
|
||||
@@ -155,6 +166,8 @@ describe('Core', () => {
|
||||
|
||||
test('should handle new challenge action', async () => {
|
||||
const checkout = new AdyenCheckout({
|
||||
environment: 'test',
|
||||
clientKey: 'test_123456',
|
||||
paymentMethodsConfiguration: {
|
||||
threeDS2: {
|
||||
challengeWindowSize: '03'
|
||||
@@ -187,6 +200,8 @@ describe('Core', () => {
|
||||
|
||||
test('paymentMethodsConfiguration properties take precedence over global configuration', async () => {
|
||||
const checkout = new AdyenCheckout({
|
||||
environment: 'test',
|
||||
clientKey: 'test_123456',
|
||||
onAdditionalDetails: onAdditionalDetailsGlobal,
|
||||
paymentMethodsConfiguration: { qrCode: { onAdditionalDetails: onAdditionalDetailsBCMC } }
|
||||
});
|
||||
@@ -203,6 +218,8 @@ describe('Core', () => {
|
||||
|
||||
test('createFromAction props take precedence over paymentMethodsConfiguration and global configuration', async () => {
|
||||
const checkout = new AdyenCheckout({
|
||||
environment: 'test',
|
||||
clientKey: 'test_123456',
|
||||
onAdditionalDetails: onAdditionalDetailsGlobal,
|
||||
paymentMethodsConfiguration: { qrCode: { onAdditionalDetails: onAdditionalDetailsBCMC } }
|
||||
});
|
||||
@@ -226,7 +243,10 @@ describe('Core', () => {
|
||||
|
||||
describe('update', () => {
|
||||
test('Should update all components under main instance', async () => {
|
||||
const checkout = new AdyenCheckout({});
|
||||
const checkout = new AdyenCheckout({
|
||||
environment: 'test',
|
||||
clientKey: 'test_123456'
|
||||
});
|
||||
await checkout.initialize();
|
||||
|
||||
const component = checkout.create('dropin').mount('body');
|
||||
@@ -249,4 +269,16 @@ describe('Core', () => {
|
||||
expect(checkout.paymentMethodsResponse).toHaveProperty('paymentMethods', paymentMethodsResponse.paymentMethods);
|
||||
});
|
||||
});
|
||||
|
||||
test('should use custom checkoutshopper URL url if available', () => {
|
||||
const checkout = new AdyenCheckout({
|
||||
environment: 'test',
|
||||
environmentUrls: {
|
||||
api: 'https://localhost:8080/checkoutshopper/'
|
||||
},
|
||||
clientKey: 'devl_FX923810'
|
||||
});
|
||||
|
||||
expect(checkout.loadingContext).toBe('https://localhost:8080/checkoutshopper/');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -39,12 +39,12 @@ class Core {
|
||||
|
||||
this.setOptions(props);
|
||||
|
||||
this.loadingContext = resolveEnvironment(this.options.environment);
|
||||
this.cdnContext = resolveCDNEnvironment(this.options.resourceEnvironment || this.options.environment);
|
||||
this.loadingContext = resolveEnvironment(this.options.environment, this.options.environmentUrls?.api);
|
||||
this.cdnContext = resolveCDNEnvironment(this.options.resourceEnvironment || this.options.environment, this.options.environmentUrls?.api);
|
||||
|
||||
const clientKeyType = this.options.clientKey?.substr(0, 4);
|
||||
if ((clientKeyType === 'test' || clientKeyType === 'live') && !this.loadingContext.includes(clientKeyType)) {
|
||||
throw new Error(`Error: you are using a ${clientKeyType} clientKey against the ${this.options.environment} environment`);
|
||||
throw new Error(`Error: you are using a '${clientKeyType}' clientKey against the '${this.options.environment}' environment`);
|
||||
}
|
||||
|
||||
// Expose version number for npm builds
|
||||
|
||||
@@ -20,6 +20,16 @@ export interface CoreOptions {
|
||||
*/
|
||||
environment?: 'test' | 'live' | 'live-us' | 'live-au' | 'live-apse' | 'live-in' | string;
|
||||
|
||||
/**
|
||||
* Used internally by Pay By Link in order to set its own URL's instead of using the ones mapped in our codebase.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
environmentUrls?: {
|
||||
api?: string;
|
||||
analytics?: string;
|
||||
};
|
||||
|
||||
/**
|
||||
* Show or hides a Pay Button for each payment method
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user