diff --git a/CHANGELOG.md b/CHANGELOG.md
index 61c7d8f36..9045a3cc6 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,7 @@
+## [0.84.19](https://github.com/juspay/hyperswitch-web/compare/v0.84.18...v0.84.19) (2024-09-10)
+
+## [0.84.18](https://github.com/juspay/hyperswitch-web/compare/v0.84.17...v0.84.18) (2024-09-09)
+
## [0.84.17](https://github.com/juspay/hyperswitch-web/compare/v0.84.16...v0.84.17) (2024-09-09)
## [0.84.16](https://github.com/juspay/hyperswitch-web/compare/v0.84.15...v0.84.16) (2024-09-09)
diff --git a/package-lock.json b/package-lock.json
index b28e41384..7a56fc0fe 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "orca-payment-page",
- "version": "0.84.17",
+ "version": "0.84.19",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "orca-payment-page",
- "version": "0.84.17",
+ "version": "0.84.19",
"hasInstallScript": true,
"dependencies": {
"@glennsl/rescript-fetch": "^0.2.0",
diff --git a/package.json b/package.json
index 06a8832f8..1eeb8f994 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "orca-payment-page",
- "version": "0.84.17",
+ "version": "0.84.19",
"main": "index.js",
"private": true,
"dependencies": {
diff --git a/src/Payments/DateOfBirth.res b/src/Payments/DateOfBirth.res
index d5c9272d7..bd8522e81 100644
--- a/src/Payments/DateOfBirth.res
+++ b/src/Payments/DateOfBirth.res
@@ -23,20 +23,25 @@ let years = Array.fromInitializer(~length=currentYear - startYear, i => currentY
let make = () => {
open Utils
let {themeObj, localeString} = Recoil.useRecoilValueFromAtom(RecoilAtoms.configAtom)
- let (selectedDate, setSelectedDate) = Recoil.useRecoilState(RecoilAtoms.dateOfBirth)
let (error, setError) = React.useState(_ => false)
let (isNotEligible, setIsNotEligible) = React.useState(_ => false)
+ let loggerState = Recoil.useRecoilValueFromAtom(RecoilAtoms.loggerAtom)
+ let (dateOfBirth, setDateOfBirth) = Recoil.useLoggedRecoilState(
+ RecoilAtoms.dateOfBirth,
+ "dateOfBirth",
+ loggerState,
+ )
let submitCallback = React.useCallback((ev: Window.event) => {
let json = ev.data->safeParse
let confirm = json->getDictFromJson->ConfirmType.itemToObjMapper
if confirm.doSubmit {
- switch selectedDate->Nullable.toOption {
+ switch dateOfBirth->Nullable.toOption {
| Some(_) => setError(_ => false)
| None => ()
}
}
- }, (selectedDate, isNotEligible))
+ }, (dateOfBirth, isNotEligible))
useSubmitPaymentData(submitCallback)
@@ -45,7 +50,7 @@ let make = () => {
| Some(val) => val->checkIs18OrAbove
| None => false
}
- setSelectedDate(_ => date)
+ setDateOfBirth(_ => date)
setIsNotEligible(_ => !isAbove18)
}
@@ -67,7 +72,7 @@ let make = () => {
showIcon=true
icon={}
className="w-full border border-gray-300 rounded p-2"
- selected={selectedDate}
+ selected={dateOfBirth}
onChange
dateFormat="dd-MM-yyyy"
wrapperClassName="datepicker"
diff --git a/src/Utilities/DynamicFieldsUtils.res b/src/Utilities/DynamicFieldsUtils.res
index e47c9350c..8c3d70b9f 100644
--- a/src/Utilities/DynamicFieldsUtils.res
+++ b/src/Utilities/DynamicFieldsUtils.res
@@ -294,7 +294,11 @@ let useSetInitialRequiredFields = (
let (cryptoCurrencyNetworks, setCryptoCurrencyNetworks) = Recoil.useRecoilState(
cryptoCurrencyNetworks,
)
- let (dateOfBirth, setDateOfBirth) = Recoil.useRecoilState(dateOfBirth)
+ let (dateOfBirth, setDateOfBirth) = Recoil.useLoggedRecoilState(
+ dateOfBirth,
+ "dateOfBirth",
+ logger,
+ )
React.useEffect(() => {
let getNameValue = (item: PaymentMethodsRecord.required_fields) => {
diff --git a/src/Utilities/PaymentHelpers.res b/src/Utilities/PaymentHelpers.res
index e0c1e47fd..957f0ca11 100644
--- a/src/Utilities/PaymentHelpers.res
+++ b/src/Utilities/PaymentHelpers.res
@@ -338,7 +338,7 @@ let rec intentCall = (
)
let handleOpenUrl = url => {
if isPaymentSession {
- Window.Location.replace(url)
+ Window.replaceRootHref(url)
} else {
openUrl(url)
}
diff --git a/src/Window.res b/src/Window.res
index 10d4907aa..6b4b754a0 100644
--- a/src/Window.res
+++ b/src/Window.res
@@ -14,8 +14,6 @@ type style
@get external cardCVCElement: window => option = "cardCvc"
@get external cardExpiryElement: window => option = "cardExpiry"
@get external value: Dom.element => 'a = "value"
-@val @scope(("window", "location"))
-external replace: string => unit = "replace"
@val @scope("document") external createElement: string => Dom.element = "createElement"
@set external windowOnload: (window, unit => unit) => unit = "onload"
@@ -131,6 +129,9 @@ module Location = {
@val @scope(("window", "location"))
external hostname: string = "hostname"
+ @val @scope(("window", "location"))
+ external href: string = "href"
+
@val @scope(("window", "location"))
external origin: string = "origin"
@@ -141,6 +142,28 @@ module Location = {
external pathname: string = "pathname"
}
+module Top = {
+ module Location = {
+ @val @scope(("window", "top", "location"))
+ external replace: string => unit = "replace"
+
+ @val @scope(("window", "top", "location"))
+ external hostname: string = "hostname"
+
+ @val @scope(("window", "top", "location"))
+ external href: string = "href"
+
+ @val @scope(("window", "top", "location"))
+ external origin: string = "origin"
+
+ @val @scope(("window", "top", "location"))
+ external protocol: string = "protocol"
+
+ @val @scope(("window", "top", "location"))
+ external pathname: string = "pathname"
+ }
+}
+
module Element = {
@get external clientWidth: Dom.element => int = "clientWidth"
}
@@ -155,3 +178,56 @@ let isSandbox = Location.hostname === "beta.hyperswitch.io"
let isInteg = Location.hostname === "dev.hyperswitch.io"
let isProd = Location.hostname === "checkout.hyperswitch.io"
+
+let isIframed = () =>
+ try {
+ Location.href !== Top.Location.href
+ } catch {
+ | e => {
+ let default = true
+ Js.Console.error3(
+ "Failed to check whether or not document is within an iframe",
+ e,
+ `Using "${default->String.make}" as default (due to DOMException)`,
+ )
+ default
+ }
+ }
+
+let getRootHostName = () =>
+ switch isIframed() {
+ | true =>
+ try {
+ Top.Location.hostname
+ } catch {
+ | e => {
+ let default = Location.hostname
+ Js.Console.error3(
+ "Failed to get root document's hostname",
+ e,
+ `Using "${default}" [window.location.hostname] as default`,
+ )
+ default
+ }
+ }
+ | false => Location.hostname
+ }
+
+let replaceRootHref = (href: string) => {
+ switch isIframed() {
+ | true =>
+ try {
+ Top.Location.replace(href)
+ } catch {
+ | e => {
+ Js.Console.error3(
+ "Failed to redirect root document",
+ e,
+ `Using [window.location.replace] for redirection`,
+ )
+ Location.replace(href)
+ }
+ }
+ | false => Location.replace(href)
+ }
+}
diff --git a/src/orca-loader/Elements.res b/src/orca-loader/Elements.res
index 691372db5..ed28ebfad 100644
--- a/src/orca-loader/Elements.res
+++ b/src/orca-loader/Elements.res
@@ -68,14 +68,13 @@ let make = (
let componentType = "preMountLoader"
let iframeDivHtml = ``
+
+ `
let iframeDiv = Window.createElement("div")
iframeDiv->Window.innerHTML(iframeDivHtml)
Window.body->Window.appendChild(iframeDiv)
@@ -645,7 +644,7 @@ let make = (
let dict = json->getDictFromJson
let status = dict->getString("status", "")
let returnUrl = dict->getString("return_url", "")
- Window.Location.replace(
+ Window.replaceRootHref(
`${returnUrl}?payment_intent_client_secret=${clientSecret}&status=${status}`,
)
resolve(JSON.Encode.null)
@@ -660,7 +659,7 @@ let make = (
})
->catch(err => {
if redirect.contents === "always" {
- Window.Location.replace(url)
+ Window.replaceRootHref(url)
}
messageCurrentWindow([
("submitSuccessful", false->JSON.Encode.bool),
diff --git a/src/orca-loader/Hyper.res b/src/orca-loader/Hyper.res
index 42cb352eb..c3f5be69c 100644
--- a/src/orca-loader/Hyper.res
+++ b/src/orca-loader/Hyper.res
@@ -320,10 +320,10 @@ let make = (publishableKey, options: option, analyticsInfo: optionJSON.Decode.bool->Option.getOr(false)) {
resolve1(json)
} else {
- Window.replace(returnUrl)
+ Window.replaceRootHref(returnUrl)
}
} else if val->JSON.Decode.bool->Option.getOr(false) && redirect === "always" {
- Window.replace(returnUrl)
+ Window.replaceRootHref(returnUrl)
} else if !(val->JSON.Decode.bool->Option.getOr(false)) {
resolve1(json)
} else {
@@ -500,7 +500,7 @@ let make = (publishableKey, options: option, analyticsInfo: optiongetString("return_url", "/")
if val->JSON.Decode.bool->Option.getOr(false) && url !== "/" {
- Window.replace(url)
+ Window.replaceRootHref(url)
} else {
resolve(json)
}
diff --git a/src/orca-loader/LoaderPaymentElement.res b/src/orca-loader/LoaderPaymentElement.res
index 94f7a1c33..028e50132 100644
--- a/src/orca-loader/LoaderPaymentElement.res
+++ b/src/orca-loader/LoaderPaymentElement.res
@@ -190,7 +190,7 @@ let make = (
switch eventDataObject->getOptionalJsonFromJson("openurl") {
| Some(val) => {
let url = val->getStringFromJson("")
- Window.Location.replace(url)
+ Window.replaceRootHref(url)
}
| None => ()
}