Skip to content
17 changes: 11 additions & 6 deletions src/Components/SavedMethods.res
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,11 @@ let make = (
loggerState.setLogError(~value=message, ~eventName=INVALID_FORMAT)
}
let (isSaveCardsChecked, setIsSaveCardsChecked) = React.useState(_ => false)
let {displaySavedPaymentMethodsCheckbox, readOnly} = Recoil.useRecoilValueFromAtom(
RecoilAtoms.optionAtom,
)
let {
displaySavedPaymentMethodsCheckbox,
readOnly,
enableUnifiedView,
} = Recoil.useRecoilValueFromAtom(RecoilAtoms.optionAtom)
let isGuestCustomer = useIsGuestCustomer()

let {iframeId, clientSecret} = Recoil.useRecoilValueFromAtom(RecoilAtoms.keys)
Expand Down Expand Up @@ -336,14 +338,17 @@ let make = (
let enableSavedPaymentShimmer = React.useMemo(() => {
savedCardlength === 0 &&
!showPaymentMethodsScreen &&
(loadSavedCards === PaymentType.LoadingSavedCards || clickToPayConfig.isReady->Option.isNone)
(loadSavedCards === PaymentType.LoadingSavedCards || clickToPayConfig.isReady->Option.isNone) &&
!enableUnifiedView
}, (savedCardlength, loadSavedCards, showPaymentMethodsScreen, clickToPayConfig.isReady))

<div className="flex flex-col overflow-auto h-auto no-scrollbar animate-slowShow">
{if enableSavedPaymentShimmer {
<PaymentElementShimmer.SavedPaymentCardShimmer />
} else {
<RenderIf condition={!showPaymentMethodsScreen}> {bottomElement} </RenderIf>
<RenderIf condition={!showPaymentMethodsScreen || enableUnifiedView}>
{bottomElement}
</RenderIf>
}}
<RenderIf condition={conditionsForShowingSaveCardCheckbox}>
<div className="pt-4 pb-2 flex items-center justify-start">
Expand All @@ -360,7 +365,7 @@ let make = (
}
/>
</RenderIf>
<RenderIf condition={!enableSavedPaymentShimmer}>
<RenderIf condition={!enableSavedPaymentShimmer && !enableUnifiedView}>
<div
className="Label flex flex-row gap-3 items-end cursor-pointer mt-4"
style={
Expand Down
31 changes: 27 additions & 4 deletions src/PaymentElement.res
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ let make = (~cardProps, ~expiryProps, ~cvcProps, ~paymentType: CardThemeType.mod

let {
paymentMethodOrder,
enableUnifiedView,
layout,
customerPaymentMethods,
displaySavedPaymentMethods,
Expand Down Expand Up @@ -278,6 +279,11 @@ let make = (~cardProps, ~expiryProps, ~cvcProps, ~paymentType: CardThemeType.mod
}, [selectedOption])
useSubmitPaymentData(submitCallback)
React.useEffect(() => {
if enableUnifiedView && selectedOption == "saved_methods" {
setShowPaymentMethodsScreen(_ => false)
} else if enableUnifiedView {
setShowPaymentMethodsScreen(_ => true)
}
setSelectedOption(prev =>
selectedOption !== ""
? prev
Expand Down Expand Up @@ -402,6 +408,19 @@ let make = (~cardProps, ~expiryProps, ~cvcProps, ~paymentType: CardThemeType.mod
</RenderIf>
}}
</SessionPaymentWrapper>
| SavedMethods =>
<SavedMethods
paymentToken
setPaymentToken
savedMethods
loadSavedCards
cvcProps
sessions
isClickToPayAuthenticateError
setIsClickToPayAuthenticateError
getVisaCards
closeComponentIfSavedMethodsAreEmpty
/>
| _ =>
<ReusableReactSuspense loaderComponent={loader()} componentName="PaymentMethodsWrapperLazy">
<PaymentMethodsWrapperLazy paymentMethodName=selectedOption />
Expand Down Expand Up @@ -458,7 +477,8 @@ let make = (~cardProps, ~expiryProps, ~cvcProps, ~paymentType: CardThemeType.mod
} else {
<RenderIf
condition={!showPaymentMethodsScreen &&
(displaySavedPaymentMethods || isShowPaymentMethodsDependingOnClickToPay)}>
(displaySavedPaymentMethods || isShowPaymentMethodsDependingOnClickToPay) &&
!optionAtomValue.enableUnifiedView}>
<SavedMethods
paymentToken
setPaymentToken
Expand All @@ -475,7 +495,7 @@ let make = (~cardProps, ~expiryProps, ~cvcProps, ~paymentType: CardThemeType.mod
}}
<RenderIf
condition={(paymentOptions->Array.length > 0 || walletOptions->Array.length > 0) &&
showPaymentMethodsScreen &&
(showPaymentMethodsScreen || optionAtomValue.enableUnifiedView) &&
clickToPayConfig.isReady->Option.isSome}>
<div
className="flex flex-col place-items-center"
Expand Down Expand Up @@ -510,7 +530,9 @@ let make = (~cardProps, ~expiryProps, ~cvcProps, ~paymentType: CardThemeType.mod
</RenderIf>
<RenderIf
condition={((displaySavedPaymentMethods && savedMethods->Array.length > 0) ||
isShowPaymentMethodsDependingOnClickToPay) && showPaymentMethodsScreen}>
isShowPaymentMethodsDependingOnClickToPay) &&
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we simplify this? It's too many conditions inside a prop - not readable

showPaymentMethodsScreen &&
!optionAtomValue.enableUnifiedView}>
<div
className="Label flex flex-row gap-3 items-end cursor-pointer mt-4"
style={
Expand Down Expand Up @@ -542,7 +564,8 @@ let make = (~cardProps, ~expiryProps, ~cvcProps, ~paymentType: CardThemeType.mod
</RenderIf>
| _ =>
<RenderIf
condition={!displaySavedPaymentMethods &&
condition={(!displaySavedPaymentMethods ||
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we simplify this? It's too many conditions inside a prop - not readable

(optionAtomValue.enableUnifiedView && savedMethods->Array.length == 0)) &&
paymentOptions->Array.length == 0 &&
walletOptions->Array.length == 0}>
<PaymentElementShimmer />
Expand Down
1 change: 1 addition & 0 deletions src/PaymentElementV2.res
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,7 @@ let make = (~cardProps, ~expiryProps, ~cvcProps, ~paymentType: CardThemeType.mod
| Boleto
| PayPal
| EFT
| SavedMethods
| Unknown => React.null
}}
</ErrorBoundary>
Expand Down
7 changes: 7 additions & 0 deletions src/Payments/PaymentMethodsRecord.res
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,13 @@ let getPaymentMethodsFields = (~localeString: LocaleStringTypes.localeStrings) =
displayName: localeString.payment_methods_card,
miniIcon: None,
},
{
paymentMethodName: "saved_methods",
icon: Some(icon("default-card", ~size=19)),
fields: [],
displayName: "Saved",
miniIcon: None,
},
{
paymentMethodName: "klarna",
icon: Some(icon("klarna", ~size=19)),
Expand Down
3 changes: 3 additions & 0 deletions src/Types/PaymentModeType.res
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ type payment =
| Boleto
| PayPal
| EFT
| SavedMethods
| Unknown

let paymentMode = str => {
Expand Down Expand Up @@ -57,11 +58,13 @@ let paymentMode = str => {
| "boleto" => Boleto
| "paypal" => PayPal
| "eft" => EFT
| "saved_methods" => SavedMethods
| _ => Unknown
}
}

let defaultOrder = [
"saved_methods",
"card",
"apple_pay",
"google_pay",
Expand Down
4 changes: 4 additions & 0 deletions src/Types/PaymentType.res
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,7 @@ type options = {
displayBillingDetails: bool,
customMessageForCardTerms: string,
showShortSurchargeMessage: bool,
enableUnifiedView: bool,
}

type payerDetails = {
Expand Down Expand Up @@ -373,6 +374,7 @@ let defaultOptions = {
displayBillingDetails: false,
customMessageForCardTerms: "",
showShortSurchargeMessage: false,
enableUnifiedView: false,
}

let getLayout = str => {
Expand Down Expand Up @@ -1064,6 +1066,7 @@ let itemToObjMapper = (dict, logger) => {
"displayBillingDetails",
"customMessageForCardTerms",
"showShortSurchargeMessage",
"enableUnifiedView",
],
dict,
"options",
Expand Down Expand Up @@ -1109,6 +1112,7 @@ let itemToObjMapper = (dict, logger) => {
displayBillingDetails: getBool(dict, "displayBillingDetails", false),
customMessageForCardTerms: getString(dict, "customMessageForCardTerms", ""),
showShortSurchargeMessage: getBool(dict, "showShortSurchargeMessage", false),
enableUnifiedView: getBool(dict, "enableUnifiedView", false),
}
}

Expand Down
157 changes: 100 additions & 57 deletions src/Utilities/PaymentUtils.res
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ let paymentListLookupNew = (
~shouldDisplayApplePayInTabs,
~shouldDisplayPayPalInTabs,
~localeString,
~showSavedPaymentMethodsTab,
) => {
let pmList = list->PaymentMethodsRecord.buildFromPaymentList(~localeString)
let walletsList = []
Expand Down Expand Up @@ -56,6 +57,10 @@ let paymentListLookupNew = (
walletToBeDisplayedInTabs->Array.push("google_pay")
}

if showSavedPaymentMethodsTab {
otherPaymentList->Array.push("saved_methods")->ignore
}

pmList->Array.forEach(item => {
if walletToBeDisplayedInTabs->Array.includes(item.paymentMethodName) {
otherPaymentList->Array.push(item.paymentMethodName)->ignore
Expand Down Expand Up @@ -391,68 +396,103 @@ let useGetPaymentMethodList = (~paymentOptions, ~paymentType, ~sessions) => {
~paymentMethodListValue,
)

React.useMemo(() => {
switch methodslist {
| Loaded(paymentlist) =>
let paymentOrder =
paymentOrder->Array.length > 0 ? paymentOrder : PaymentModeType.defaultOrder
let plist = paymentlist->getDictFromJson->PaymentMethodsRecord.itemToObjMapper

let shouldDisplayApplePayInTabs =
!paymentMethodListValue.collect_billing_details_from_wallets &&
!areAllApplePayRequiredFieldsPrefilled &&
isApplePayReady

let isShowPaypal = optionAtomValue.wallets.payPal === Auto

let shouldDisplayPayPalInTabs =
isShowPaypal &&
!paymentMethodListValue.collect_billing_details_from_wallets &&
!areAllPaypalRequiredFieldsPreFilled &&
isPaypalRedirectFlow &&
(!isPaypalSDKFlow || !isPaypalTokenExist)

let (wallets, otherOptions) =
plist->paymentListLookupNew(
~order=paymentOrder,
~isShowPaypal,
~isShowKlarnaOneClick=optionAtomValue.wallets.klarna === Auto,
~isKlarnaSDKFlow,
~paymentMethodListValue=plist,
~areAllGooglePayRequiredFieldsPrefilled,
~isGooglePayReady,
~shouldDisplayApplePayInTabs,
~shouldDisplayPayPalInTabs,
~localeString,
)
let processPaymentsList = (
~paymentList,
~savedPaymentMethods: option<array<PaymentType.customerMethods>>,
) => {
let paymentOrder = paymentOrder->Array.length > 0 ? paymentOrder : PaymentModeType.defaultOrder

let plist = paymentList->getDictFromJson->PaymentMethodsRecord.itemToObjMapper

let shouldDisplayApplePayInTabs =
!paymentMethodListValue.collect_billing_details_from_wallets &&
!areAllApplePayRequiredFieldsPrefilled &&
isApplePayReady

let isShowPaypal = optionAtomValue.wallets.payPal === Auto

let shouldDisplayPayPalInTabs =
isShowPaypal &&
!paymentMethodListValue.collect_billing_details_from_wallets &&
!areAllPaypalRequiredFieldsPreFilled &&
isPaypalRedirectFlow &&
(!isPaypalSDKFlow || !isPaypalTokenExist)

let filteredSaved = switch savedPaymentMethods {
| Some(methods) =>
methods
->Array.copy
->Array.filter(savedMethod =>
switch savedMethod.paymentMethodType {
| Some("apple_pay") => isApplePayReady
| Some("google_pay") => isGooglePayReady
| _ => true
}
)
| None => []
}

let klarnaPaymentMethodExperience = PaymentMethodsRecord.getPaymentExperienceTypeFromPML(
~paymentMethodList=plist,
~paymentMethodName="pay_later",
~paymentMethodType="klarna",
let showSavedPaymentMethodsTab =
optionAtomValue.enableUnifiedView &&
filteredSaved->Array.length != 0 &&
optionAtomValue.displaySavedPaymentMethods

let (wallets, otherOptions) =
plist->paymentListLookupNew(
~order=paymentOrder,
~isShowPaypal,
~isShowKlarnaOneClick=optionAtomValue.wallets.klarna === Auto,
~isKlarnaSDKFlow,
~paymentMethodListValue=plist,
~areAllGooglePayRequiredFieldsPrefilled,
~isGooglePayReady,
~shouldDisplayApplePayInTabs,
~shouldDisplayPayPalInTabs,
~localeString,
~showSavedPaymentMethodsTab,
)

let isKlarnaInvokeSDKExperience = klarnaPaymentMethodExperience->Array.includes(InvokeSDK)
let klarnaPaymentMethodExperience = PaymentMethodsRecord.getPaymentExperienceTypeFromPML(
~paymentMethodList=plist,
~paymentMethodName="pay_later",
~paymentMethodType="klarna",
)

let filterPaymentMethods = (paymentOptionsList: array<string>) => {
paymentOptionsList->Array.filter(paymentOptionsName => {
switch paymentOptionsName {
| "klarna" => !(isKlarnaSDKFlow && isKlarnaInvokeSDKExperience)
| "apple_pay" => shouldDisplayApplePayInTabs
| _ => true
}
})
}
let isKlarnaInvokeSDKExperience = klarnaPaymentMethodExperience->Array.includes(InvokeSDK)

(
wallets->removeDuplicate->Utils.getWalletPaymentMethod(paymentType),
paymentOptions
->Array.concat(otherOptions)
->removeDuplicate
->filterPaymentMethods,
otherOptions,
)
| SemiLoaded => checkPriorityList(paymentMethodOrder) ? ([], ["card"], []) : ([], [], [])
let filterPaymentMethods = (paymentOptionsList: array<string>) => {
paymentOptionsList->Array.filter(paymentOptionsName => {
switch paymentOptionsName {
| "klarna" => !(isKlarnaSDKFlow && isKlarnaInvokeSDKExperience)
| "apple_pay" => shouldDisplayApplePayInTabs
| _ => true
}
})
}

(
wallets->removeDuplicate->Utils.getWalletPaymentMethod(paymentType),
paymentOptions
->Array.concat(otherOptions)
->removeDuplicate
->filterPaymentMethods,
otherOptions,
)
}

React.useMemo(() => {
switch (
methodslist,
optionAtomValue.customerPaymentMethods,
optionAtomValue.enableUnifiedView,
) {
| (Loaded(paymentlist), _, false)
| (Loaded(paymentlist), NoResult(_), _) =>
processPaymentsList(~paymentList=paymentlist, ~savedPaymentMethods=None)
| (Loaded(paymentlist), LoadedSavedCards(savedPaymentMethods, _), true) =>
processPaymentsList(~paymentList=paymentlist, ~savedPaymentMethods=Some(savedPaymentMethods))
| (SemiLoaded, _, _) =>
checkPriorityList(paymentMethodOrder) ? ([], ["card"], []) : ([], [], [])
| _ => ([], [], [])
}
}, (
Expand All @@ -466,6 +506,9 @@ let useGetPaymentMethodList = (~paymentOptions, ~paymentType, ~sessions) => {
areAllGooglePayRequiredFieldsPrefilled,
isApplePayReady,
isGooglePayReady,
optionAtomValue.customerPaymentMethods,
optionAtomValue.displaySavedPaymentMethods,
optionAtomValue.enableUnifiedView,
))
}

Expand Down