From 0c4c6adffea7ca0ba80e4e4e66810c8ce647c932 Mon Sep 17 00:00:00 2001
From: Jeeva Ramachandran <120017870+JeevaRamu0104@users.noreply.github.com>
Date: Wed, 17 Apr 2024 19:41:07 +0530
Subject: [PATCH] chore: support merchant business country apple pay (#587)

---
 .../Wallets/ApplePayWalletIntegration.res     | 245 +++++++++++++-----
 .../ApplePayWalletIntegrationUtils.res        |   9 +
 src/screens/Connectors/Wallets/Wallet.res     |  24 +-
 3 files changed, 210 insertions(+), 68 deletions(-)

diff --git a/src/screens/Connectors/Wallets/ApplePayWalletIntegration.res b/src/screens/Connectors/Wallets/ApplePayWalletIntegration.res
index cad36c30c..09ec9c285 100644
--- a/src/screens/Connectors/Wallets/ApplePayWalletIntegration.res
+++ b/src/screens/Connectors/Wallets/ApplePayWalletIntegration.res
@@ -13,6 +13,55 @@ module HostURL = {
   }
 }
 
+module MerchantBussinessCountry = {
+  @react.component
+  let make = (~fieldsArray: array<ReactFinalForm.fieldRenderProps>, ~options) => {
+    let defaultInput: ReactFinalForm.fieldRenderProps = {
+      input: ReactFinalForm.makeInputRecord(""->JSON.Encode.string, _e => ()),
+      meta: ReactFinalForm.makeCustomError(None),
+    }
+    let operator = (fieldsArray->Array.get(0)->Option.getOr(defaultInput)).input
+    let input: ReactFinalForm.fieldRenderPropsInput = {
+      name: "string",
+      onBlur: _ev => (),
+      onChange: ev => {
+        let value = ev->Identity.formReactEventToString
+        operator.onChange(value->Identity.anyTypeToReactEvent)
+      },
+      onFocus: _ev => (),
+      value: operator.value,
+      checked: true,
+    }
+
+    <SelectBox.BaseDropdown
+      allowMultiSelect=false
+      buttonText="Select Operator"
+      input
+      options
+      hideMultiSelectButtons=true
+      customButtonStyle="w-full"
+      fullLength=true
+    />
+  }
+}
+
+let renderCountryInp = (options, fieldsArray: array<ReactFinalForm.fieldRenderProps>) => {
+  <MerchantBussinessCountry fieldsArray options />
+}
+
+let countryInput = (~id, ~options) => {
+  open FormRenderer
+  makeMultiInputFieldInfoOld(
+    ~label="Merchant Business Country",
+    ~comboCustomInput=renderCountryInp(options),
+    ~inputFields=[
+      makeInputFieldInfo(~name=`${id}`, ()),
+      makeInputFieldInfo(~name=`${id}.default`, ()),
+    ],
+    (),
+  )
+}
+
 module Simplified = {
   @react.component
   let make = (
@@ -21,6 +70,7 @@ module Simplified = {
     ~update,
     ~setApplePayIntegrationSteps,
     ~setVefifiedDomainList,
+    ~merchantBusinessCountry,
   ) => {
     open WalletHelper
     open APIUtils
@@ -32,23 +82,32 @@ module Simplified = {
     let connectorID = url.path->List.toArray->Array.get(1)->Option.getOr("")
     let merchantDetailsValue = HSwitchUtils.useMerchantDetailsValue()
     let merchantId = merchantDetailsValue.merchant_id
-    let prefix = "apple_pay_combined.simplified.session_token_data.initiative_context"
+    let namePrefix = `apple_pay_combined.simplified.session_token_data`
     let inputField =
-      <FormRenderer.FieldRenderer
-        field={FormRenderer.makeFieldInfo(
-          ~label="",
-          ~name={prefix},
-          ~placeholder="eg. example.com",
-          ~customInput=InputFields.textInput(
-            ~customStyle="w-64",
-            ~autoComplete="off",
-            ~autoFocus=true,
+      [
+        <FormRenderer.FieldRenderer
+          labelClass="font-semibold !text-hyperswitch_black"
+          field={FormRenderer.makeFieldInfo(
+            ~label="Domain Name",
+            ~name={`${namePrefix}.initiative_context`},
+            ~placeholder="eg. example.com",
+            ~customInput=InputFields.textInput(
+              ~customStyle="w-64",
+              ~autoComplete="off",
+              ~autoFocus=true,
+              (),
+            ),
             (),
-          ),
-          (),
-        )}
-      />
-
+          )}
+        />,
+        <FormRenderer.FieldRenderer
+          labelClass="font-semibold !text-hyperswitch_black"
+          field={countryInput(
+            ~id={`${namePrefix}.merchant_business_country`},
+            ~options=merchantBusinessCountry,
+          )}
+        />,
+      ]->React.array
     let downloadApplePayCert = () => {
       open Promise
       fetchApi(HSwitchGlobalVars.urlToDownloadApplePayCertificate, ~method_=Get, ())
@@ -127,7 +186,7 @@ module Simplified = {
           "Host the downloaded verification file at your sandbox domain in the following location :-",
         )
         stepNumber="3"
-        customElement=Some(<HostURL prefix />)
+        customElement=Some(<HostURL prefix={`${namePrefix}.initiative_context`} />)
       />
       <div className="w-full flex gap-2 justify-end p-6">
         <Button
@@ -152,32 +211,42 @@ module Manual = {
     ~update,
     ~setApplePayIntegrationSteps,
     ~setVefifiedDomainList,
+    ~merchantBusinessCountry,
   ) => {
     open WalletHelper
     open LogicUtils
     open ApplePayWalletIntegrationUtils
-
+    open FormRenderer
     let configurationFields =
       metadataInputs->getDictfromDict("apple_pay")->getDictfromDict("session_token_data")
-
+    let namePrefix = `apple_pay_combined.manual.session_token_data`
     let fields = {
       configurationFields
       ->Dict.keysToArray
       ->Array.mapWithIndex((field, index) => {
-        let label = configurationFields->getString(field, "")
-        <div key={index->Int.toString}>
-          <FormRenderer.FieldRenderer
+        switch field->customApplePlayFields {
+        | #merchant_business_country =>
+          <FieldRenderer
             labelClass="font-semibold !text-hyperswitch_black"
-            field={FormRenderer.makeFieldInfo(
-              ~label,
-              ~name={`apple_pay_combined.manual.session_token_data.${field}`},
-              ~placeholder={`Enter ${label->snakeToTitle}`},
-              ~customInput=InputFields.textInput(),
-              ~isRequired=true,
-              (),
-            )}
+            field={countryInput(~id={`${namePrefix}.${field}`}, ~options=merchantBusinessCountry)}
           />
-        </div>
+        | _ => {
+            let label = configurationFields->getString(field, "")
+            <div key={index->Int.toString}>
+              <FormRenderer.FieldRenderer
+                labelClass="font-semibold !text-hyperswitch_black"
+                field={FormRenderer.makeFieldInfo(
+                  ~label,
+                  ~name={`${namePrefix}.${field}`},
+                  ~placeholder={`Enter ${label->snakeToTitle}`},
+                  ~customInput=InputFields.textInput(),
+                  ~isRequired=true,
+                  (),
+                )}
+              />
+            </div>
+          }
+        }
       })
       ->React.array
     }
@@ -351,40 +420,96 @@ module Verified = {
 }
 
 @react.component
-let make = (~metadataInputs, ~update, ~metaData, ~setShowWalletConfigurationModal) => {
+let make = (~metadataInputs, ~update, ~metaData, ~setShowWalletConfigurationModal, ~connector) => {
   open ApplePayWalletIntegrationTypes
-
+  open APIUtils
   open WalletHelper
   let (appleIntegrationType, setApplePayIntegrationType) = React.useState(_ => #simplified)
   let (applePayIntegrationStep, setApplePayIntegrationSteps) = React.useState(_ => Landing)
   let (verifiedDomainList, setVefifiedDomainList) = React.useState(_ => [])
-  <div>
-    <Heading />
-    {switch applePayIntegrationStep {
-    | Landing =>
-      <Landing
-        setApplePayIntegrationType
-        setShowWalletConfigurationModal
-        setApplePayIntegrationSteps
-        appleIntegrationType
-      />
-    | Configure =>
-      switch appleIntegrationType {
-      | #simplified =>
-        <Simplified
-          metadataInputs metaData update setApplePayIntegrationSteps setVefifiedDomainList
+  let (merchantBusinessCountry, setMerchantBusinessCountry) = React.useState(_ => [])
+  let (screenState, setScreenState) = React.useState(_ => PageLoaderWrapper.Success)
+  let fetchDetails = useGetMethod()
+  let getProcessorDetails = async () => {
+    open LogicUtils
+    try {
+      setScreenState(_ => Loading)
+      let paymentMethoConfigUrl = getURL(~entityName=PAYMENT_METHOD_CONFIG, ~methodType=Get, ())
+      let res = await fetchDetails(
+        `${paymentMethoConfigUrl}?connector=${connector}&paymentMethodType=apple_pay`,
+      )
+      let countries =
+        res
+        ->getDictFromJsonObject
+        ->getArrayFromDict("countries", [])
+        ->Array.map(item => {
+          let dict = item->getDictFromJsonObject
+          let a: SelectBox.dropdownOption = {
+            label: dict->getString("name", ""),
+            value: dict->getString("code", ""),
+          }
+          a
+        })
+
+      setMerchantBusinessCountry(_ => countries)
+      setScreenState(_ => Success)
+    } catch {
+    | _ => setScreenState(_ => Success)
+    }
+  }
+
+  React.useEffect0(() => {
+    getProcessorDetails()->ignore
+    None
+  })
+  <PageLoaderWrapper
+    screenState={screenState}
+    customLoader={<div className="mt-60 w-scrren flex flex-col justify-center items-center">
+      <div className={`animate-spin mb-1`}>
+        <Icon name="spinner" size=20 />
+      </div>
+    </div>}
+    sectionHeight="!h-screen">
+    <div>
+      <Heading />
+      {switch applePayIntegrationStep {
+      | Landing =>
+        <Landing
+          setApplePayIntegrationType
+          setShowWalletConfigurationModal
+          setApplePayIntegrationSteps
+          appleIntegrationType
         />
-      | #manual =>
-        <Manual metadataInputs metaData update setApplePayIntegrationSteps setVefifiedDomainList />
-      }
-    | Verify =>
-      <Verified
-        verifiedDomainList
-        setApplePayIntegrationType
-        setShowWalletConfigurationModal
-        setApplePayIntegrationSteps
-        appleIntegrationType
-      />
-    }}
-  </div>
+      | Configure =>
+        switch appleIntegrationType {
+        | #simplified =>
+          <Simplified
+            metadataInputs
+            metaData
+            update
+            setApplePayIntegrationSteps
+            setVefifiedDomainList
+            merchantBusinessCountry
+          />
+        | #manual =>
+          <Manual
+            metadataInputs
+            metaData
+            update
+            setApplePayIntegrationSteps
+            setVefifiedDomainList
+            merchantBusinessCountry
+          />
+        }
+      | Verify =>
+        <Verified
+          verifiedDomainList
+          setApplePayIntegrationType
+          setShowWalletConfigurationModal
+          setApplePayIntegrationSteps
+          appleIntegrationType
+        />
+      }}
+    </div>
+  </PageLoaderWrapper>
 }
diff --git a/src/screens/Connectors/Wallets/ApplePayWalletIntegrationUtils.res b/src/screens/Connectors/Wallets/ApplePayWalletIntegrationUtils.res
index 714c5c99b..c3d31a202 100644
--- a/src/screens/Connectors/Wallets/ApplePayWalletIntegrationUtils.res
+++ b/src/screens/Connectors/Wallets/ApplePayWalletIntegrationUtils.res
@@ -71,3 +71,12 @@ let constructVerifyApplePayReq = (values, connectorID) => {
   }
   (body, domainName)
 }
+
+type customApplePayFields = [#merchant_business_country | #other]
+
+let customApplePlayFields = field => {
+  switch field {
+  | "merchant_business_country" => #merchant_business_country
+  | _ => #other
+  }
+}
diff --git a/src/screens/Connectors/Wallets/Wallet.res b/src/screens/Connectors/Wallets/Wallet.res
index 1dd308375..a85047897 100644
--- a/src/screens/Connectors/Wallets/Wallet.res
+++ b/src/screens/Connectors/Wallets/Wallet.res
@@ -122,6 +122,7 @@ module Wallets = {
       })
       ->React.array
     }
+    Js.log(configurationFields->Dict.keysToArray)
     <div>
       {switch (
         method.payment_method_type->getPaymentMethodTypeFromString,
@@ -130,15 +131,22 @@ module Wallets = {
       | (ApplePay, Processors(STRIPE))
       | (ApplePay, Processors(BANKOFAMERICA))
       | (ApplePay, Processors(CYBERSOURCE)) =>
-        <ApplePayWalletIntegration metadataInputs update metaData setShowWalletConfigurationModal />
+        <ApplePayWalletIntegration
+          metadataInputs update metaData setShowWalletConfigurationModal connector
+        />
       | _ =>
-        <Form initialValues={metaData} onSubmit validate>
-          {fields}
-          <FormRenderer.SubmitButton
-            text="Proceed" showToolTip=true buttonSize=Button.Large customSumbitButtonStyle="w-full"
-          />
-          <FormValuesSpy />
-        </Form>
+        <UIUtils.RenderIf condition={configurationFields->Dict.keysToArray->Array.length > 0}>
+          <Form initialValues={metaData} onSubmit validate>
+            {fields}
+            <FormRenderer.SubmitButton
+              text="Proceed"
+              showToolTip=true
+              buttonSize=Button.Large
+              customSumbitButtonStyle="w-full"
+            />
+            <FormValuesSpy />
+          </Form>
+        </UIUtils.RenderIf>
       }}
     </div>
   }