Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 24 additions & 6 deletions src/CardUtils.res
Original file line number Diff line number Diff line change
Expand Up @@ -743,13 +743,31 @@ let getCardBrandInvalidError = (~cardBrand, ~localeString: LocaleStringTypes.loc
}
}

let emitExpiryDate = formattedExpiry =>
Utils.messageParentWindow([("expiryDate", formattedExpiry->JSON.Encode.string)])
let emitExpiryDate = (formattedExpiry, ~subscriptionEvents) => {
if (
subscriptionEvents->Option.isNone ||
PaymentEventData.shouldEmitEvent(
~subscribedEvents=subscriptionEvents->Option.getOr([]),
~eventType=PaymentEventTypes.UnknownEvent,
)
) {
Utils.messageParentWindow([("expiryDate", formattedExpiry->JSON.Encode.string)])
}
}

let emitIsFormReadyForSubmission = isFormReadyForSubmission =>
Utils.messageParentWindow([
("isFormReadyForSubmission", isFormReadyForSubmission->JSON.Encode.bool),
])
let emitIsFormReadyForSubmission = (isFormReadyForSubmission, ~subscriptionEvents) => {
if (
subscriptionEvents->Option.isNone ||
PaymentEventData.shouldEmitEvent(
~subscribedEvents=subscriptionEvents->Option.getOr([]),
~eventType=PaymentEventTypes.UnknownEvent,
)
) {
Utils.messageParentWindow([
("isFormReadyForSubmission", isFormReadyForSubmission->JSON.Encode.bool),
])
}
}

let getCardBin = cardNumber =>
cardNumber->CardValidations.clearSpaces->String.substring(~start=0, ~end=6)
Expand Down
8 changes: 8 additions & 0 deletions src/Components/AccordionContainer.res
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,14 @@ let make = (
~cardProps,
~expiryProps,
)
SubscriptionEventHooks.usePaymentMethodStatus(
~paymentMethodName=selectedOption,
~paymentMethods=paymentMethodListValue.payment_methods,
~isSavedPaymentMethod=false,
~isOneClickWallet=false,
)

SubscriptionEventHooks.useBillingAddress()

let cardOptionDetails =
paymentOptions
Expand Down
3 changes: 2 additions & 1 deletion src/Components/LoaderPaymentShimmer.res
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
let make = () => {
open RecoilAtoms
let selectedOption = Recoil.useRecoilValueFromAtom(selectedOptionAtom)
UtilityHooks.useHandlePostMessages(~complete=false, ~empty=false, ~paymentType=selectedOption)
SubscriptionEventHooks.useFormStatus(~empty=true, ~complete=false)
UtilityHooks.useHandlePostMessages(~complete=false, ~empty=true, ~paymentType=selectedOption)
<PaymentShimmer />
}
23 changes: 20 additions & 3 deletions src/Components/SavedCardItem.res
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ let make = (
| None => "debit"
}
let {country, state, pinCode} = PaymentUtils.useNonPiiAddressData()

