From 58839b4a52b5c4c9cfe672bf7b03c00d59d39095 Mon Sep 17 00:00:00 2001 From: Riddhi Agrawal Date: Wed, 24 Jan 2024 17:39:47 +0530 Subject: [PATCH] fix: code refactoring and bug fixes --- .../ConnectPayPalFlow/ConnectPayPal.res | 250 ++++++++---------- .../ConnectPayPalFlow/PayPalFlowUtils.res | 20 +- .../HyperSwitch/Connectors/ConnectorHome.res | 62 ++++- .../Connectors/ConnectorPreview.res | 47 +--- .../ProdOnboardingLanding.res | 1 + 5 files changed, 199 insertions(+), 181 deletions(-) diff --git a/src/screens/HyperSwitch/Connectors/ConnectPayPalFlow/ConnectPayPal.res b/src/screens/HyperSwitch/Connectors/ConnectPayPalFlow/ConnectPayPal.res index 38b0414da..ada412677 100644 --- a/src/screens/HyperSwitch/Connectors/ConnectPayPalFlow/ConnectPayPal.res +++ b/src/screens/HyperSwitch/Connectors/ConnectPayPalFlow/ConnectPayPal.res @@ -123,7 +123,7 @@ module LandingScreen = { } module ErrorPage = { @react.component - let make = (~setupAccountStatus, ~actionUrl, ~getStatus, ~setScreenState) => { + let make = (~setupAccountStatus, ~actionUrl, ~getPayPalStatus, ~setScreenState) => { let errorPageDetails = setupAccountStatus->PayPalFlowUtils.getPageDetailsForAutomatic
@@ -147,7 +147,7 @@ module ErrorPage = { text="Refresh status" buttonType={Secondary} buttonSize=Small - onClick={_ => getStatus()->ignore} + onClick={_ => getPayPalStatus()->ignore} />
Belt.Option.isSome}> @@ -163,12 +163,13 @@ module ErrorPage = { } module RedirectionToPayPalFlow = { @react.component - let make = (~connectorId, ~getStatus) => { + let make = (~getPayPalStatus) => { open APIUtils open PayPalFlowTypes let url = RescriptReactRouter.useUrl() let path = url.path->Belt.List.toArray->Array.joinWith("/") + let connectorId = url.path->Belt.List.toArray->Belt.Array.get(1)->Belt.Option.getWithDefault("") let updateDetails = useUpdateMethod(~showErrorToast=false, ()) let (screenState, setScreenState) = React.useState(_ => PageLoaderWrapper.Loading) let (actionUrl, setActionUrl) = React.useState(_ => "") @@ -228,23 +229,35 @@ module RedirectionToPayPalFlow = { text="Refresh status " buttonType={Secondary} buttonSize=Small - onClick={_ => getStatus()->ignore} + onClick={_ => getPayPalStatus()->ignore} /> - | _ => + | _ => }} } } @react.component -let make = (~connector, ~isUpdateFlow, ~setInitialValues, ~initialValues, ~setCurrentStep) => { - open APIUtils +let make = ( + ~connector, + ~isUpdateFlow, + ~setInitialValues, + ~initialValues, + ~setCurrentStep, + ~getPayPalStatus, +) => { open LogicUtils let url = RescriptReactRouter.useUrl() let showToast = ToastState.useShowToast() + let showPopUp = PopUpState.useShowPopUp() + let updateConnectorAccountDetails = PayPalFlowUtils.useDeleteConnectorAccountDetails() + let deleteTrackingDetails = PayPalFlowUtils.useDeleteTrackingDetails() + let (setupAccountStatus, setSetupAccountStatus) = Recoil.useRecoilState( + HyperswitchAtom.paypalAccountStatusAtom, + ) let connectorValue = isUpdateFlow ? url.path->Belt.List.toArray->Belt.Array.get(1)->Belt.Option.getWithDefault("") : url.search @@ -253,9 +266,6 @@ let make = (~connector, ~isUpdateFlow, ~setInitialValues, ~initialValues, ~setCu ->Belt.Option.getWithDefault("") let (connectorId, setConnectorId) = React.useState(_ => connectorValue) - let updateDetails = useUpdateMethod(~showErrorToast=false, ()) - let updateConnectorAccountDetails = PayPalFlowUtils.useDeleteConnectorAccountDetails() - let deleteTrackingDetails = PayPalFlowUtils.useDeleteTrackingDetails() let isRedirectedFromPaypalModal = url.search ->getDictFromUrlSearchParams @@ -266,9 +276,6 @@ let make = (~connector, ~isUpdateFlow, ~setInitialValues, ~initialValues, ~setCu let (screenState, setScreenState) = React.useState(_ => PageLoaderWrapper.Success) let (configuartionType, setConfigurationType) = React.useState(_ => PayPalFlowTypes.NotSelected) - let (setupAccountStatus, setSetupAccountStatus) = Recoil.useRecoilState( - HyperswitchAtom.paypalAccountStatusAtom, - ) let selectedConnector = connector->ConnectorUtils.getConnectorNameTypeFromString->ConnectorUtils.getConnectorInfo let defaultBusinessProfile = Recoil.useRecoilValueFromAtom(HyperswitchAtom.businessProfilesAtom) @@ -277,13 +284,13 @@ let make = (~connector, ~isUpdateFlow, ~setInitialValues, ~initialValues, ~setCu defaultBusinessProfile->MerchantAccountUtils.getValueFromBusinessProfile let updatedInitialVal = React.useMemo1(() => { - let initialValuesToDict = initialValues->LogicUtils.getDictFromJsonObject + let initialValuesToDict = initialValues->getDictFromJsonObject if !isUpdateFlow { initialValuesToDict->Dict.set( "connector_label", initialValues - ->LogicUtils.getDictFromJsonObject - ->LogicUtils.getString("connector_label", "paypal_default") + ->getDictFromJsonObject + ->getString("connector_label", "paypal_default") ->Js.Json.string, ) initialValuesToDict->Dict.set("profile_id", activeBusinessProfile.profile_id->Js.Json.string) @@ -293,89 +300,69 @@ let make = (~connector, ~isUpdateFlow, ~setInitialValues, ~initialValues, ~setCu } else { initialValues } - }, [connector]) + }, [initialValues]) + + let setConnectorAsActive = values => { + // sets the status as active and diabled as false + let dictOfInitialValues = values->getDictFromJsonObject + dictOfInitialValues->Dict.set("disabled", false->Js.Json.boolean) + dictOfInitialValues->Dict.set("status", "active"->Js.Json.string) + setInitialValues(_ => dictOfInitialValues->Js.Json.object_) + } let updateConnectorDetails = async values => { open ConnectorUtils try { setScreenState(_ => Loading) - let res = await updateConnectorAccountDetails(values, connectorId, connector, isUpdateFlow) - - setInitialValues(_ => res) + let res = await updateConnectorAccountDetails( + values, + connectorId, + connector, + isUpdateFlow, + true, + "inactive", + ) + if configuartionType === Manual { + setConnectorAsActive(res) + } else { + setInitialValues(_ => res) + } let connectorId = res->getDictFromJsonObject->getString("merchant_connector_id", "") setConnectorId(_ => connectorId) setScreenState(_ => Success) - setSetupAccountStatus(._ => Redirecting_to_paypal) + RescriptReactRouter.replace(`/connectors/${connectorId}?name=paypal`) } catch { - | Js.Exn.Error(e) => { - switch Js.Exn.message(e) { - | Some(message) => { - let errMsg = message->parseIntoMyData - if errMsg.code->Belt.Option.getWithDefault("")->Js.String2.includes("HE_01") { - showToast( - ~message="This configuration already exists for the connector. Please try with a different country or label under advanced settings.", - ~toastType=ToastState.ToastError, - (), - ) - setCurrentStep(_ => ConnectorTypes.AutomaticFlow) - setSetupAccountStatus(._ => Connect_paypal_landing) - setScreenState(_ => Success) - } else { - showToast( - ~message="Failed to Save the Configuration!", - ~toastType=ToastState.ToastError, - (), - ) - setScreenState(_ => Error(message)) - } + | Js.Exn.Error(e) => + switch Js.Exn.message(e) { + | Some(message) => { + let errMsg = message->parseIntoMyData + if errMsg.code->Belt.Option.getWithDefault("")->Js.String2.includes("HE_01") { + showToast( + ~message="This configuration already exists for the connector. Please try with a different country or label under advanced settings.", + ~toastType=ToastState.ToastError, + (), + ) + setCurrentStep(_ => ConnectorTypes.AutomaticFlow) + setSetupAccountStatus(._ => Connect_paypal_landing) + setScreenState(_ => Success) + } else { + showToast( + ~message="Failed to Save the Configuration!", + ~toastType=ToastState.ToastError, + (), + ) + setScreenState(_ => Error(message)) } - - | None => setScreenState(_ => Error("Failed to Fetch!")) } - Js.Exn.raiseError("Failed to Fetch!") - } - } - } - let handleStateToNextPage = () => { - setCurrentStep(_ => ConnectorTypes.PaymentMethods) - } - let getStatus = React.useCallback0(async () => { - open PayPalFlowUtils - try { - setScreenState(_ => PageLoaderWrapper.Loading) - let profileId = initialValues->getDictFromJsonObject->getString("profile_id", "") - let paypalBody = generatePayPalBody( - ~connectorId={connectorId}, - ~profileId=Some(profileId), - (), - ) - let url = `${getURL(~entityName=PAYPAL_ONBOARDING, ~methodType=Post, ())}/sync` - let responseValue = await updateDetails(url, paypalBody, Fetch.Post, ()) - let paypalDict = responseValue->getDictFromJsonObject->getJsonObjectFromDict("paypal") - - switch paypalDict->Js.Json.classify { - | JSONString(str) => setSetupAccountStatus(._ => str->stringToVariantMapper) - | JSONObject(dict) => - handleObjectResponse( - ~dict, - ~setSetupAccountStatus, - ~setInitialValues, - ~connector, - ~handleStateToNextPage, - ) - | _ => () + | None => setScreenState(_ => Error("Failed to Fetch!")) } - setScreenState(_ => PageLoaderWrapper.Success) - } catch { - // TODO: check error cases - | _ => setScreenState(_ => PageLoaderWrapper.Error("")) } - }) + } React.useEffect0(() => { if isRedirectedFromPaypalModal { - getStatus()->ignore + getPayPalStatus()->ignore } if !isUpdateFlow { RescriptReactRouter.replace("/connectors/new?name=paypal") @@ -394,67 +381,64 @@ let make = (~connector, ~isUpdateFlow, ~setInitialValues, ~initialValues, ~setCu errors->Js.Json.object_ } - let handleConnector = async values => { + let handleChangeAuthType = async values => { try { - await updateConnectorDetails(values) - } catch { - | Js.Exn.Error(_e) => () - } - } - - let setConnectorAsActive = values => { - // sets the status as active and diabled as false - let dictOfInitialValues = values->getDictFromJsonObject - dictOfInitialValues->Dict.set("disabled", false->Js.Json.boolean) - dictOfInitialValues->Dict.set("status", "active"->Js.Json.string) - setInitialValues(_ => dictOfInitialValues->Js.Json.object_) - } - - let handleOnSubmit = async (values, _) => { - if setupAccountStatus === Connect_paypal_landing { - let authType = - initialValues - ->getDictFromJsonObject - ->getDictfromDict("connector_account_details") - ->getString("auth_type", "") - ->Js.String2.toLowerCase - ->ConnectorUtils.mapAuthType - // This will only be called whenever there is a update flow // And whenever we are changing the flow from Manual to Automatic or vice-versa // To check if the flow is changed we are using auth type (BodyKey for Manual and SignatureKey for Automatic) // It deletes the old tracking id associated with the connector id and deletes the connector credentials - if ( - isUpdateFlow && - authType !== - PayPalFlowUtils.getBodyType(isUpdateFlow, configuartionType) - ->String.toLowerCase - ->ConnectorUtils.mapAuthType - ) { - let _ = await deleteTrackingDetails(connectorId, connector) - let dictOfInitialValues = values->getDictFromJsonObject - let temporaryAuthDict = - [("auth_type", "TemporaryAuth"->Js.Json.string)]->getJsonFromArrayOfJson - dictOfInitialValues->Dict.set("connector_account_details", temporaryAuthDict) - setInitialValues(_ => dictOfInitialValues->Js.Json.object_) - let res = await updateConnectorAccountDetails( - dictOfInitialValues->Js.Json.object_, - connectorId, - connector, - isUpdateFlow, - ) - setInitialValues(_ => res) + + let _ = await deleteTrackingDetails(connectorId, connector) + let _ = await updateConnectorDetails(values) + + switch configuartionType { + | Automatic => setSetupAccountStatus(._ => Redirecting_to_paypal) + | Manual | _ => setCurrentStep(_ => ConnectorTypes.IntegFields) } + } catch { + | Js.Exn.Error(_e) => () + } + } + + let handleOnSubmitRevamp = async (values, _) => { + open PayPalFlowUtils + let authType = initialValues->getAuthTypeFromConnectorDetails - // Functionality when the proceed button is clicked + // create flow + if !isUpdateFlow { switch configuartionType { | Automatic => { - setInitialValues(_ => values) - handleConnector(values)->ignore + await updateConnectorDetails(values) + setSetupAccountStatus(._ => Redirecting_to_paypal) } + + | Manual | _ => + setConnectorAsActive(values) + setCurrentStep(_ => ConnectorTypes.IntegFields) + } + } // update flow if body type is changed + else if ( + authType !== + PayPalFlowUtils.getBodyType(isUpdateFlow, configuartionType) + ->String.toLowerCase + ->ConnectorUtils.mapAuthType + ) { + showPopUp({ + popUpType: (Warning, WithIcon), + heading: "Warning changing configuration", + description: React.string(`Modifying the configuration will result in the loss of existing details associated with this connector. Are you certain you want to continue?`), + handleConfirm: { + text: "Proceed", + onClick: {_ => handleChangeAuthType(values)->ignore}, + }, + handleCancel: {text: "Cancel"}, + }) + } else { + // update flow if body type is not changed + switch configuartionType { + | Automatic => setCurrentStep(_ => ConnectorTypes.PaymentMethods) | Manual | _ => { setConnectorAsActive(values) - setInitialValues(_ => values) setCurrentStep(_ => ConnectorTypes.IntegFields) } } @@ -487,7 +471,7 @@ let make = (~connector, ~isUpdateFlow, ~setInitialValues, ~initialValues, ~setCu
+ onSubmit={handleOnSubmitRevamp}>
- + | _ => React.null }}
diff --git a/src/screens/HyperSwitch/Connectors/ConnectPayPalFlow/PayPalFlowUtils.res b/src/screens/HyperSwitch/Connectors/ConnectPayPalFlow/PayPalFlowUtils.res index 45ac0e261..f789fec5e 100644 --- a/src/screens/HyperSwitch/Connectors/ConnectPayPalFlow/PayPalFlowUtils.res +++ b/src/screens/HyperSwitch/Connectors/ConnectPayPalFlow/PayPalFlowUtils.res @@ -125,6 +125,8 @@ let generateConnectorPayloadPayPal = ( ~connector, ~bodyType, ~connectorLabel, + ~disabled, + ~status, ) => { open ConnectorUtils let initialValues = @@ -132,9 +134,9 @@ let generateConnectorPayloadPayPal = ( ("profile_id", profileId->Js.Json.string), ("connector_name", connector->String.toLowerCase->Js.Json.string), ("connector_type", "payment_processor"->Js.Json.string), - ("disabled", true->Js.Json.boolean), + ("disabled", disabled->Js.Json.boolean), ("test_mode", true->Js.Json.boolean), - ("status", "inactive"->Js.Json.string), + ("status", status->Js.Json.string), ("connector_label", connectorLabel->Js.Json.string), ]->LogicUtils.getJsonFromArrayOfJson @@ -196,7 +198,7 @@ let useDeleteConnectorAccountDetails = () => { open APIUtils let updateDetails = useUpdateMethod(~showErrorToast=false, ()) - async (initialValues, connectorId, connector, isUpdateFlow) => { + async (initialValues, connectorId, connector, isUpdateFlow, disabled, status) => { try { let dictOfJson = initialValues->getDictFromJsonObject let profileIdValue = dictOfJson->getString("profile_id", "") @@ -208,6 +210,8 @@ let useDeleteConnectorAccountDetails = () => { ~connectorLabel={ dictOfJson->getString("connector_label", "") }, + ~disabled, + ~status, ) let url = getURL( ~entityName=CONNECTOR, @@ -225,3 +229,13 @@ let useDeleteConnectorAccountDetails = () => { } } } + +let getAuthTypeFromConnectorDetails = json => { + open LogicUtils + json + ->getDictFromJsonObject + ->getDictfromDict("connector_account_details") + ->getString("auth_type", "") + ->Js.String2.toLowerCase + ->ConnectorUtils.mapAuthType +} diff --git a/src/screens/HyperSwitch/Connectors/ConnectorHome.res b/src/screens/HyperSwitch/Connectors/ConnectorHome.res index 8a6ee7da8..c722a358f 100644 --- a/src/screens/HyperSwitch/Connectors/ConnectorHome.res +++ b/src/screens/HyperSwitch/Connectors/ConnectorHome.res @@ -58,6 +58,7 @@ let make = (~isPayoutFlow=false, ~showStepIndicator=true, ~showBreadCrumb=true) open ConnectorUtils open APIUtils let url = RescriptReactRouter.useUrl() + let updateDetails = useUpdateMethod() let connector = UrlUtils.useGetFilterDictFromUrl("")->LogicUtils.getString("name", "") let connectorID = url.path->Belt.List.toArray->Belt.Array.get(1)->Option.getWithDefault("") let (screenState, setScreenState) = React.useState(_ => PageLoaderWrapper.Loading) @@ -129,7 +130,61 @@ let make = (~isPayoutFlow=false, ~showStepIndicator=true, ~showBreadCrumb=true) let stepsArr = isPayoutFlow ? payoutStepsArr : stepsArr let borderWidth = isPayoutFlow ? "w-8/12" : "w-9/12" - + let setSetupAccountStatus = Recoil.useSetRecoilState(HyperswitchAtom.paypalAccountStatusAtom) + let getPayPalStatus = React.useCallback2(async () => { + open PayPalFlowUtils + open LogicUtils + try { + setScreenState(_ => PageLoaderWrapper.Loading) + let profileId = initialValues->getDictFromJsonObject->getString("profile_id", "") + let paypalBody = generatePayPalBody( + ~connectorId={connectorID}, + ~profileId=Some(profileId), + (), + ) + let url = `${getURL(~entityName=PAYPAL_ONBOARDING, ~methodType=Post, ())}/sync` + let responseValue = await updateDetails(url, paypalBody, Fetch.Post, ()) + let paypalDict = responseValue->getDictFromJsonObject->getJsonObjectFromDict("paypal") + + switch paypalDict->Js.Json.classify { + | JSONString(str) => { + setSetupAccountStatus(._ => str->stringToVariantMapper) + setCurrentStep(_ => AutomaticFlow) + } + | JSONObject(dict) => + handleObjectResponse( + ~dict, + ~setSetupAccountStatus, + ~setInitialValues, + ~connector, + ~handleStateToNextPage={_ => setCurrentStep(_ => PaymentMethods)}, + ) + | _ => () + } + setScreenState(_ => PageLoaderWrapper.Success) + } catch { + // TODO: check error cases + | _ => setScreenState(_ => PageLoaderWrapper.Custom) + } + }, (setInitialValues, setSetupAccountStatus)) + + let customUI = + { + setCurrentStep(_ => AutomaticFlow) + setSetupAccountStatus(._ => PayPalFlowTypes.Connect_paypal_landing) + setScreenState(_ => PageLoaderWrapper.Success) + }} + isButton=true + /> + +
switch connector->ConnectorUtils.getConnectorNameTypeFromString { | PAYPAL => - + | _ => React.null } | IntegFields => @@ -178,6 +235,7 @@ let make = (~isPayoutFlow=false, ~showStepIndicator=true, ~showBreadCrumb=true) isUpdateFlow isPayoutFlow setInitialValues + getPayPalStatus /> }}
diff --git a/src/screens/HyperSwitch/Connectors/ConnectorPreview.res b/src/screens/HyperSwitch/Connectors/ConnectorPreview.res index dc3f4724c..df700c1c5 100644 --- a/src/screens/HyperSwitch/Connectors/ConnectorPreview.res +++ b/src/screens/HyperSwitch/Connectors/ConnectorPreview.res @@ -135,6 +135,8 @@ module MenuOptionForPayPal = { connectorInfo.merchant_connector_id, connectorInfo.connector_name, isUpdateFlow, + true, + "inactive", ) setInitialValues(_ => res) setScreenState(_ => Success) @@ -144,15 +146,11 @@ module MenuOptionForPayPal = { } let handleNewPayPalAccount = async () => { - open LogicUtils try { await deleteTrackingDetails( connectorInfo.merchant_connector_id, connectorInfo.connector_name, ) - let temporaryAuthDict = - [("auth_type", "TemporaryAuth"->Js.Json.string)]->getJsonFromArrayOfJson - connectorInfoDict->Dict.set("connector_account_details", temporaryAuthDict) await updateConnectorAuthType(connectorInfoDict->Js.Json.object_) } catch { | _ => () @@ -353,6 +351,7 @@ let make = ( ~isPayoutFlow, ~showMenuOption=true, ~setInitialValues, + ~getPayPalStatus, ) => { open APIUtils open ConnectorUtils @@ -366,7 +365,6 @@ let make = ( let connectorInfoDict = connectorInfo->LogicUtils.getDictFromJsonObject let connectorInfo = connectorInfo->LogicUtils.getDictFromJsonObject->ConnectorTableUtils.getProcessorPayloadType - let setSetupAccountStatus = Recoil.useSetRecoilState(HyperswitchAtom.paypalAccountStatusAtom) let connectorCount = ListHooks.useListCount(~entityName=CONNECTOR) let isFeedbackModalToBeOpen = @@ -396,43 +394,6 @@ let make = ( } } - let handleStateToNextPage = () => { - setCurrentStep(_ => ConnectorTypes.PaymentMethods) - } - let getStatus = async () => { - open PayPalFlowUtils - open LogicUtils - try { - setScreenState(_ => PageLoaderWrapper.Loading) - let paypalBody = PayPalFlowUtils.generatePayPalBody( - ~connectorId={connectorInfo.merchant_connector_id}, - ~profileId=Some(connectorInfo.profile_id), - (), - ) - let url = `${getURL(~entityName=PAYPAL_ONBOARDING, ~methodType=Post, ())}/sync` - let responseValue = await updateDetails(url, paypalBody, Fetch.Post, ()) - let paypalDict = responseValue->getDictFromJsonObject->getJsonObjectFromDict("paypal") - switch paypalDict->Js.Json.classify { - | JSONString(str) => { - setCurrentStep(_ => AutomaticFlow) - setSetupAccountStatus(._ => str->PayPalFlowUtils.stringToVariantMapper) - } - | JSONObject(dict) => - handleObjectResponse( - ~dict, - ~setSetupAccountStatus, - ~setInitialValues, - ~connector, - ~handleStateToNextPage, - ) - | _ => () - } - setScreenState(_ => PageLoaderWrapper.Success) - } catch { - | _ => setScreenState(_ => PageLoaderWrapper.Error("")) - } - } - let connectorStatusStyle = connectorStatus => switch connectorStatus { | false => "border bg-green-600 bg-opacity-40 border-green-700 text-green-800" @@ -453,7 +414,7 @@ let make = (
{switch (currentStep, connector->getConnectorNameTypeFromString, connectorInfo.status) { | (Preview, PAYPAL, "inactive") => -