From 8f2e4085a65aff510ae49b416bc987aa2ca5b4da Mon Sep 17 00:00:00 2001 From: ArushKapoorJuspay <121166031+ArushKapoorJuspay@users.noreply.github.com> Date: Thu, 13 Jun 2024 14:06:42 +0530 Subject: [PATCH 01/11] fix: removed fallback in case of sessions call fail based on payment experience (#440) --- src/PaymentElement.res | 10 ++--- src/Payments/CardPayment.res | 5 +-- src/Payments/PaymentMethodsRecord.res | 31 +++++++++++++-- src/Utilities/PaymentUtils.res | 56 +++++++++++++++++++-------- 4 files changed, 71 insertions(+), 31 deletions(-) diff --git a/src/PaymentElement.res b/src/PaymentElement.res index fd4941143..2d6803821 100644 --- a/src/PaymentElement.res +++ b/src/PaymentElement.res @@ -45,8 +45,6 @@ let make = (~cardProps, ~expiryProps, ~cvcProps, ~paymentType: CardThemeType.mod setLoadSavedCards: (savedCardsLoadState => savedCardsLoadState) => unit, ) = React.useState(_ => LoadingSavedCards) - let isKlarnaRedirectFlow = PaymentUtils.getIsKlarnaRedirectFlow(sessions) - React.useEffect(() => { switch (displaySavedPaymentMethods, customerPaymentMethods) { | (false, _) => { @@ -246,11 +244,9 @@ let make = (~cardProps, ~expiryProps, ~cvcProps, ~paymentType: CardThemeType.mod {switch selectedOption->PaymentModeType.paymentMode { | Card => | Klarna => - - - - - + + + | ACHTransfer => diff --git a/src/Payments/CardPayment.res b/src/Payments/CardPayment.res index abd90fb4d..dcaba65d0 100644 --- a/src/Payments/CardPayment.res +++ b/src/Payments/CardPayment.res @@ -78,10 +78,7 @@ let make = ( let cardPaymentMethod = paymentMethodListValue.payment_methods ->Array.find(ele => ele.payment_method === "card") - ->Option.getOr({ - payment_method: "card", - payment_method_types: [], - }) + ->Option.getOr(PaymentMethodsRecord.defaultMethods) let cardNetworks = cardPaymentMethod.payment_method_types->Array.map(ele => ele.card_networks) diff --git a/src/Payments/PaymentMethodsRecord.res b/src/Payments/PaymentMethodsRecord.res index d5197e904..8472352f2 100644 --- a/src/Payments/PaymentMethodsRecord.res +++ b/src/Payments/PaymentMethodsRecord.res @@ -742,6 +742,11 @@ type methods = { payment_method_types: array, } +let defaultMethods = { + payment_method: "card", + payment_method_types: [], +} + type mandateType = { amount: int, currency: string, @@ -1049,10 +1054,7 @@ let getPaymentMethodTypeFromList = ( ->Array.find(item => { item.payment_method == paymentMethod }) - ->Option.getOr({ - payment_method: "card", - payment_method_types: [], - }) + ->Option.getOr(defaultMethods) ).payment_method_types->Array.find(item => { item.payment_method_type == paymentMethodType }) @@ -1064,3 +1066,24 @@ let getCardNetwork = (~paymentMethodType, ~cardBrand) => { ->Array.get(0) ->Option.getOr(defaultCardNetworks) } + +let getPaymentExperienceTypeFromPML = ( + ~paymentMethodList: paymentMethodList, + ~paymentMethodName, + ~paymentMethodType, +) => { + paymentMethodList.payment_methods + ->Array.filter(paymentMethod => paymentMethod.payment_method === paymentMethodName) + ->Array.get(0) + ->Option.flatMap(method => + method.payment_method_types + ->Array.filter(methodTypes => methodTypes.payment_method_type === paymentMethodType) + ->Array.get(0) + ) + ->Option.flatMap(paymentMethodTypes => + paymentMethodTypes.payment_experience + ->Array.map(paymentExperience => paymentExperience.payment_experience_type) + ->Some + ) + ->Option.getOr([]) +} diff --git a/src/Utilities/PaymentUtils.res b/src/Utilities/PaymentUtils.res index f9b1a654c..d761b007e 100644 --- a/src/Utilities/PaymentUtils.res +++ b/src/Utilities/PaymentUtils.res @@ -5,7 +5,8 @@ let paymentListLookupNew = ( ~order, ~isShowPaypal, ~isShowKlarnaOneClick, - ~isKlarnaRedirectFlow, + ~isKlarnaSDKFlow, + ~paymentMethodListValue: PaymentMethodsRecord.paymentMethodList, ) => { let pmList = list->PaymentMethodsRecord.buildFromPaymentList let walletsList = [] @@ -43,8 +44,21 @@ let paymentListLookupNew = ( } else if item.methodType == "reward" { otherPaymentList->Array.push(item.paymentMethodName)->ignore } else if item.methodType == "pay_later" { - if item.paymentMethodName === "klarna" && !isKlarnaRedirectFlow && isShowKlarnaOneClick { - walletsList->Array.push(item.paymentMethodName)->ignore + if item.paymentMethodName === "klarna" { + let klarnaPaymentMethodExperience = PaymentMethodsRecord.getPaymentExperienceTypeFromPML( + ~paymentMethodList=paymentMethodListValue, + ~paymentMethodName=item.methodType, + ~paymentMethodType=item.paymentMethodName, + ) + + let isInvokeSDKExperience = klarnaPaymentMethodExperience->Array.includes(InvokeSDK) + let isRedirectExperience = klarnaPaymentMethodExperience->Array.includes(RedirectToURL) + + if isKlarnaSDKFlow && isShowKlarnaOneClick && isInvokeSDKExperience { + walletsList->Array.push(item.paymentMethodName)->ignore + } else if isRedirectExperience { + otherPaymentList->Array.push(item.paymentMethodName)->ignore + } } else { otherPaymentList->Array.push(item.paymentMethodName)->ignore } @@ -265,13 +279,13 @@ let useAreAllRequiredFieldsPrefilled = ( }) } -let getIsKlarnaRedirectFlow = sessions => { +let getIsKlarnaSDKFlow = sessions => { let dict = sessions->Utils.getDictFromJson let sessionObj = SessionsType.itemToObjMapper(dict, Others) let klarnaTokenObj = SessionsType.getPaymentSessionObj(sessionObj.sessionsToken, Klarna) switch klarnaTokenObj { - | OtherTokenOptional(optToken) => optToken->Option.isNone - | _ => true + | OtherTokenOptional(optToken) => optToken->Option.isSome + | _ => false } } @@ -286,13 +300,7 @@ let useGetPaymentMethodList = (~paymentOptions, ~paymentType, ~sessions) => { let paymentOrder = paymentMethodOrder->getOptionalArr->removeDuplicate - let isKlarnaRedirectFlow = getIsKlarnaRedirectFlow(sessions) - - let filterPaymentMethods = (paymentOptionsList: array, ~isKlarnaRedirectFlow) => { - paymentOptionsList->Array.filter(paymentOptionsName => - !(paymentOptionsName === "klarna" && !isKlarnaRedirectFlow) - ) - } + let isKlarnaSDKFlow = getIsKlarnaSDKFlow(sessions) React.useMemo(() => { switch methodslist { @@ -305,14 +313,30 @@ let useGetPaymentMethodList = (~paymentOptions, ~paymentType, ~sessions) => { ~order=paymentOrder, ~isShowPaypal=optionAtomValue.wallets.payPal === Auto, ~isShowKlarnaOneClick=optionAtomValue.wallets.klarna === Auto, - ~isKlarnaRedirectFlow, + ~isKlarnaSDKFlow, + ~paymentMethodListValue=plist, ) + + let klarnaPaymentMethodExperience = PaymentMethodsRecord.getPaymentExperienceTypeFromPML( + ~paymentMethodList=plist, + ~paymentMethodName="pay_later", + ~paymentMethodType="klarna", + ) + + let isKlarnaInvokeSDKExperience = klarnaPaymentMethodExperience->Array.includes(InvokeSDK) + + let filterPaymentMethods = (paymentOptionsList: array) => { + paymentOptionsList->Array.filter(paymentOptionsName => + !(paymentOptionsName === "klarna" && isKlarnaSDKFlow && isKlarnaInvokeSDKExperience) + ) + } + ( wallets->removeDuplicate->Utils.getWalletPaymentMethod(paymentType), paymentOptions ->Array.concat(otherOptions) ->removeDuplicate - ->filterPaymentMethods(~isKlarnaRedirectFlow), + ->filterPaymentMethods, otherOptions, ) | SemiLoaded => @@ -327,7 +351,7 @@ let useGetPaymentMethodList = (~paymentOptions, ~paymentType, ~sessions) => { optionAtomValue.wallets.payPal, optionAtomValue.wallets.klarna, paymentType, - isKlarnaRedirectFlow, + isKlarnaSDKFlow, )) } From 9d09b71dd72cfe18539cdc7c76d8da7ff936e59c Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Thu, 13 Jun 2024 08:38:11 +0000 Subject: [PATCH 02/11] chore(release): 0.62.3 [skip ci] ## [0.62.3](https://github.com/juspay/hyperswitch-web/compare/v0.62.2...v0.62.3) (2024-06-13) ### Bug Fixes * removed fallback in case of sessions call fail based on payment experience ([#440](https://github.com/juspay/hyperswitch-web/issues/440)) ([8f2e408](https://github.com/juspay/hyperswitch-web/commit/8f2e4085a65aff510ae49b416bc987aa2ca5b4da)) --- CHANGELOG.md | 7 +++++++ package-lock.json | 4 ++-- package.json | 2 +- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fc5f07853..cd66bbef6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## [0.62.3](https://github.com/juspay/hyperswitch-web/compare/v0.62.2...v0.62.3) (2024-06-13) + + +### Bug Fixes + +* removed fallback in case of sessions call fail based on payment experience ([#440](https://github.com/juspay/hyperswitch-web/issues/440)) ([8f2e408](https://github.com/juspay/hyperswitch-web/commit/8f2e4085a65aff510ae49b416bc987aa2ca5b4da)) + ## [0.62.2](https://github.com/juspay/hyperswitch-web/compare/v0.62.1...v0.62.2) (2024-06-11) diff --git a/package-lock.json b/package-lock.json index ea7e42c55..0b72d10a5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "orca-payment-page", - "version": "0.62.2", + "version": "0.62.3", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "orca-payment-page", - "version": "0.62.2", + "version": "0.62.3", "hasInstallScript": true, "dependencies": { "@aws-sdk/client-cloudfront": "^3.414.0", diff --git a/package.json b/package.json index 041f52f9c..f09c4aa4f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "orca-payment-page", - "version": "0.62.2", + "version": "0.62.3", "main": "index.js", "private": true, "dependencies": { From ad43a5cbe8a53ca06aff77b852d76d84f2b1df05 Mon Sep 17 00:00:00 2001 From: Vrishab Srivatsa <136090360+vsrivatsa-juspay@users.noreply.github.com> Date: Thu, 13 Jun 2024 14:12:37 +0530 Subject: [PATCH 03/11] feat: log href without including search params (#439) --- src/LoaderController.res | 2 +- src/Window.res | 7 ++++++- src/orca-loader/Hyper.res | 19 ++++++++++++++----- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/LoaderController.res b/src/LoaderController.res index a22245d5f..a0b9e4402 100644 --- a/src/LoaderController.res +++ b/src/LoaderController.res @@ -270,7 +270,7 @@ let make = (~children, ~paymentMode, ~setIntegrateErrorError, ~logger, ~initTime setLaunchTime(_ => newLaunchTime) let initLoadlatency = Date.now() -. newLaunchTime logger.setLogInfo( - ~value=Window.href, + ~value=Window.hrefWithoutSearch, ~eventName=APP_RENDERED, ~latency=initLoadlatency, (), diff --git a/src/Window.res b/src/Window.res index 16e00bab9..6224f3e33 100644 --- a/src/Window.res +++ b/src/Window.res @@ -122,11 +122,14 @@ external sendBeacon: (string, string) => unit = "sendBeacon" external hostname: string = "hostname" @val @scope(("window", "location")) -external href: string = "href" +external origin: string = "origin" @val @scope(("window", "location")) external protocol: string = "protocol" +@val @scope(("window", "location")) +external pathname: string = "pathname" + let isSandbox = hostname === "beta.hyperswitch.io" let isInteg = hostname === "dev.hyperswitch.io" @@ -140,3 +143,5 @@ module Location = { module Element = { @get external clientWidth: Dom.element => int = "clientWidth" } + +let hrefWithoutSearch = origin ++ pathname diff --git a/src/orca-loader/Hyper.res b/src/orca-loader/Hyper.res index 45e741b28..8379fa373 100644 --- a/src/orca-loader/Hyper.res +++ b/src/orca-loader/Hyper.res @@ -128,7 +128,12 @@ let make = (publishableKey, options: option, analyticsInfo: option { logger.setMerchantId(publishableKey) logger.setSessionId(sessionID) - logger.setLogInfo(~value=Window.href, ~eventName=APP_INITIATED, ~timestamp=sdkTimestamp, ()) + logger.setLogInfo( + ~value=Window.hrefWithoutSearch, + ~eventName=APP_INITIATED, + ~timestamp=sdkTimestamp, + (), + ) } }->Sentry.sentryLogger let isSecure = Window.protocol === "https:" @@ -137,8 +142,8 @@ let make = (publishableKey, options: option, analyticsInfo: optionArray.find(url => Window.hostname->String.includes(url)) ->Option.isSome if !isSecure && !isLocal { - manageErrorWarning(HTTP_NOT_ALLOWED, ~dynamicStr=Window.href, ~logger, ()) - Exn.raiseError("Insecure domain: " ++ Window.href) + manageErrorWarning(HTTP_NOT_ALLOWED, ~dynamicStr=Window.hrefWithoutSearch, ~logger, ()) + Exn.raiseError("Insecure domain: " ++ Window.hrefWithoutSearch) } switch Window.getHyper->Nullable.toOption { | Some(hyperMethod) => { @@ -404,7 +409,7 @@ let make = (publishableKey, options: option, analyticsInfo: optionthen(_ => { - logger.setLogInfo(~value=Window.href, ~eventName=ORCA_ELEMENTS_CALLED, ()) + logger.setLogInfo(~value=Window.hrefWithoutSearch, ~eventName=ORCA_ELEMENTS_CALLED, ()) resolve() }) ->ignore @@ -544,7 +549,11 @@ let make = (publishableKey, options: option, analyticsInfo: optionthen(_ => { - logger.setLogInfo(~value=Window.href, ~eventName=PAYMENT_SESSION_INITIATED, ()) + logger.setLogInfo( + ~value=Window.hrefWithoutSearch, + ~eventName=PAYMENT_SESSION_INITIATED, + (), + ) resolve() }) ->ignore From 4193f169dc8e48cc4a83e81a1f580144e2a031f7 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Thu, 13 Jun 2024 08:44:10 +0000 Subject: [PATCH 04/11] chore(release): 0.63.0 [skip ci] # [0.63.0](https://github.com/juspay/hyperswitch-web/compare/v0.62.3...v0.63.0) (2024-06-13) ### Features * log href without including search params ([#439](https://github.com/juspay/hyperswitch-web/issues/439)) ([ad43a5c](https://github.com/juspay/hyperswitch-web/commit/ad43a5cbe8a53ca06aff77b852d76d84f2b1df05)) --- CHANGELOG.md | 7 +++++++ package-lock.json | 4 ++-- package.json | 2 +- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cd66bbef6..3985946be 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +# [0.63.0](https://github.com/juspay/hyperswitch-web/compare/v0.62.3...v0.63.0) (2024-06-13) + + +### Features + +* log href without including search params ([#439](https://github.com/juspay/hyperswitch-web/issues/439)) ([ad43a5c](https://github.com/juspay/hyperswitch-web/commit/ad43a5cbe8a53ca06aff77b852d76d84f2b1df05)) + ## [0.62.3](https://github.com/juspay/hyperswitch-web/compare/v0.62.2...v0.62.3) (2024-06-13) diff --git a/package-lock.json b/package-lock.json index 0b72d10a5..3a011dea0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "orca-payment-page", - "version": "0.62.3", + "version": "0.63.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "orca-payment-page", - "version": "0.62.3", + "version": "0.63.0", "hasInstallScript": true, "dependencies": { "@aws-sdk/client-cloudfront": "^3.414.0", diff --git a/package.json b/package.json index f09c4aa4f..ff2c9f6e5 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "orca-payment-page", - "version": "0.62.3", + "version": "0.63.0", "main": "index.js", "private": true, "dependencies": { From 5e46da0924977fa00ccd5ce716c1ed494076ae7f Mon Sep 17 00:00:00 2001 From: Pritish Budhiraja Date: Thu, 13 Jun 2024 15:55:51 +0530 Subject: [PATCH 05/11] feat: added confirm and get handler for last used payment (#428) Co-authored-by: Arush --- src/orca-loader/PaymentSessionMethods.res | 280 ++++++++++++---------- src/orca-loader/Types.res | 10 + 2 files changed, 168 insertions(+), 122 deletions(-) diff --git a/src/orca-loader/PaymentSessionMethods.res b/src/orca-loader/PaymentSessionMethods.res index 6342f43be..819b6881f 100644 --- a/src/orca-loader/PaymentSessionMethods.res +++ b/src/orca-loader/PaymentSessionMethods.res @@ -1,3 +1,17 @@ +let sortFunctions = (a, b) => { + open Utils + let temp1 = Date.fromString(a->getDictFromJson->getString("last_used_at", "")) + let temp2 = Date.fromString(b->getDictFromJson->getString("last_used_at", "")) + + if temp1 === temp2 { + 0. + } else if temp1 > temp2 { + -1. + } else { + 1. + } +} + let getCustomerSavedPaymentMethods = ( ~clientSecret, ~publishableKey, @@ -17,140 +31,162 @@ let getCustomerSavedPaymentMethods = ( ~isPaymentSession=true, ) ->then(customerDetails => { - let customerPaymentMethods = + let customerDetailsArray = customerDetails ->JSON.Decode.object ->Option.flatMap(x => x->Dict.get("customer_payment_methods")) ->Option.flatMap(JSON.Decode.array) ->Option.getOr([]) - ->Array.filter(customerPaymentMethod => { - customerPaymentMethod - ->JSON.Decode.object - ->Option.flatMap(x => x->Dict.get("default_payment_method_set")) - ->Option.flatMap(JSON.Decode.bool) - ->Option.getOr(false) - }) - - switch customerPaymentMethods->Array.get(0) { - | Some(customerDefaultPaymentMethod) => - let getCustomerDefaultSavedPaymentMethodData = () => { - customerDefaultPaymentMethod + + let customerPaymentMethods = customerDetailsArray->Array.filter(customerPaymentMethod => { + customerPaymentMethod + ->JSON.Decode.object + ->Option.flatMap(x => x->Dict.get("default_payment_method_set")) + ->Option.flatMap(JSON.Decode.bool) + ->Option.getOr(false) + }) + + let paymentNotExist = ( + ~message="There is no default saved payment method data for this customer", + ) => + [ + ( + "error", + [ + ("type", "no_data"->JSON.Encode.string), + ("message", message->JSON.Encode.string), + ]->getJsonFromArrayOfJson, + ), + ]->getJsonFromArrayOfJson + + let getCustomerDefaultSavedPaymentMethodData = () => + switch customerPaymentMethods->Array.get(0) { + | Some(customerDefaultPaymentMethod) => customerDefaultPaymentMethod + | None => paymentNotExist() } - let confirmWithCustomerDefaultPaymentMethod = payload => { - let customerPaymentMethod = - customerDefaultPaymentMethod->JSON.Decode.object->Option.getOr(Dict.make()) - let paymentToken = customerPaymentMethod->getJsonFromDict("payment_token", JSON.Encode.null) - let paymentMethod = - customerPaymentMethod->getJsonFromDict("payment_method", JSON.Encode.null) - let paymentMethodType = - customerPaymentMethod->getJsonFromDict("payment_method_type", JSON.Encode.null) - - let confirmParams = - payload - ->JSON.Decode.object - ->Option.flatMap(x => x->Dict.get("confirmParams")) - ->Option.getOr(JSON.Encode.null) - - let redirect = - payload - ->JSON.Decode.object - ->Option.flatMap(x => x->Dict.get("redirect")) - ->Option.flatMap(JSON.Decode.string) - ->Option.getOr("if_required") - - let returnUrl = - confirmParams - ->JSON.Decode.object - ->Option.flatMap(x => x->Dict.get("return_url")) - ->Option.flatMap(JSON.Decode.string) - ->Option.getOr("") - - let confirmParam: ConfirmType.confirmParams = { - return_url: returnUrl, - publishableKey, - redirect, - } - - let paymentIntentID = String.split(clientSecret, "_secret_")[0]->Option.getOr("") - let endpoint = ApiEndpoint.getApiEndPoint( - ~publishableKey=confirmParam.publishableKey, - ~isConfirmCall=true, - (), - ) - let uri = `${endpoint}/payments/${paymentIntentID}/confirm` - let headers = [ - ("Content-Type", "application/json"), - ("api-key", confirmParam.publishableKey), - ] - - let paymentType: PaymentHelpers.payment = switch paymentMethodType - ->JSON.Decode.string - ->Option.getOr("") { - | "apple_pay" => Applepay - | "google_pay" => Gpay - | "debit" - | "credit" - | "" => - Card - | _ => Other - } - - let broswerInfo = BrowserSpec.broswerInfo() - - let body = [ - ("client_secret", clientSecret->JSON.Encode.string), - ("payment_method", paymentMethod), - ("payment_token", paymentToken), - ("payment_method_type", paymentMethodType), - ] - - let bodyStr = body->Array.concat(broswerInfo)->getJsonFromArrayOfJson->JSON.stringify - - PaymentHelpers.intentCall( - ~fetchApi, - ~uri, - ~headers, - ~bodyStr, - ~confirmParam: ConfirmType.confirmParams, - ~clientSecret, - ~optLogger=Some(logger), - ~handleUserError=false, - ~paymentType, - ~iframeId="", - ~fetchMethod=#POST, - ~setIsManualRetryEnabled={_ => ()}, - ~switchToCustomPod=false, - ~sdkHandleOneClickConfirmPayment=false, - ~counter=0, - ~isPaymentSession=true, - (), - ) + let getCustomerLastUsedPaymentMethodData = () => { + let customerPaymentMethodsCopy = customerDetailsArray->Array.copy + customerPaymentMethodsCopy->Array.sort(sortFunctions) + + switch customerPaymentMethodsCopy->Array.get(0) { + | Some(customerLastPaymentUsed) => customerLastPaymentUsed + | None => paymentNotExist(~message="No recent payments found for this customer.") } + } + + let confirmCallForParticularPaymentObject = (~paymentMethodObject, ~payload) => { + let customerPaymentMethod = paymentMethodObject->getDictFromJson + + let paymentToken = customerPaymentMethod->getJsonFromDict("payment_token", JSON.Encode.null) + + let paymentMethod = customerPaymentMethod->getJsonFromDict("payment_method", JSON.Encode.null) + + let paymentMethodType = + customerPaymentMethod->getJsonFromDict("payment_method_type", JSON.Encode.null) - { - getCustomerDefaultSavedPaymentMethodData, - confirmWithCustomerDefaultPaymentMethod, + let confirmParams = + payload + ->getDictFromJson + ->getDictFromDict("confirmParams") + + let redirect = confirmParams->getString("redirect", "if_required") + + let returnUrl = confirmParams->getString("return_url", "") + + let confirmParam: ConfirmType.confirmParams = { + return_url: returnUrl, + publishableKey, + redirect, } - ->Identity.anyTypeToJson - ->resolve - | None => { - let updatedCustomerDetails = - [ - ( - "error", - [ - ("type", "no_data"->JSON.Encode.string), - ( - "message", - "There is no customer default saved payment method data"->JSON.Encode.string, - ), - ]->getJsonFromArrayOfJson, - ), - ]->getJsonFromArrayOfJson - updatedCustomerDetails->resolve + + let paymentIntentID = String.split(clientSecret, "_secret_")[0]->Option.getOr("") + + let endpoint = ApiEndpoint.getApiEndPoint( + ~publishableKey=confirmParam.publishableKey, + ~isConfirmCall=true, + (), + ) + let uri = `${endpoint}/payments/${paymentIntentID}/confirm` + let headers = [("Content-Type", "application/json"), ("api-key", confirmParam.publishableKey)] + + let paymentType: PaymentHelpers.payment = switch paymentMethodType + ->JSON.Decode.string + ->Option.getOr("") { + | "apple_pay" => Applepay + | "google_pay" => Gpay + | "debit" + | "credit" + | "" => + Card + | _ => Other + } + + let broswerInfo = BrowserSpec.broswerInfo() + + let body = [ + ("client_secret", clientSecret->JSON.Encode.string), + ("payment_method", paymentMethod), + ("payment_token", paymentToken), + ("payment_method_type", paymentMethodType), + ] + + let bodyStr = body->Array.concat(broswerInfo)->getJsonFromArrayOfJson->JSON.stringify + + PaymentHelpers.intentCall( + ~fetchApi, + ~uri, + ~headers, + ~bodyStr, + ~confirmParam: ConfirmType.confirmParams, + ~clientSecret, + ~optLogger=Some(logger), + ~handleUserError=false, + ~paymentType, + ~iframeId="", + ~fetchMethod=#POST, + ~setIsManualRetryEnabled={_ => ()}, + ~switchToCustomPod=false, + ~sdkHandleOneClickConfirmPayment=false, + ~counter=0, + ~isPaymentSession=true, + (), + ) + } + + let confirmWithCustomerDefaultPaymentMethod = payload => { + switch customerPaymentMethods->Array.get(0) { + | Some(customerDefaultPaymentMethod) => + confirmCallForParticularPaymentObject( + ~paymentMethodObject=customerDefaultPaymentMethod, + ~payload, + ) + | None => paymentNotExist()->resolve } } + + let confirmWithLastUsedPaymentMethod = payload => { + let customerPaymentMethodsCopy = customerDetailsArray->Array.copy + customerPaymentMethodsCopy->Array.sort(sortFunctions) + + switch customerPaymentMethodsCopy->Array.get(0) { + | Some(customerLastPaymentUsed) => + confirmCallForParticularPaymentObject( + ~paymentMethodObject=customerLastPaymentUsed, + ~payload, + ) + | None => paymentNotExist(~message="No recent payments found for this customer.")->resolve + } + } + + { + getCustomerDefaultSavedPaymentMethodData, + getCustomerLastUsedPaymentMethodData, + confirmWithCustomerDefaultPaymentMethod, + confirmWithLastUsedPaymentMethod, + } + ->Identity.anyTypeToJson + ->resolve }) ->catch(err => { let exceptionMessage = err->formatException->JSON.stringify diff --git a/src/orca-loader/Types.res b/src/orca-loader/Types.res index ced9a31e4..8d396c99a 100644 --- a/src/orca-loader/Types.res +++ b/src/orca-loader/Types.res @@ -41,7 +41,9 @@ type element = { type getCustomerSavedPaymentMethods = { getCustomerDefaultSavedPaymentMethodData: unit => JSON.t, + getCustomerLastUsedPaymentMethodData: unit => JSON.t, confirmWithCustomerDefaultPaymentMethod: JSON.t => Promise.t, + confirmWithLastUsedPaymentMethod: JSON.t => Promise.t, } type initPaymentSession = {getCustomerSavedPaymentMethods: unit => Promise.t} @@ -122,10 +124,18 @@ let getCustomerDefaultSavedPaymentMethodData = () => { JSON.Encode.null } +let getCustomerLastUsedPaymentMethodData = () => { + JSON.Encode.null +} + let confirmWithCustomerDefaultPaymentMethod = _confirmParams => { Promise.resolve(Dict.make()->JSON.Encode.object) } +let confirmWithLastUsedPaymentMethod = _confirmParams => { + Promise.resolve(Dict.make()->JSON.Encode.object) +} + let defaultGetCustomerSavedPaymentMethods = () => { // TODO: After rescript migration to v11, add this without TAG using enums // Promise.resolve({ From b02a25c410b62ecd7dd112ca6b1b816a9bc4a628 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Thu, 13 Jun 2024 10:27:26 +0000 Subject: [PATCH 06/11] chore(release): 0.64.0 [skip ci] # [0.64.0](https://github.com/juspay/hyperswitch-web/compare/v0.63.0...v0.64.0) (2024-06-13) ### Features * added confirm and get handler for last used payment ([#428](https://github.com/juspay/hyperswitch-web/issues/428)) ([5e46da0](https://github.com/juspay/hyperswitch-web/commit/5e46da0924977fa00ccd5ce716c1ed494076ae7f)) --- CHANGELOG.md | 7 +++++++ package-lock.json | 4 ++-- package.json | 2 +- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3985946be..d2405aee5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +# [0.64.0](https://github.com/juspay/hyperswitch-web/compare/v0.63.0...v0.64.0) (2024-06-13) + + +### Features + +* added confirm and get handler for last used payment ([#428](https://github.com/juspay/hyperswitch-web/issues/428)) ([5e46da0](https://github.com/juspay/hyperswitch-web/commit/5e46da0924977fa00ccd5ce716c1ed494076ae7f)) + # [0.63.0](https://github.com/juspay/hyperswitch-web/compare/v0.62.3...v0.63.0) (2024-06-13) diff --git a/package-lock.json b/package-lock.json index 3a011dea0..3542fd75e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "orca-payment-page", - "version": "0.63.0", + "version": "0.64.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "orca-payment-page", - "version": "0.63.0", + "version": "0.64.0", "hasInstallScript": true, "dependencies": { "@aws-sdk/client-cloudfront": "^3.414.0", diff --git a/package.json b/package.json index ff2c9f6e5..39e78d75b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "orca-payment-page", - "version": "0.63.0", + "version": "0.64.0", "main": "index.js", "private": true, "dependencies": { From b141aedf07e8eff9d6653440631aa193e72db712 Mon Sep 17 00:00:00 2001 From: Pritish Budhiraja Date: Thu, 13 Jun 2024 15:58:40 +0530 Subject: [PATCH 07/11] feat: added prop for displayDefaultSavedPaymentIcon (#434) Co-authored-by: Praful Koppalkar <126236898+prafulkoppalkar@users.noreply.github.com> --- src/Components/SavedCardItem.res | 8 ++++++-- src/Types/PaymentType.res | 4 ++++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/Components/SavedCardItem.res b/src/Components/SavedCardItem.res index 12bb74ca1..940b31aa9 100644 --- a/src/Components/SavedCardItem.res +++ b/src/Components/SavedCardItem.res @@ -11,7 +11,9 @@ let make = ( ~setRequiredFieldsBody, ) => { let {themeObj, config, localeString} = Recoil.useRecoilValueFromAtom(RecoilAtoms.configAtom) - let {hideExpiredPaymentMethods} = Recoil.useRecoilValueFromAtom(RecoilAtoms.optionAtom) + let {hideExpiredPaymentMethods, displayDefaultSavedPaymentIcon} = Recoil.useRecoilValueFromAtom( + RecoilAtoms.optionAtom, + ) let (cardBrand, setCardBrand) = Recoil.useRecoilState(RecoilAtoms.cardBrand) let ( isCVCValid, @@ -116,7 +118,9 @@ let make = ( :
{React.string(paymentMethodType->Utils.snakeToTitleCase)}
} - + diff --git a/src/Types/PaymentType.res b/src/Types/PaymentType.res index a9b3c807c..adf21f04c 100644 --- a/src/Types/PaymentType.res +++ b/src/Types/PaymentType.res @@ -164,6 +164,7 @@ type options = { paymentMethodsHeaderText?: string, savedPaymentMethodsHeaderText?: string, hideExpiredPaymentMethods: bool, + displayDefaultSavedPaymentIcon: bool, } let defaultCardDetails = { scheme: None, @@ -295,6 +296,7 @@ let defaultOptions = { billingAddress: defaultBillingAddress, sdkHandleConfirmPayment: defaultSdkHandleConfirmPayment, hideExpiredPaymentMethods: false, + displayDefaultSavedPaymentIcon: true, } let getLayout = (str, logger) => { switch str { @@ -978,6 +980,7 @@ let itemToObjMapper = (dict, logger) => { "paymentMethodsHeaderText", "savedPaymentMethodsHeaderText", "hideExpiredPaymentMethods", + "displayDefaultSavedPaymentIcon", ], dict, "options", @@ -1019,6 +1022,7 @@ let itemToObjMapper = (dict, logger) => { paymentMethodsHeaderText: ?getOptionString(dict, "paymentMethodsHeaderText"), savedPaymentMethodsHeaderText: ?getOptionString(dict, "savedPaymentMethodsHeaderText"), hideExpiredPaymentMethods: getBool(dict, "hideExpiredPaymentMethods", false), + displayDefaultSavedPaymentIcon: getBool(dict, "displayDefaultSavedPaymentIcon", true), } } From 4897ed7551b15d6e1da7dce4fdb7efe1bb3e6a58 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Thu, 13 Jun 2024 10:30:12 +0000 Subject: [PATCH 08/11] chore(release): 0.65.0 [skip ci] # [0.65.0](https://github.com/juspay/hyperswitch-web/compare/v0.64.0...v0.65.0) (2024-06-13) ### Features * added prop for displayDefaultSavedPaymentIcon ([#434](https://github.com/juspay/hyperswitch-web/issues/434)) ([b141aed](https://github.com/juspay/hyperswitch-web/commit/b141aedf07e8eff9d6653440631aa193e72db712)) --- CHANGELOG.md | 7 +++++++ package-lock.json | 4 ++-- package.json | 2 +- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d2405aee5..b6dc1925b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +# [0.65.0](https://github.com/juspay/hyperswitch-web/compare/v0.64.0...v0.65.0) (2024-06-13) + + +### Features + +* added prop for displayDefaultSavedPaymentIcon ([#434](https://github.com/juspay/hyperswitch-web/issues/434)) ([b141aed](https://github.com/juspay/hyperswitch-web/commit/b141aedf07e8eff9d6653440631aa193e72db712)) + # [0.64.0](https://github.com/juspay/hyperswitch-web/compare/v0.63.0...v0.64.0) (2024-06-13) diff --git a/package-lock.json b/package-lock.json index 3542fd75e..0f02a990a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "orca-payment-page", - "version": "0.64.0", + "version": "0.65.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "orca-payment-page", - "version": "0.64.0", + "version": "0.65.0", "hasInstallScript": true, "dependencies": { "@aws-sdk/client-cloudfront": "^3.414.0", diff --git a/package.json b/package.json index 39e78d75b..b90d8c067 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "orca-payment-page", - "version": "0.64.0", + "version": "0.65.0", "main": "index.js", "private": true, "dependencies": { From 4745fa259ef3398fd0c9a39b12fe622b29a824ca Mon Sep 17 00:00:00 2001 From: ArushKapoorJuspay <121166031+ArushKapoorJuspay@users.noreply.github.com> Date: Thu, 13 Jun 2024 16:30:00 +0530 Subject: [PATCH 09/11] fix: transforming billing and shipping country code to touppercase for applepay (#441) --- src/Utilities/DynamicFieldsUtils.res | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/Utilities/DynamicFieldsUtils.res b/src/Utilities/DynamicFieldsUtils.res index 13b62e520..976d62f7f 100644 --- a/src/Utilities/DynamicFieldsUtils.res +++ b/src/Utilities/DynamicFieldsUtils.res @@ -818,6 +818,9 @@ let getApplePayRequiredFields = ( addressLines->Array.get(index)->Option.getOr("") } + let billingCountryCode = billingContact.countryCode->String.toUpperCase + let shippingCountryCode = shippingContact.countryCode->String.toUpperCase + let fieldVal = switch item.field_type { | FullName | BillingName => @@ -833,11 +836,10 @@ let getApplePayRequiredFields = ( Utils.getStateNameFromStateCodeAndCountry( statesList, billingContact.administrativeArea, - billingContact.countryCode, + billingCountryCode, ) | Country - | AddressCountry(_) => - billingContact.countryCode + | AddressCountry(_) => billingCountryCode | AddressPincode => billingContact.postalCode | Email => shippingContact.emailAddress | PhoneNumber => shippingContact.phoneNumber @@ -849,9 +851,9 @@ let getApplePayRequiredFields = ( Utils.getStateNameFromStateCodeAndCountry( statesList, shippingContact.administrativeArea, - shippingContact.countryCode, + shippingCountryCode, ) - | ShippingAddressCountry(_) => shippingContact.countryCode + | ShippingAddressCountry(_) => shippingCountryCode | ShippingAddressPincode => shippingContact.postalCode | _ => "" } From d923d7f058bc3b4037007cdc20cc4f7b7a44c2a9 Mon Sep 17 00:00:00 2001 From: Pritish Budhiraja Date: Thu, 13 Jun 2024 16:30:33 +0530 Subject: [PATCH 10/11] refactor: sort saved customer methods (#427) --- src/PaymentElement.res | 4 ++++ src/Types/PaymentType.res | 4 ++++ src/Utilities/Utils.res | 10 ++++++++++ 3 files changed, 18 insertions(+) diff --git a/src/PaymentElement.res b/src/PaymentElement.res index 2d6803821..3546bee9e 100644 --- a/src/PaymentElement.res +++ b/src/PaymentElement.res @@ -66,6 +66,10 @@ let make = (~cardProps, ~expiryProps, ~cvcProps, ~paymentType: CardThemeType.mod | None => savedCardsWithoutDefaultPaymentMethod } + finalSavedPaymentMethods->Array.sort((a, b) => + compareLogic(Date.fromString(a.lastUsedAt), Date.fromString(b.lastUsedAt)) + ) + setSavedMethods(_ => finalSavedPaymentMethods) setLoadSavedCards(_ => finalSavedPaymentMethods->Array.length == 0 diff --git a/src/Types/PaymentType.res b/src/Types/PaymentType.res index adf21f04c..7fa528e48 100644 --- a/src/Types/PaymentType.res +++ b/src/Types/PaymentType.res @@ -128,6 +128,7 @@ type customerMethods = { paymentMethodType: option, defaultPaymentMethodSet: bool, requiresCvv: bool, + lastUsedAt: string, } type savedCardsLoadState = LoadingSavedCards | LoadedSavedCards(array, bool) | NoResult(bool) @@ -184,6 +185,7 @@ let defaultCustomerMethods = { paymentMethodType: None, defaultPaymentMethodSet: false, requiresCvv: true, + lastUsedAt: "", } let defaultLayout = { defaultCollapsed: false, @@ -877,6 +879,7 @@ let createCustomerObjArr = dict => { paymentMethodType: getPaymentMethodType(dict), defaultPaymentMethodSet: getBool(dict, "default_payment_method_set", false), requiresCvv: getBool(dict, "requires_cvv", true), + lastUsedAt: getString(dict, "last_used_at", ""), } }) LoadedSavedCards(customerPaymentMethods, isGuestCustomer) @@ -899,6 +902,7 @@ let getCustomerMethods = (dict, str) => { paymentMethodType: getPaymentMethodType(dict), defaultPaymentMethodSet: getBool(dict, "default_payment_method_set", false), requiresCvv: getBool(dict, "requires_cvv", true), + lastUsedAt: getString(dict, "last_used_at", ""), } }) LoadedSavedCards(customerPaymentMethods, false) diff --git a/src/Utilities/Utils.res b/src/Utilities/Utils.res index dd475b9f4..8336197e7 100644 --- a/src/Utilities/Utils.res +++ b/src/Utilities/Utils.res @@ -1283,6 +1283,16 @@ let getStateNameFromStateCodeAndCountry = (list: JSON.t, stateCode: string, coun let removeHyphen = str => str->String.replaceRegExp(%re("/-/g"), "") +let compareLogic = (a, b) => { + if a == b { + 0. + } else if a > b { + -1. + } else { + 1. + } +} + let currencyNetworksDict = [ ("BTC", ["bitcoin", "bnb_smart_chain"]), From ebe60f5e29f507cb47e73b7da451e3f7e71b98af Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Thu, 13 Jun 2024 11:02:05 +0000 Subject: [PATCH 11/11] chore(release): 0.65.1 [skip ci] ## [0.65.1](https://github.com/juspay/hyperswitch-web/compare/v0.65.0...v0.65.1) (2024-06-13) ### Bug Fixes * transforming billing and shipping country code to touppercase for applepay ([#441](https://github.com/juspay/hyperswitch-web/issues/441)) ([4745fa2](https://github.com/juspay/hyperswitch-web/commit/4745fa259ef3398fd0c9a39b12fe622b29a824ca)) --- CHANGELOG.md | 7 +++++++ package-lock.json | 4 ++-- package.json | 2 +- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b6dc1925b..277aa2771 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## [0.65.1](https://github.com/juspay/hyperswitch-web/compare/v0.65.0...v0.65.1) (2024-06-13) + + +### Bug Fixes + +* transforming billing and shipping country code to touppercase for applepay ([#441](https://github.com/juspay/hyperswitch-web/issues/441)) ([4745fa2](https://github.com/juspay/hyperswitch-web/commit/4745fa259ef3398fd0c9a39b12fe622b29a824ca)) + # [0.65.0](https://github.com/juspay/hyperswitch-web/compare/v0.64.0...v0.65.0) (2024-06-13) diff --git a/package-lock.json b/package-lock.json index 0f02a990a..60c2c1ce4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "orca-payment-page", - "version": "0.65.0", + "version": "0.65.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "orca-payment-page", - "version": "0.65.0", + "version": "0.65.1", "hasInstallScript": true, "dependencies": { "@aws-sdk/client-cloudfront": "^3.414.0", diff --git a/package.json b/package.json index b90d8c067..feb42c94d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "orca-payment-page", - "version": "0.65.0", + "version": "0.65.1", "main": "index.js", "private": true, "dependencies": {