Skip to content

Commit

Permalink
feat(PaymentElement): moved SavedCards component outside card form (#197
Browse files Browse the repository at this point in the history
)
  • Loading branch information
prafulkoppalkar authored Mar 8, 2024
1 parent ff22896 commit 8e11c40
Show file tree
Hide file tree
Showing 3 changed files with 122 additions and 102 deletions.
47 changes: 46 additions & 1 deletion src/Components/SavedMethods.res
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
open CardUtils
open Utils
@react.component
let make = (
~paymentToken,
Expand All @@ -8,10 +9,16 @@ let make = (
~cvcProps,
~paymentType,
~list,
~setRequiredFieldsBody,
) => {
let {themeObj, localeString} = Recoil.useRecoilValueFromAtom(RecoilAtoms.configAtom)
let (showFields, setShowFields) = Recoil.useRecoilState(RecoilAtoms.showCardFieldsAtom)
let areRequiredFieldsValid = Recoil.useRecoilValueFromAtom(RecoilAtoms.areRequiredFieldsValid)
let (requiredFieldsBody, setRequiredFieldsBody) = React.useState(_ => Js.Dict.empty())
let setUserError = message => {
postFailedSubmitResponse(~errortype="validation_error", ~message)
}
let loggerState = Recoil.useRecoilValueFromAtom(RecoilAtoms.loggerAtom)
let intent = PaymentHelpers.usePaymentIntent(Some(loggerState), Card)
let (token, _) = paymentToken
let savedCardlength = savedMethods->Js.Array2.length
let bottomElement = {
Expand Down Expand Up @@ -41,6 +48,44 @@ let make = (
->React.array
}

let (isCVCValid, _, cvcNumber, _, _, _, _, _, _, setCvcError) = cvcProps
let complete = switch isCVCValid {
| Some(val) => token !== "" && val
| _ => false
}
let empty = cvcNumber == ""

let submitCallback = React.useCallback4((ev: Window.event) => {
let json = ev.data->Js.Json.parseExn
let confirm = json->getDictFromJson->ConfirmType.itemToObjMapper
let (token, customerId) = paymentToken
let savedCardBody = PaymentBody.savedCardBody(~paymentToken=token, ~customerId, ~cvcNumber)
if confirm.doSubmit {
if areRequiredFieldsValid && complete && !empty {
intent(
~bodyArr=savedCardBody
->Js.Dict.fromArray
->Js.Json.object_
->OrcaUtils.flattenObject(true)
->OrcaUtils.mergeTwoFlattenedJsonDicts(requiredFieldsBody)
->OrcaUtils.getArrayOfTupleFromDict,
~confirmParam=confirm.confirmParams,
~handleUserError=false,
(),
)
} else {
if cvcNumber === "" {
setCvcError(_ => localeString.cvcNumberEmptyText)
setUserError(localeString.enterFieldsText)
}
if !(isCVCValid->Belt.Option.getWithDefault(false)) {
setUserError(localeString.enterValidDetailsText)
}
}
}
}, (areRequiredFieldsValid, requiredFieldsBody, empty, complete))
submitPaymentData(submitCallback)

<>
<div
className="flex flex-col overflow-auto h-auto no-scrollbar animate-slowShow"
Expand Down
73 changes: 68 additions & 5 deletions src/PaymentElement.res
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,13 @@ let make = (
~paymentType: CardThemeType.mode,
) => {
let sessionsObj = Recoil.useRecoilValueFromAtom(sessions)
let {showCardFormByDefault, paymentMethodOrder, layout} = Recoil.useRecoilValueFromAtom(
optionAtom,
)
let {
showCardFormByDefault,
paymentMethodOrder,
layout,
customerPaymentMethods,
disableSaveCards,
} = Recoil.useRecoilValueFromAtom(optionAtom)
let isApplePayReady = Recoil.useRecoilValueFromAtom(isApplePayReady)
let isGooglePayReady = Recoil.useRecoilValueFromAtom(isGooglePayReady)
let methodslist = Recoil.useRecoilValueFromAtom(list)
Expand All @@ -36,6 +40,59 @@ let make = (
let loggerState = Recoil.useRecoilValueFromAtom(loggerAtom)
let isShowOrPayUsing = Recoil.useRecoilValueFromAtom(isShowOrPayUsing)

let (showFields, setShowFields) = Recoil.useRecoilState(RecoilAtoms.showCardFieldsAtom)
let (paymentToken, setPaymentToken) = Recoil.useRecoilState(RecoilAtoms.paymentTokenAtom)
let (savedMethods, setSavedMethods) = React.useState(_ => [])
let (
loadSavedCards: PaymentType.savedCardsLoadState,
setLoadSavedCards: (PaymentType.savedCardsLoadState => PaymentType.savedCardsLoadState) => unit,
) = React.useState(_ => PaymentType.LoadingSavedCards)

React.useEffect1(() => {
switch customerPaymentMethods {
| LoadingSavedCards => ()
| LoadedSavedCards(arr, isGuestCustomer) => {
let savedCards = arr->Js.Array2.filter((item: PaymentType.customerMethods) => {
item.paymentMethod == "card"
})
setSavedMethods(_ => savedCards)
setLoadSavedCards(_ =>
savedCards->Js.Array2.length == 0
? NoResult(isGuestCustomer)
: LoadedSavedCards(savedCards, isGuestCustomer)
)
setShowFields(.prev => savedCards->Js.Array2.length == 0 || prev)
}
| NoResult(isGuestCustomer) => {
setLoadSavedCards(_ => NoResult(isGuestCustomer))
setShowFields(._ => true)
}
}

None
}, [customerPaymentMethods])

React.useEffect1(() => {
if disableSaveCards {
setShowFields(._ => true)
setLoadSavedCards(_ => LoadedSavedCards([], true))
}
None
}, [disableSaveCards])

React.useEffect1(() => {
let tokenobj =
savedMethods->Js.Array2.length > 0
? Some(savedMethods->Belt.Array.get(0)->Belt.Option.getWithDefault(defaultCustomerMethods))
: None

switch tokenobj {
| Some(obj) => setPaymentToken(._ => (obj.paymentToken, obj.customerId))
| None => ()
}
None
}, [savedMethods])

let (walletList, paymentOptionsList, actualList) = React.useMemo4(() => {
switch methodslist {
| Loaded(paymentlist) =>
Expand Down Expand Up @@ -297,8 +354,14 @@ let make = (
</ErrorBoundary>
}
<>
<RenderIf condition={!showFields}>
<SavedMethods
paymentToken setPaymentToken savedMethods loadSavedCards cvcProps paymentType list
/>
</RenderIf>
<RenderIf
condition={paymentOptions->Js.Array2.length > 0 || walletOptions->Js.Array2.length > 0}>
condition={(paymentOptions->Js.Array2.length > 0 || walletOptions->Js.Array2.length > 0) &&
showFields}>
<div className="flex flex-col place-items-center">
<ErrorBoundary key="payment_request_buttons_all" level={ErrorBoundary.RequestButton}>
<PaymentRequestButtonElement sessions walletOptions list />
Expand All @@ -322,8 +385,8 @@ let make = (
<PayNowButton />
</div>
</RenderIf>
<PoweredBy />
</RenderIf>
<PoweredBy />
{switch methodslist {
| LoadError(_) => React.null
| _ =>
Expand Down
104 changes: 8 additions & 96 deletions src/Payments/CardPayment.res
Original file line number Diff line number Diff line change
Expand Up @@ -57,19 +57,9 @@ let make = (
cvcError,
setCvcError,
) = cvcProps
let {customerPaymentMethods, disableSaveCards} = Recoil.useRecoilValueFromAtom(
RecoilAtoms.optionAtom,
)
let intent = PaymentHelpers.usePaymentIntent(Some(loggerState), Card)
let (savedMethods, setSavedMethods) = React.useState(_ => [])
let (showFields, setShowFields) = Recoil.useRecoilState(RecoilAtoms.showCardFieldsAtom)
let (paymentToken, setPaymentToken) = Recoil.useRecoilState(RecoilAtoms.paymentTokenAtom)
let (token, _) = paymentToken
let setComplete = Recoil.useSetRecoilState(RecoilAtoms.fieldsComplete)
let (
loadSavedCards: PaymentType.savedCardsLoadState,
setLoadSavedCards: (PaymentType.savedCardsLoadState => PaymentType.savedCardsLoadState) => unit,
) = React.useState(_ => PaymentType.LoadingSavedCards)
let (isSaveCardsChecked, setIsSaveCardsChecked) = React.useState(_ => false)

let setUserError = message => {
Expand All @@ -80,58 +70,8 @@ let make = (

let areRequiredFieldsValid = Recoil.useRecoilValueFromAtom(RecoilAtoms.areRequiredFieldsValid)

React.useEffect1(() => {
switch customerPaymentMethods {
| LoadingSavedCards => ()
| LoadedSavedCards(arr, isGuestCustomer) => {
let savedCards = arr->Js.Array2.filter((item: PaymentType.customerMethods) => {
item.paymentMethod == "card"
})
setSavedMethods(_ => savedCards)
setLoadSavedCards(_ =>
savedCards->Js.Array2.length == 0
? NoResult(isGuestCustomer)
: LoadedSavedCards(savedCards, isGuestCustomer)
)
setShowFields(.prev => savedCards->Js.Array2.length == 0 || prev)
}
| NoResult(isGuestCustomer) => {
setLoadSavedCards(_ => NoResult(isGuestCustomer))
setShowFields(._ => true)
}
}

None
}, [customerPaymentMethods])

React.useEffect1(() => {
if disableSaveCards {
setShowFields(._ => true)
setLoadSavedCards(_ => LoadedSavedCards([], true))
}
None
}, [disableSaveCards])

React.useEffect1(() => {
let tokenobj =
savedMethods->Js.Array2.length > 0
? Some(savedMethods->Belt.Array.get(0)->Belt.Option.getWithDefault(defaultCustomerMethods))
: None

switch tokenobj {
| Some(obj) => setPaymentToken(._ => (obj.paymentToken, obj.customerId))
| None => ()
}
None
}, [savedMethods])

let complete = showFields
? isAllValid(isCardValid, isCVCValid, isExpiryValid, true, "payment")
: switch isCVCValid {
| Some(val) => token !== "" && !isBancontact && val
| _ => false
}
let empty = showFields ? cardNumber == "" || cardExpiry == "" || cvcNumber == "" : cvcNumber == ""
let complete = isAllValid(isCardValid, isCVCValid, isExpiryValid, true, "payment")
let empty = cardNumber == "" || cardExpiry == "" || cvcNumber == ""
React.useEffect1(() => {
setComplete(._ => complete)
None
Expand All @@ -142,14 +82,13 @@ let make = (
None
}, (empty, complete))

let isGuestCustomer = React.useMemo1(() => {
switch customerPaymentMethods {
| LoadedSavedCards(_, false)
| NoResult(false) => false
| _ => true
let (savedMethods, isGuestCustomer) = React.useMemo1(() => {
switch options.customerPaymentMethods {
| LoadedSavedCards(savedMethods, isGuest) => (savedMethods, isGuest)
| NoResult(isGuest) => ([], isGuest)
| _ => ([], true)
}
}, [customerPaymentMethods])

}, [options.customerPaymentMethods])
let isCvcValidValue = CardUtils.getBoolOptionVal(isCVCValid)
let (cardEmpty, cardComplete, cardInvalid) = CardUtils.useCardDetails(
~cvcNumber,
Expand All @@ -161,9 +100,6 @@ let make = (
let json = ev.data->Js.Json.parseExn
let confirm = json->getDictFromJson->ConfirmType.itemToObjMapper
let (month, year) = CardUtils.getExpiryDates(cardExpiry)
let (token, customerId) = paymentToken
let savedCardBody = PaymentBody.savedCardBody(~paymentToken=token, ~customerId, ~cvcNumber)

let onSessionBody = [("setup_future_usage", "on_session"->Js.Json.string)]
let cardNetwork = {
if cardBrand != "" {
Expand Down Expand Up @@ -204,18 +140,6 @@ let make = (
~handleUserError=false,
(),
)
} else if areRequiredFieldsValid && complete && !empty {
intent(
~bodyArr=savedCardBody
->Js.Dict.fromArray
->Js.Json.object_
->OrcaUtils.flattenObject(true)
->OrcaUtils.mergeTwoFlattenedJsonDicts(requiredFieldsBody)
->OrcaUtils.getArrayOfTupleFromDict,
~confirmParam=confirm.confirmParams,
~handleUserError=false,
(),
)
} else {
if cardNumber === "" {
setCardError(_ => localeString.cardNumberEmptyText)
Expand All @@ -241,18 +165,6 @@ let make = (
let paymentMethodType = isBancontact ? "bancontact_card" : "debit"

<div className="animate-slowShow">
<RenderIf condition={!showFields && !isBancontact}>
<SavedMethods
paymentToken
setPaymentToken
savedMethods
loadSavedCards
cvcProps
paymentType
list
setRequiredFieldsBody
/>
</RenderIf>
<RenderIf condition={showFields || isBancontact}>
<div
className="flex flex-col"
Expand Down

0 comments on commit 8e11c40

Please sign in to comment.