diff --git a/env.default b/env.default
index a2bcc1ddb0..1b6dee8377 100644
--- a/env.default
+++ b/env.default
@@ -1,4 +1,4 @@
-API_VERSION=v68
+API_VERSION=v69
CHECKOUT_API_KEY=
diff --git a/packages/e2e-playwright/package.json b/packages/e2e-playwright/package.json
index 125ab1ab50..df0432d9d4 100644
--- a/packages/e2e-playwright/package.json
+++ b/packages/e2e-playwright/package.json
@@ -25,6 +25,6 @@
"webpack-dev-server": "4.13.3"
},
"dependencies": {
- "@adyen/adyen-web": "5.50.1"
+ "@adyen/adyen-web": "5.51.0"
}
}
diff --git a/packages/e2e/package.json b/packages/e2e/package.json
index ff4739c7da..45947bc449 100644
--- a/packages/e2e/package.json
+++ b/packages/e2e/package.json
@@ -41,6 +41,6 @@
"whatwg-fetch": "^3.6.2"
},
"dependencies": {
- "@adyen/adyen-web": "5.50.1"
+ "@adyen/adyen-web": "5.51.0"
}
}
diff --git a/packages/lib/CHANGELOG.md b/packages/lib/CHANGELOG.md
index 987a99a7a6..e35f5344fc 100644
--- a/packages/lib/CHANGELOG.md
+++ b/packages/lib/CHANGELOG.md
@@ -1,5 +1,11 @@
# @adyen/adyen-web
+## 5.51.0
+
+### Minor Changes
+
+- Add 'redirectFromTopWhenInIframe' config prop to allow top level redirect when Checkout loaded in an iframe ([#2325](https://github.com/Adyen/adyen-web/pull/2325))
+
## 5.50.1
### Patch Changes
diff --git a/packages/lib/package.json b/packages/lib/package.json
index 80ba1b7bf8..4d6ba83c09 100644
--- a/packages/lib/package.json
+++ b/packages/lib/package.json
@@ -24,7 +24,7 @@
"./dist/es/adyen.css": "./dist/es/adyen.css",
"./package.json": "./package.json"
},
- "version": "5.50.1",
+ "version": "5.51.0",
"license": "MIT",
"homepage": "https://docs.adyen.com/checkout",
"repository": "github:Adyen/adyen-web",
diff --git a/packages/lib/src/components/Redirect/Redirect.test.tsx b/packages/lib/src/components/Redirect/Redirect.test.tsx
index d1fd718726..2d65fcb4e9 100644
--- a/packages/lib/src/components/Redirect/Redirect.test.tsx
+++ b/packages/lib/src/components/Redirect/Redirect.test.tsx
@@ -3,6 +3,12 @@ import { h } from 'preact';
import Redirect from './Redirect';
import RedirectShopper from './components/RedirectShopper';
+jest.mock('../../utils/detectInIframe', () => {
+ return jest.fn().mockImplementation(() => {
+ return true;
+ });
+});
+
describe('Redirect', () => {
describe('isValid', () => {
test('Is always valid', () => {
@@ -19,6 +25,17 @@ describe('Redirect', () => {
expect(wrapper.find('form')).toHaveLength(1);
expect(wrapper.find('form').prop('action')).toBe('http://www.adyen.com');
+ expect(wrapper.find('form').prop('target')).toBe(undefined);
+ setTimeout(() => expect(window.HTMLFormElement.prototype.submit).toHaveBeenCalled(), 0);
+ });
+
+ test('Accepts a POST redirect status, setting target to _top, when the config prop tells it to', () => {
+ window.HTMLFormElement.prototype.submit = jest.fn();
+
+ const wrapper = mount();
+
+ expect(wrapper.find('form')).toHaveLength(1);
+ expect(wrapper.find('form').prop('target')).toBe('_top');
setTimeout(() => expect(window.HTMLFormElement.prototype.submit).toHaveBeenCalled(), 0);
});
});
diff --git a/packages/lib/src/components/Redirect/components/RedirectShopper/RedirectShopper.tsx b/packages/lib/src/components/Redirect/components/RedirectShopper/RedirectShopper.tsx
index c625c817d0..ac69bd52a8 100644
--- a/packages/lib/src/components/Redirect/components/RedirectShopper/RedirectShopper.tsx
+++ b/packages/lib/src/components/Redirect/components/RedirectShopper/RedirectShopper.tsx
@@ -1,10 +1,12 @@
import { Component, h } from 'preact';
+import detectInIframe from '../../../../utils/detectInIframe';
interface RedirectShopperProps {
beforeRedirect: (resolve, reject, url) => Promise;
url: string;
method: 'GET' | 'POST';
data?: any;
+ redirectFromTopWhenInIframe?: boolean;
}
class RedirectShopper extends Component {
@@ -19,7 +21,12 @@ class RedirectShopper extends Component {
if (this.postForm) {
this.postForm.submit();
} else {
- window.location.assign(this.props.url);
+ if (this.props.redirectFromTopWhenInIframe && detectInIframe()) {
+ // if in an iframe and the config prop allows it - try to redirect from the top level window
+ window.top.location.assign?.(this.props.url);
+ } else {
+ window.location.assign(this.props.url);
+ }
}
};
@@ -44,6 +51,7 @@ class RedirectShopper extends Component {
ref={ref => {
this.postForm = ref;
}}
+ {...(this.props.redirectFromTopWhenInIframe && detectInIframe() && { target: '_top' })}
>
{Object.keys(data).map(key => (
diff --git a/packages/lib/src/core/config.ts b/packages/lib/src/core/config.ts
index 79c438618b..ef81e05816 100644
--- a/packages/lib/src/core/config.ts
+++ b/packages/lib/src/core/config.ts
@@ -15,6 +15,7 @@ export const GENERIC_OPTIONS = [
'session',
'clientKey',
'showPayButton',
+ 'redirectFromTopWhenInIframe',
'installmentOptions',
// Events
diff --git a/packages/lib/src/utils/detectInIframe.ts b/packages/lib/src/utils/detectInIframe.ts
new file mode 100644
index 0000000000..5307d7028e
--- /dev/null
+++ b/packages/lib/src/utils/detectInIframe.ts
@@ -0,0 +1,2 @@
+// Returns true if the page is being run in an iframe
+export default () => window.location !== window.parent.location;
diff --git a/packages/playground/package.json b/packages/playground/package.json
index 264783d13c..72c468194a 100644
--- a/packages/playground/package.json
+++ b/packages/playground/package.json
@@ -41,6 +41,6 @@
"whatwg-fetch": "^3.6.2"
},
"dependencies": {
- "@adyen/adyen-web": "5.50.1"
+ "@adyen/adyen-web": "5.51.0"
}
}
diff --git a/packages/playground/src/config/paymentsConfig.js b/packages/playground/src/config/paymentsConfig.js
index ac7d553974..e89ba72fb4 100644
--- a/packages/playground/src/config/paymentsConfig.js
+++ b/packages/playground/src/config/paymentsConfig.js
@@ -9,23 +9,23 @@ const paymentsConfig = {
origin,
returnUrl,
reference: `${identifier}-checkout-components-ref`,
- additionalData: {
- // Force response code. See https://docs.adyen.com/development-resources/test-cards/result-code-testing/adyen-response-codes
- // RequestedTestAcquirerResponseCode: 2,
- allow3DS2: true
- // To force threeds2InMDFlow:
- // comment out "allow3DS2" & comment in the following 2 lines:
- // threeDS2InMDFlow: true,
- // executeThreeD: true
- },
- // Ready for v69 - lose any additionalData 3DS2 related lines e.g. allow3DS2: true
- // authenticationData: {
- // attemptAuthentication: 'always',
- // // To force MDFlow: comment out below, and just keep line above
- // threeDSRequestData: {
- // nativeThreeDS: 'preferred'
- // }
+ // additionalData: {
+ // // Force response code. See https://docs.adyen.com/development-resources/test-cards/result-code-testing/adyen-response-codes
+ // // RequestedTestAcquirerResponseCode: 2,
+ // allow3DS2: true
+ // // To force threeds2InMDFlow:
+ // // comment out "allow3DS2" & comment in the following 2 lines:
+ // // threeDS2InMDFlow: true,
+ // // executeThreeD: true
// },
+ // Ready for v69+ - lose any additionalData 3DS2 related lines e.g. allow3DS2: true
+ authenticationData: {
+ attemptAuthentication: 'always',
+ // To force MDFlow: comment out below, and just keep line above
+ threeDSRequestData: {
+ nativeThreeDS: 'preferred'
+ }
+ },
shopperEmail: 'test-shopper@storytel.com',
shopperIP: '172.30.0.1',
// threeDS2RequestData: {