Skip to content

Commit

Permalink
Merge branch 'main' into fix/apple-pay-dynamic-fields
Browse files Browse the repository at this point in the history
  • Loading branch information
akash-c-k authored Mar 22, 2024
2 parents 4324c18 + fcfaa44 commit f3be78d
Show file tree
Hide file tree
Showing 14 changed files with 1,839 additions and 1,526 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
# [0.34.0](https://github.com/juspay/hyperswitch-web/compare/v0.33.12...v0.34.0) (2024-03-22)


### Features

* 3DS without redirection ([#249](https://github.com/juspay/hyperswitch-web/issues/249)) ([70911e5](https://github.com/juspay/hyperswitch-web/commit/70911e5c5ce23ff6e8936cd8028e6bf037b96686))

## [0.33.12](https://github.com/juspay/hyperswitch-web/compare/v0.33.11...v0.33.12) (2024-03-21)


Expand Down
3,025 changes: 1,505 additions & 1,520 deletions package-lock.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "orca-payment-page",
"version": "0.33.12",
"version": "0.34.0",
"main": "index.js",
"private": true,
"dependencies": {
Expand Down
2 changes: 2 additions & 0 deletions src/App.res
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ let make = () => {
<FullScreenDivDriver />
</div>
| "qrData" => <QRCodeDisplay />
| "3dsAuth" => <ThreeDSAuth />
| "3ds" => <ThreeDSMethod />
| "voucherData" => <VoucherDisplay />
| "preMountLoader" => {
let clientSecret = CardUtils.getQueryParamsDictforKey(url.search, "clientSecret")
Expand Down
3 changes: 2 additions & 1 deletion src/CardUtils.res
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,8 @@ let calculateLuhn = value => {
let sumofCheckArr = Array.reduce(checkArr, 0, (acc, val) => acc + val->toInt)
let sumofUnCheckedArr = Array.reduce(unCheckArr, 0, (acc, val) => acc + val->toInt)
let totalSum = sumofCheckArr + sumofUnCheckedArr
mod(totalSum, 10) == 0

mod(totalSum, 10) == 0 || ["3000100811111072", "4000100511112003"]->Array.includes(card) // test cards
}

let getCardBrandIcon = (cardType, paymentType) => {
Expand Down
2 changes: 1 addition & 1 deletion src/Components/NicknamePaymentInput.res
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ let make = (~paymentType: CardThemeType.mode, ~value, ~setValue) => {
onChange
paymentType
appearance=config.appearance
inputRef={React.useRef(Js.Nullable.null)}
inputRef={React.useRef(Nullable.null)}
placeholder=localeString.nicknamePlaceholder
/>
}
91 changes: 91 additions & 0 deletions src/ThreeDSAuth.res
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
open Utils

@react.component
let make = () => {
let (openModal, setOpenModal) = React.useState(_ => false)
let (loader, setloader) = React.useState(_ => true)

let logger = Recoil.useRecoilValueFromAtom(RecoilAtoms.loggerAtom)

React.useEffect0(() => {
handlePostMessage([("iframeMountedCallback", true->JSON.Encode.bool)])
let handle = (ev: Window.event) => {
let json = ev.data->JSON.parseExn
let dict = json->Utils.getDictFromJson
if dict->Dict.get("fullScreenIframeMounted")->Option.isSome {
let metadata = dict->getJsonObjectFromDict("metadata")
let metaDataDict = metadata->JSON.Decode.object->Option.getOr(Dict.make())
let paymentIntentId = metaDataDict->getString("paymentIntentId", "")
let headersDict =
metaDataDict
->getJsonObjectFromDict("headers")
->JSON.Decode.object
->Option.getOr(Dict.make())
let threeDsAuthoriseUrl =
metaDataDict
->getJsonObjectFromDict("threeDSData")
->JSON.Decode.object
->Option.getOr(Dict.make())
->getString("three_ds_authorize_url", "")
let headers =
headersDict
->Dict.toArray
->Array.map(entries => {
let (x, val) = entries
(x, val->JSON.Decode.string->Option.getOr(""))
})

let threeDsMethodComp = metaDataDict->getString("3dsMethodComp", "U")
open Promise
PaymentHelpers.threeDsAuth(
~optLogger=Some(logger),
~clientSecret=paymentIntentId,
~threeDsMethodComp,
~headers,
)
->then(json => {
let dict = json->JSON.Decode.object->Option.getOr(Dict.make())
let creq = dict->getString("challenge_request", "")
let transStatus = dict->getString("trans_status", "Y")
let acsUrl = dict->getString("acs_url", "")

let ele = Window.querySelector("#threeDsAuthDiv")

switch ele->Nullable.toOption {
| Some(elem) =>
if transStatus === "C" {
setloader(_ => false)
let form = elem->OrcaUtils.makeForm(acsUrl, "3dsChallenge")
let input = Types.createElement("input")
input.name = "creq"
input.value = creq
form.target = "threeDsAuthFrame"
form.appendChild(input)
form.submit()
} else {
let form1 = elem->OrcaUtils.makeForm(threeDsAuthoriseUrl, "3dsFrintionLess")
form1.submit()
}
| None => ()
}
resolve(json)
})
->ignore
}
}
Window.addEventListener("message", handle)
Some(() => {Window.removeEventListener("message", handle)})
})

<Modal loader={loader} showClose=false openModal setOpenModal>
<div className="backdrop-blur-xl">
<div id="threeDsAuthDiv" className="hidden" />
<iframe
id="threeDsAuthFrame"
name="threeDsAuthFrame"
style={ReactDOMStyle.make(~minHeight="500px", ())}
width="100%"
/>
</div>
</Modal>
}
93 changes: 93 additions & 0 deletions src/ThreeDSMethod.res
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
open Utils
@react.component
let make = () => {
let logger = Recoil.useRecoilValueFromAtom(RecoilAtoms.loggerAtom)

let mountToInnerHTML = innerHTML => {
let ele = Window.querySelector("#threeDsInvisibleIframe")
switch ele->Nullable.toOption {
| Some(elem) => elem->Window.innerHTML(innerHTML)
| None =>
Console.warn(
"INTEGRATION ERROR: Div does not seem to exist on which threeDSMethod is to be mounted",
)
}
}

React.useEffect0(() => {
handlePostMessage([("iframeMountedCallback", true->JSON.Encode.bool)])
let handle = (ev: Window.event) => {
let json = ev.data->JSON.parseExn
let dict = json->Utils.getDictFromJson
if dict->Dict.get("fullScreenIframeMounted")->Option.isSome {
let metadata = dict->getJsonObjectFromDict("metadata")
let metaDataDict = metadata->JSON.Decode.object->Option.getOr(Dict.make())
let threeDsDataDict =
metaDataDict
->Dict.get("threeDSData")
->Belt.Option.flatMap(JSON.Decode.object)
->Option.getOr(Dict.make())
let threeDsUrl =
threeDsDataDict
->Dict.get("three_ds_method_details")
->Belt.Option.flatMap(JSON.Decode.object)
->Belt.Option.flatMap(x => x->Dict.get("three_ds_method_url"))
->Belt.Option.flatMap(JSON.Decode.string)
->Option.getOr("")
let threeDsMethodData =
threeDsDataDict
->Dict.get("three_ds_method_details")
->Belt.Option.flatMap(JSON.Decode.object)
->Belt.Option.flatMap(x => x->Dict.get("three_ds_method_data"))
->Option.getOr(Dict.make()->JSON.Encode.object)
let iframeId = metaDataDict->getString("iframeId", "")

open Promise
PaymentHelpers.threeDsMethod(threeDsUrl, threeDsMethodData, ~optLogger=Some(logger))
->then(res => {
mountToInnerHTML(res)
resolve(res)
})
->then(res => {
metadata->Utils.getDictFromJson->Dict.set("3dsMethodComp", "Y"->JSON.Encode.string)
handlePostMessage([
("fullscreen", true->JSON.Encode.bool),
("param", `3dsAuth`->JSON.Encode.string),
("iframeId", iframeId->JSON.Encode.string),
("metadata", metadata),
])
resolve(res)
})
->catch(e => {
metadata->Utils.getDictFromJson->Dict.set("3dsMethodComp", "N"->JSON.Encode.string)
handlePostMessage([
("fullscreen", true->JSON.Encode.bool),
("param", `3dsAuth`->JSON.Encode.string),
("iframeId", iframeId->JSON.Encode.string),
("metadata", metadata),
])
reject(e)
})
->ignore

let headersDict =
metaDataDict
->getJsonObjectFromDict("headers")
->JSON.Decode.object
->Option.getOr(Dict.make())
let headers = Dict.make()

headersDict
->Dict.toArray
->Array.forEach(entries => {
let (x, val) = entries
Dict.set(headers, x, val->JSON.Decode.string->Option.getOr(""))
})
}
}
Window.addEventListener("message", handle)
Some(() => {Window.removeEventListener("message", handle)})
})

<div id="threeDsInvisibleIframe" className="bg-black-100 h-96" />
}
7 changes: 7 additions & 0 deletions src/Types/PaymentConfirmTypes.res
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ type nextAction = {
bank_transfer_steps_and_charges_details: option<JSON.t>,
session_token: option<JSON.t>,
image_data_url: option<string>,
three_ds_data: option<JSON.t>,
voucher_details: option<voucherDetails>,
display_to_timestamp: option<float>,
}
Expand All @@ -63,6 +64,7 @@ let defaultNextAction = {
bank_transfer_steps_and_charges_details: None,
session_token: None,
image_data_url: None,
three_ds_data: None,
voucher_details: None,
display_to_timestamp: None,
}
Expand Down Expand Up @@ -140,6 +142,11 @@ let getNextAction = (dict, str) => {
getJsonObjFromDict(json, "session_token", Dict.make())->JSON.Encode.object,
),
image_data_url: Some(json->getString("image_data_url", "")),
three_ds_data: Some(
json
->Dict.get("three_ds_data")
->Option.getOr(Dict.make()->JSON.Encode.object),
),
display_to_timestamp: Some(
json
->Dict.get("display_to_timestamp")
Expand Down
2 changes: 1 addition & 1 deletion src/Utilities/ApiEndpoint.res
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ let switchToInteg = false
let isLocal = false
let sdkDomainUrl = `${GlobalVars.sdkUrl}${GlobalVars.repoPublicPath}`

let apiEndPoint = ref(None)
let apiEndPoint: ref<option<string>> = ref(None)

let setApiEndPoint = str => {
apiEndPoint := Some(str)
Expand Down
Loading

0 comments on commit f3be78d

Please sign in to comment.