-
Notifications
You must be signed in to change notification settings - Fork 35
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: pm auth connector integration - Plaid (#461)
Co-authored-by: Pritish Budhiraja <pritish.budhiraja@gmail.com> Co-authored-by: vsrivatsa-juspay <vrishab.srivatsa@juspay.in>
- Loading branch information
1 parent
1bbc48c
commit 222b322
Showing
17 changed files
with
575 additions
and
72 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
module Loader = { | ||
@react.component | ||
let make = () => { | ||
let {themeObj} = Recoil.useRecoilValueFromAtom(RecoilAtoms.configAtom) | ||
<div className="w-full flex items-center justify-center"> | ||
<div className="w-8 h-8 animate-spin" style={color: themeObj.colorTextSecondary}> | ||
<Icon size=32 name="loader" /> | ||
</div> | ||
</div> | ||
} | ||
} | ||
|
||
@react.component | ||
let make = (~paymentMethodType) => { | ||
open Utils | ||
open Promise | ||
let {publishableKey, clientSecret, iframeId} = Recoil.useRecoilValueFromAtom(RecoilAtoms.keys) | ||
let {themeObj} = Recoil.useRecoilValueFromAtom(RecoilAtoms.configAtom) | ||
let setOptionValue = Recoil.useSetRecoilState(RecoilAtoms.optionAtom) | ||
let paymentMethodListValue = Recoil.useRecoilValueFromAtom(PaymentUtils.paymentMethodListValue) | ||
let setShowFields = Recoil.useSetRecoilState(RecoilAtoms.showCardFieldsAtom) | ||
let (showLoader, setShowLoader) = React.useState(() => false) | ||
|
||
let pmAuthConnectorsArr = | ||
PmAuthConnectorUtils.findPmAuthAllPMAuthConnectors( | ||
paymentMethodListValue.payment_methods, | ||
)->PmAuthConnectorUtils.getAllRequiredPmAuthConnectors | ||
|
||
React.useEffect0(() => { | ||
let onPlaidCallback = (ev: Window.event) => { | ||
let json = ev.data->JSON.parseExn | ||
let dict = json->Utils.getDictFromJson | ||
if dict->getBool("isPlaid", false) { | ||
let publicToken = dict->getDictFromDict("data")->getString("publicToken", "") | ||
let isExited = dict->getDictFromDict("data")->getBool("isExited", false) | ||
setShowLoader(_ => !isExited) | ||
if publicToken->String.length > 0 { | ||
PaymentHelpers.callAuthExchange( | ||
~publicToken, | ||
~clientSecret, | ||
~paymentMethodType, | ||
~publishableKey, | ||
~setOptionValue, | ||
) | ||
->then(_ => { | ||
handlePostMessage([("fullscreen", false->JSON.Encode.bool)]) | ||
setShowFields(_ => false) | ||
JSON.Encode.null->resolve | ||
}) | ||
->catch(_ => JSON.Encode.null->resolve) | ||
->ignore | ||
} | ||
} | ||
} | ||
|
||
Window.addEventListener("message", onPlaidCallback) | ||
Some( | ||
() => { | ||
Window.removeEventListener("message", ev => onPlaidCallback(ev)) | ||
}, | ||
) | ||
}) | ||
|
||
let submitCallback = React.useCallback((ev: Window.event) => { | ||
let json = ev.data->JSON.parseExn | ||
let confirm = json->getDictFromJson->ConfirmType.itemToObjMapper | ||
if confirm.doSubmit { | ||
postFailedSubmitResponse( | ||
~errortype="validation_error", | ||
~message="Please add Bank Details and then confirm payment with the added payment methods.", | ||
) | ||
} | ||
}, []) | ||
useSubmitPaymentData(submitCallback) | ||
|
||
let onClickHandler = () => { | ||
setShowLoader(_ => true) | ||
PaymentHelpers.callAuthLink( | ||
~publishableKey, | ||
~clientSecret, | ||
~iframeId, | ||
~paymentMethodType, | ||
~pmAuthConnectorsArr, | ||
)->ignore | ||
} | ||
|
||
<button | ||
onClick={_ => onClickHandler()} | ||
disabled={showLoader} | ||
style={ | ||
width: "100%", | ||
padding: "20px", | ||
cursor: "pointer", | ||
borderRadius: themeObj.borderRadius, | ||
borderColor: themeObj.borderColor, | ||
borderWidth: "2px", | ||
}> | ||
{if showLoader { | ||
<Loader /> | ||
} else { | ||
{React.string("Add Bank Details")} | ||
}} | ||
</button> | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
@react.component | ||
let make = () => { | ||
open Utils | ||
|
||
let logger = Recoil.useRecoilValueFromAtom(RecoilAtoms.loggerAtom) | ||
let (linkToken, setLinkToken) = React.useState(_ => "") | ||
let (isReady, setIsReady) = React.useState(_ => false) | ||
let (pmAuthConnectorsArr, setPmAuthConnectorsArr) = React.useState(_ => []) | ||
|
||
React.useEffect0(() => { | ||
handlePostMessage([("iframeMountedCallback", true->JSON.Encode.bool)]) | ||
let handle = (ev: Window.event) => { | ||
let json = ev.data->JSON.parseExn | ||
|
||
let metaData = json->getDictFromJson->getDictFromDict("metadata") | ||
let linkToken = metaData->getString("linkToken", "") | ||
if linkToken->String.length > 0 { | ||
let pmAuthConnectorArray = | ||
metaData | ||
->getArray("pmAuthConnectorArray") | ||
->Array.map(ele => ele->JSON.Decode.string) | ||
|
||
setLinkToken(_ => linkToken) | ||
setPmAuthConnectorsArr(_ => pmAuthConnectorArray) | ||
} | ||
} | ||
Window.addEventListener("message", handle) | ||
Some(() => {Window.removeEventListener("message", handle)}) | ||
}) | ||
|
||
React.useEffect(() => { | ||
PmAuthConnectorUtils.mountAllRequriedAuthConnectorScripts( | ||
~pmAuthConnectorsArr, | ||
~onScriptLoaded=authConnector => { | ||
switch authConnector->PmAuthConnectorUtils.pmAuthNameToTypeMapper { | ||
| PLAID => setIsReady(_ => true) | ||
| NONE => () | ||
} | ||
}, | ||
~logger, | ||
) | ||
None | ||
}, [pmAuthConnectorsArr]) | ||
|
||
React.useEffect(() => { | ||
if isReady && linkToken->String.length > 0 { | ||
let handler = Plaid.create({ | ||
token: linkToken, | ||
onSuccess: (publicToken, _) => { | ||
handlePostMessage([ | ||
("isPlaid", true->JSON.Encode.bool), | ||
("publicToken", publicToken->JSON.Encode.string), | ||
]) | ||
}, | ||
onExit: _ => { | ||
handlePostMessage([ | ||
("fullscreen", false->JSON.Encode.bool), | ||
("isPlaid", true->JSON.Encode.bool), | ||
("isExited", true->JSON.Encode.bool), | ||
("publicToken", ""->JSON.Encode.string), | ||
]) | ||
}, | ||
}) | ||
|
||
handler.open_() | ||
} | ||
|
||
None | ||
}, (isReady, linkToken)) | ||
|
||
<div | ||
className="PlaidIframe h-screen w-screen bg-black/40 backdrop-blur-sm m-auto" | ||
style={ | ||
transition: "opacity .35s ease .1s,background-color 600ms linear", | ||
opacity: "100", | ||
} | ||
/> | ||
} |
Oops, something went wrong.