diff --git a/src/LoaderController.res b/src/LoaderController.res index d81b6457..31fa6e4a 100644 --- a/src/LoaderController.res +++ b/src/LoaderController.res @@ -35,6 +35,9 @@ let make = (~children, ~paymentMode, ~setIntegrateErrorError, ~logger, ~initTime let setUserAddressState = Recoil.useLoggedSetRecoilState(userAddressState, "state", logger) let setUserAddressCountry = Recoil.useLoggedSetRecoilState(userAddressCountry, "country", logger) let (_country, setCountry) = Recoil.useRecoilState(userCountry) + let (isCompleteCallbackUsed, setIsCompleteCallbackUsed) = Recoil.useRecoilState( + isCompleteCallbackUsed, + ) let optionsCallback = (optionsPayment: PaymentType.options) => { [ @@ -245,6 +248,10 @@ let make = (~children, ~paymentMode, ~setIntegrateErrorError, ~logger, ~initTime let metadata = dict->getJsonObjectFromDict("analyticsMetadata") logger.setMetadata(metadata) } + if dict->getDictIsSome("onCompleteDoThisUsed") { + let isCallbackUsedVal = dict->Utils.getBool("onCompleteDoThisUsed", false) + setIsCompleteCallbackUsed(_ => isCallbackUsedVal) + } if dict->getDictIsSome("paymentOptions") { let paymentOptions = dict->getDictFromObj("paymentOptions") diff --git a/src/Payments/PaypalSDK.res b/src/Payments/PaypalSDK.res index 7763a6fd..f92957c6 100644 --- a/src/Payments/PaypalSDK.res +++ b/src/Payments/PaypalSDK.res @@ -9,6 +9,7 @@ let make = (~sessionObj: SessionsType.token, ~paymentType: CardThemeType.mode) = let areOneClickWalletsRendered = Recoil.useSetRecoilState(RecoilAtoms.areOneClickWalletsRendered) let paymentMethodListValue = Recoil.useRecoilValueFromAtom(PaymentUtils.paymentMethodListValue) let (isCompleted, setIsCompleted) = React.useState(_ => false) + let isCallbackUsedVal = Recoil.useRecoilValueFromAtom(RecoilAtoms.isCompleteCallbackUsed) let token = sessionObj.token let orderDetails = sessionObj.orderDetails->getOrderDetails(paymentType) @@ -90,6 +91,7 @@ let make = (~sessionObj: SessionsType.token, ~paymentType: CardThemeType.mode) = ~handleCloseLoader, ~areOneClickWalletsRendered, ~setIsCompleted, + ~isCallbackUsedVal, ) }) Window.body->Window.appendChild(paypalScript) diff --git a/src/Payments/PaypalSDKHelpers.res b/src/Payments/PaypalSDKHelpers.res index 71c08e1e..c9287ff5 100644 --- a/src/Payments/PaypalSDKHelpers.res +++ b/src/Payments/PaypalSDKHelpers.res @@ -20,6 +20,7 @@ let loadPaypalSDK = ( RecoilAtoms.areOneClickWalletsRendered => RecoilAtoms.areOneClickWalletsRendered ) => unit, ~setIsCompleted, + ~isCallbackUsedVal: bool, ) => { loggerState.setLogInfo( ~value="Paypal SDK Button Clicked", diff --git a/src/Utilities/PaymentHelpers.res b/src/Utilities/PaymentHelpers.res index af404ea1..981517c5 100644 --- a/src/Utilities/PaymentHelpers.res +++ b/src/Utilities/PaymentHelpers.res @@ -315,9 +315,11 @@ let rec intentCall = ( ~sdkHandleOneClickConfirmPayment, ~counter, ~isPaymentSession=false, + ~isCallbackUsedVal=?, ) => { open Promise let isConfirm = uri->String.includes("/confirm") + let isCompleteAuthorize = uri->String.includes("/complete_authorize") let (eventName: OrcaLogger.eventName, initEventName: OrcaLogger.eventName) = switch ( isConfirm, @@ -506,14 +508,28 @@ let rec intentCall = ( | (Applepay, false) | (Paypal, false) => if !isPaymentSession { - closePaymentLoaderIfAny() + if isCallbackUsedVal->Option.getOr(false) { + Utils.handleOnCompleteDoThisMessage() + } else { + closePaymentLoaderIfAny() + } + postSubmitResponse(~jsonData=data, ~url=url.href) } else if confirmParam.redirect === Some("always") { - handleOpenUrl(url.href) + if isCallbackUsedVal->Option.getOr(false) { + Utils.handleOnCompleteDoThisMessage() + } else { + handleOpenUrl(url.href) + } } else { resolve(data) } - | _ => handleOpenUrl(url.href) + | _ => + if isCallbackUsedVal->Option.getOr(false) { + Utils.handleOnCompleteDoThisMessage() + } else { + handleOpenUrl(url.href) + } } } @@ -890,6 +906,7 @@ let usePaymentSync = (optLogger: option, paymentType: pay open RecoilAtoms let paymentMethodList = Recoil.useRecoilValueFromAtom(paymentMethodList) let keys = Recoil.useRecoilValueFromAtom(keys) + let isCallbackUsedVal = Recoil.useRecoilValueFromAtom(RecoilAtoms.isCompleteCallbackUsed) let customPodUri = Recoil.useRecoilValueFromAtom(customPodUri) let setIsManualRetryEnabled = Recoil.useSetRecoilState(isManualRetryEnabled) (~handleUserError=false, ~confirmParam: ConfirmType.confirmParams, ~iframeId="") => { @@ -917,6 +934,7 @@ let usePaymentSync = (optLogger: option, paymentType: pay ~customPodUri, ~sdkHandleOneClickConfirmPayment=keys.sdkHandleOneClickConfirmPayment, ~counter=0, + ~isCallbackUsedVal, )->ignore } switch paymentMethodList { @@ -963,6 +981,7 @@ let usePaymentIntent = (optLogger, paymentType) => { let customPodUri = Recoil.useRecoilValueFromAtom(customPodUri) let paymentMethodList = Recoil.useRecoilValueFromAtom(paymentMethodList) let keys = Recoil.useRecoilValueFromAtom(keys) + let isCallbackUsedVal = Recoil.useRecoilValueFromAtom(RecoilAtoms.isCompleteCallbackUsed) let setIsManualRetryEnabled = Recoil.useSetRecoilState(isManualRetryEnabled) ( @@ -1056,6 +1075,7 @@ let usePaymentIntent = (optLogger, paymentType) => { ~customPodUri, ~sdkHandleOneClickConfirmPayment=keys.sdkHandleOneClickConfirmPayment, ~counter=0, + ~isCallbackUsedVal, ) ->then(val => { intentCallback(val) @@ -1140,6 +1160,7 @@ let useCompleteAuthorize = (optLogger: option, paymentTyp let customPodUri = Recoil.useRecoilValueFromAtom(customPodUri) let setIsManualRetryEnabled = Recoil.useSetRecoilState(isManualRetryEnabled) let url = RescriptReactRouter.useUrl() + let isCallbackUsedVal = Recoil.useRecoilValueFromAtom(RecoilAtoms.isCompleteCallbackUsed) let paymentTypeFromUrl = CardUtils.getQueryParamsDictforKey(url.search, "componentName")->CardThemeType.getPaymentMode ( @@ -1183,6 +1204,7 @@ let useCompleteAuthorize = (optLogger: option, paymentTyp ~customPodUri, ~sdkHandleOneClickConfirmPayment=keys.sdkHandleOneClickConfirmPayment, ~counter=0, + ~isCallbackUsedVal, )->ignore } switch paymentMethodList { diff --git a/src/Utilities/RecoilAtoms.res b/src/Utilities/RecoilAtoms.res index 26752e0f..6c2da891 100644 --- a/src/Utilities/RecoilAtoms.res +++ b/src/Utilities/RecoilAtoms.res @@ -73,6 +73,7 @@ let userVpaId = Recoil.atom("userVpaId", defaultFieldValues) let userPixKey = Recoil.atom("userPixKey", defaultFieldValues) let userPixCPF = Recoil.atom("userPixCPF", defaultFieldValues) let userPixCNPJ = Recoil.atom("userPixCNPJ", defaultFieldValues) +let isCompleteCallbackUsed = Recoil.atom("isCompleteCallbackUsed", false) type areOneClickWalletsRendered = { isGooglePay: bool, diff --git a/src/Utilities/Utils.res b/src/Utilities/Utils.res index a571fd0f..5c35b352 100644 --- a/src/Utilities/Utils.res +++ b/src/Utilities/Utils.res @@ -28,6 +28,10 @@ let handleOnFocusPostMessage = (~targetOrigin="*") => { messageParentWindow([("focus", true->JSON.Encode.bool)], ~targetOrigin) } +let handleOnCompleteDoThisMessage = (~targetOrigin="*") => { + messageParentWindow([("completeDoThis", true->JSON.Encode.bool)], ~targetOrigin) +} + let handleOnBlurPostMessage = (~targetOrigin="*") => { messageParentWindow([("blur", true->JSON.Encode.bool)], ~targetOrigin) } @@ -1148,6 +1152,7 @@ let eventHandlerFunc = ( | Click | Ready | Focus + | CompleteDoThis | ConfirmPayment | OneClickConfirmPayment | Blur => diff --git a/src/orca-loader/Elements.res b/src/orca-loader/Elements.res index a493e6ed..fa7bf126 100644 --- a/src/orca-loader/Elements.res +++ b/src/orca-loader/Elements.res @@ -317,6 +317,10 @@ let make = ( ("analyticsMetadata", analyticsMetadata), ("launchTime", launchTime->JSON.Encode.float), ("customBackendUrl", customBackendUrl->JSON.Encode.string), + ( + "onCompleteDoThisUsed", + LoaderPaymentElement.onCompleteDoThisUsed.contents->JSON.Encode.bool, + ), ]->Dict.fromArray let wallets = PaymentType.getWallets(newOptions->getDictFromJson, "wallets", logger) diff --git a/src/orca-loader/LoaderPaymentElement.res b/src/orca-loader/LoaderPaymentElement.res index 028e5013..455eb3e1 100644 --- a/src/orca-loader/LoaderPaymentElement.res +++ b/src/orca-loader/LoaderPaymentElement.res @@ -6,6 +6,7 @@ open Identity @val @scope(("navigator", "clipboard")) external writeText: string => promise<'a> = "writeText" +let onCompleteDoThisUsed = ref(false) let make = ( componentType, options, @@ -47,6 +48,15 @@ let make = ( }, "onEscape", ) + | CompleteDoThis => { + onCompleteDoThisUsed := true + eventHandlerFunc( + ev => ev.data.completeDoThis, + eventHandler, + CompleteDoThis, + "onCompleteDoThis", + ) + } | Change => eventHandlerFunc( ev => ev.data.elementType === componentType, diff --git a/src/orca-loader/Types.res b/src/orca-loader/Types.res index 5186769d..74e8eb07 100644 --- a/src/orca-loader/Types.res +++ b/src/orca-loader/Types.res @@ -4,6 +4,7 @@ type eventData = { blur: bool, ready: bool, clickTriggered: bool, + completeDoThis: bool, elementType: string, classChange: bool, newClassType: string, @@ -184,7 +185,16 @@ let defaultHyperInstance = { } type eventType = - Escape | Change | Click | Ready | Focus | Blur | ConfirmPayment | OneClickConfirmPayment | None + | Escape + | Change + | Click + | Ready + | Focus + | Blur + | CompleteDoThis + | ConfirmPayment + | OneClickConfirmPayment + | None let eventTypeMapper = event => { switch event { @@ -192,6 +202,7 @@ let eventTypeMapper = event => { | "change" => Change | "clickTriggered" => Click | "ready" => Ready + | "completeDoThis" => CompleteDoThis | "focus" => Focus | "blur" => Blur | "confirmTriggered" => ConfirmPayment