From 25134c56b9c12a637b589a72bb316ec564b8e81b Mon Sep 17 00:00:00 2001 From: Sanskar Atrey Date: Wed, 14 Aug 2024 16:55:10 +0530 Subject: [PATCH 1/4] feat: added support for cobadged cards --- src/CardSchemeComponent.res | 37 ++++++++++++++++++++++++++++ src/CardUtils.res | 10 ++++++++ src/Components/DynamicFields.res | 2 ++ src/Components/PaymentInputField.res | 3 ++- src/Payment.res | 27 ++++++++++++-------- src/Payments/CardPayment.res | 7 +++--- src/RenderPaymentMethods.res | 1 + src/SingleLineCardPayment.res | 1 + 8 files changed, 73 insertions(+), 15 deletions(-) create mode 100644 src/CardSchemeComponent.res diff --git a/src/CardSchemeComponent.res b/src/CardSchemeComponent.res new file mode 100644 index 000000000..b52179e67 --- /dev/null +++ b/src/CardSchemeComponent.res @@ -0,0 +1,37 @@ +module CoBadgeCardSchemeDropDown = { + @react.component + let make = (~cardNumber, ~setCardBrand) => { + + } +} + +@react.component +let make = (~cardNumber, ~paymentType, ~cardBrand, ~setCardBrand, ~isCardCoBadged=false) => { + let cardType = React.useMemo1(_ => cardBrand->CardUtils.getCardType, [cardBrand]) + let animate = cardType == NOTFOUND ? "animate-slideLeft" : "animate-slideRight" + + let cardBrandIcon = React.useMemo1( + _ => CardUtils.getCardBrandIcon(cardType, paymentType), + [cardBrand], + ) +
+ cardBrandIcon + {isCardCoBadged ? : React.null} +
+} diff --git a/src/CardUtils.res b/src/CardUtils.res index a20967fdc..0700af886 100644 --- a/src/CardUtils.res +++ b/src/CardUtils.res @@ -26,6 +26,7 @@ type cardProps = ( string, (string => string) => unit, int, + string, ) type expiryProps = ( @@ -655,3 +656,12 @@ let getPaymentMethodBrand = (customerMethod: PaymentType.customerMethods) => { ) } } + +let getCoBadgesCardSchemes = cardNumber => { + CardPattern.cardPatterns->Array.reduce([], (acc, item) => { + if String.match(cardNumber, item.pattern)->Option.isSome { + acc->Array.push(item.issuer) + } + acc + }) +} diff --git a/src/Components/DynamicFields.res b/src/Components/DynamicFields.res index 3fc1d3b90..f12709881 100644 --- a/src/Components/DynamicFields.res +++ b/src/Components/DynamicFields.res @@ -109,6 +109,7 @@ let make = ( "", _ => (), 0, + "", ) let defaultExpiryProps = ( @@ -163,6 +164,7 @@ let make = ( cardError, _, maxCardLength, + cardScheme, ) = switch cardProps { | Some(cardProps) => cardProps | None => defaultCardProps diff --git a/src/Components/PaymentInputField.res b/src/Components/PaymentInputField.res index 98ba1809d..27913c92c 100644 --- a/src/Components/PaymentInputField.res +++ b/src/Components/PaymentInputField.res @@ -20,6 +20,7 @@ let make = ( ~placeholder="", ~appearance: CardThemeType.appearance, ~className="", + ~rightIconClassName="-ml-10", ~inputRef, ) => { let {themeObj, config} = Recoil.useRecoilValueFromAtom(configAtom) @@ -131,7 +132,7 @@ let make = ( -
{rightIcon}
+
{rightIcon}
{switch errorString { diff --git a/src/Payment.res b/src/Payment.res index 13dd3d733..9f9914ded 100644 --- a/src/Payment.res +++ b/src/Payment.res @@ -47,13 +47,15 @@ let make = (~paymentMode, ~integrateError, ~logger) => { let (isZipValid, setIsZipValid) = React.useState(_ => None) let (isCardSupported, setIsCardSupported) = React.useState(_ => None) - let (cardBrand, maxCardLength) = React.useMemo(() => { - let brand = getCardBrand(cardNumber) - let maxLength = getMaxLength(cardNumber) - let isNotBancontact = selectedOption !== "bancontact_card" && brand == "" - !showFields && isNotBancontact ? (cardScheme, maxLength) : (brand, maxLength) + let maxCardLength = React.useMemo(() => { + getMaxLength(cardNumber) }, (cardNumber, cardScheme, showFields)) + let cardBrand = getCardBrand(cardNumber) + let isNotBancontact = selectedOption !== "bancontact_card" && cardBrand == "" + let (cardBrand, setCardBrand) = React.useState(_ => + !showFields && isNotBancontact ? cardScheme : cardBrand + ) let supportedCardBrands = React.useMemo(() => { paymentMethodListValue->PaymentUtils.getSupportedCardBrands }, [paymentMethodListValue]) @@ -219,7 +221,7 @@ let make = (~paymentMode, ~integrateError, ~logger) => { } let cardNetwork = { if cardBrand != "" { - [("card_network", cardNumber->CardUtils.getCardBrand->JSON.Encode.string)] + [("card_network", cardBrand->JSON.Encode.string)] } else { [] } @@ -350,11 +352,15 @@ let make = (~paymentMode, ~integrateError, ~logger) => { None }, (isExpiryValid, isExpiryComplete(cardExpiry))) + React.useEffect(() => { + // Console.log("changing card brand" ++ cardBrand ++ cardNumber) + setCardBrand(_ => cardNumber->CardUtils.getCardBrand) + None + }, [cardNumber]) + let icon = React.useMemo(() => { - let animate = cardType == NOTFOUND ? "animate-slideLeft" : "animate-slideRight" - let cardBrandIcon = getCardBrandIcon(cardType, paymentType) -
cardBrandIcon
- }, (cardType, paymentType)) + + }, (cardType, paymentType, cardBrand, cardNumber)) let cardProps: CardUtils.cardProps = ( isCardValid, @@ -368,6 +374,7 @@ let make = (~paymentMode, ~integrateError, ~logger) => { cardError, setCardError, maxCardLength, + cardBrand, ) let expiryProps: CardUtils.expiryProps = ( diff --git a/src/Payments/CardPayment.res b/src/Payments/CardPayment.res index 7e1e811fd..eee784376 100644 --- a/src/Payments/CardPayment.res +++ b/src/Payments/CardPayment.res @@ -35,12 +35,9 @@ let make = ( cardError, setCardError, maxCardLength, + cardBrand, ) = cardProps - let cardBrand = React.useMemo(() => { - cardNumber->CardUtils.getCardBrand - }, [cardNumber]) - let ( isExpiryValid, setIsExpiryValid, @@ -207,6 +204,7 @@ let make = ( nickname, isCardBrandValid, isManualRetryEnabled, + cardProps, )) useSubmitPaymentData(submitCallback) @@ -258,6 +256,7 @@ let make = ( ? "border-b-0" : ""} name=TestUtils.cardNoInputTestId + rightIconClassName="-ml-12" />
Date: Mon, 26 Aug 2024 13:42:36 +0530 Subject: [PATCH 2/4] refactor: comments resolution --- src/CardSchemeComponent.res | 8 +++++--- src/Payment.res | 4 ++-- src/Payments/CardPayment.res | 4 +++- src/Utilities/RecoilAtoms.res | 1 + 4 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/CardSchemeComponent.res b/src/CardSchemeComponent.res index b52179e67..8bf13dc96 100644 --- a/src/CardSchemeComponent.res +++ b/src/CardSchemeComponent.res @@ -2,7 +2,7 @@ module CoBadgeCardSchemeDropDown = { @react.component let make = (~cardNumber, ~setCardBrand) => { { @@ -9,8 +9,7 @@ module CoBadgeCardSchemeDropDown = { setCardBrand(_ => value) }}> - {cardNumber - ->CardUtils.getCoBadgesCardSchemes + {eligibleCardSchemes ->Array.mapWithIndex((item, i) => {
{switch errorString { diff --git a/src/Payments/CardPayment.res b/src/Payments/CardPayment.res index c1508adf5..bdb3a5071 100644 --- a/src/Payments/CardPayment.res +++ b/src/Payments/CardPayment.res @@ -20,7 +20,6 @@ let make = ( let options = Recoil.useRecoilValueFromAtom(RecoilAtoms.optionAtom) let loggerState = Recoil.useRecoilValueFromAtom(RecoilAtoms.loggerAtom) let paymentMethodListValue = Recoil.useRecoilValueFromAtom(PaymentUtils.paymentMethodListValue) - let isCardCoBadged = Recoil.useRecoilValueFromAtom(RecoilAtoms.isCardCoBadged) let (nickname, setNickname) = React.useState(_ => "") @@ -219,7 +218,6 @@ let make = ( !isBancontact let nicknameFieldClassName = conditionsForShowingSaveCardCheckbox ? "pt-2" : "pt-5" - let cardInputRightIconClassName = isCardCoBadged ? "-ml-12" : "-ml-10" let compressedLayoutStyleForCvcError = innerLayout === Compressed && cvcError->String.length > 0 ? "!border-l-0" : "" @@ -258,7 +256,6 @@ let make = ( ? "border-b-0" : ""} name=TestUtils.cardNoInputTestId - rightIconClassName=cardInputRightIconClassName />