{"version":3,"file":"PaymentForm.mjs","names":["React","FC","useRef","useEffect","useMemo","useState","useCallback","Form","useTranslation","UdpFlexbox","UdpButton","UdpProgressBar","UdpMessageBar","UdpRadioGroup","UdpTablist","CreditCardForm","BankAccountForm","CashForm","ConfigService","apiMutate","useUser","IPaymentMethodTab","PaymentDetails","PaymentVendorFactoryEnum","PaymentMethodTypeEnum","PaymentAccount","usePaymentContext","PaymentMethodProps","id","activeTab","externalId","paymentAccounts","paymentDetails","bankAccountTypes","loading","onTabChange","event","ChangeEvent","paymentMethodTab","onFormStatusChange","paymentFormResult","onSubmitCompleted","FormEvent","HTMLFormElement","result","submit","presetDataRequest","formData","paymentMethod","isHostedPayment","children","ReactNode","childrenPosition","actionLabel","render","params","showSandboxBanner","s2sToken","s2sTenantId","refreshS2sToken","Promise","allowSavePaymentMethod","methodPicker","actionsStart","onSubmittingChange","submitting","onReadyChange","ready","PAYMENT_METHODS","CREDIT_CARD","CASH","E_CHECK","DEBIT_CARD","PaymentForm","user","t","defaultAccountTypes","name","defaultValue","value","resolvedBankAccountTypes","setValue","formRef","methodBoxRef","HTMLDivElement","methodBoxReleaseTimer","freezeMethodBoxHeight","box","current","style","minHeight","offsetHeight","window","clearTimeout","setTimeout","s2sTokenRef","paymentFormStatus","setPaymentFormStatus","setSelectedHostedPayment","selectedPaymentType","setSelectedPaymentType","CreditCard","loadingProcessPayment","setLoadingProcessPayment","selectedPaymentAccount","setSelectedPaymentAccount","methods","paymentMethodsArray","isLoading","loadingPaymentMethods","fetchPaymentMethod","currentTenantID","paymentMethodId","token","path","config","method","headers","Authorization","currentTenantId","pgV1ApiUrl","fetchPaymentMethodDetails","tenantID","methodId","data","Error","executePaymentPG","paymentType","requestBody","body","executeHostedPaymentPG","console","log","basePath","paymentTokenId","paymentMethodLabels","key","handleChange","newValue","selectedPaymentMethod","enabledMethods","paymentVendorConnection","paymentVendorFactoryID","paymentMethodID","handleStatusChange","renderPaymentMethodForm","isFormDisabled","toLowerCase","undefined","String","filter","m","enabled","activeMethod","isSandBoxMode","isLiveMode","isAutoSubmitHostedMethod","isHostedPaymentPage","providerType","ICheck","Paymentus","length","getPaymentMethodLabel","normalizedMethodName","replace","methodLabel","createHostedPaymentRequest","baseRequest","vendorFactoryID","vendorRequest","Fiserv","HostedPageToken","payload","message","expiry","Expiry","isValid","errorMessage","responseObjet","JSON","parse","ResponseData","transactionResponse","paymentTokenID","NameOnAccount","CardHolderName","Token","ExpiryDate","PaymentTokenId","request","PaymentVendorFactoryID","createNonHostedPaymentRequest","dataRequest","Object","assign","setCreditCardAttr","eCheck","setECheckAttr","createDataRequest","executePayment","paymentMethodName","response","expireMonth","expiryDate","split","expireYear","expirationDate","CardNumber","cardNumber","ExpirationDate","SecurityCode","cvv","routingNumber","accountNumber","submitPaymentForm","freshToken","error","warn","retryOnAuthError","call","T","status","hostedPaymentPageSetup","useHostedPaymentPage","paymentResult","handleICheckPaymentFormStatus","vendor","selectedHostedPayment","isAutoSubmitVendor","firstEnabled","find","isReadyToSubmit","form","hasMultipleMethods","hasNoMethods","isSubmitting","Boolean","map","label","e","CustomEvent","detail","nextIdx","findIndex","target"],"sources":["../../../../src/utilities/form/paymentForm/PaymentForm.tsx"],"sourcesContent":["import React, { FC, useRef, useEffect, useMemo, useState, useCallback } from 'react';\nimport { Form } from '../Form';\nimport { useTranslation } from 'react-i18next';\nimport { UdpFlexbox } from '../../../UI/fluent-web-components/UdpFlexbox';\nimport { UdpButton } from '../../../UI/fluent-web-components/UdpButton';\nimport { UdpProgressBar } from '../../../UI/fluent-web-components/UdpProgressBar';\nimport { UdpMessageBar } from '../../../UI/fluent-web-components/UdpMessageBar';\nimport { UdpRadioGroup } from '../../../UI/fluent-web-components/UdpRadioGroup';\nimport { UdpTablist } from '../../../UI/fluent-web-components/UdpTablist';\nimport { CreditCardForm } from './CreditCardForm';\nimport { BankAccountForm } from './BankAccountForm';\nimport { CashForm } from './CashForm';\nimport { ConfigService } from '../../../configService';\nimport { apiMutate } from '../../useAxiosMutate';\nimport { useUser } from '../../auth/useUser';\nimport { IPaymentMethodTab, PaymentDetails } from './AccountPayment.model';\nimport { PaymentVendorFactoryEnum } from '../../../enums/paymentVendorFactoryEnum';\nimport { PaymentMethodTypeEnum } from '../../../enums/paymentMethodTypeEnum';\nimport { PaymentAccount } from './PaymentAccount.model';\nimport { usePaymentContext } from './usePaymentContext';\n\nexport interface PaymentMethodProps {\n  id: string;\n  activeTab?: number;\n  externalId?: string | number;\n  /**\n   * Currently unused at this level — kept for API compatibility with V1 and\n   * existing back-office consumers that already pass it.\n   *\n   * NOTE: not to be confused with the `paymentAccounts` variable inside\n   * `CreditCardForm` / `BankAccountForm`, which is the locally fetched\n   * saved-tokens list and is unrelated to this prop.\n   */\n  paymentAccounts?: any[];\n  paymentDetails: PaymentDetails;\n  bankAccountTypes?: any[];\n  loading: boolean;\n  onTabChange: (event: React.ChangeEvent<{}>, paymentMethodTab: any) => void;\n  onFormStatusChange?: (paymentFormResult: any) => void;\n  onSubmitCompleted?: (event: React.FormEvent<HTMLFormElement> | null, result: any) => void;\n  submit?: (event: React.FormEvent<HTMLFormElement>) => void;\n  presetDataRequest: (formData: any, paymentMethod: any, isHostedPayment: boolean) => any;\n  children?: React.ReactNode;\n  childrenPosition?: \"before\" | \"after\" | \"outside\";\n  actionLabel?: string;\n  render?: React.ReactNode | ((params: any) => React.ReactNode);\n  /**\n   * Whether to show the \"Sandbox / test mode\" banner when the active payment\n   * vendor connection is in non-live mode. Defaults to `true` to preserve the\n   * behaviour back-office consumers rely on. Payer-facing flows (e.g. the\n   * standalone invoice page) should pass `false`.\n   */\n  showSandboxBanner?: boolean;\n  /**\n   * S2S bearer token obtained by the consuming application via Unity Keeper.\n   * When present the component operates in S2S mode: all Payment Portal API\n   * calls use the `/S2S` endpoint variants and this token as the Authorization\n   * header instead of the Unity user session token.\n   */\n  s2sToken?: string;\n  /** Tenant ID required alongside `s2sToken` for S2S mode API calls. */\n  s2sTenantId?: string;\n  /**\n   * Called at the start of submit to obtain a fresh S2S token. Payment-link\n   * tokens can be very short-lived (observed TTL: 60s), so a token minted at\n   * page load is often already expired by the time the payer submits. When\n   * provided, the returned token is used for the submit-path API calls;\n   * on failure the existing token is kept as a fallback.\n   */\n  refreshS2sToken?: () => Promise<string | undefined>;\n  /**\n   * Whether the manual entry forms (card, eCheck) offer the \"save this\n   * method\" checkbox. Defaults to `true` for account-connected flows.\n   * Guest/standalone flows (e.g. the invoice payment link) should pass\n   * `false` — there is no user account to save the method to.\n   */\n  allowSavePaymentMethod?: boolean;\n  /**\n   * Visual style of the payment-method picker shown when more than one\n   * method is enabled. Defaults to 'radio'.\n   */\n  methodPicker?: 'radio' | 'tabs';\n  /**\n   * Rendered at the start of the action row, before the submit button.\n   * Lets hosts (e.g. a stepper) place secondary actions like \"Back\" in the\n   * same row as the pay button instead of a second, disconnected button row.\n   */\n  actionsStart?: React.ReactNode;\n  /**\n   * Notifies the host when payment processing starts (true) and settles\n   * (false). Lets an external submit button — connected via the form\n   * registry (`<UdpButton type=\"submit\" form={id}>`) when no `submit` prop\n   * is passed — mirror the internal button's loading/disabled behaviour.\n   */\n  onSubmittingChange?: (submitting: boolean) => void;\n  /**\n   * Notifies the host whether a submit can currently succeed — false while\n   * method discovery is in flight, when no payable method exists, or in\n   * hosted-iframe mode until the vendor iframe reports a token. Lets an\n   * external submit button mirror the internal button's disabled state.\n   */\n  onReadyChange?: (ready: boolean) => void;\n}\n\nconst PAYMENT_METHODS = {\n  CREDIT_CARD: 'credit card',\n  CASH: 'cash',\n  E_CHECK: 'echeck',\n  DEBIT_CARD: 'debit card'\n};\n\n/**\n * PaymentForm Component\n *\n * This component provides a user interface for selecting and handling different payment methods.\n * It allows users to switch between available payment methods using tabs and handles the form submission process.\n * Each payment method has its own form component that is displayed based on the selected tab.\n *\n * Props:\n *   @param {PaymentMethodProps} props - Object containing the following properties:\n *     @param {string} id - Unique identifier for the payment form.\n *     @param {number} [activeTab=0] - The index of the currently active tab. Defaults to 0.  [OPTIONAL]\n *     @param {any[]} [paymentAccounts] - Array of payment accounts associated with the user. [OPTIONAL]\n *     @param {PaymentDetails} paymentDetails - Object containing details about the customer's payment information.\n *     @param {any[]} [bankAccountTypes=DEFAULT_ACCOUNT_TYPES] - Array of available bank account types, with a default value.\n *     @param {boolean} loading - Boolean flag indicating if asynchronous operations like data fetching are in progress.\n *     @param {Function} onTabChange - Function to be called when the active tab changes.\n *     @param {Function} [onFormStatusChange] - Optional function to handle status changes during form interactions.\n *     @param {Function} [onSubmitCompleted] - Optional function to be called upon successful form submission.\n *     @param {Function} presetDataRequest - Function to prepare the data request for payment processing.\n *     @param {Function} [submit] - Optional function to be called on form submission.\n *     @param {any} [children] - Optional elements to be rendered inside the form.\n *     @param {\"before\" | \"after\" | \"outside\"} [childrenPosition=\"before\"] - Position of the children elements relative to the form.\n *     @param {string} [actionLabel] - Optional label for the form action button.\n *     @param {any} [render] - Optional render function for custom rendering inside the component.\n *\n * Usage:\n * The component renders tabs to switch between different payment methods and handles form interactions\n * for submitting payments. It integrates with Material-UI components to render the form and uses React hooks\n * for managing state, such as the currently active tab and form interaction data.\n *\n * The component uses the `useMemo` hook to optimize rendering performance and to handle the memoization of\n * computed payment fields. It ensures that the form submission process is smooth, even for hosted payments.\n *\n * Each payment method form (e.g., CreditCardForm, eCheckForm, etc.) is conditionally rendered based on the\n * currently selected payment method, ensuring a consistent user experience.\n *\n * Example:\n * <PaymentForm\n *   id=\"paymentForm\"\n *   activeTab={0}\n *   paymentAccounts={accounts}\n *   paymentDetails={paymentDetails}\n *   bankAccountTypes={accountTypes}\n *   loading={isLoading}\n *   onTabChange={handleTabChange}\n *   onFormStatusChange={handleStatusChange}\n *   presetDataRequest={createDataRequest}\n *   onSubmitCompleted={handleSubmitCompleted}\n *   actionLabel=\"Enter Card Details\"\n *   submit={handleSubmit}\n * />\n *\n * Note:\n * This component should be used within a React environment that supports hooks and functional components.\n * It relies on Material-UI for UI components and theming.\n */\nexport const PaymentForm: FC<PaymentMethodProps> = ({\n  id,\n  activeTab = 0,\n  externalId,\n  // eslint-disable-next-line @typescript-eslint/no-unused-vars\n  paymentAccounts,\n  paymentDetails,\n  bankAccountTypes,\n  loading,\n  presetDataRequest,\n  onTabChange,\n  onFormStatusChange,\n  onSubmitCompleted,\n  submit,\n  children,\n  childrenPosition = \"before\",\n  actionLabel,\n  render,\n  showSandboxBanner = true,\n  s2sToken,\n  s2sTenantId,\n  refreshS2sToken,\n  allowSavePaymentMethod = true,\n  methodPicker = 'radio',\n  actionsStart,\n  onSubmittingChange,\n  onReadyChange,\n}) => {\n  const user = useUser();\n  const { t } = useTranslation();\n\n  // Default bank-account types live inside the component (rather than as a\n  // module constant) so their display names re-resolve when the language changes.\n  const defaultAccountTypes = useMemo(\n    () => [\n      { name: t('payments.bank.checking', { defaultValue: 'Checking' }), value: 'checking' },\n      { name: t('payments.bank.savings', { defaultValue: 'Savings' }), value: 'savings' },\n    ],\n    [t]\n  );\n  const resolvedBankAccountTypes = bankAccountTypes ?? defaultAccountTypes;\n\n  const [value, setValue] = useState(activeTab);\n  const formRef = useRef<any>(null);\n  const methodBoxRef = useRef<HTMLDivElement | null>(null);\n  const methodBoxReleaseTimer = useRef<number | null>(null);\n  /**\n   * Freeze the method-form area's current height while switching methods.\n   * The outgoing form unmounts synchronously but the incoming form's web\n   * components hydrate asynchronously, so the area collapses to ~zero height\n   * for a few frames. Inside a scroll container that collapse clamps the\n   * scroll position (the page appears to jump to the top). Holding the\n   * previous height through the swap keeps the scroll position stable.\n   */\n  const freezeMethodBoxHeight = () => {\n    const box = methodBoxRef.current;\n    if (!box) return;\n    box.style.minHeight = `${box.offsetHeight}px`;\n    if (methodBoxReleaseTimer.current) {\n      window.clearTimeout(methodBoxReleaseTimer.current);\n    }\n    methodBoxReleaseTimer.current = window.setTimeout(() => {\n      box.style.minHeight = '';\n      methodBoxReleaseTimer.current = null;\n    }, 400);\n  };\n\n  useEffect(\n    () => () => {\n      if (methodBoxReleaseTimer.current) {\n        window.clearTimeout(methodBoxReleaseTimer.current);\n      }\n    },\n    []\n  );\n\n  // Submit-path calls read the token through this ref so refreshS2sToken can\n  // swap in a fresh one mid-submit without waiting for a re-render.\n  const s2sTokenRef = useRef<string | undefined>(s2sToken);\n  useEffect(() => {\n    s2sTokenRef.current = s2sToken;\n  }, [s2sToken]);\n\n  const [paymentFormStatus, setPaymentFormStatus] = useState<any>(null);\n  const [, setSelectedHostedPayment] = useState<PaymentVendorFactoryEnum | null>(null);\n  const [selectedPaymentType, setSelectedPaymentType] = useState(PaymentMethodTypeEnum.CreditCard);\n  const [loadingProcessPayment, setLoadingProcessPayment] = useState<boolean>(false);\n  const [selectedPaymentAccount, setSelectedPaymentAccount] = useState<PaymentAccount | null>(null);\n\n  // #region [API Calls]\n\n  /**\n   * Discovery: resolved list of payment methods + vendor/hosted-page info.\n   * When the backend ships a single payment-context endpoint, replace the\n   * usePaymentContext implementation — no other change in this file is needed.\n   */\n  const { methods: paymentMethodsArray, isLoading: loadingPaymentMethods } = usePaymentContext(s2sToken, s2sTenantId);\n\n  /**\n   * API call to fetchPaymentMethod\n   *\n   * @param {string} currentTenantID\n   * @param {string} paymentMethodId\n   * @return {*}\n   */\n  const fetchPaymentMethod = useCallback(\n    async (currentTenantID: string, paymentMethodId: string | number) => {\n      if (!currentTenantID || !paymentMethodId) {\n        return null;\n      }\n\n      const token = s2sTokenRef.current;\n      const path = token\n        ? `AppPaymentVendor/PaymentMethod/${paymentMethodId}/S2S`\n        : `AppPaymentVendor/PaymentMethod/${paymentMethodId}`;\n      const config = token\n        ? { method: 'GET', headers: { Authorization: `Bearer ${token}`, currentTenantId: s2sTenantId } }\n        : { method: 'GET' };\n      return apiMutate(ConfigService.pgV1ApiUrl, path, config, {});\n    },\n    [s2sTenantId]\n  );\n\n  /**\n   * fetchPaymentMethodDetails\n   *\n   * @param {*} tenantID\n   * @param {*} methodId\n   * @return {*}\n   */\n  const fetchPaymentMethodDetails = useCallback(\n    async (tenantID: any, methodId: any): Promise<any> => {\n      const result = await fetchPaymentMethod(tenantID, methodId);\n      const paymentMethod = result?.data;\n\n      if (!paymentMethod) {\n        throw new Error(\n          `${t('payments.form.methodConfigNotFound', {\n            defaultValue: 'Payment method configuration not found',\n          })}: ${methodId}`\n        );\n      }\n\n      return paymentMethod;\n    },\n    [fetchPaymentMethod, t]\n  );\n\n  /**\n   * executePaymentPG\n   *\n   * @param {string} paymentType\n   * @param {any} requestBody\n   * @return {*}\n   */\n  const executePaymentPG = useCallback(\n    async (paymentType: string, requestBody: any) => {\n      if (!paymentType || !requestBody) {\n        return null;\n      }\n\n      const token = s2sTokenRef.current;\n      const path = token\n        ? `ProcessPayment/${paymentType}/S2S`\n        : `ProcessPayment/${paymentType}`;\n      const body = requestBody as unknown;\n      const config = token\n        ? { method: 'POST', data: body, headers: { Authorization: `Bearer ${token}`, currentTenantId: s2sTenantId } }\n        : { method: 'POST', data: body };\n\n      return apiMutate(ConfigService.pgV1ApiUrl, path, config, {});\n    },\n    [s2sTenantId]\n  );\n\n  /**\n   * executeHostedPaymentPG\n   *\n   * @param {string} paymentType\n   * @param {any} requestBody\n   * @return {*}\n   */\n  const executeHostedPaymentPG = useCallback(\n    async (paymentType: string, requestBody: any) => {\n\n      console.log('executeHostedPaymentPG started')\n\n      if (!paymentType || !requestBody) {\n        return null;\n      }\n      const body = requestBody as unknown;\n      const token = s2sTokenRef.current;\n      const basePath = (requestBody as { paymentTokenId?: unknown })?.paymentTokenId\n        ? `ProcessPayment/${paymentType}Profile`\n        : `ProcessHostedPaymentPagePayment/${paymentType}`;\n      const path = token ? `${basePath}/S2S` : basePath;\n\n      console.log(`this is the path: ${path}`);\n      console.log(body);\n\n      return apiMutate(\n        ConfigService.pgV1ApiUrl,\n        path,\n        token\n          ? { method: 'POST', data: body, headers: { Authorization: `Bearer ${token}`, currentTenantId: s2sTenantId } }\n          : { method: 'POST', data: body },\n        {}\n      );\n    },\n    [s2sTenantId]\n  );\n\n  // #endregion\n\n  // #region [Methods]\n\n  const paymentMethodLabels: { [key: string]: string } = useMemo(() => ({\n    \"creditcard\": t(\"payments.form.methods.creditCard\", { defaultValue: \"Credit Card\" }),\n    \"debitcard\": t(\"payments.form.methods.debitCard\", { defaultValue: \"Debit Card\" }),\n    \"echeck\": t(\"payments.form.methods.echeck\", { defaultValue: \"eCheck\" }),\n    \"check\": t(\"payments.form.methods.check\", { defaultValue: \"Check\" }),\n    \"cash\": t(\"payments.form.methods.cash\", { defaultValue: \"Cash\" })\n  }), [t]);\n\n  /**\n   * handleChange\n   *\n   * @param {React.ChangeEvent<{}>} event\n   * @param {number} newValue\n   */\n  /**\n   * Update the active method by index into the enabled list.\n   * `event` is forwarded to `onTabChange` for back-compat with consumers that\n   * expected the legacy MUI tab-change signature.\n   */\n  const handleChange = (event: React.ChangeEvent<any>, newValue: number) => {\n    freezeMethodBoxHeight();\n    setValue(newValue);\n\n    const selectedPaymentMethod = enabledMethods?.[newValue];\n\n    setSelectedHostedPayment(\n      selectedPaymentMethod?.paymentVendorConnection?.paymentVendorFactoryID as PaymentVendorFactoryEnum | null\n    );\n    setSelectedPaymentType(selectedPaymentMethod?.paymentMethodID as PaymentMethodTypeEnum);\n\n    onTabChange(event, selectedPaymentMethod);\n  };\n\n  // onFormStatusChange is fired by the useEffect on `paymentFormStatus` below;\n  // do NOT also call it here or consumers receive the same status twice per change.\n  const handleStatusChange = (paymentFormStatus: any): void => {\n    setPaymentFormStatus(paymentFormStatus);\n  };\n\n  /**\n   * Render the form for the currently-selected method. The picker only ever\n   * surfaces enabled methods, so no disabled-overlay branch is needed.\n   *\n   * @param method  the active payment method\n   * @param isFormDisabled  when true, locks every input in the rendered form.\n   *                        Driven by RFF `submitting` + our own\n   *                        `loadingProcessPayment` so the user can't change\n   *                        values mid-submit.\n   */\n  const renderPaymentMethodForm = useCallback((method: any, isFormDisabled: boolean) => {\n    const name = method?.name?.toLowerCase();\n\n    if (name === PAYMENT_METHODS.CREDIT_CARD) {\n      return (\n        <CreditCardForm\n          onStatusChange={handleStatusChange}\n          paymentDetails={paymentDetails}\n          externalId={externalId !== undefined ? String(externalId) : undefined}\n          setSelectedPaymentAccount={setSelectedPaymentAccount}\n          actionLabel={actionLabel}\n          isFormDisabled={isFormDisabled}\n          allowSaveMethod={allowSavePaymentMethod}\n          s2sToken={s2sToken}\n          s2sTenantId={s2sTenantId}\n          {...method}\n        />\n      );\n    }\n    if (name === PAYMENT_METHODS.CASH) {\n      return (\n        <CashForm\n          onStatusChange={handleStatusChange}\n          paymentDetails={paymentDetails}\n          isFormDisabled={isFormDisabled}\n          {...method}\n        />\n      );\n    }\n    if (name === PAYMENT_METHODS.E_CHECK) {\n      return (\n        <BankAccountForm\n          bankAccountTypes={resolvedBankAccountTypes}\n          onStatusChange={handleStatusChange}\n          paymentDetails={paymentDetails}\n          externalId={externalId !== undefined ? String(externalId) : undefined}\n          setSelectedPaymentAccount={setSelectedPaymentAccount}\n          actionLabel={actionLabel}\n          isFormDisabled={isFormDisabled}\n          allowSaveMethod={allowSavePaymentMethod}\n          s2sToken={s2sToken}\n          s2sTenantId={s2sTenantId}\n          {...method}\n        />\n      );\n    }\n    if (name === PAYMENT_METHODS.DEBIT_CARD) {\n      // TODO: Implement Debit Card form. Falls back to CreditCardForm until then.\n      return (\n        <CreditCardForm\n          onStatusChange={handleStatusChange}\n          paymentDetails={paymentDetails}\n          isFormDisabled={isFormDisabled}\n          allowSaveMethod={allowSavePaymentMethod}\n          s2sToken={s2sToken}\n          s2sTenantId={s2sTenantId}\n          {...method}\n        />\n      );\n    }\n    return null;\n  }, [paymentDetails, resolvedBankAccountTypes, externalId, actionLabel, allowSavePaymentMethod, s2sToken, s2sTenantId]);\n\n  /**\n   * Enabled (configured) methods only. Unconfigured methods are hidden from the\n   * picker entirely — today's behaviour of \"show a disabled tab with a !\n   * badge\" was confusing and inaccessible.\n   */\n  const enabledMethods = useMemo<IPaymentMethodTab[]>(\n    () => paymentMethodsArray?.filter((m) => m.enabled) ?? [],\n    [paymentMethodsArray]\n  );\n\n  const activeMethod = enabledMethods[value] ?? enabledMethods[0];\n\n  /**\n   * Sandbox mode for the currently-selected method's vendor connection.\n   */\n  const isSandBoxMode = useMemo(() => {\n    const isLiveMode = activeMethod?.paymentVendorConnection?.isLiveMode;\n    return isLiveMode === false;\n  }, [activeMethod]);\n\n  /**\n   * ICheck and Paymentus both render their own submit button inside the\n   * hosted iframe and auto-submit this form once the iframe posts back a\n   * token (see handleICheckPaymentFormStatus below) — our own submit button\n   * would just be a confusing second button. Fiserv's hosted iframe has no\n   * button of its own, so it still needs ours.\n   */\n  const isAutoSubmitHostedMethod =\n    activeMethod?.isHostedPaymentPage === true &&\n    (activeMethod?.providerType === PaymentVendorFactoryEnum.ICheck ||\n      activeMethod?.providerType === PaymentVendorFactoryEnum.Paymentus);\n\n  // Clamp `value` if the enabled-methods list shrinks (e.g. discovery\n  // returned fewer methods than expected).\n  useEffect(() => {\n    if (enabledMethods.length === 0) return;\n    if (value >= enabledMethods.length) {\n      setValue(0);\n    }\n  }, [enabledMethods.length, value]);\n\n  /**\n   * getPaymentMethodLabel\n   *\n   * @param {*} method\n   * @return {*}\n   */\n  const getPaymentMethodLabel = (method: { name: string; }) => {\n    const normalizedMethodName = method?.name?.toLowerCase().replace(/\\s+/g, '') || '';\n    const methodLabel = paymentMethodLabels?.[normalizedMethodName as keyof typeof paymentMethodLabels] || method.name;\n\n    return methodLabel;\n  };\n\n  /**\n   * createHostedPaymentRequest\n   *\n   * @param {*} baseRequest\n   * @param {*} paymentMethod\n   * @return {*}\n   */\n  const createHostedPaymentRequest = useCallback(\n    (baseRequest: any, paymentMethod: any, paymentMethodId: string | number, selectedPaymentAccount: PaymentAccount | null): any => {\n      const vendorFactoryID =\n        paymentMethod.paymentVendorConnection?.paymentVendorFactoryID;\n      let vendorRequest = {};\n\n      switch (vendorFactoryID) {\n        case PaymentVendorFactoryEnum.Fiserv:\n          vendorRequest = {\n            HostedPageToken:\n              paymentFormStatus?.payload?.token ||\n              paymentFormStatus?.payload?.message,\n            ...(paymentFormStatus?.payload?.expiry && {\n              Expiry: paymentFormStatus?.payload?.expiry,\n            }),\n          };\n          break;\n        case PaymentVendorFactoryEnum.ICheck:\n          if (!paymentFormStatus?.isValid) {\n            throw new Error(\n              `${t('payments.form.paymentErrorCheckForm', {\n                defaultValue: 'Payment error. Please check the form and try again',\n              })} ${paymentFormStatus?.errorMessage}`\n            );\n          }\n          const responseObjet = JSON.parse(paymentFormStatus?.payload);\n\n          vendorRequest = {\n            ResponseData: responseObjet?.transactionResponse,\n          };\n          break;\n        case PaymentVendorFactoryEnum.Paymentus:\n          const paymentTokenId = selectedPaymentAccount ? selectedPaymentAccount?.paymentTokenID : null;\n\n          /* Paymentus uses a PaymentTokenId like an a Payment Account */\n          vendorRequest = {\n            NameOnAccount: paymentFormStatus?.payload?.CardHolderName,\n            HostedPageToken: paymentFormStatus?.payload?.Token,\n            ...(paymentFormStatus?.payload?.ExpiryDate && {\n              Expiry: paymentFormStatus?.payload?.ExpiryDate,\n            }),\n            ...(paymentTokenId && { PaymentTokenId: paymentTokenId }),\n          };\n          break;\n        default:\n          break;\n      }\n      const request = {\n        ...baseRequest,\n        PaymentVendorFactoryID: vendorFactoryID,\n        ...vendorRequest,\n      };\n\n      return request;\n    },\n    [paymentFormStatus, t]\n  );\n\n  /**\n   * createNonHostedPaymentRequest\n   *\n   * @param {*} baseRequest\n   * @param {*} formData\n   * @return {*}\n   */\n  const createNonHostedPaymentRequest = useCallback(\n    (baseRequest: any, formData: any): any => {\n      let dataRequest = { ...baseRequest };\n\n      if (selectedPaymentType === PaymentMethodTypeEnum.CreditCard) {\n        Object.assign(dataRequest, setCreditCardAttr(formData));\n      } else if (selectedPaymentType === PaymentMethodTypeEnum.eCheck) {\n        Object.assign(dataRequest, setECheckAttr(formData));\n      }\n      return dataRequest;\n    },\n    [selectedPaymentType]\n  );\n\n  /**\n   * createDataRequest\n   *\n   * @param {*} formData\n   * @param {*} paymentMethod\n   * @param {*} isHostedPayment\n   * @return {*}\n   */\n  const createDataRequest = useCallback(\n    (formData: any, paymentMethod: any, isHostedPayment: any, paymentMethodId: string | number, selectedPaymentAccount: PaymentAccount | null): any => {\n      const baseRequest = presetDataRequest(formData, paymentMethod, isHostedPayment);\n\n      return isHostedPayment\n        ? createHostedPaymentRequest(baseRequest, paymentMethod, paymentMethodId, selectedPaymentAccount)\n        : createNonHostedPaymentRequest(baseRequest, formData);\n    },\n    [paymentFormStatus, user, presetDataRequest, paymentDetails, selectedPaymentType]\n  );\n\n  /**\n   * executePayment\n   * Executes the payment process based on the payment method and request data.\n   *\n   * @param {*} paymentMethodId The ID of the payment method.\n   * @param {*} dataRequest The request data for the payment.\n   * @param {boolean} isHostedPayment Indicates if the payment is a hosted payment.\n   * @return {*} The result of the payment execution.\n   */\n  const executePayment = useCallback(\n    async (\n      paymentMethodId: any,\n      dataRequest: any,\n      isHostedPayment: boolean\n    ): Promise<any> => {\n      if (!paymentMethodId || !dataRequest) {\n        throw new Error(\n          t('payments.form.invalidPaymentData', { defaultValue: 'Invalid payment data' })\n        );\n      }\n      if (typeof isHostedPayment !== 'boolean') {\n        throw new Error(\n          t('payments.form.invalidHostedFlag', { defaultValue: 'Invalid hosted payment flag' })\n        );\n      }\n\n      console.log(`execute payment start`);\n      // console.log(body);\n\n      const paymentMethodName = PaymentMethodTypeEnum?.[paymentMethodId];\n\n      if (!paymentMethodName) {\n        throw new Error(\n          t('payments.form.unknownPaymentMethod', { defaultValue: 'Unknown payment method' }) +\n          `: ${paymentMethodId}`\n        );\n      }\n\n      const response = isHostedPayment\n        ? await executeHostedPaymentPG(paymentMethodName, dataRequest)\n        : await executePaymentPG(paymentMethodName, dataRequest);\n\n      return response?.data || null;\n    },\n    [executePaymentPG, executeHostedPaymentPG, t]\n  );\n\n  /**\n   * setCreditCardAttr\n   *\n   * @param {*} formData\n   * @param {string} currentTenantID\n   * @param {IPaymentMethod} paymentMethod\n   * @return {*}\n   */\n  const setCreditCardAttr = (formData: any) => {\n    const expireMonth = formData.expiryDate.split('/')?.[0];\n    const expireYear = formData.expiryDate.split('/')?.[1];\n    const expirationDate = `20${expireYear}-${expireMonth}-01`;\n\n    return {\n      CardNumber: formData.cardNumber.replace(/\\s/g, ''),\n      ExpirationDate: expirationDate,\n      SecurityCode: formData.cvv,\n    };\n  };\n\n  /**\n   * setECheckAttr\n   * @param {*} formData\n   */\n  const setECheckAttr = (formData: any) => ({\n    routingNumber: formData.routingNumber.replace(/\\s/g, ''),\n    accountNumber: formData.accountNumber.replace(/\\s/g, ''),\n  });\n\n  // #endregion\n\n  // #region [Submit]\n\n  /**\n   * submitPaymentForm\n   * Processes the payment form submission.\n   * @param {*} formData The form data.\n   */\n  const submitPaymentForm = useCallback(\n    async (formData: any): Promise<void> => {\n      if (!formData) return;\n\n      // Discovery still in flight or returned no payable methods — no method\n      // fields are mounted yet, so nothing validated and formData is empty.\n      // The internal button is disabled in this window, but external\n      // form-registry submit buttons can still land here.\n      if (loadingPaymentMethods || enabledMethods.length === 0) return;\n\n      setLoadingProcessPayment(true);\n\n      // Payment-link tokens can expire between page load and submit; re-mint\n      // when the host provides a way to. Failure keeps the existing token.\n      if (refreshS2sToken) {\n        try {\n          const freshToken = await refreshS2sToken();\n          if (freshToken) {\n            s2sTokenRef.current = freshToken;\n          }\n        } catch (error) {\n          console.warn('refreshS2sToken failed; submitting with the existing token', error);\n        }\n      }\n\n      // Reactive backstop to the proactive refresh above: when a call is\n      // rejected with a 403 (how the Payment Portal reports an expired S2S\n      // token), re-mint the token and re-issue that call once. Never retries\n      // other statuses — a 500 from ProcessPayment is a real error and may\n      // mean the charge already went through.\n      const retryOnAuthError = async <T,>(call: () => Promise<T>): Promise<T> => {\n        try {\n          return await call();\n        } catch (error: any) {\n          if (!refreshS2sToken || error?.response?.status !== 403) throw error;\n          let freshToken: string | undefined;\n          try {\n            freshToken = await refreshS2sToken();\n          } catch {\n            throw error;\n          }\n          if (!freshToken) throw error;\n          s2sTokenRef.current = freshToken;\n          return call();\n        }\n      };\n\n      const currentTenantID = s2sTokenRef.current ? s2sTenantId : user?.currentTenantId;\n      const paymentMethodId = selectedPaymentType;\n\n      if (!currentTenantID || !paymentMethodId) {\n        onSubmitCompleted?.(null, {\n          error: true,\n          message: t('payments.form.missingTenantOrMethod', {\n            defaultValue: 'Missing tenant ID or payment method ID',\n          }),\n        });\n        setLoadingProcessPayment(false);\n        return;\n      }\n\n      console.log('started exectute payment');\n\n      try {\n        const paymentMethod = await retryOnAuthError(() =>\n          fetchPaymentMethodDetails(currentTenantID, paymentMethodId)\n        );\n        const isHostedPayment =\n          paymentMethod.paymentVendorConnection?.hostedPaymentPageSetup?.[0]\n            ?.useHostedPaymentPage || false;\n\n        const dataRequest = createDataRequest(\n          formData,\n          paymentMethod,\n          isHostedPayment,\n          paymentMethodId,\n          selectedPaymentAccount\n        );\n\n        const paymentResult = await retryOnAuthError(() =>\n          executePayment(paymentMethodId, dataRequest, isHostedPayment)\n        );\n\n        onSubmitCompleted?.(formData, paymentResult);\n\n      } catch (error: any) {\n        // Route failures through onSubmitCompleted so consumers can react\n        // (previous behaviour threw from an async event handler -> unhandled rejection).\n        console.error('Error processing payment:', error);\n        onSubmitCompleted?.(formData, {\n          error: true,\n          message:\n            error?.message ??\n            t('payments.form.errorProcessingPayment', {\n              defaultValue: 'Error processing payment',\n            }),\n        });\n      } finally {\n        setLoadingProcessPayment(false);\n      }\n    },\n    [createDataRequest, selectedPaymentType, user, selectedPaymentAccount, s2sTenantId, refreshS2sToken, executePayment, fetchPaymentMethodDetails, onSubmitCompleted, loadingPaymentMethods, enabledMethods, t]\n  );\n\n  /**\n   * Handles the form submission for iCheck payments.\n   *\n   * This function checks if the selected payment method is `ECheck` (electronic check)\n   * from the `PaymentVendorFactoryEnum`. If it is, and the form reference (`formRef`) exists\n   * and is currently mounted in the component, it programmatically triggers the form submission.\n   *\n   */\n  const handleICheckPaymentFormStatus = useCallback(() => {\n    const vendor = paymentFormStatus?.selectedHostedPayment;\n    const isAutoSubmitVendor =\n      vendor === PaymentVendorFactoryEnum.ICheck ||\n      vendor === PaymentVendorFactoryEnum.Paymentus;\n\n    if (isAutoSubmitVendor && formRef?.current) {\n      formRef.current.submit();\n    }\n  }, [paymentFormStatus]);\n\n  // #endregion\n\n  // #region [Effects]\n\n  // Default the selected vendor to the first enabled method once discovery\n  // completes. Matches the previous behaviour from setPaymentMethodsEnabled.\n  useEffect(() => {\n    if (!paymentMethodsArray) return;\n    const firstEnabled = paymentMethodsArray.find((m) => m.enabled);\n    setSelectedHostedPayment(firstEnabled?.providerType ?? null);\n  }, [paymentMethodsArray]);\n\n  useEffect(() => {\n    onFormStatusChange?.(paymentFormStatus);\n    handleICheckPaymentFormStatus();\n  }, [paymentFormStatus]);\n\n  // onSubmittingChange is intentionally omitted from deps; consumers may pass\n  // unstable references and we only want to fire when the window changes.\n  useEffect(() => {\n    onSubmittingChange?.(loadingProcessPayment);\n    // eslint-disable-next-line react-hooks/exhaustive-deps\n  }, [loadingProcessPayment]);\n\n  // Mirrors the internal submit button's disabled conditions so hosts with\n  // external submit buttons can gate them identically. Callback omitted from\n  // deps for the same unstable-reference reason as above.\n  const isReadyToSubmit =\n    !loadingPaymentMethods &&\n    enabledMethods.length > 0 &&\n    paymentFormStatus?.isValid !== false;\n\n  useEffect(() => {\n    onReadyChange?.(isReadyToSubmit);\n    // eslint-disable-next-line react-hooks/exhaustive-deps\n  }, [isReadyToSubmit]);\n\n  // #endregion\n\n  return (\n    <>\n      <Form\n        id={id}\n        onSubmit={submitPaymentForm}\n        render={(params: any) => {\n          formRef.current = params?.form;\n\n          const hasMultipleMethods = enabledMethods.length > 1;\n          // Discovery has completed and there are no enabled methods.\n          const hasNoMethods =\n            paymentMethodsArray !== undefined &&\n            enabledMethods.length === 0 &&\n            !loadingPaymentMethods;\n          // RFF `submitting` flips while the Promise returned from\n          // submitPaymentForm is in flight. loadingProcessPayment is our own\n          // signal for the same window. Either way, lock the UI so the user\n          // can't change values or switch methods mid-submit.\n          const isSubmitting = Boolean(params?.submitting) || loadingProcessPayment;\n\n          return (\n            <>\n              <UdpFlexbox direction=\"column\" gap=\"md\" wrap=\"nowrap\">\n                {childrenPosition === \"before\" && children}\n\n                {(loading || loadingPaymentMethods) && <UdpProgressBar />}\n\n                {hasNoMethods && (\n                  <UdpMessageBar intent=\"error\">\n                    {t(\"payments.form.noMethodsAvailable\", {\n                      defaultValue: \"No payment methods are available for this account\",\n                    })}\n                  </UdpMessageBar>\n                )}\n\n                {showSandboxBanner && isSandBoxMode && (\n                  <UdpMessageBar intent=\"warning\">\n                    {t(\"payments.form.sandboxBanner\", {\n                      defaultValue: \"You are currently in test mode using a Sandbox account\",\n                    })}\n                  </UdpMessageBar>\n                )}\n\n                {hasMultipleMethods && methodPicker === 'tabs' && (\n                  <UdpTablist\n                    size=\"small\"\n                    disabled={isSubmitting}\n                    activeId={String(activeMethod?.paymentMethodID ?? '')}\n                    tabList={enabledMethods.map((m) => ({\n                      id: String(m.paymentMethodID),\n                      label: getPaymentMethodLabel(m),\n                    }))}\n                    onTabChange={(e: CustomEvent<string | number>) => {\n                      const id = String(e.detail);\n                      const nextIdx = enabledMethods.findIndex(\n                        (m) => String(m.paymentMethodID) === id\n                      );\n                      if (nextIdx >= 0) {\n                        handleChange(e as unknown as React.ChangeEvent<any>, nextIdx);\n                      }\n                    }}\n                  />\n                )}\n\n                {hasMultipleMethods && methodPicker === 'radio' && (\n                  <UdpRadioGroup\n                    label={t(\"payments.form.paymentMethod\", { defaultValue: \"Payment method\" })}\n                    name=\"paymentMethod\"\n                    disabled={isSubmitting}\n                    includeErrorPadding={false}\n                    value={String(activeMethod?.paymentMethodID ?? '')}\n                    items={enabledMethods.map((m) => ({\n                      label: getPaymentMethodLabel(m),\n                      value: String(m.paymentMethodID),\n                    }))}\n                    onChange={(e) => {\n                      const id = e.target.value;\n                      const nextIdx = enabledMethods.findIndex(\n                        (m) => String(m.paymentMethodID) === id\n                      );\n                      if (nextIdx >= 0) {\n                        handleChange(e as unknown as React.ChangeEvent<any>, nextIdx);\n                      }\n                    }}\n                  />\n                )}\n\n                <div ref={methodBoxRef}>\n                  {activeMethod && renderPaymentMethodForm(activeMethod, isSubmitting)}\n                </div>\n\n                {submit && (\n                  <UdpFlexbox direction=\"row\" gap=\"sm\" align=\"center\" wrap=\"nowrap\">\n                    {actionsStart}\n                    {!isAutoSubmitHostedMethod && (\n                    <UdpButton\n                      type=\"submit\"\n                      form={id}\n                      appearance=\"primary\"\n                      loading={loading || loadingProcessPayment}\n                      // Not actionable until discovery resolves a payable method\n                      // (no fields mounted yet — a click would submit an empty\n                      // form), nor in hosted-iframe mode until the vendor iframe\n                      // reports a token (isValid). Tokenization is driven inside\n                      // the iframe, so this cannot deadlock the flow.\n                      disabled={loadingPaymentMethods || hasNoMethods || paymentFormStatus?.isValid === false}\n                    >\n                      {actionLabel || t('common.save', { defaultValue: 'Save' })}\n                    </UdpButton>\n                    )}\n                  </UdpFlexbox>\n                )}\n\n                {childrenPosition === \"after\" && children}\n                {typeof render === 'function' ? render(params) : render}\n              </UdpFlexbox>\n\n              {childrenPosition === \"outside\" && children}\n            </>\n          );\n        }}\n      />\n    </>\n  );\n}\n"],"mappings":"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"}