diff --git a/src/Payments/PaymentMethodsRecord.res b/src/Payments/PaymentMethodsRecord.res index 7a9896cc4..ccbaefeae 100644 --- a/src/Payments/PaymentMethodsRecord.res +++ b/src/Payments/PaymentMethodsRecord.res @@ -499,6 +499,13 @@ let paymentMethodsFields = [ fields: [InfoElement], miniIcon: Some(icon("bank", ~size=19)), }, + { + paymentMethodName: "open_banking_pis", + icon: Some(icon("bank", ~size=19)), + displayName: "Open Banking", + fields: [InfoElement], + miniIcon: Some(icon("bank", ~size=19)), + }, { paymentMethodName: "evoucher", icon: Some(icon("cashtocode", ~size=50)), @@ -739,9 +746,6 @@ let getPaymentDetails = (arr: array) => { finalArr } -type paymentMethod = - Cards | Wallets | PayLater | BankRedirect | BankTransfer | BankDebit | Crypto | Voucher | NONE - type cardType = Credit | Debit type paymentExperience = { @@ -825,19 +829,6 @@ let defaultList = { merchant_name: "", collect_billing_details_from_wallets: true, } -let getMethod = str => { - switch str { - | "card" => Cards - | "wallet" => Wallets - | "pay_later" => PayLater - | "bank_redirect" => BankRedirect - | "bank_transfer" => BankTransfer - | "bank_debit" => BankDebit - | "crypto" => Crypto - | "voucher" => Voucher - | _ => NONE - } -} let getPaymentExperienceType = str => { switch str { diff --git a/src/Payments/PlaidSDKIframe.res b/src/Payments/PlaidSDKIframe.res index 0350cc519..43a66bf4c 100644 --- a/src/Payments/PlaidSDKIframe.res +++ b/src/Payments/PlaidSDKIframe.res @@ -6,10 +6,11 @@ let make = () => { let (isReady, setIsReady) = React.useState(_ => false) let (pmAuthConnectorsArr, setPmAuthConnectorsArr) = React.useState(_ => []) let (publishableKey, setPublishableKey) = React.useState(_ => "") - let (paymentId, setPaymentId) = React.useState(_ => "") + let (clientSecret, setClientSecret) = React.useState(_ => "") + let (isForceSync, setIsForceSync) = React.useState(_ => false) let logger = React.useMemo(() => { - OrcaLogger.make(~source=Elements(Payment), ~clientSecret=paymentId, ~merchantId=publishableKey) - }, (publishableKey, paymentId)) + OrcaLogger.make(~source=Elements(Payment), ~clientSecret, ~merchantId=publishableKey) + }, (publishableKey, clientSecret)) React.useEffect0(() => { let handle = (ev: Window.event) => { @@ -24,8 +25,9 @@ let make = () => { setLinkToken(_ => linkToken) setPmAuthConnectorsArr(_ => pmAuthConnectorArray) - setPublishableKey(_ => metaData->getString("payment_id", "")) - setPaymentId(_ => metaData->getString("publishableKey", "")) + setPublishableKey(_ => metaData->getString("publishableKey", "")) + setClientSecret(_ => metaData->getString("clientSecret", "")) + setIsForceSync(_ => metaData->getBool("isForceSync", false)) } } Window.addEventListener("message", handle) @@ -47,6 +49,50 @@ let make = () => { None }, [pmAuthConnectorsArr]) + let callbackOnSuccessOfPlaidPaymentsFlow = () => { + open Promise + let headers = [("Content-Type", "application/json"), ("api-key", publishableKey)] + + PaymentHelpers.retrievePaymentIntent( + clientSecret, + headers, + ~optLogger=Some(logger), + ~switchToCustomPod=false, + ~isForceSync=true, + ) + ->then(json => { + let dict = json->getDictFromJson + let status = dict->getString("status", "") + let return_url = dict->getString("return_url", "") + + if ( + status === "succeeded" || status === "requires_customer_action" || status === "processing" + ) { + postSubmitResponse(~jsonData=json, ~url=return_url) + } else if status === "failed" { + postFailedSubmitResponse( + ~errortype="confirm_payment_failed", + ~message="Payment failed. Try again!", + ) + } else { + postFailedSubmitResponse( + ~errortype="sync_payment_failed", + ~message="Payment is processing. Try again later!", + ) + } + handlePostMessage([("fullscreen", false->JSON.Encode.bool)]) + resolve(json) + }) + ->then(_ => { + resolve(Nullable.null) + }) + ->catch(e => { + logInfo(Console.log2("Retrieve Failed", e)) + resolve(Nullable.null) + }) + ->ignore + } + React.useEffect(() => { if isReady && linkToken->String.length > 0 { let handler = Plaid.create({ @@ -59,14 +105,21 @@ let make = () => { ("isPlaid", true->JSON.Encode.bool), ("publicToken", publicToken->JSON.Encode.string), ]) + if isForceSync { + callbackOnSuccessOfPlaidPaymentsFlow() + } }, onExit: _ => { - handlePostMessage([ - ("fullscreen", false->JSON.Encode.bool), - ("isPlaid", true->JSON.Encode.bool), - ("isExited", true->JSON.Encode.bool), - ("publicToken", ""->JSON.Encode.string), - ]) + if isForceSync { + callbackOnSuccessOfPlaidPaymentsFlow() + } else { + handlePostMessage([ + ("fullscreen", false->JSON.Encode.bool), + ("isPlaid", true->JSON.Encode.bool), + ("isExited", true->JSON.Encode.bool), + ("publicToken", ""->JSON.Encode.string), + ]) + } }, }) diff --git a/src/Payments/QRCodeDisplay.res b/src/Payments/QRCodeDisplay.res index dbcadd077..212c826a1 100644 --- a/src/Payments/QRCodeDisplay.res +++ b/src/Payments/QRCodeDisplay.res @@ -91,7 +91,7 @@ let make = () => { ~switchToCustomPod, ) ->then(json => { - let dict = json->JSON.Decode.object->Option.getOr(Dict.make()) + let dict = json->getDictFromJson let status = dict->getString("status", "") if ( diff --git a/src/ThreeDSAuth.res b/src/ThreeDSAuth.res index 911b98406..91262087c 100644 --- a/src/ThreeDSAuth.res +++ b/src/ThreeDSAuth.res @@ -61,7 +61,7 @@ let make = () => { ~headers, ) ->then(json => { - let dict = json->JSON.Decode.object->Option.getOr(Dict.make()) + let dict = json->getDictFromJson if dict->Dict.get("error")->Option.isSome { let errorObj = PaymentError.itemToObjMapper(dict) handlePostMessage([("fullscreen", false->JSON.Encode.bool)]) diff --git a/src/Utilities/PaymentHelpers.res b/src/Utilities/PaymentHelpers.res index 6b1960483..253f1a17b 100644 --- a/src/Utilities/PaymentHelpers.res +++ b/src/Utilities/PaymentHelpers.res @@ -176,7 +176,7 @@ let rec pollRetrievePaymentIntent = ( open Promise retrievePaymentIntent(clientSecret, headers, ~optLogger, ~switchToCustomPod, ~isForceSync) ->then(json => { - let dict = json->JSON.Decode.object->Option.getOr(Dict.make()) + let dict = json->getDictFromJson let status = dict->getString("status", "") if status === "succeeded" || status === "failed" { @@ -261,7 +261,7 @@ let rec pollStatus = ( open Promise retrieveStatus(~headers, ~switchToCustomPod, pollId, logger) ->then(json => { - let dict = json->JSON.Decode.object->Option.getOr(Dict.make()) + let dict = json->getDictFromJson let status = dict->getString("status", "") Promise.make((resolve, _) => { if status === "completed" { @@ -693,12 +693,33 @@ let rec intentCall = ( | None => Dict.make() } let walletName = session_token->getString("wallet_name", "") + let message = switch walletName { | "apple_pay" => [ ("applePayButtonClicked", true->JSON.Encode.bool), ("applePayPresent", session_token->anyTypeToJson), ] | "google_pay" => [("googlePayThirdPartyFlow", session_token->anyTypeToJson)] + | "open_banking" => { + let metaData = [ + ( + "linkToken", + session_token + ->getString("open_banking_session_token", "") + ->JSON.Encode.string, + ), + ("pmAuthConnectorArray", ["plaid"]->Identity.anyTypeToJson), + ("publishableKey", confirmParam.publishableKey->JSON.Encode.string), + ("clientSecret", clientSecret->JSON.Encode.string), + ("isForceSync", true->JSON.Encode.bool), + ]->getJsonFromArrayOfJson + [ + ("fullscreen", true->JSON.Encode.bool), + ("param", "plaidSDK"->JSON.Encode.string), + ("iframeId", iframeId->JSON.Encode.string), + ("metadata", metaData), + ] + } | _ => [] } @@ -1687,8 +1708,9 @@ let callAuthLink = ( [ ("linkToken", data->getDictFromJson->getString("link_token", "")->JSON.Encode.string), ("pmAuthConnectorArray", pmAuthConnectorsArr->Identity.anyTypeToJson), - ("payment_id", clientSecret->Option.getOr("")->getPaymentId->JSON.Encode.string), ("publishableKey", publishableKey->JSON.Encode.string), + ("clientSecret", clientSecret->Option.getOr("")->JSON.Encode.string), + ("isForceSync", false->JSON.Encode.bool), ]->getJsonFromArrayOfJson handlePostMessage([ diff --git a/src/orca-loader/Elements.res b/src/orca-loader/Elements.res index 229d27ed9..32679f401 100644 --- a/src/orca-loader/Elements.res +++ b/src/orca-loader/Elements.res @@ -643,7 +643,7 @@ let make = ( ) ->then(json => { if redirect.contents === "always" { - let dict = json->JSON.Decode.object->Option.getOr(Dict.make()) + let dict = json->getDictFromJson let status = dict->getString("status", "") let returnUrl = dict->getString("return_url", "") Window.Location.replace(