let options = Recoil.useRecoilValueFromAtom(RecoilAtoms.optionAtom)
React.useEffect(() => {
open CardUtils

Expand All @@ -111,7 +111,7 @@ let make = (
// * Sending card expiry to handle cases where the card expires before the use date.
`${expiryMonth}${String.substring(~start=2, ~end=4, expiryYear)}`
->CardValidations.formatCardExpiryNumber
->emitExpiryDate
->emitExpiryDate(~subscriptionEvents=options.subscriptionEvents)

PaymentUtils.emitPaymentMethodInfo(
~paymentMethod=paymentItem.paymentMethod,
Expand All @@ -125,13 +125,30 @@ let make = (
~cardLast4,
~cardBin,
~isSavedPaymentMethod=true,
~subscriptionEvents=options.subscriptionEvents,
)
SubscriptionEventHooks.emitPaymentMethodStatus(
~subscriptionEvents=options.subscriptionEvents,
~paymentMethod=paymentItem.paymentMethod,
~paymentMethodType,
~isSavedPaymentMethod=true,
~isOneClickWallet=false,
)
SubscriptionEventHooks.emitBillingAddress(
~subscriptionEvents=options.subscriptionEvents,
~country,
~state,
~postalCode=pinCode,
)
}
None
}, (isActive, paymentItem, country, state, pinCode))

React.useEffect(() => {
CardUtils.emitIsFormReadyForSubmission(isCVCValid->Option.getOr(false))
CardUtils.emitIsFormReadyForSubmission(
isCVCValid->Option.getOr(false),
~subscriptionEvents=options.subscriptionEvents,
)
None
}, [isCVCValid])

Expand Down
26 changes: 25 additions & 1 deletion src/Components/SavedMethods.res
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,8 @@ let make = (
let (selectedInstallmentPlan, setSelectedInstallmentPlan) = React.useState(_ => None)
let (showInstallments, setShowInstallments) = React.useState(_ => false)

let options = Recoil.useRecoilValueFromAtom(RecoilAtoms.optionAtom)

let shouldShowClickToPaySection =
clickToPayConfig.isReady == Some(true) &&
(!groupSavedMethodsWithPaymentMethods || selectedOption == "card")
Expand Down Expand Up @@ -153,8 +155,30 @@ let make = (

let paymentMethodType =
customerMethod.paymentMethodType->Option.getOr(customerMethod.paymentMethod)
SubscriptionEventHooks.useFormStatus(~empty, ~complete)
UtilityHooks.useHandlePostMessages(
~complete,
~empty,
~paymentType=paymentMethodType,
~savedMethod=true,
)

useHandlePostMessages(~complete, ~empty, ~paymentType=paymentMethodType, ~savedMethod=true)
// Emit card info for saved card methods
React.useEffect(() => {
if isCardPaymentMethod && !isUnknownPaymentMethod {
let card = customerMethod.card
let cardInfo = PaymentEventData.buildCardInfoFromSavedCard(
~bin=card.cardBin,
~last4=card.last4Digits,
~brand=card.scheme->Option.getOr(""),
~expiryMonth=card.expiryMonth,
~expiryYear=card.expiryYear,
~isCvcComplete=complete,
)
SubscriptionEventHooks.emitCardInfo(~subscriptionEvents=options.subscriptionEvents, ~cardInfo)
}
None
}, (customerMethod, isCardPaymentMethod, isUnknownPaymentMethod, complete))

GooglePayHelpers.useHandleGooglePayResponse(~connectors=[], ~intent, ~isSavedMethodsFlow=true)

Expand Down
4 changes: 3 additions & 1 deletion src/Hooks/CommonCardProps.res
Original file line number Diff line number Diff line change
Expand Up @@ -139,13 +139,15 @@ let useCardForm = (~logger, ~paymentType) => {
}
}

let options = Recoil.useRecoilValueFromAtom(RecoilAtoms.optionAtom)

let changeCardExpiry = ev => {
let val = ReactEvent.Form.target(ev)["value"]
logInputChangeInfo("cardExpiry", logger)
let formattedExpiry = val->CardValidations.formatCardExpiryNumber
if isExipryValid(formattedExpiry) {
handleInputFocus(~currentRef=expiryRef, ~destinationRef=cvcRef)
emitExpiryDate(formattedExpiry)
CardUtils.emitExpiryDate(formattedExpiry, ~subscriptionEvents=options.subscriptionEvents)
}
setExpiryValid(formattedExpiry, setIsExpiryValid)
setCardExpiry(_ => formattedExpiry)
Expand Down
129 changes: 129 additions & 0 deletions src/Hooks/SubscriptionEventHooks.res
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
open SubscriptionEventTypes
open PaymentEventData
open PaymentEventTypes

let emitCardInfo = (~subscriptionEvents, ~cardInfo: cardInfo) => {
if (
subscriptionEvents->Option.isNone ||
shouldEmitEvent(
~subscribedEvents=subscriptionEvents->Option.getOr([]),
~eventType=PaymentMethodInfoCard,
)
) {
let payload = createCardInfoPayload(cardInfo)
Utils.messageParentWindow(payload)
}
}

let emitPaymentMethodStatus = (
~subscriptionEvents,
~paymentMethod,
~paymentMethodType,
~isSavedPaymentMethod,
~isOneClickWallet=false,
) => {
if (
subscriptionEvents->Option.isNone ||
shouldEmitEvent(
~subscribedEvents=subscriptionEvents->Option.getOr([]),
~eventType=PaymentMethodStatus,
)
) {
let payload = createPaymentMethodStatusPayload(
~paymentMethod,
~paymentMethodType,
~isSavedPaymentMethod,
~isOneClickWallet,
)
Utils.messageParentWindow(payload)
}
}

let emitBillingAddress = (~subscriptionEvents, ~country, ~state, ~postalCode) => {
if (
subscriptionEvents->Option.isNone ||
shouldEmitEvent(
~subscribedEvents=subscriptionEvents->Option.getOr([]),
~eventType=PaymentMethodInfoBillingAddress,
)
) {
let payload = createBillingAddressPayload(~country, ~state, ~postalCode)
Utils.messageParentWindow(payload)
}
}

let useFormStatus = (~empty: bool, ~complete: bool, ~isOneClickWallet: bool=false) => {
let options = Recoil.useRecoilValueFromAtom(RecoilAtoms.optionAtom)
let subscriptionEvents = options.subscriptionEvents

React.useEffect(() => {
if !isOneClickWallet {
let formStatusValue = computeFormStatus(~isComplete=complete, ~isEmpty=empty)
if (
subscriptionEvents->Option.isNone ||
shouldEmitEvent(
~subscribedEvents=subscriptionEvents->Option.getOr([]),
~eventType=FormStatus,
)
) {
let payload = SubscriptionEventTypes.createFormStatusPayload(~status=formStatusValue)
Utils.messageParentWindow(payload)
}
}
None
}, (empty, complete, isOneClickWallet, subscriptionEvents))
}

let useBillingAddress = () => {
let country = Recoil.useRecoilValueFromAtom(RecoilAtoms.userCountry)
let state = Recoil.useRecoilValueFromAtom(RecoilAtoms.userAddressState).value
let pinCode = Recoil.useRecoilValueFromAtom(RecoilAtoms.userAddressPincode).value
let options = Recoil.useRecoilValueFromAtom(RecoilAtoms.optionAtom)

React.useEffect(() => {
emitBillingAddress(
~subscriptionEvents=options.subscriptionEvents,
~country,
~state,
~postalCode=pinCode,
)

None
}, (country, state, pinCode, options.subscriptionEvents))
}

let usePaymentMethodStatus = (
~paymentMethodName: string,
~paymentMethods: array<PaymentMethodsRecord.methods>,
~isSavedPaymentMethod: bool,
~isOneClickWallet: bool,
) => {
let loggerState = Recoil.useRecoilValueFromAtom(RecoilAtoms.loggerAtom)
let options = Recoil.useRecoilValueFromAtom(RecoilAtoms.optionAtom)

React.useEffect(() => {
switch PaymentUtils.getPaymentMethodAndType(
~paymentMethodName,
~paymentMethods,
~logger=loggerState,
) {
| Some((paymentMethod, paymentMethodType)) =>
emitPaymentMethodStatus(
~subscriptionEvents=options.subscriptionEvents,
~paymentMethod,
~paymentMethodType,
~isSavedPaymentMethod,
~isOneClickWallet,
)
| None => ()
}

None
}, (
paymentMethodName,
paymentMethods,
isSavedPaymentMethod,
isOneClickWallet,
options.subscriptionEvents,
))
}
12 changes: 10 additions & 2 deletions src/Hooks/UtilityHooks.res
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,19 @@ let useHandlePostMessages = (~complete, ~empty, ~paymentType, ~savedMethod=false
open RecoilAtoms

let loggerState = Recoil.useRecoilValueFromAtom(loggerAtom)
let options = Recoil.useRecoilValueFromAtom(optionAtom)

React.useEffect(() => {
Utils.handlePostMessageEvents(~complete, ~empty, ~paymentType, ~loggerState, ~savedMethod)
Utils.handlePostMessageEvents(
~complete,
~empty,
~paymentType,
~loggerState,
~savedMethod,
~subscriptionEvents=options.subscriptionEvents,
)
None
}, (complete, empty, paymentType))
}, (complete, empty, paymentType, options.subscriptionEvents))
}

let useIsCustomerAcceptanceRequired = (
Expand Down
2 changes: 2 additions & 0 deletions src/Payment.res
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ let setUserError = message => {
@react.component
let make = (~paymentMode, ~integrateError, ~logger) => {
let {localeString} = Recoil.useRecoilValueFromAtom(configAtom)
let options = Recoil.useRecoilValueFromAtom(optionAtom)
let {iframeId} = Recoil.useRecoilValueFromAtom(keys)
let isManualRetryEnabled = Recoil.useRecoilValueFromAtom(isManualRetryEnabled)
let areRequiredFieldsValid = Recoil.useRecoilValueFromAtom(areRequiredFieldsValid)
Expand Down Expand Up @@ -39,6 +40,7 @@ let make = (~paymentMode, ~integrateError, ~logger) => {
| (Some(cardValid), Some(expiryValid), Some(cvcValid)) =>
CardUtils.emitIsFormReadyForSubmission(
cardValid && expiryValid && cvcValid && areRequiredFieldsValid,
~subscriptionEvents=options.subscriptionEvents,
)
| _ => ()
}
Expand Down
8 changes: 8 additions & 0 deletions src/PaymentOptions.res
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,14 @@ let make = (
~expiryProps,
)

SubscriptionEventHooks.useBillingAddress()
SubscriptionEventHooks.usePaymentMethodStatus(
~paymentMethodName=selectedPaymentOption.paymentMethodName,
~paymentMethods=paymentMethodListValue.payment_methods,
~isSavedPaymentMethod=false,
~isOneClickWallet=false,
)

let displayIcon = ele => {
<span className={`scale-90 animate-slowShow ${toggleIconElement ? "hidden" : ""}`}> ele </span>
}
Expand Down
5 changes: 3 additions & 2 deletions src/Payments/ACHBankDebit.res
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
open RecoilAtoms
open Utils
open PaymentModeType

@react.component
let make = () => {
Expand Down Expand Up @@ -61,7 +60,9 @@ let make = () => {
fullName.value != "" &&
email.isValid->Option.getOr(false) &&
modalData->Option.isSome
let empty = email.value == "" || fullName.value != ""
let empty = email.value == "" || fullName.value == ""

SubscriptionEventHooks.useFormStatus(~complete, ~empty)

UtilityHooks.useHandlePostMessages(~complete, ~empty, ~paymentType="ach_bank_debit")

Expand Down
3 changes: 2 additions & 1 deletion src/Payments/ACHBankTransfer.res
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ let make = () => {
let complete = email.value != "" && email.isValid->Option.getOr(false)
let empty = email.value == ""

UtilityHooks.useHandlePostMessages(~complete, ~empty, ~paymentType="bank_transfer")
SubscriptionEventHooks.useFormStatus(~empty, ~complete)
UtilityHooks.useHandlePostMessages(~complete, ~empty, ~paymentType="ach_bank_transfer")

React.useEffect(() => {
setComplete(_ => complete)
Expand Down
Loading
Loading