diff --git a/server.js b/server.js index 38f8465..ba6d068 100644 --- a/server.js +++ b/server.js @@ -5,7 +5,7 @@ app.use(cors()); app.use(express.static('./dist')); app.use(express.json()); -require('dotenv').config({path: './.env'}); +require('dotenv').config({ path: './.env' }); try { var hyper = require('@juspay-tech/hyperswitch-node')( @@ -18,12 +18,18 @@ try { app.get('/create-payment-intent', async (req, res) => { try { - var paymentIntent = await hyper.paymentIntents.create({ - amount: 2999, - currency: 'USD', - }); + var paymentIntent = await hyper.paymentIntents.create( + { + amount: 6540, + currency: 'USD', + + customer_id: 'StripeCustomer', + + + profile_id: process.env.HYPERSWITCH_PROFILE_ID, + }); + - // Send publishable key and PaymentIntent details to client res.send({ publishableKey: process.env.HYPERSWITCH_PUBLISHABLE_KEY, clientSecret: paymentIntent.client_secret, @@ -47,7 +53,7 @@ app.get('/create-ephemeral-key', async (req, res) => { 'Content-Type': 'application/json', 'api-key': process.env.HYPERSWITCH_SECRET_KEY, }, - body: JSON.stringify({customer_id: "hyperswitch_sdk_demo_id"}), + body: JSON.stringify({ customer_id: "hyperswitch_sdk_demo_id" }), }, ); const ephemeralKey = await response.json(); diff --git a/src/hooks/AllPaymentHooks.res b/src/hooks/AllPaymentHooks.res index 60417f9..e429c3b 100644 --- a/src/hooks/AllPaymentHooks.res +++ b/src/hooks/AllPaymentHooks.res @@ -487,6 +487,10 @@ let useRedirectHook = () => { ~errorCallback, ~processor=body, ) + responseCallback( + ~paymentStatus=LoadingContext.ProcessingPayments(None), + ~status={status, message: "", code: "", type_: ""}, + ) } | statusVal => logger( diff --git a/src/hooks/PMListModifier.res b/src/hooks/PMListModifier.res index 69b825c..771b771 100644 --- a/src/hooks/PMListModifier.res +++ b/src/hooks/PMListModifier.res @@ -206,6 +206,20 @@ let useListModifier = () => { />, }) : None + | BANK_DEBIT(achDebitVal) => + let fields = + redirectionList + ->Array.find(l => l.name == achDebitVal.payment_method_type) + ->Option.getOr(Types.defaultRedirectType) + + Some({ + name: fields.text, + componentHoc: (~isScreenFocus, ~setConfirmButtonDataRef) => + , + }) + | CRYPTO(cryptoVal) => let fields = redirectionList diff --git a/src/icons/Icon.res b/src/icons/Icon.res index 8c3656b..7fb5e09 100644 --- a/src/icons/Icon.res +++ b/src/icons/Icon.res @@ -35,6 +35,7 @@ let camera = `` let checkboxclicked = `` let checkboxnotclicked = `` +let achBankDebit = `` type uri = { uri: string, @@ -96,6 +97,7 @@ let make = ( | "checkboxclicked" => checkboxclicked | "checkboxnotclicked" => checkboxnotclicked | "open banking" => openBanking + | "bank debit" => achBankDebit | _ => "" } localName == "" diff --git a/src/pages/payment/Redirect.res b/src/pages/payment/Redirect.res index f9928b1..3c44437 100644 --- a/src/pages/payment/Redirect.res +++ b/src/pages/payment/Redirect.res @@ -33,6 +33,23 @@ let make = ( let (isEmailValid, setIsEmailValid) = React.useState(_ => None) let (emailIsFocus, setEmailIsFocus) = React.useState(_ => false) + let (accountnum, setaccountnum) = React.useState(_ => None) + let (isaccountnumValid, setisaccountnumValid) = React.useState(_ => None) + let (routingnum, setroutingnum) = React.useState(_ => None) + let (isroutingnumValid, setisroutingnumValid) = React.useState(_ => None) + let (address, setaddress) = React.useState(_ => None) + let (address2, setaddress2) = React.useState(_ => None) + let (isAddressValid, setIsAddressValid) = React.useState(_ => None) + let (isAddress2Valid, setIsAddress2Valid) = React.useState(_ => None) + let (account, setaccount) = React.useState(_ => None) + let (isNicknameSelected, setIsNicknameSelected) = React.useState(_ => false) + let (state, setState) = React.useState(_ => Some(nativeProp.hyperParams.state)) + let (postalCode, setpostalCode) = React.useState(_ => None) + let (city, setcity) = React.useState(_ => None) + let (iscityValid, setIscityValid) = React.useState(_ => None) + let (statesJson, setStatesJson) = React.useState(_ => None) + //let (AddressIsFocus, setAddressIsFocus) = React.useState(_ => false) + let (name, setName) = React.useState(_ => None) let (isNameValid, setIsNameValid) = React.useState(_ => None) let (nameIsFocus, setNameIsFocus) = React.useState(_ => false) @@ -66,6 +83,7 @@ let make = ( | BANK_REDIRECT(prop) => prop.payment_method_type | CRYPTO(prop) => prop.payment_method_type | OPEN_BANKING(prop) => prop.payment_method_type + | BANK_DEBIT(prop) => prop.payment_method_type } let paymentExperience = switch redirectProp { | CARD(_) => None @@ -88,6 +106,10 @@ let make = ( prop.payment_experience ->Array.get(0) ->Option.map(paymentExperience => paymentExperience.payment_experience_type_decode) + | BANK_DEBIT(prop) => + prop.payment_experience + ->Array.get(0) + ->Option.map(paymentExperience => paymentExperience.payment_experience_type_decode) } let paymentMethodType = switch redirectProp { | BANK_REDIRECT(prop) => prop.payment_method_type @@ -107,6 +129,18 @@ let make = ( value: item.hyperSwitch, } }) + let accounts = ["savings", "current"] // Hard Coded The Account_Type Fields in ACHBankDebi + + let accountTypesList = accounts->Js.Array.sortInPlace + + let accountItems = Bank.bankNameConverter(accountTypesList) + + let accountTypes: array = accountItems->Array.map(item => { + { + name: item.displayName, + value: item.hyperSwitch, + } + }) let countryData: array = Country.country->Array.map(item => { { @@ -116,6 +150,33 @@ let make = ( } }) + React.useEffect0(() => { + // Dynamically import/download Postal codes and states JSON + RequiredFieldsTypes.importStates("./../../utility/reusableCodeFromWeb/States.json") + ->Promise.then(res => { + setStatesJson(_ => Some(res.states)) + Promise.resolve() + }) + ->Promise.catch(_ => { + setStatesJson(_ => None) // W1 + Promise.resolve() + }) + ->ignore + + None + }) + + let getStateData = states => { + states + ->Utils.getStateNames(country->Option.getOr("")) + ->Array.map((item): CustomPicker.customPickerType => { + { + name: item, + value: item, + } + }) + } + let (selectedBank, setSelectedBank) = React.useState(_ => Some( switch bankItems->Array.get(0) { | Some(x) => x.hyperSwitch @@ -137,10 +198,25 @@ let make = ( (), ) } + let onChangeState = val => { + setState(val) + logger( + ~logType=INFO, + ~value=country->Option.getOr(""), + ~category=USER_EVENT, + ~eventName=STATE_CHANGED, + ~paymentMethod, + ~paymentExperience?, + (), + ) + } let onChangeBank = val => { setSelectedBank(val) } + let onChangeAccountType = val => { + setaccount(val) + } let onChangeBlikCode = (val: string) => { let onlyNumerics = val->String.replaceRegExp(%re("/\D+/g"), "") @@ -157,6 +233,11 @@ let make = ( setBlikCode(_ => Some(finalVal)) } + let onChangePostalCode = (val: string) => { + let onlyNumerics = val->String.replaceRegExp(%re("/\D+/g"), "") + setpostalCode(_ => Some(onlyNumerics)) + } + let (error, setError) = React.useState(_ => None) let handleSuccessFailure = AllPaymentHooks.useHandleSuccessFailure() @@ -229,23 +310,35 @@ let make = ( billing: ?nativeProp.configuration.defaultBillingDetails, shipping: ?nativeProp.configuration.shippingDetails, setup_future_usage: ?( - allApiData.additionalPMLData.mandateType != NORMAL ? Some("off_session") : None + // "off_session", + allApiData.additionalPMLData.mandateType == NORMAL ? Some("off_session") : None ), payment_type: ?allApiData.additionalPMLData.paymentType, - // mandate_data: ?( - // allApiData.mandateType != NORMAL - // ? Some({ - // customer_acceptance: { - // acceptance_type: "online", - // accepted_at: Date.now()->Date.fromTime->Date.toISOString, - // online: { - // ip_address: ?nativeProp.hyperParams.ip, - // user_agent: ?nativeProp.hyperParams.userAgent, - // }, - // }, - // }) - // : None - // ), + mandate_data: ?( + allApiData.additionalPMLData.mandateType == NORMAL + ? Some({ + customer_acceptance: { + acceptance_type: "offline", + accepted_at: "1963-05-03T04:07:52.723Z", + online: { + ip_address: "125.0.0.1", + user_agent: "amet irure esse", + }, + }, + mandate_type: { + multi_use: { + amount: 1000, + currency: "USD", + start_date: "2023-04-21T00:00:00Z", + end_date: "2023-05-21T00:00:00Z", + metadata: { + frequency: "13", + }, + }, + }, + }) + : None + ), customer_acceptance: ?( allApiData.additionalPMLData.mandateType->PaymentUtils.checkIfMandate ? Some({ @@ -786,6 +879,69 @@ let make = ( ) } + let processRequestBankDebit = (prop: payment_method_types_ach_bank_debit) => { + let payment_method_data = + [ + ( + prop.payment_method, + [ + ( + "ach_bank_debit", + [ + ("account_number", accountnum->Option.getOr("")->JSON.Encode.string), + ("routing_number", routingnum->Option.getOr("")->JSON.Encode.string), + ] + ->Dict.fromArray + ->JSON.Encode.object, + ), + ] + ->Dict.fromArray + ->JSON.Encode.object, + ), + ( + "billing", + [ + ( + "address", + [ + ( + "first_name", + switch name { + | Some(text) => text->String.split(" ")->Array.get(0) + | _ => Some("") + } + ->Option.getOr("") + ->JSON.Encode.string, + ), + ( + "last_name", + switch name { + | Some(text) => text->String.split(" ")->Array.get(1) + | _ => Some("") + } + ->Option.getOr("") + ->JSON.Encode.string, + ), + ] + ->Dict.fromArray + ->JSON.Encode.object, + ), + ] + ->Dict.fromArray + ->JSON.Encode.object, + ), + ] + ->Dict.fromArray + ->JSON.Encode.object + + processRequest( + ~payment_method_data, + ~payment_method=prop.payment_method, + ~payment_method_type=prop.payment_method_type, + (), + ) + } + let handlePress = _ => { setLoading(ProcessingPayments(None)) switch redirectProp { @@ -797,6 +953,7 @@ let make = ( | CRYPTO(prop) => processRequestCrypto(prop) | WALLET(prop) => processRequestWallet(prop) | OPEN_BANKING(prop) => processRequestOpenBanking(prop) + | BANK_DEBIT(prop) => processRequestBankDebit(prop) | _ => () } } @@ -814,20 +971,84 @@ let make = ( setIsNameValid(_ => y) setName(_ => Some(text)) } + let handlecity = text => { + let y = if text->String.length >= 3 { + Some(true) + } else { + None + } + setIscityValid(_ => y) + setcity(_ => Some(text)) + } + let handleAddress1 = text => { + let y = if text->String.length >= 5 { + Some(true) + } else { + None + } + setIsAddressValid(_ => y) + setaddress(_ => Some(text)) + } + let handleAddress2 = text => { + let y = if text->String.length >= 5 { + Some(true) + } else { + None + } + setIsAddress2Valid(_ => y) + setaddress2(_ => Some(text)) + } + let handlePressAccNum = number => { + let onlyNumerics = number->String.replaceRegExp(%re("/\D+/g"), "") + let y = if number->String.length === 12 { + Some(true) + } else { + None + } + setisaccountnumValid(_ => y) + setaccountnum(_ => Some(onlyNumerics)) + } + + let handlePressRouNum = number => { + let onlyNumerics = number->String.replaceRegExp(%re("/\D+/g"), "") + let y = if number->String.length === 9 { + Some(true) + } else { + None + } + setisroutingnumValid(_ => y) + setroutingnum(_ => Some(onlyNumerics)) + } + let isEmailValidForFocus = { emailIsFocus ? true : isEmailValid->Option.getOr(true) } let isNameValidForFocus = { nameIsFocus ? true : isNameValid->Option.getOr(true) } + // let isAddressValidForFocus = { + // AddressIsFocus ? true : isAddressValid->Option.getOr(true) + // } let hasSomeFields = fields.fields->Array.length > 0 - let isAllValuesValid = React.useMemo3(() => { - ((fields.fields->Array.includes("email") ? isEmailValid->Option.getOr(false) : true) && ( - fields.fields->Array.includes("name") ? isNameValid->Option.getOr(false) : true + // let isAllValuesValid = React.useMemo3(() => { + // ((fields.fields->Array.includes("email") ? isEmailValid->Option.getOr(false) : true) && ( + // fields.fields->Array.includes("name") ? isNameValid->Option.getOr(false) : true + // )) || (fields.name == "klarna" && isKlarna) + // }, (isEmailValid, isNameValid, allApiData.sessions)) + let isAllValuesValid = React.useMemo5(() => { + ((fields.fields->Array.includes("email") ? isEmailValid->Option.getOr(false) : true) && + (fields.fields->Array.includes("name") ? isNameValid->Option.getOr(false) : true) && + (fields.fields->Array.includes("routing_number") + ? isroutingnumValid->Option.getOr(false) + : true) && + (fields.fields->Array.includes("account_number") + ? isaccountnumValid->Option.getOr(false) + : true) && ( + fields.fields->Array.includes("account_type") ? isaccountnumValid->Option.getOr(false) : true )) || (fields.name == "klarna" && isKlarna) - }, (isEmailValid, isNameValid, allApiData.sessions)) + }, (isEmailValid, isNameValid, isaccountnumValid, isroutingnumValid, allApiData.sessions)) React.useEffect(() => { if isScreenFocus { @@ -858,115 +1079,252 @@ let make = ( selectedBank, )) - <> + - - String.length > 0}> - - - {KlarnaModule.klarnaReactPaymentView->Option.isSome && fields.name == "klarna" && isKlarna - ? <> - - - - - : <> - {fields.fields - ->Array.mapWithIndex((field, index) => - Int.toString}`}> - - {switch field { - | "email" => - Option.getOr("")} - setState={handlePressEmail} - placeholder=localeObject.emailLabel - keyboardType=#"email-address" - borderBottomLeftRadius=borderRadius - borderBottomRightRadius=borderRadius - borderTopLeftRadius=borderRadius - borderTopRightRadius=borderRadius - borderTopWidth=borderWidth - borderBottomWidth=borderWidth - borderLeftWidth=borderWidth - borderRightWidth=borderWidth - isValid=isEmailValidForFocus - onFocus={_ => { - setEmailIsFocus(_ => true) - }} - onBlur={_ => { - setEmailIsFocus(_ => false) - }} - textColor=component.color - /> - | "name" => - Option.getOr("")} - setState={handlePressName} - placeholder=localeObject.fullNameLabel - keyboardType=#default - isValid=isNameValidForFocus - onFocus={_ => { - setNameIsFocus(_ => true) - }} - onBlur={_ => { - setNameIsFocus(_ => false) - }} - textColor=component.color - borderBottomLeftRadius=borderRadius - borderBottomRightRadius=borderRadius - borderTopLeftRadius=borderRadius - borderTopRightRadius=borderRadius - borderTopWidth=borderWidth - borderBottomWidth=borderWidth - borderLeftWidth=borderWidth - borderRightWidth=borderWidth - /> - | "country" => - - | "bank" => - - | "blik_code" => - Option.getOr("")} - setState={onChangeBlikCode} - borderBottomLeftRadius=borderRadius - borderBottomRightRadius=borderRadius - borderBottomWidth=borderWidth - placeholder="000-000" - keyboardType=#numeric - maxLength=Some(7) - /> - | _ => React.null - }} - - ) - ->React.array} - - - } - - - + {switch paymentMethod { + | "ach" => + | _ => React.null + }} + {<> + + String.length > 0}> + + + {KlarnaModule.klarnaReactPaymentView->Option.isSome && fields.name == "klarna" && isKlarna + ? <> + + + + + : <> + {fields.fields + ->Array.mapWithIndex((field, index) => + Int.toString}`}> + + {switch field { + | "email" => + Option.getOr("")} + setState={handlePressEmail} + placeholder=localeObject.emailLabel + keyboardType=#"email-address" + borderBottomLeftRadius=borderRadius + borderBottomRightRadius=borderRadius + borderTopLeftRadius=borderRadius + borderTopRightRadius=borderRadius + borderTopWidth=borderWidth + borderBottomWidth=borderWidth + borderLeftWidth=borderWidth + borderRightWidth=borderWidth + isValid=isEmailValidForFocus + onFocus={_ => { + setEmailIsFocus(_ => true) + }} + onBlur={_ => { + setEmailIsFocus(_ => false) + }} + textColor=component.color + /> + | "name" => + Option.getOr("")} + setState={handlePressName} + placeholder=localeObject.fullNameLabel + keyboardType=#default + isValid=isNameValidForFocus + onFocus={_ => { + setNameIsFocus(_ => true) + }} + onBlur={_ => { + setNameIsFocus(_ => false) + }} + textColor=component.color + borderBottomLeftRadius=borderRadius + borderBottomRightRadius=borderRadius + borderTopLeftRadius=borderRadius + borderTopRightRadius=borderRadius + borderTopWidth=borderWidth + borderBottomWidth=borderWidth + borderLeftWidth=borderWidth + borderRightWidth=borderWidth + /> + | "country" => + + + | "State" => + switch statesJson { + | Some(states) => + getStateData} + placeholderText=localeObject.stateLabel + /> + | None => React.null + } + + | "bank" => + + | "blik_code" => + Option.getOr("")} + setState={onChangeBlikCode} + borderBottomLeftRadius=borderRadius + borderBottomRightRadius=borderRadius + borderBottomWidth=borderWidth + placeholder="000-000" + keyboardType=#numeric + maxLength=Some(7) + /> + | "Address_Line_1" => + Option.getOr("")} + setState={handleAddress1} + placeholder="Address Line 1" + keyboardType=#default + textColor=component.color + borderBottomLeftRadius=borderRadius + borderBottomRightRadius=borderRadius + borderTopLeftRadius=borderRadius + borderTopRightRadius=borderRadius + borderTopWidth=borderWidth + borderBottomWidth=borderWidth + borderLeftWidth=borderWidth + borderRightWidth=borderWidth + /> + + | "Address_Line_2" => + Option.getOr("")} + setState={handleAddress2} + placeholder="Address Line 2" + keyboardType=#default + textColor=component.color + borderBottomLeftRadius=borderRadius + borderBottomRightRadius=borderRadius + borderTopLeftRadius=borderRadius + borderTopRightRadius=borderRadius + borderTopWidth=borderWidth + borderBottomWidth=borderWidth + borderLeftWidth=borderWidth + borderRightWidth=borderWidth + /> + | "City" => + Option.getOr("")} + setState={handlecity} + placeholder="City" + keyboardType=#default + textColor=component.color + borderBottomLeftRadius=borderRadius + borderBottomRightRadius=borderRadius + borderTopLeftRadius=borderRadius + borderTopRightRadius=borderRadius + borderTopWidth=borderWidth + borderBottomWidth=borderWidth + borderLeftWidth=borderWidth + borderRightWidth=borderWidth + /> + | "account_type" => + <> + + + + + + + + + + | "postal_code" => + Option.getOr("")} + setState={onChangePostalCode} + borderBottomLeftRadius=borderRadius + borderBottomRightRadius=borderRadius + borderBottomWidth=borderWidth + placeholder="Postal Code" + keyboardType=#numeric + maxLength=Some(120) + /> + + | "account_number" => + Option.getOr("")} + setState={handlePressAccNum} + placeholder="Account Number" + borderBottomLeftRadius=borderRadius + borderBottomRightRadius=borderRadius + borderBottomWidth=borderWidth + maxLength=Some(12) + keyboardType=#numeric + /> + | "routing_number" => + Option.getOr("")} + setState={handlePressRouNum} + placeholder="Routing Number" + keyboardType=#numeric + borderBottomLeftRadius=borderRadius + borderBottomRightRadius=borderRadius + borderBottomWidth=borderWidth + maxLength=Some(9) + /> + + | _ => React.null + }} + + ) + ->React.array} + + {switch paymentMethod { + | "ach" => React.null + | _ => + }} + } + + + } + } diff --git a/src/types/LoggerTypes.res b/src/types/LoggerTypes.res index 935204f..f3f14c3 100644 --- a/src/types/LoggerTypes.res +++ b/src/types/LoggerTypes.res @@ -7,6 +7,7 @@ type eventName = | APP_RENDERED | INACTIVE_SCREEN | COUNTRY_CHANGED + | STATE_CHANGED | SDK_CLOSED | PAYMENT_METHOD_CHANGED | PAYMENT_DATA_FILLED diff --git a/src/types/PaymentMethodListType.res b/src/types/PaymentMethodListType.res index 846e44c..e805fd6 100644 --- a/src/types/PaymentMethodListType.res +++ b/src/types/PaymentMethodListType.res @@ -63,6 +63,14 @@ type payment_method_types_open_banking = { required_field: RequiredFieldsTypes.required_fields, } +type payment_method_types_ach_bank_debit = { + payment_method: string, + payment_method_type: string, + payment_experience: array, // ACHBankDebit + required_field: RequiredFieldsTypes.required_fields, + mandate_data: string, +} + type payment_method = | CARD(payment_method_types_card) | WALLET(payment_method_types_wallet) @@ -70,6 +78,13 @@ type payment_method = | BANK_REDIRECT(payment_method_types_bank_redirect) | CRYPTO(payment_method_types_pay_later) | OPEN_BANKING(payment_method_types_open_banking) + | BANK_DEBIT(payment_method_types_ach_bank_debit) // ACHBankDebit + +type payment_method_type = { + payment_method: string, + payment_method_type: string, + required_field: array, +} type online = { ip_address?: string, @@ -88,7 +103,17 @@ type customer_acceptance = { accepted_at: string, online: online, } -type mandate_data = {customer_acceptance: customer_acceptance} +type mandate_type_meta_data = {frequency: string} +type multi_use = { + amount: int, + currency: string, + start_date: string, + end_date: string, + metadata: mandate_type_meta_data, +} +type mandate_type = {multi_use: multi_use} +type mandate_data = {customer_acceptance: customer_acceptance, mandate_type: mandate_type} + type redirectType = { client_secret: string, return_url?: string, @@ -105,6 +130,7 @@ type redirectType = { setup_future_usage?: string, payment_type?: string, mandate_data?: mandate_data, + mandate_type?: mandate_type, browser_info?: online, customer_acceptance?: customer_acceptance, card_cvc?: string, @@ -227,7 +253,7 @@ let flattenPaymentListArray = (plist, item) => { required_field: dict2->RequiredFieldsTypes.getRequiredFieldsFromDict, })->Js.Array.push(plist) }) - | "open_banking" => + | "open_banking" => payment_method_types_array->Array.map(item2 => { let dict2 = item2->getDictFromJson OPEN_BANKING({ @@ -249,6 +275,29 @@ let flattenPaymentListArray = (plist, item) => { required_field: dict2->RequiredFieldsTypes.getRequiredFieldsFromDict, })->Js.Array.push(plist) }) + | "bank_debit" => + payment_method_types_array->Array.map(item2 => { + let dict2 = item2->getDictFromJson + BANK_DEBIT({ + payment_method: "bank_debit", + mandate_data: dict2->getString("mandate_data", ""), + payment_method_type: dict2->getString("payment_method_type", ""), + payment_experience: dict2 + ->getArray("payment_experience") + ->Array.map(item3 => { + let dict3 = item3->getDictFromJson + { + payment_experience_type: dict3->getString("payment_experience_type", ""), + payment_experience_type_decode: switch dict3->getString("payment_experience_type", "") { + | "redirect_to_url" => REDIRECT_TO_URL + | _ => NONE + }, + eligible_connectors: dict3->getArray("eligible_connectors"), + } + }), + required_field: dict2->RequiredFieldsTypes.getRequiredFieldsFromDict, + })->Js.Array.push(plist) + }) | _ => [] }->ignore @@ -263,6 +312,7 @@ let getPaymentMethodType = pm => { | BANK_REDIRECT(payment_method_type) => payment_method_type.payment_method_type | CRYPTO(payment_method_type) => payment_method_type.payment_method_type | OPEN_BANKING(payment_method_type) => payment_method_type.payment_method_type + | BANK_DEBIT(payment_method_type) => payment_method_type.payment_method_type } } @@ -356,7 +406,8 @@ let getPaymentBody = (body, dynamicFieldsJson) => { } let jsonToSavedPMObj = data => { - let customerSavedPMs = data->Utils.getDictFromJson->Utils.getArrayFromDict("customer_payment_methods", []) + let customerSavedPMs = + data->Utils.getDictFromJson->Utils.getArrayFromDict("customer_payment_methods", []) customerSavedPMs->Array.reduce([], (acc, obj) => { let savedPMData = obj->Utils.getDictFromJson diff --git a/src/types/RequiredFieldsTypes.res b/src/types/RequiredFieldsTypes.res index 78606da..ebba706 100644 --- a/src/types/RequiredFieldsTypes.res +++ b/src/types/RequiredFieldsTypes.res @@ -24,6 +24,8 @@ type paymentMethodsFields = | AddressState | AddressCountry(array) | BlikCode + | AccountNumber + | RoutingNumber | Currency(array) type requiredField = @@ -223,8 +225,7 @@ let checkIsValid = ( switch text->ValidationFunctions.isValidEmail { | Some(false) => Some(localeObject.emailInvalidText) | Some(true) => None - | None => - Some(localeObject.emailEmptyText) + | None => Some(localeObject.emailEmptyText) } | _ => None } @@ -290,6 +291,8 @@ let useGetPlaceholder = ( | AddressCountry(_) => localeObject.countryLabel | Currency(_) => localeObject.currencyLabel | InfoElement + | AccountNumber + | RoutingNumber | SpecialField(_) | UnKnownField(_) | PhoneNumber diff --git a/src/types/SdkTypes.res b/src/types/SdkTypes.res index 0c92bcf..451b97e 100644 --- a/src/types/SdkTypes.res +++ b/src/types/SdkTypes.res @@ -296,6 +296,7 @@ type hyperParams = { confirm: bool, appId?: string, country: string, + state: string, disableBranding: bool, ip: option, userAgent: option, @@ -913,6 +914,7 @@ let nativeJsonToRecord = (jsonFromNative, rootTag) => { hyperParams: { appId: ?getOptionString(hyperParams, "appId"), country: getString(hyperParams, "country", ""), + state: getString(hyperParams, "state", ""), disableBranding: getBool(hyperParams, "disableBranding", true), ip: getOptionString(hyperParams, "ip"), userAgent: getOptionString(hyperParams, "user-agent"), diff --git a/src/types/Types.res b/src/types/Types.res index 18d3348..eb80987 100644 --- a/src/types/Types.res +++ b/src/types/Types.res @@ -20,7 +20,15 @@ type config = { let defaultConfig = { priorityArr: { - let priorityArr = ["card", "klarna", "afterpay_clearpay", "crypto", "paypal", "google_pay"] + let priorityArr = [ + "card", + "klarna", + "afterpay_clearpay", + "ach", + "crypto", + "paypal", + "google_pay", + ] priorityArr->Array.reverse priorityArr }, @@ -97,6 +105,23 @@ let defaultConfig = { header: "", fields: [], }, + { + name: "ach", + text: "Bank Debit", + header: "", + fields: [ + "name", + "routing_number", + "account_number", + "account_type", + "Address_Line_1", + "Address_Line_2", + "country", + "State", + "City", + "postal_code", + ], + }, // { // name: "google_pay", // text: "Google Pay",