From 01db104a2512e99eb38305751a9e9395e0812940 Mon Sep 17 00:00:00 2001 From: sakksham7 <130480324+sakksham7@users.noreply.github.com> Date: Tue, 26 Nov 2024 16:52:13 +0530 Subject: [PATCH 01/22] feat: samsung pay added (#806) Co-authored-by: Pritish Budhiraja --- src/CardUtils.res | 6 +- src/Components/SurchargeUtils.res | 2 + src/LoaderController.res | 5 + src/Payments/GPay.res | 4 +- src/Payments/KlarnaSDK.res | 2 +- src/Payments/PayPal.res | 4 +- src/Payments/PaymentRequestButtonElement.res | 19 +- src/Payments/PaypalSDK.res | 4 +- src/Payments/SamsungPayComponent.res | 105 +++++++++++ src/RenderPaymentMethods.res | 1 + src/Types/CardThemeType.res | 2 + src/Types/PaymentModeType.res | 3 + src/Types/PaymentType.res | 173 ++++++++++--------- src/Types/SamsungPayType.res | 46 +++++ src/Types/SessionsType.res | 15 +- src/Utilities/PaymentBody.res | 12 ++ src/Utilities/PaymentHelpers.res | 1 + src/Utilities/PaymentHelpersTypes.res | 11 +- src/Utilities/PaymentUtils.res | 1 - src/Utilities/RecoilAtoms.res | 3 + src/Utilities/SamsungPayHelpers.res | 60 +++++++ src/Utilities/Utils.res | 3 + src/hyper-loader/Elements.res | 131 ++++++++++++-- src/hyper-loader/Hyper.res | 12 ++ 24 files changed, 501 insertions(+), 124 deletions(-) create mode 100644 src/Payments/SamsungPayComponent.res create mode 100644 src/Types/SamsungPayType.res create mode 100644 src/Utilities/SamsungPayHelpers.res diff --git a/src/CardUtils.res b/src/CardUtils.res index 4ed5fe889..3bb719c6f 100644 --- a/src/CardUtils.res +++ b/src/CardUtils.res @@ -362,6 +362,7 @@ let getCardBrandIcon = (cardType, paymentType) => { | GooglePayElement | PayPalElement | ApplePayElement + | SamsungPayElement | KlarnaElement | ExpressCheckoutElement | PaymentMethodsManagement @@ -677,10 +678,7 @@ let getCardBrandFromStates = (cardBrand, cardScheme, showFields) => { !showFields ? cardScheme : cardBrand } -let getCardBrandInvalidError = ( - ~cardNumber, - ~localeString: OrcaPaymentPage.LocaleStringTypes.localeStrings, -) => { +let getCardBrandInvalidError = (~cardNumber, ~localeString: LocaleStringTypes.localeStrings) => { switch cardNumber->getCardBrand { | "" => localeString.enterValidCardNumberErrorText | cardBrandValue => localeString.cardBrandConfiguredErrorText(cardBrandValue) diff --git a/src/Components/SurchargeUtils.res b/src/Components/SurchargeUtils.res index e97445d4b..ab6cc6774 100644 --- a/src/Components/SurchargeUtils.res +++ b/src/Components/SurchargeUtils.res @@ -4,6 +4,7 @@ type oneClickWallets = { } let oneClickWallets = [ {paymentMethodType: "apple_pay", displayName: "ApplePay"}, + {paymentMethodType: "samsung_pay", displayName: "SamsungPay"}, {paymentMethodType: "paypal", displayName: "Paypal"}, {paymentMethodType: "google_pay", displayName: "GooglePay"}, {paymentMethodType: "klarna", displayName: "Klarna"}, @@ -23,6 +24,7 @@ let useSurchargeDetailsForOneClickWallets = (~paymentMethodListValue) => { oneClickWallets->Array.reduce([], (acc, wallet) => { let (isWalletBtnRendered, paymentMethod) = switch wallet.paymentMethodType { | "apple_pay" => (areOneClickWalletsRendered.isApplePay, "wallet") + | "samsung_pay" => (areOneClickWalletsRendered.isSamsungPay, "wallet") | "paypal" => (areOneClickWalletsRendered.isPaypal, "wallet") | "google_pay" => (areOneClickWalletsRendered.isGooglePay, "wallet") | "klarna" => (areOneClickWalletsRendered.isKlarna, "pay_later") diff --git a/src/LoaderController.res b/src/LoaderController.res index 57b6d4b89..b2a35c77f 100644 --- a/src/LoaderController.res +++ b/src/LoaderController.res @@ -14,6 +14,7 @@ let make = (~children, ~paymentMode, ~setIntegrateErrorError, ~logger, ~initTime let setCustomPodUri = Recoil.useSetRecoilState(customPodUri) let setIsGooglePayReady = Recoil.useSetRecoilState(isGooglePayReady) let setIsApplePayReady = Recoil.useSetRecoilState(isApplePayReady) + let setIsSamsungPayReady = Recoil.useSetRecoilState(isSamsungPayReady) let (divH, setDivH) = React.useState(_ => 0.0) let (launchTime, setLaunchTime) = React.useState(_ => 0.0) let {showCardFormByDefault, paymentMethodOrder} = optionsPayment @@ -96,6 +97,7 @@ let make = (~children, ~paymentMode, ~setIntegrateErrorError, ~logger, ~initTime | GooglePayElement | PayPalElement | ApplePayElement + | SamsungPayElement | KlarnaElement | PazeElement | ExpressCheckoutElement @@ -385,6 +387,9 @@ let make = (~children, ~paymentMode, ~setIntegrateErrorError, ~logger, ~initTime dict->getJsonObjectFromDict("isReadyToPay")->JSON.Decode.bool->Option.getOr(false) ) } + if dict->getDictIsSome("isSamsungPayReady") { + setIsSamsungPayReady(_ => dict->getBool("isSamsungPayReady", false)) + } if ( dict->getDictIsSome("customBackendUrl") && dict diff --git a/src/Payments/GPay.res b/src/Payments/GPay.res index d9e0c69d1..2ea74b97d 100644 --- a/src/Payments/GPay.res +++ b/src/Payments/GPay.res @@ -77,8 +77,8 @@ let make = ( GooglePayHelpers.useHandleGooglePayResponse(~connectors, ~intent, ~isWallet, ~requiredFieldsBody) - let (_, buttonType, _) = options.wallets.style.type_ - let (_, heightType, _, _) = options.wallets.style.height + let (_, buttonType, _, _) = options.wallets.style.type_ + let (_, heightType, _, _, _) = options.wallets.style.height let height = switch heightType { | GooglePay(val) => val | _ => 48 diff --git a/src/Payments/KlarnaSDK.res b/src/Payments/KlarnaSDK.res index ea7ab5303..8cdb4b188 100644 --- a/src/Payments/KlarnaSDK.res +++ b/src/Payments/KlarnaSDK.res @@ -24,7 +24,7 @@ let make = (~sessionObj: SessionsType.token) => { let setAreOneClickWalletsRendered = Recoil.useSetRecoilState(areOneClickWalletsRendered) let (stateJson, setStatesJson) = React.useState(_ => JSON.Encode.null) - let (_, _, _, heightType) = options.wallets.style.height + let (_, _, _, heightType, _) = options.wallets.style.height let height = switch heightType { | Klarna(val) => val | _ => 48 diff --git a/src/Payments/PayPal.res b/src/Payments/PayPal.res index 32e27aaac..0e494e8f3 100644 --- a/src/Payments/PayPal.res +++ b/src/Payments/PayPal.res @@ -22,12 +22,12 @@ let make = (~paymentType, ~walletOptions) => { let isWallet = walletOptions->Array.includes("paypal") let (requiredFieldsBody, setRequiredFieldsBody) = React.useState(_ => Dict.make()) - let (_, _, labelType) = options.wallets.style.type_ + let (_, _, labelType, _) = options.wallets.style.type_ let _label = switch labelType { | Paypal(val) => val->PaypalSDKTypes.getLabel | _ => Paypal->PaypalSDKTypes.getLabel } - let (_, _, heightType, _) = options.wallets.style.height + let (_, _, heightType, _, _) = options.wallets.style.height let height = switch heightType { | Paypal(val) => val | _ => 48 diff --git a/src/Payments/PaymentRequestButtonElement.res b/src/Payments/PaymentRequestButtonElement.res index 7ea122073..04a521a2b 100644 --- a/src/Payments/PaymentRequestButtonElement.res +++ b/src/Payments/PaymentRequestButtonElement.res @@ -1,4 +1,5 @@ -type wallet = GPayWallet | PaypalWallet | ApplePayWallet | KlarnaWallet | PazeWallet | NONE +type wallet = + GPayWallet | PaypalWallet | ApplePayWallet | KlarnaWallet | SamsungPayWallet | PazeWallet | NONE let paymentMode = str => { switch str { | "gpay" @@ -8,6 +9,9 @@ let paymentMode = str => { | "applepay" | "apple_pay" => ApplePayWallet + | "samsungpay" + | "samsung_pay" => + SamsungPayWallet | "klarna" => KlarnaWallet | "paze" => PazeWallet | _ => NONE @@ -18,7 +22,7 @@ module WalletsSaveDetailsText = { @react.component let make = (~paymentType) => { open RecoilAtoms - let {isGooglePay, isApplePay, isPaypal} = Recoil.useRecoilValueFromAtom( + let {isGooglePay, isApplePay, isPaypal, isSamsungPay} = Recoil.useRecoilValueFromAtom( areOneClickWalletsRendered, ) let {localeString} = Recoil.useRecoilValueFromAtom(configAtom) @@ -26,7 +30,7 @@ module WalletsSaveDetailsText = { + (isGooglePay || isApplePay || isPaypal || isSamsungPay)}>
@@ -55,6 +59,9 @@ let make = (~sessions, ~walletOptions, ~paymentType) => { let applePaySessionObj = itemToObjMapper(dict, ApplePayObject) let applePayToken = getPaymentSessionObj(applePaySessionObj.sessionsToken, ApplePay) + let samsungPaySessionObj = itemToObjMapper(dict, SamsungPayObject) + let samsungPayToken = getPaymentSessionObj(samsungPaySessionObj.sessionsToken, SamsungPay) + let googlePayThirdPartySessionObj = itemToObjMapper(dict, GooglePayThirdPartyObject) let googlePayThirdPartyToken = getPaymentSessionObj( googlePayThirdPartySessionObj.sessionsToken, @@ -122,6 +129,12 @@ let make = (~sessions, ~walletOptions, ~paymentType) => { | _ => React.null } + | SamsungPayWallet => + switch samsungPayToken { + | SamsungPayTokenOptional(optToken) => + + | _ => React.null + } | KlarnaWallet => {switch klarnaTokenObj { diff --git a/src/Payments/PaypalSDK.res b/src/Payments/PaypalSDK.res index 5825e5fd6..178526952 100644 --- a/src/Payments/PaypalSDK.res +++ b/src/Payments/PaypalSDK.res @@ -32,8 +32,8 @@ let make = (~sessionObj: SessionsType.token, ~paymentType: CardThemeType.mode) = let (stateJson, setStatesJson) = React.useState(_ => JSON.Encode.null) let options = Recoil.useRecoilValueFromAtom(RecoilAtoms.optionAtom) - let (_, _, buttonType) = options.wallets.style.type_ - let (_, _, heightType, _) = options.wallets.style.height + let (_, _, buttonType, _) = options.wallets.style.type_ + let (_, _, heightType, _, _) = options.wallets.style.height let buttonStyle = { layout: "vertical", color: options.wallets.style.theme == Outline diff --git a/src/Payments/SamsungPayComponent.res b/src/Payments/SamsungPayComponent.res new file mode 100644 index 000000000..22533b638 --- /dev/null +++ b/src/Payments/SamsungPayComponent.res @@ -0,0 +1,105 @@ +@react.component +let make = (~sessionObj: option, ~walletOptions) => { + open Utils + open RecoilAtoms + + let url = RescriptReactRouter.useUrl() + let isSamsungPayReady = Recoil.useRecoilValueFromAtom(isSamsungPayReady) + let loggerState = Recoil.useRecoilValueFromAtom(loggerAtom) + let options = Recoil.useRecoilValueFromAtom(optionAtom) + let isManualRetryEnabled = Recoil.useRecoilValueFromAtom(isManualRetryEnabled) + let setIsShowOrPayUsing = Recoil.useSetRecoilState(isShowOrPayUsing) + let areOneClickWalletsRendered = Recoil.useSetRecoilState(areOneClickWalletsRendered) + let {publishableKey, iframeId} = Recoil.useRecoilValueFromAtom(keys) + let status = CommonHooks.useScript("https://img.mpay.samsung.com/gsmpi/sdk/samsungpay_web_sdk.js") + let isWallet = walletOptions->Array.includes("samsung_pay") + let componentName = CardUtils.getQueryParamsDictforKey(url.search, "componentName") + let intent = PaymentHelpers.usePaymentIntent(Some(loggerState), Samsungpay) + + let (_, _, _, _, heightType) = options.wallets.style.height + let height = switch heightType { + | SamsungPay(val) => val + | _ => 48 + } + + let getSamsungPaymentsClient = _ => + SamsungPayType.samsung({ + environment: publishableKey->String.startsWith("pk_prd_") ? "PRODUCTION" : "STAGE", + }) + + let onSamsungPaymentButtonClick = _ => { + SamsungPayHelpers.handleSamsungPayClicked( + ~sessionObj=sessionObj->Option.getOr(JSON.Encode.null)->getDictFromJson, + ~componentName, + ~iframeId, + ~readOnly=options.readOnly, + ) + } + + let buttonStyle = { + "onClick": onSamsungPaymentButtonClick, + "buttonStyle": "black", + "type": "buy", + }->Identity.anyTypeToJson + + let addSamsungPayButton = _ => { + let paymentClient = getSamsungPaymentsClient() + let button = paymentClient.createButton(buttonStyle) + let spayWrapper = GooglePayType.getElementById(GooglePayType.document, "samsungpay-container") + spayWrapper.innerHTML = "" + spayWrapper.appendChild(button) + } + + React.useEffect(() => { + if status == "ready" && isSamsungPayReady && isWallet { + setIsShowOrPayUsing(_ => true) + addSamsungPayButton() + } + None + }, (status, sessionObj, isSamsungPayReady)) + + React.useEffect0(() => { + let handleSamsung = (ev: Window.event) => { + let json = ev.data->safeParse + let dict = json->getDictFromJson + if dict->Dict.get("samsungPayResponse")->Option.isSome { + let metadata = dict->getJsonObjectFromDict("samsungPayResponse") + let getBody = SamsungPayHelpers.getSamsungPayBodyFromResponse(~sPayResponse=metadata) + let body = PaymentBody.samsungPayBody( + ~metadata=getBody.paymentMethodData->Identity.anyTypeToJson, + ) + + intent( + ~bodyArr=body, + ~confirmParam={ + return_url: options.wallets.walletReturnUrl, + publishableKey, + }, + ~handleUserError=false, + ~manualRetry=isManualRetryEnabled, + ) + } + if dict->Dict.get("samsungPayError")->Option.isSome { + messageParentWindow([("fullscreen", false->JSON.Encode.bool)]) + } + } + Window.addEventListener("message", handleSamsung) + Some(() => {Window.removeEventListener("message", handleSamsung)}) + }) + + let isRenderSamsungPayButton = isSamsungPayReady && isWallet + + React.useEffect(() => { + areOneClickWalletsRendered(prev => { + ...prev, + isSamsungPay: isRenderSamsungPayButton, + }) + None + }, [isRenderSamsungPayButton]) + +
Int.toString}px`} + id="samsungpay-container" + className={`w-full flex flex-row justify-center rounded-md [&>*]:w-full [&>button]:!bg-contain`} + /> +} diff --git a/src/RenderPaymentMethods.res b/src/RenderPaymentMethods.res index 4efbd2d8d..4296496ce 100644 --- a/src/RenderPaymentMethods.res +++ b/src/RenderPaymentMethods.res @@ -85,6 +85,7 @@ let make = ( | GooglePayElement | PayPalElement | ApplePayElement + | SamsungPayElement | KlarnaElement | PazeElement | ExpressCheckoutElement diff --git a/src/Types/CardThemeType.res b/src/Types/CardThemeType.res index 6a0a5592b..2584d8a68 100644 --- a/src/Types/CardThemeType.res +++ b/src/Types/CardThemeType.res @@ -14,6 +14,7 @@ type mode = | GooglePayElement | PayPalElement | ApplePayElement + | SamsungPayElement | KlarnaElement | PazeElement | ExpressCheckoutElement @@ -104,6 +105,7 @@ let getPaymentMode = val => { | "payPal" => PayPalElement | "applePay" => ApplePayElement | "paymentMethodCollect" => PaymentMethodCollectElement + | "samsungPay" => SamsungPayElement | "klarna" => KlarnaElement | "expressCheckout" => ExpressCheckoutElement | "paze" => PazeElement diff --git a/src/Types/PaymentModeType.res b/src/Types/PaymentModeType.res index 074f872fd..e8a06fd04 100644 --- a/src/Types/PaymentModeType.res +++ b/src/Types/PaymentModeType.res @@ -18,6 +18,7 @@ type payment = | BanContactCard | GooglePay | ApplePay + | SamsungPay | Boleto | PayPal | NONE @@ -43,6 +44,7 @@ let paymentMode = str => { | "bancontact_card" => BanContactCard | "google_pay" => GooglePay | "apple_pay" => ApplePay + | "samsung_pay" => SamsungPay | "boleto" => Boleto | "paypal" => PayPal | _ => NONE @@ -55,6 +57,7 @@ let defaultOrder = [ "google_pay", "paypal", "klarna", + "samsung_pay", "affirm", "afterpay_clearpay", "ach_transfer", diff --git a/src/Types/PaymentType.res b/src/Types/PaymentType.res index 11d4b36f4..346efa081 100644 --- a/src/Types/PaymentType.res +++ b/src/Types/PaymentType.res @@ -60,8 +60,10 @@ type terms = { usBankAccount: showTerms, } type buttonHeight = Default | Custom -type heightType = ApplePay(int) | GooglePay(int) | Paypal(int) | Klarna(int) +type heightType = ApplePay(int) | GooglePay(int) | Paypal(int) | Klarna(int) | SamsungPay(int) type googlePayStyleType = Default | Buy | Donate | Checkout | Subscribe | Book | Pay | Order +type samsungPayStyleType = Buy + type paypalStyleType = Paypal | Checkout | Buynow | Pay | Installment type applePayStyleType = | Default @@ -81,12 +83,13 @@ type styleType = | ApplePay(applePayStyleType) | GooglePay(googlePayStyleType) | Paypal(paypalStyleType) -type styleTypeArray = (styleType, styleType, styleType) + | SamsungPay(samsungPayStyleType) +type styleTypeArray = (styleType, styleType, styleType, styleType) type theme = Dark | Light | Outline type style = { type_: styleTypeArray, theme: theme, - height: (heightType, heightType, heightType, heightType), + height: (heightType, heightType, heightType, heightType, heightType), buttonRadius: int, } type wallets = { @@ -96,6 +99,7 @@ type wallets = { payPal: showType, klarna: showType, paze: showType, + samsungPay: showType, style: style, } type business = {name: string} @@ -273,9 +277,9 @@ let defaultFields = { billingDetails: JSONObject(defaultBilling), } let defaultStyle = { - type_: (ApplePay(Default), GooglePay(Default), Paypal(Paypal)), + type_: (ApplePay(Default), GooglePay(Default), Paypal(Paypal), SamsungPay(Buy)), theme: Light, - height: (ApplePay(48), GooglePay(48), Paypal(48), Klarna(48)), + height: (ApplePay(48), GooglePay(48), Paypal(48), Klarna(48), SamsungPay(48)), buttonRadius: 2, } let defaultWallets = { @@ -285,6 +289,7 @@ let defaultWallets = { payPal: Auto, klarna: Auto, paze: Auto, + samsungPay: Auto, style: defaultStyle, } let defaultBillingAddress = { @@ -467,6 +472,11 @@ let getGooglePayType = str => { GooglePay(Default) } } +let getSamsungPayType = str => { + switch str { + | _ => SamsungPay(Buy) + } +} let getPayPalType = str => { switch str { | "check-out" @@ -505,7 +515,7 @@ let getTypeArray = (str, logger) => { if !Array.includes(goodVals, str) { str->unknownPropValueWarning(goodVals, "options.wallets.style.type", ~logger) } - (str->getApplePayType, str->getGooglePayType, str->getPayPalType) + (str->getApplePayType, str->getGooglePayType, str->getPayPalType, str->getSamsungPayType) } let getShowDetails = (~billingDetails, ~logger) => { @@ -688,86 +698,72 @@ let getTerms = (dict, str, logger) => { }) ->Option.getOr(defaultTerms) } -let getApplePayHeight = (val, logger) => { - let val: heightType = - val >= 45 - ? ApplePay(val) - : { - valueOutRangeWarning( - val, - "options.style.height", - "[h>=45] - ApplePay. Value set to min", - ~logger, - ) - ApplePay(48) - } - val -} -let getGooglePayHeight = (val, logger) => { - let val: heightType = - val >= 48 - ? GooglePay(val) - : { - valueOutRangeWarning( - val, - "options.style.height", - "[h>=48] - GooglePay. Value set to min", - ~logger, - ) - GooglePay(48) - } - val -} -let getPaypalHeight = (val, logger) => { - let val: heightType = - val < 25 - ? { - valueOutRangeWarning( - val, - "options.style.height", - "[25-55] - Paypal. Value set to min", - ~logger, - ) - Paypal(25) - } - : val > 55 - ? { - valueOutRangeWarning( - val, - "options.style.height", - "[25-55] - Paypal. Value set to max", - ~logger, - ) - Paypal(55) - } - : Paypal(val) - val -} -let getKlarnaHeight = (val, logger) => { - let val: heightType = - val < 40 - ? { - valueOutRangeWarning( - val, - "options.style.height", - "[40-60] - Klarna. Value set to min", - ~logger, - ) - Klarna(40) - } - : val > 60 - ? { - valueOutRangeWarning( - val, - "options.style.height", - "[40-60] - Paypal. Value set to max", - ~logger, - ) - Klarna(60) - } - : Klarna(val) - val +let getApplePayHeight: (int, 'a) => heightType = (val, logger) => { + if val >= 45 { + ApplePay(val) + } else { + valueOutRangeWarning( + val, + "options.style.height", + "[h>=45] - ApplePay. Value set to min", + ~logger, + ) + ApplePay(48) + } } + +let getGooglePayHeight: (int, 'a) => heightType = (val, logger) => { + if val >= 45 { + GooglePay(val) + } else { + valueOutRangeWarning( + val, + "options.style.height", + "[h>=45] - GooglePay. Value set to min", + ~logger, + ) + GooglePay(48) + } +} + +let getSamsungPayHeight: (int, 'a) => heightType = (val, logger) => { + if val >= 45 { + SamsungPay(val) + } else { + valueOutRangeWarning( + val, + "options.style.height", + "[h>=45] - SamsungPay. Value set to min", + ~logger, + ) + SamsungPay(48) + } +} + +let getPaypalHeight: (int, 'a) => heightType = (val, logger) => { + if val < 25 { + valueOutRangeWarning(val, "options.style.height", "[25-55] - Paypal. Value set to min", ~logger) + Paypal(25) + } else if val > 55 { + valueOutRangeWarning(val, "options.style.height", "[25-55] - Paypal. Value set to max", ~logger) + Paypal(55) + } else { + Paypal(val) + } +} + +let getKlarnaHeight: (int, 'a) => heightType = (val, logger) => { + if val < 40 { + valueOutRangeWarning(val, "options.style.height", "[40-60] - Klarna. Value set to min", ~logger) + Klarna(40) + } else if val > 60 { + valueOutRangeWarning(val, "options.style.height", "[40-60] - Paypal. Value set to max", ~logger) + Klarna(60) + } else { + Klarna(val) + } +} + let getTheme = (str, logger) => { switch str { | "outline" => Outline @@ -784,6 +780,7 @@ let getHeightArray = (val, logger) => { val->getGooglePayHeight(logger), val->getPaypalHeight(logger), val->getKlarnaHeight(logger), + val->getSamsungPayHeight(logger), ) } let getStyle = (dict, str, logger) => { @@ -808,7 +805,7 @@ let getWallets = (dict, str, logger) => { ->Option.flatMap(JSON.Decode.object) ->Option.map(json => { unknownKeysWarning( - ["applePay", "googlePay", "style", "walletReturnUrl", "payPal", "klarna"], + ["applePay", "googlePay", "style", "walletReturnUrl", "payPal", "klarna", "samsungPay"], json, "options.wallets", ~logger, @@ -836,6 +833,10 @@ let getWallets = (dict, str, logger) => { "options.wallets.paze", logger, ), + samsungPay: getWarningString(json, "samsungPay", "auto", ~logger)->getShowType( + "options.wallets.samsungPay", + logger, + ), style: getStyle(json, "style", logger), } }) diff --git a/src/Types/SamsungPayType.res b/src/Types/SamsungPayType.res new file mode 100644 index 000000000..78a503dbb --- /dev/null +++ b/src/Types/SamsungPayType.res @@ -0,0 +1,46 @@ +type client = { + isReadyToPay: JSON.t => promise, + createButton: JSON.t => Dom.element, + loadPaymentSheet: (JSON.t, JSON.t) => promise, + notify: JSON.t => unit, +} + +type env = {environment: string} + +@new external samsung: env => client = "SamsungPay.PaymentClient" + +type merchant = { + name: string, + url: string, + countryCode: string, +} +type amount = { + option: string, + currency: string, + total: string, +} +type transactionDetail = { + orderNumber: string, + merchant: merchant, + amount: amount, +} +type paymentMethods = { + version: string, + serviceId: string, + protocol: string, + allowedBrands: array, +} + +type threeDS = { + \"type": string, + version: string, + data: string, +} +type paymentMethodData = { + method: string, + recurring_payment: bool, + card_brand: string, + card_last4digits: string, + @as("3_d_s") threeDS: threeDS, +} +type paymentData = {paymentMethodData: paymentMethodData} diff --git a/src/Types/SessionsType.res b/src/Types/SessionsType.res index 07d0396c7..27673c709 100644 --- a/src/Types/SessionsType.res +++ b/src/Types/SessionsType.res @@ -1,8 +1,8 @@ open Utils -type wallet = Gpay | Paypal | Klarna | ApplePay | Paze | NONE - -type tokenCategory = ApplePayObject | GooglePayThirdPartyObject | PazeObject | Others +type wallet = Gpay | Paypal | Klarna | ApplePay | SamsungPay | Paze | NONE +type tokenCategory = + ApplePayObject | GooglePayThirdPartyObject | SamsungPayObject | PazeObject | Others type paymentType = Wallet | Others @@ -30,12 +30,14 @@ type tokenType = | ApplePayToken(array) | GooglePayThirdPartyToken(array) | PazeToken(array) + | SamsungPayToken(array) | OtherToken(array) type optionalTokenType = | ApplePayTokenOptional(option) | GooglePayThirdPartyTokenOptional(option) | PazeTokenOptional(option) + | SamsungPayTokenOptional(option) | OtherTokenOptional(option) type sessions = { @@ -67,6 +69,7 @@ let getWallet = str => { | "apple_pay" => ApplePay | "paypal" => Paypal | "klarna" => Klarna + | "samsung_pay" => SamsungPay | "google_pay" => Gpay | "paze" => Paze | _ => NONE @@ -124,6 +127,11 @@ let itemToObjMapper = (dict, returnType) => { clientSecret: getString(dict, "client_secret", ""), sessionsToken: PazeToken(getSessionsTokenJson(dict, "session_token")), } + | SamsungPayObject => { + paymentId: getString(dict, "payment_id", ""), + clientSecret: getString(dict, "client_secret", ""), + sessionsToken: SamsungPayToken(getSessionsTokenJson(dict, "session_token")), + } | Others => { paymentId: getString(dict, "payment_id", ""), @@ -149,5 +157,6 @@ let getPaymentSessionObj = (tokenType, val) => | GooglePayThirdPartyToken(arr) => GooglePayThirdPartyTokenOptional(getWalletFromTokenType(arr, val)) | PazeToken(arr) => PazeTokenOptional(getWalletFromTokenType(arr, val)) + | SamsungPayToken(arr) => SamsungPayTokenOptional(getWalletFromTokenType(arr, val)) | OtherToken(arr) => OtherTokenOptional(arr->Array.find(item => item.walletName == val)) } diff --git a/src/Utilities/PaymentBody.res b/src/Utilities/PaymentBody.res index 3774f02ac..9b6a9aaab 100644 --- a/src/Utilities/PaymentBody.res +++ b/src/Utilities/PaymentBody.res @@ -386,6 +386,18 @@ let paypalSdkBody = (~token, ~connectors) => [ ), ] +let samsungPayBody = (~metadata) => { + let paymentCredential = [("payment_credential", metadata)]->Utils.getJsonFromArrayOfJson + let spayBody = [("samsung_pay", paymentCredential)]->Utils.getJsonFromArrayOfJson + let paymentMethodData = [("wallet", spayBody)]->Utils.getJsonFromArrayOfJson + + [ + ("payment_method", "wallet"->JSON.Encode.string), + ("payment_method_type", "samsung_pay"->JSON.Encode.string), + ("payment_method_data", paymentMethodData), + ] +} + let gpayBody = (~payObj: GooglePayType.paymentData, ~connectors: array) => { let gPayBody = [ ("payment_method", "wallet"->JSON.Encode.string), diff --git a/src/Utilities/PaymentHelpers.res b/src/Utilities/PaymentHelpers.res index 39fb85d29..259342fac 100644 --- a/src/Utilities/PaymentHelpers.res +++ b/src/Utilities/PaymentHelpers.res @@ -7,6 +7,7 @@ open URLModule let getPaymentType = paymentMethodType => switch paymentMethodType { | "apple_pay" => Applepay + | "samsung_pay" => Samsungpay | "google_pay" => Gpay | "paze" => Paze | "debit" diff --git a/src/Utilities/PaymentHelpersTypes.res b/src/Utilities/PaymentHelpersTypes.res index 64ff04258..614d8ad36 100644 --- a/src/Utilities/PaymentHelpersTypes.res +++ b/src/Utilities/PaymentHelpersTypes.res @@ -1,5 +1,14 @@ type payment = - Card | BankTransfer | BankDebits | KlarnaRedirect | Gpay | Applepay | Paypal | Paze | Other + | Card + | BankTransfer + | BankDebits + | KlarnaRedirect + | Gpay + | Applepay + | Paypal + | Samsungpay + | Paze + | Other type paymentIntent = ( ~handleUserError: bool=?, diff --git a/src/Utilities/PaymentUtils.res b/src/Utilities/PaymentUtils.res index 4a4c8a92a..ed289517f 100644 --- a/src/Utilities/PaymentUtils.res +++ b/src/Utilities/PaymentUtils.res @@ -28,7 +28,6 @@ let paymentListLookupNew = ( "gcash", "momo", "touch_n_go", - "samsung_pay", "mifinity", ] let otherPaymentList = [] diff --git a/src/Utilities/RecoilAtoms.res b/src/Utilities/RecoilAtoms.res index 5281dc20b..b84380843 100644 --- a/src/Utilities/RecoilAtoms.res +++ b/src/Utilities/RecoilAtoms.res @@ -53,6 +53,7 @@ let userPhoneNumber = Recoil.atom( let userCardNickName = Recoil.atom("userCardNickName", defaultFieldValues) let isGooglePayReady = Recoil.atom("isGooglePayReady", false) let isApplePayReady = Recoil.atom("isApplePayReady", false) +let isSamsungPayReady = Recoil.atom("isSamsungPayReady", false) let userCountry = Recoil.atom("userCountry", "") let userBank = Recoil.atom("userBank", "") let userAddressline1 = Recoil.atom("userAddressline1", defaultFieldValues) @@ -84,6 +85,7 @@ type areOneClickWalletsRendered = { isApplePay: bool, isPaypal: bool, isKlarna: bool, + isSamsungPay: bool, } let defaultAreOneClickWalletsRendered = { @@ -91,6 +93,7 @@ let defaultAreOneClickWalletsRendered = { isApplePay: false, isPaypal: false, isKlarna: false, + isSamsungPay: false, } let areOneClickWalletsRendered = Recoil.atom( diff --git a/src/Utilities/SamsungPayHelpers.res b/src/Utilities/SamsungPayHelpers.res new file mode 100644 index 000000000..d00e86e7b --- /dev/null +++ b/src/Utilities/SamsungPayHelpers.res @@ -0,0 +1,60 @@ +open SamsungPayType +open Utils + +let getTransactionDetail = dict => { + let amountDict = dict->getDictFromDict("amount") + let merchantDict = dict->getDictFromDict("merchant") + { + orderNumber: dict->getString("order_number", ""), + amount: { + option: amountDict->getString("option", ""), + currency: amountDict->getString("currency_code", ""), + total: amountDict->getString("total", ""), + }, + merchant: { + name: merchantDict->getString("name", ""), + countryCode: merchantDict->getString("country_code", ""), + url: merchantDict->getString("url", ""), + }, + } +} + +let handleSamsungPayClicked = (~sessionObj, ~componentName, ~iframeId, ~readOnly) => { + messageParentWindow([ + ("fullscreen", true->JSON.Encode.bool), + ("param", "paymentloader"->JSON.Encode.string), + ("iframeId", iframeId->JSON.Encode.string), + ("componentName", componentName->JSON.Encode.string), + ]) + + if !readOnly { + messageParentWindow([ + ("SamsungPayClicked", true->JSON.Encode.bool), + ("SPayPaymentDataRequest", getTransactionDetail(sessionObj)->Identity.anyTypeToJson), + ]) + } +} + +let getPaymentMethodData = dict => { + let threeDSDict = dict->getDictFromDict("3DS") + + { + method: dict->getString("method", ""), + recurring_payment: dict->getBool("recurring_payment", false), + card_brand: dict->getString("card_brand", ""), + card_last4digits: dict->getString("card_last4digits", ""), + threeDS: { + \"type": threeDSDict->getString("type", ""), + version: threeDSDict->getString("version", ""), + data: threeDSDict->getString("data", ""), + }, + } +} + +let itemToObjMapper = dict => { + paymentMethodData: getPaymentMethodData(dict), +} + +let getSamsungPayBodyFromResponse = (~sPayResponse) => { + sPayResponse->getDictFromJson->itemToObjMapper +} diff --git a/src/Utilities/Utils.res b/src/Utilities/Utils.res index 745478b07..b52413668 100644 --- a/src/Utilities/Utils.res +++ b/src/Utilities/Utils.res @@ -1285,6 +1285,7 @@ let getWalletPaymentMethod = (wallets, paymentType: CardThemeType.mode) => { | ApplePayElement => wallets->Array.filter(item => item === "apple_pay") | KlarnaElement => wallets->Array.filter(item => item === "klarna") | PazeElement => wallets->Array.filter(item => item === "paze") + | SamsungPayElement => wallets->Array.filter(item => item === "samsung_pay") | _ => wallets } } @@ -1295,6 +1296,7 @@ let expressCheckoutComponents = [ "applePay", "klarna", "paze", + "samsungPay", "expressCheckout", ] @@ -1317,6 +1319,7 @@ let walletElementPaymentType: array = [ GooglePayElement, PayPalElement, ApplePayElement, + SamsungPayElement, KlarnaElement, PazeElement, ExpressCheckoutElement, diff --git a/src/hyper-loader/Elements.res b/src/hyper-loader/Elements.res index 4eda0f499..49395e7f0 100644 --- a/src/hyper-loader/Elements.res +++ b/src/hyper-loader/Elements.res @@ -101,7 +101,7 @@ let make = ( let preMountLoaderMountedPromise = Promise.make((resolve, _reject) => { let preMountLoaderIframeCallback = (ev: Types.event) => { - let json = ev.data->Identity.anyTypeToJson + let json = ev.data->anyTypeToJson let dict = json->getDictFromJson if dict->Dict.get("preMountLoaderIframeMountedCallback")->Option.isSome { resolve(true->JSON.Encode.bool) @@ -118,7 +118,7 @@ let make = ( let onPlaidCallback = mountedIframeRef => { (ev: Types.event) => { - let json = ev.data->Identity.anyTypeToJson + let json = ev.data->anyTypeToJson let dict = json->getDictFromJson let isPlaidExist = dict->getBool("isPlaid", false) if isPlaidExist { @@ -131,7 +131,7 @@ let make = ( let onPazeCallback = mountedIframeRef => { (event: Types.event) => { - let json = event.data->Identity.anyTypeToJson + let json = event.data->anyTypeToJson let dict = json->getDictFromJson if dict->getBool("isPaze", false) { let componentName = dict->getString("componentName", "payment") @@ -143,7 +143,7 @@ let make = ( let fetchPaymentsList = (mountedIframeRef, componentType) => { let handlePaymentMethodsLoaded = (event: Types.event) => { - let json = event.data->Identity.anyTypeToJson + let json = event.data->anyTypeToJson let dict = json->getDictFromJson let isPaymentMethodsData = dict->getString("data", "") === "payment_methods" if isPaymentMethodsData { @@ -210,7 +210,7 @@ let make = ( ) => { if !disableSavedPaymentMethods { let handleCustomerPaymentMethodsLoaded = (event: Types.event) => { - let json = event.data->Identity.anyTypeToJson + let json = event.data->anyTypeToJson let dict = json->getDictFromJson let isCustomerPaymentMethodsData = dict->getString("data", "") === "customer_payment_methods" @@ -293,6 +293,7 @@ let make = ( | "klarna" | "expressCheckout" | "paze" + | "samsungPay" | "paymentMethodsManagement" | "payment" => () | str => manageErrorWarning(UNKNOWN_KEY, ~dynamicStr=`${str} type in create`, ~logger) @@ -539,7 +540,7 @@ let make = ( } let handleApplePayThirdPartyFlow = (event: Types.event) => { - let json = event.data->Identity.anyTypeToJson + let json = event.data->anyTypeToJson let dict = json->getDictFromJson switch dict->Dict.get("applePayButtonClicked") { | Some(val) => @@ -702,7 +703,7 @@ let make = ( } messageCurrentWindow([ ("submitSuccessful", false->JSON.Encode.bool), - ("error", err->Identity.anyTypeToJson), + ("error", err->anyTypeToJson), ("url", url->JSON.Encode.string), ]) } @@ -727,7 +728,7 @@ let make = ( ->then(json => json->handleRetrievePaymentResponse) ->catch(err => { err->handleErrorResponse - resolve(err->Identity.anyTypeToJson) + resolve(err->anyTypeToJson) }) ->ignore ->resolve @@ -767,10 +768,10 @@ let make = ( } else { messageCurrentWindow([ ("submitSuccessful", false->JSON.Encode.bool), - ("error", err->Identity.anyTypeToJson), + ("error", err->anyTypeToJson), ("url", redirectUrl), ]) - resolve(err->Identity.anyTypeToJson) + resolve(err->anyTypeToJson) } }) ->finally(_ => messageCurrentWindow([("fullscreen", false->JSON.Encode.bool)])) @@ -787,7 +788,7 @@ let make = ( let fetchSessionTokens = mountedIframeRef => { let handleSessionTokensLoaded = (event: Types.event) => { - let json = event.data->Identity.anyTypeToJson + let json = event.data->anyTypeToJson let dict = json->getDictFromJson let sessionTokensData = dict->getString("data", "") === "session_tokens" if sessionTokensData { @@ -827,17 +828,21 @@ let make = ( ->Option.getOr("") x === "google_pay" || x === "googlepay" }) + let samsungPayPresent = sessionsArr->Array.find(item => { + let walletName = item->getDictFromJson->getString("wallet_name", "") + walletName === "samsung_pay" || walletName === "samsungpay" + }) - (json, applePayPresent, googlePayPresent)->resolve + (json, applePayPresent, googlePayPresent, samsungPayPresent)->resolve } ->then(res => { - let (json, applePayPresent, googlePayPresent) = res + let (json, applePayPresent, googlePayPresent, samsungPayPresent) = res if ( componentType->getIsComponentTypeForPaymentElementCreate && applePayPresent->Option.isSome ) { let handleApplePayMessages = (applePayEvent: Types.event) => { - let json = applePayEvent.data->Identity.anyTypeToJson + let json = applePayEvent.data->anyTypeToJson let dict = json->getDictFromJson let componentName = dict->getString("componentName", "payment") @@ -930,10 +935,10 @@ let make = ( let payRequest = GooglePayType.assign( Dict.make()->JSON.Encode.object, - GooglePayType.baseRequest->Identity.anyTypeToJson, + GooglePayType.baseRequest->anyTypeToJson, { "allowedPaymentMethods": gpayobj.allowed_payment_methods->arrayJsonToCamelCase, - }->Identity.anyTypeToJson, + }->anyTypeToJson, ) try { @@ -1034,13 +1039,13 @@ let make = ( "paymentDataCallbacks": { "onPaymentDataChanged": onPaymentDataChanged, }, - }->Identity.anyTypeToJson + }->anyTypeToJson } else { { "environment": publishableKey->String.startsWith("pk_prd_") ? "PRODUCTION" : "TEST", - }->Identity.anyTypeToJson + }->anyTypeToJson } let gPayClient = GooglePayType.google(gpayClientRequest) @@ -1054,7 +1059,7 @@ let make = ( }) ->catch(err => { logger.setLogInfo( - ~value=err->Identity.anyTypeToJson->JSON.stringify, + ~value=err->anyTypeToJson->JSON.stringify, ~eventName=GOOGLE_PAY_FLOW, ~paymentMethod="GOOGLE_PAY", ~logType=DEBUG, @@ -1122,6 +1127,94 @@ let make = ( ~logType=INFO, ) } + if ( + componentType->getIsComponentTypeForPaymentElementCreate && + samsungPayPresent->Option.isSome && + wallets.samsungPay === Auto + ) { + let dict = json->getDictFromJson + let sessionObj = SessionsType.itemToObjMapper(dict, SamsungPayObject) + let samsungPayToken = SessionsType.getPaymentSessionObj( + sessionObj.sessionsToken, + SamsungPay, + ) + let tokenObj = switch samsungPayToken { + | SamsungPayTokenOptional(optToken) => optToken + | _ => None + } + + let sessionObject = + tokenObj + ->Option.flatMap(JSON.Decode.object) + ->Option.getOr(Dict.make()) + + let allowedBrands = + sessionObject + ->getStrArray("allowed_brands") + ->Array.map(str => str->String.toLowerCase) + + let payRequest = { + "version": sessionObject->getString("version", ""), + "allowedBrands": allowedBrands, + "protocol": sessionObject->getString("protocol", ""), + "serviceId": sessionObject->getString("service_id", ""), + }->anyTypeToJson + + try { + let samsungPayClient = SamsungPayType.samsung({ + environment: publishableKey->String.startsWith("pk_prd_") + ? "PRODUCTION" + : "STAGE", + }) + samsungPayClient.isReadyToPay(payRequest) + ->then(res => { + let dict = res->getDictFromJson + let isReadyToPay = dict->getBool("result", false) + let msg = + [("isSamsungPayReady", isReadyToPay->JSON.Encode.bool)]->Dict.fromArray + mountedIframeRef->Window.iframePostMessage(msg) + resolve() + }) + ->catch(_ => resolve()) + ->ignore + + let handleSamsungPayMessages = (event: Types.event) => { + let evJson = event.data->anyTypeToJson + let samsungPayClicked = + evJson + ->getOptionalJsonFromJson("SamsungPayClicked") + ->getBoolFromOptionalJson(false) + + let paymentDataRequest = + evJson + ->getOptionalJsonFromJson("SPayPaymentDataRequest") + ->Option.getOr(JSON.Encode.null) + + if samsungPayClicked && paymentDataRequest !== JSON.Encode.null { + samsungPayClient.loadPaymentSheet(payRequest, paymentDataRequest) + ->then(json => { + let msg = [("samsungPayResponse", json->anyTypeToJson)]->Dict.fromArray + event.source->Window.sendPostMessage(msg) + resolve() + }) + ->catch(err => { + event.source->Window.sendPostMessage( + [("samsungPayError", err->anyTypeToJson)]->Dict.fromArray, + ) + resolve() + }) + ->ignore + } + } + addSmartEventListener( + "message", + handleSamsungPayMessages, + "onSamsungPayMessages", + ) + } catch { + | _ => Console.log("Error loading Samsung Pay") + } + } json->resolve }) diff --git a/src/hyper-loader/Hyper.res b/src/hyper-loader/Hyper.res index eac314c90..e712c61de 100644 --- a/src/hyper-loader/Hyper.res +++ b/src/hyper-loader/Hyper.res @@ -272,6 +272,18 @@ let make = (publishableKey, options: option, analyticsInfo: optionArray.length === 0 + ) { + let samsungPayScriptUrl = "https://img.mpay.samsung.com/gsmpi/sdk/samsungpay_web_sdk.js" + let samsungPayScript = Window.createElement("script") + samsungPayScript->Window.elementSrc(samsungPayScriptUrl) + samsungPayScript->Window.elementOnerror(err => { + Console.log2("ERROR LOADING SAMSUNG PAY SCRIPT", err) + }) + Window.body->Window.appendChild(samsungPayScript) + } + let iframeRef = ref([]) let clientSecret = ref("") let ephemeralKey = ref("") From 814d5a72439be0f799991a04b94c9bef105b14df Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Tue, 26 Nov 2024 11:24:12 +0000 Subject: [PATCH 02/22] chore(release): 0.104.0 [skip ci] # [0.104.0](https://github.com/juspay/hyperswitch-web/compare/v0.103.2...v0.104.0) (2024-11-26) ### Features * samsung pay added ([#806](https://github.com/juspay/hyperswitch-web/issues/806)) ([01db104](https://github.com/juspay/hyperswitch-web/commit/01db104a2512e99eb38305751a9e9395e0812940)) --- 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 7480bae48..5ee7d9184 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +# [0.104.0](https://github.com/juspay/hyperswitch-web/compare/v0.103.2...v0.104.0) (2024-11-26) + + +### Features + +* samsung pay added ([#806](https://github.com/juspay/hyperswitch-web/issues/806)) ([01db104](https://github.com/juspay/hyperswitch-web/commit/01db104a2512e99eb38305751a9e9395e0812940)) + ## [0.103.2](https://github.com/juspay/hyperswitch-web/compare/v0.103.1...v0.103.2) (2024-11-26) ## [0.103.1](https://github.com/juspay/hyperswitch-web/compare/v0.103.0...v0.103.1) (2024-11-25) diff --git a/package-lock.json b/package-lock.json index 357030234..8b4eeec16 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "orca-payment-page", - "version": "0.103.2", + "version": "0.104.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "orca-payment-page", - "version": "0.103.2", + "version": "0.104.0", "hasInstallScript": true, "dependencies": { "@glennsl/rescript-fetch": "^0.2.0", diff --git a/package.json b/package.json index 96b133260..ef9f52009 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "orca-payment-page", - "version": "0.103.2", + "version": "0.104.0", "main": "index.js", "private": true, "dependencies": { From 6c525a62739f808ecb54149cc34ee341d8bed57b Mon Sep 17 00:00:00 2001 From: sakksham7 <130480324+sakksham7@users.noreply.github.com> Date: Mon, 2 Dec 2024 11:59:12 +0530 Subject: [PATCH 03/22] chore: added payment id in query params (#813) --- src/Utilities/PaymentHelpers.res | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/Utilities/PaymentHelpers.res b/src/Utilities/PaymentHelpers.res index 259342fac..9340e6643 100644 --- a/src/Utilities/PaymentHelpers.res +++ b/src/Utilities/PaymentHelpers.res @@ -340,6 +340,7 @@ let rec intentCall = ( let url = makeUrl(confirmParam.return_url) url.searchParams.set("payment_intent_client_secret", clientSecret) url.searchParams.set("status", "failed") + url.searchParams.set("payment_id", clientSecret->getPaymentId) messageParentWindow([("confirmParams", confirmParam->anyTypeToJson)]) if statusCode->String.charAt(0) !== "2" { @@ -485,6 +486,7 @@ let rec intentCall = ( let url = makeUrl(confirmParam.return_url) url.searchParams.set("payment_intent_client_secret", clientSecret) + url.searchParams.set("payment_id", clientSecret->getPaymentId) url.searchParams.set("status", intent.status) let handleProcessingStatus = (paymentType, sdkHandleOneClickConfirmPayment) => { @@ -827,6 +829,7 @@ let rec intentCall = ( try { let url = makeUrl(confirmParam.return_url) url.searchParams.set("payment_intent_client_secret", clientSecret) + url.searchParams.set("payment_id", clientSecret->getPaymentId) url.searchParams.set("status", "failed") let exceptionMessage = err->formatException logApi( From 046f5778a205e0c993c0a0ef7fddab256fe13d6b Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Mon, 2 Dec 2024 06:31:16 +0000 Subject: [PATCH 04/22] chore(release): 0.104.1 [skip ci] ## [0.104.1](https://github.com/juspay/hyperswitch-web/compare/v0.104.0...v0.104.1) (2024-12-02) --- CHANGELOG.md | 2 ++ package-lock.json | 4 ++-- package.json | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5ee7d9184..44f218b84 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,5 @@ +## [0.104.1](https://github.com/juspay/hyperswitch-web/compare/v0.104.0...v0.104.1) (2024-12-02) + # [0.104.0](https://github.com/juspay/hyperswitch-web/compare/v0.103.2...v0.104.0) (2024-11-26) diff --git a/package-lock.json b/package-lock.json index 8b4eeec16..0e463b96f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "orca-payment-page", - "version": "0.104.0", + "version": "0.104.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "orca-payment-page", - "version": "0.104.0", + "version": "0.104.1", "hasInstallScript": true, "dependencies": { "@glennsl/rescript-fetch": "^0.2.0", diff --git a/package.json b/package.json index ef9f52009..5fb846fcc 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "orca-payment-page", - "version": "0.104.0", + "version": "0.104.1", "main": "index.js", "private": true, "dependencies": { From cfa8aa3ddc3150bd16e59922681f4c435b0ee8ce Mon Sep 17 00:00:00 2001 From: sakksham7 <130480324+sakksham7@users.noreply.github.com> Date: Mon, 2 Dec 2024 14:29:56 +0530 Subject: [PATCH 05/22] refactor: moved the expiry message to on change (#814) --- src/Payment.res | 2 ++ src/Payments/CardPayment.res | 3 --- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/Payment.res b/src/Payment.res index 250dfe3a5..a99badcfb 100644 --- a/src/Payment.res +++ b/src/Payment.res @@ -115,6 +115,8 @@ let make = (~paymentMode, ~integrateError, ~logger) => { } setExpiryValid(formattedExpiry, setIsExpiryValid) setCardExpiry(_ => formattedExpiry) + // * Sending card expiry to handle cases where the card expires before the use date. + Utils.messageParentWindow([("expiryDate", formattedExpiry->JSON.Encode.string)]) } let changeCVCNumber = ev => { diff --git a/src/Payments/CardPayment.res b/src/Payments/CardPayment.res index 7af2f4b23..2758da9ee 100644 --- a/src/Payments/CardPayment.res +++ b/src/Payments/CardPayment.res @@ -154,9 +154,6 @@ let make = ( defaultCardBody } if confirm.doSubmit { - // * Sending card expiry to handle cases where the card expires before the use date. - messageParentWindow([("expiryDate", cardExpiry->JSON.Encode.string)]) - let isCardDetailsValid = isCVCValid->Option.getOr(false) && isCardValid->Option.getOr(false) && From 75994d83330987a4967423fddd84954dfee54548 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Mon, 2 Dec 2024 09:01:53 +0000 Subject: [PATCH 06/22] chore(release): 0.104.2 [skip ci] ## [0.104.2](https://github.com/juspay/hyperswitch-web/compare/v0.104.1...v0.104.2) (2024-12-02) --- CHANGELOG.md | 2 ++ package-lock.json | 4 ++-- package.json | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 44f218b84..4cd60ae43 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,5 @@ +## [0.104.2](https://github.com/juspay/hyperswitch-web/compare/v0.104.1...v0.104.2) (2024-12-02) + ## [0.104.1](https://github.com/juspay/hyperswitch-web/compare/v0.104.0...v0.104.1) (2024-12-02) # [0.104.0](https://github.com/juspay/hyperswitch-web/compare/v0.103.2...v0.104.0) (2024-11-26) diff --git a/package-lock.json b/package-lock.json index 0e463b96f..d3c541889 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "orca-payment-page", - "version": "0.104.1", + "version": "0.104.2", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "orca-payment-page", - "version": "0.104.1", + "version": "0.104.2", "hasInstallScript": true, "dependencies": { "@glennsl/rescript-fetch": "^0.2.0", diff --git a/package.json b/package.json index 5fb846fcc..0b960008d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "orca-payment-page", - "version": "0.104.1", + "version": "0.104.2", "main": "index.js", "private": true, "dependencies": { From 3dcf3c7c8d3da2dbac54ea2e00883e3dbc2ecaa6 Mon Sep 17 00:00:00 2001 From: sakksham7 <130480324+sakksham7@users.noreply.github.com> Date: Mon, 2 Dec 2024 15:07:53 +0530 Subject: [PATCH 07/22] refactor: added checks for expiry (#815) --- src/Payment.res | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Payment.res b/src/Payment.res index a99badcfb..e10c1b30e 100644 --- a/src/Payment.res +++ b/src/Payment.res @@ -112,11 +112,12 @@ let make = (~paymentMode, ~integrateError, ~logger) => { let formattedExpiry = val->formatCardExpiryNumber if isExipryValid(formattedExpiry) { handleInputFocus(~currentRef=expiryRef, ~destinationRef=cvcRef) + + // * Sending card expiry to handle cases where the card expires before the use date. + Utils.messageParentWindow([("expiryDate", formattedExpiry->JSON.Encode.string)]) } setExpiryValid(formattedExpiry, setIsExpiryValid) setCardExpiry(_ => formattedExpiry) - // * Sending card expiry to handle cases where the card expires before the use date. - Utils.messageParentWindow([("expiryDate", formattedExpiry->JSON.Encode.string)]) } let changeCVCNumber = ev => { From bf64610c8af37a2e311fb3392a5bf4e303eb8386 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Mon, 2 Dec 2024 09:43:58 +0000 Subject: [PATCH 08/22] chore(release): 0.104.3 [skip ci] ## [0.104.3](https://github.com/juspay/hyperswitch-web/compare/v0.104.2...v0.104.3) (2024-12-02) --- CHANGELOG.md | 2 ++ package-lock.json | 4 ++-- package.json | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4cd60ae43..663736ce5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,5 @@ +## [0.104.3](https://github.com/juspay/hyperswitch-web/compare/v0.104.2...v0.104.3) (2024-12-02) + ## [0.104.2](https://github.com/juspay/hyperswitch-web/compare/v0.104.1...v0.104.2) (2024-12-02) ## [0.104.1](https://github.com/juspay/hyperswitch-web/compare/v0.104.0...v0.104.1) (2024-12-02) diff --git a/package-lock.json b/package-lock.json index d3c541889..cb3adc20f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "orca-payment-page", - "version": "0.104.2", + "version": "0.104.3", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "orca-payment-page", - "version": "0.104.2", + "version": "0.104.3", "hasInstallScript": true, "dependencies": { "@glennsl/rescript-fetch": "^0.2.0", diff --git a/package.json b/package.json index 0b960008d..5fddcd178 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "orca-payment-page", - "version": "0.104.2", + "version": "0.104.3", "main": "index.js", "private": true, "dependencies": { From 00e8562b97c20ed02dc86eaf139ffafb822be075 Mon Sep 17 00:00:00 2001 From: sakksham7 <130480324+sakksham7@users.noreply.github.com> Date: Tue, 3 Dec 2024 16:46:54 +0530 Subject: [PATCH 09/22] fix: show card form by default rendering issue (#817) --- src/PaymentElement.res | 19 ++++++++++++++----- src/Utilities/PaymentUtils.res | 1 + 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/src/PaymentElement.res b/src/PaymentElement.res index d5fd4364a..e97420f6e 100644 --- a/src/PaymentElement.res +++ b/src/PaymentElement.res @@ -168,9 +168,12 @@ let make = (~cardProps, ~expiryProps, ~cvcProps, ~paymentType: CardThemeType.mod | Loaded(paymentlist) => let plist = paymentlist->getDictFromJson->PaymentMethodsRecord.itemToObjMapper - setPaymentOptions(_ => { - paymentOptionsList - }) + setPaymentOptions(_ => + [ + ...showCardFormByDefault && checkPriorityList(paymentMethodOrder) ? ["card"] : [], + ...paymentOptionsList, + ]->removeDuplicate + ) setWalletOptions(_ => walletList) setPaymentMethodListValue(_ => plist) showCardFormByDefault @@ -199,7 +202,7 @@ let make = (~cardProps, ~expiryProps, ~cvcProps, ~paymentType: CardThemeType.mod | _ => () } None - }, (paymentMethodList, walletList, paymentOptionsList, actualList)) + }, (paymentMethodList, walletList, paymentOptionsList, actualList, showCardFormByDefault)) React.useEffect(() => { switch sessionsObj { | Loaded(ssn) => setSessions(_ => ssn) @@ -275,7 +278,13 @@ let make = (~cardProps, ~expiryProps, ~cvcProps, ~paymentType: CardThemeType.mod } ) None - }, (layoutClass.defaultCollapsed, paymentOptions, paymentMethodList, selectedOption)) + }, ( + layoutClass.defaultCollapsed, + paymentOptions, + paymentMethodList, + selectedOption, + showCardFormByDefault, + )) let checkRenderOrComp = () => { walletOptions->Array.includes("paypal") || isShowOrPayUsing } diff --git a/src/Utilities/PaymentUtils.res b/src/Utilities/PaymentUtils.res index ed289517f..cb1c91bfb 100644 --- a/src/Utilities/PaymentUtils.res +++ b/src/Utilities/PaymentUtils.res @@ -453,6 +453,7 @@ let useGetPaymentMethodList = (~paymentOptions, ~paymentType, ~sessions) => { areAllGooglePayRequiredFieldsPrefilled, isApplePayReady, isGooglePayReady, + showCardFormByDefault, )) } From 3706cd1f9f067d86aeab50425c71dc5d61370fec Mon Sep 17 00:00:00 2001 From: sakksham7 <130480324+sakksham7@users.noreply.github.com> Date: Tue, 3 Dec 2024 16:47:18 +0530 Subject: [PATCH 10/22] chore: added prod env in samsung pay always (#819) Co-authored-by: Pritish Budhiraja --- src/Payment.res | 3 +-- src/Payments/SamsungPayComponent.res | 2 +- src/hyper-loader/Elements.res | 4 +--- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/src/Payment.res b/src/Payment.res index e10c1b30e..19028b56f 100644 --- a/src/Payment.res +++ b/src/Payment.res @@ -11,14 +11,13 @@ let setUserError = message => { @react.component let make = (~paymentMode, ~integrateError, ~logger) => { let {localeString} = Recoil.useRecoilValueFromAtom(configAtom) - let keys = Recoil.useRecoilValueFromAtom(keys) + let {iframeId} = Recoil.useRecoilValueFromAtom(keys) let cardScheme = Recoil.useRecoilValueFromAtom(cardBrand) let showFields = Recoil.useRecoilValueFromAtom(showCardFieldsAtom) let selectedOption = Recoil.useRecoilValueFromAtom(selectedOptionAtom) let isManualRetryEnabled = Recoil.useRecoilValueFromAtom(isManualRetryEnabled) let paymentToken = Recoil.useRecoilValueFromAtom(paymentTokenAtom) let paymentMethodListValue = Recoil.useRecoilValueFromAtom(PaymentUtils.paymentMethodListValue) - let {iframeId} = keys let (cardNumber, setCardNumber) = React.useState(_ => "") let (cardExpiry, setCardExpiry) = React.useState(_ => "") diff --git a/src/Payments/SamsungPayComponent.res b/src/Payments/SamsungPayComponent.res index 22533b638..72560487b 100644 --- a/src/Payments/SamsungPayComponent.res +++ b/src/Payments/SamsungPayComponent.res @@ -24,7 +24,7 @@ let make = (~sessionObj: option, ~walletOptions) => { let getSamsungPaymentsClient = _ => SamsungPayType.samsung({ - environment: publishableKey->String.startsWith("pk_prd_") ? "PRODUCTION" : "STAGE", + environment: "PRODUCTION", }) let onSamsungPaymentButtonClick = _ => { diff --git a/src/hyper-loader/Elements.res b/src/hyper-loader/Elements.res index 49395e7f0..c32755c67 100644 --- a/src/hyper-loader/Elements.res +++ b/src/hyper-loader/Elements.res @@ -1162,9 +1162,7 @@ let make = ( try { let samsungPayClient = SamsungPayType.samsung({ - environment: publishableKey->String.startsWith("pk_prd_") - ? "PRODUCTION" - : "STAGE", + environment: "PRODUCTION", }) samsungPayClient.isReadyToPay(payRequest) ->then(res => { From a07be05decaa4c3ae3e26786af30efab09e0a786 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Tue, 3 Dec 2024 11:34:19 +0000 Subject: [PATCH 11/22] chore(release): 0.104.4 [skip ci] ## [0.104.4](https://github.com/juspay/hyperswitch-web/compare/v0.104.3...v0.104.4) (2024-12-03) ### Bug Fixes * show card form by default rendering issue ([#817](https://github.com/juspay/hyperswitch-web/issues/817)) ([00e8562](https://github.com/juspay/hyperswitch-web/commit/00e8562b97c20ed02dc86eaf139ffafb822be075)) --- 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 663736ce5..b0802d4d3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## [0.104.4](https://github.com/juspay/hyperswitch-web/compare/v0.104.3...v0.104.4) (2024-12-03) + + +### Bug Fixes + +* show card form by default rendering issue ([#817](https://github.com/juspay/hyperswitch-web/issues/817)) ([00e8562](https://github.com/juspay/hyperswitch-web/commit/00e8562b97c20ed02dc86eaf139ffafb822be075)) + ## [0.104.3](https://github.com/juspay/hyperswitch-web/compare/v0.104.2...v0.104.3) (2024-12-02) ## [0.104.2](https://github.com/juspay/hyperswitch-web/compare/v0.104.1...v0.104.2) (2024-12-02) diff --git a/package-lock.json b/package-lock.json index cb3adc20f..049c48880 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "orca-payment-page", - "version": "0.104.3", + "version": "0.104.4", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "orca-payment-page", - "version": "0.104.3", + "version": "0.104.4", "hasInstallScript": true, "dependencies": { "@glennsl/rescript-fetch": "^0.2.0", diff --git a/package.json b/package.json index 5fddcd178..a3e089528 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "orca-payment-page", - "version": "0.104.3", + "version": "0.104.4", "main": "index.js", "private": true, "dependencies": { From b0338ed5f54da7d5511d4ade9d65c426521ab86b Mon Sep 17 00:00:00 2001 From: sakksham7 <130480324+sakksham7@users.noreply.github.com> Date: Tue, 3 Dec 2024 17:08:46 +0530 Subject: [PATCH 12/22] chore: loader after closing paze full screen iframe (#820) --- src/Payments/PazeButton.res | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/Payments/PazeButton.res b/src/Payments/PazeButton.res index e0dcd5cd8..9fe799f0e 100644 --- a/src/Payments/PazeButton.res +++ b/src/Payments/PazeButton.res @@ -45,6 +45,11 @@ let make = (~token: SessionsType.token) => { let dict = json->Utils.getDictFromJson->getDictFromDict("data") if dict->getBool("isPaze", false) { setShowLoader(_ => false) + messageParentWindow([ + ("fullscreen", true->JSON.Encode.bool), + ("param", "paymentloader"->JSON.Encode.string), + ("iframeId", iframeId->JSON.Encode.string), + ]) if dict->getOptionString("completeResponse")->Option.isSome { let completeResponse = dict->getString("completeResponse", "") intent( From 11f0b45e26eb6d4c053daccd4fa253a713b1230e Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Tue, 3 Dec 2024 11:51:39 +0000 Subject: [PATCH 13/22] chore(release): 0.104.5 [skip ci] ## [0.104.5](https://github.com/juspay/hyperswitch-web/compare/v0.104.4...v0.104.5) (2024-12-03) --- CHANGELOG.md | 2 ++ package-lock.json | 4 ++-- package.json | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b0802d4d3..7b24ac185 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,5 @@ +## [0.104.5](https://github.com/juspay/hyperswitch-web/compare/v0.104.4...v0.104.5) (2024-12-03) + ## [0.104.4](https://github.com/juspay/hyperswitch-web/compare/v0.104.3...v0.104.4) (2024-12-03) diff --git a/package-lock.json b/package-lock.json index 049c48880..097deea68 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "orca-payment-page", - "version": "0.104.4", + "version": "0.104.5", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "orca-payment-page", - "version": "0.104.4", + "version": "0.104.5", "hasInstallScript": true, "dependencies": { "@glennsl/rescript-fetch": "^0.2.0", diff --git a/package.json b/package.json index a3e089528..381361ed8 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "orca-payment-page", - "version": "0.104.4", + "version": "0.104.5", "main": "index.js", "private": true, "dependencies": { From 9cc35447dd3ddc66ecca023c073c4482ecc5eb13 Mon Sep 17 00:00:00 2001 From: Pritish Budhiraja Date: Wed, 4 Dec 2024 14:34:06 +0530 Subject: [PATCH 14/22] chore: cardNumberLabel change for zh - locale (#821) --- src/LocaleStrings/ChineseLocale.res | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/LocaleStrings/ChineseLocale.res b/src/LocaleStrings/ChineseLocale.res index 4115df3f4..31d1471e2 100644 --- a/src/LocaleStrings/ChineseLocale.res +++ b/src/LocaleStrings/ChineseLocale.res @@ -1,7 +1,7 @@ let localeStrings: LocaleStringTypes.localeStrings = { locale: `zh`, localeDirection: `ltr`, - cardNumberLabel: `卡号`, + cardNumberLabel: `卡號`, inValidCardErrorText: `卡号无效。`, inCompleteCVCErrorText: `您的卡片安全码不完整。`, inCompleteExpiryErrorText: `您的卡片到期日期不完整。`, From 10aedba0ce3e01248c817466e7ab55dd1c5a4bcf Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Wed, 4 Dec 2024 09:06:19 +0000 Subject: [PATCH 15/22] chore(release): 0.104.6 [skip ci] ## [0.104.6](https://github.com/juspay/hyperswitch-web/compare/v0.104.5...v0.104.6) (2024-12-04) --- CHANGELOG.md | 2 ++ package-lock.json | 4 ++-- package.json | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7b24ac185..22b5c5fb0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,5 @@ +## [0.104.6](https://github.com/juspay/hyperswitch-web/compare/v0.104.5...v0.104.6) (2024-12-04) + ## [0.104.5](https://github.com/juspay/hyperswitch-web/compare/v0.104.4...v0.104.5) (2024-12-03) ## [0.104.4](https://github.com/juspay/hyperswitch-web/compare/v0.104.3...v0.104.4) (2024-12-03) diff --git a/package-lock.json b/package-lock.json index 097deea68..36be6536b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "orca-payment-page", - "version": "0.104.5", + "version": "0.104.6", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "orca-payment-page", - "version": "0.104.5", + "version": "0.104.6", "hasInstallScript": true, "dependencies": { "@glennsl/rescript-fetch": "^0.2.0", diff --git a/package.json b/package.json index 381361ed8..57cb126e8 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "orca-payment-page", - "version": "0.104.5", + "version": "0.104.6", "main": "index.js", "private": true, "dependencies": { From 27079236edef9bdd776753b67a70c474a794dd72 Mon Sep 17 00:00:00 2001 From: Debarati Ghatak <88573135+cookieg13@users.noreply.github.com> Date: Wed, 4 Dec 2024 22:38:24 +0530 Subject: [PATCH 16/22] feat: add traditional chinese locale (#822) --- src/LocaleStrings/LocaleStringHelper.res | 1 + src/LocaleStrings/LocaleStringTypes.res | 2 +- .../TraditionalChineseLocale.res | 154 ++++++++++++++++++ 3 files changed, 156 insertions(+), 1 deletion(-) create mode 100644 src/LocaleStrings/TraditionalChineseLocale.res diff --git a/src/LocaleStrings/LocaleStringHelper.res b/src/LocaleStrings/LocaleStringHelper.res index 7b63c2058..002f81dbb 100644 --- a/src/LocaleStrings/LocaleStringHelper.res +++ b/src/LocaleStrings/LocaleStringHelper.res @@ -17,6 +17,7 @@ let mapLocalStringToTypeLocale = val => { | "sv" => SV | "ru" => RU | "zh" => ZH + | "zh-Hant" => ZH_HANT | "en" | _ => EN diff --git a/src/LocaleStrings/LocaleStringTypes.res b/src/LocaleStrings/LocaleStringTypes.res index 3f605a158..ce4840630 100644 --- a/src/LocaleStrings/LocaleStringTypes.res +++ b/src/LocaleStrings/LocaleStringTypes.res @@ -1,5 +1,5 @@ type locale = - EN | HE | FR | EN_GB | AR | JA | DE | FR_BE | ES | CA | PT | IT | PL | NL | SV | RU | ZH + EN | HE | FR | EN_GB | AR | JA | DE | FR_BE | ES | CA | PT | IT | PL | NL | SV | RU | ZH | ZH_HANT type localeStrings = { locale: string, diff --git a/src/LocaleStrings/TraditionalChineseLocale.res b/src/LocaleStrings/TraditionalChineseLocale.res new file mode 100644 index 000000000..ce1539157 --- /dev/null +++ b/src/LocaleStrings/TraditionalChineseLocale.res @@ -0,0 +1,154 @@ +let localeStrings: LocaleStringTypes.localeStrings = { + locale: `zh-HANT`, + localeDirection: `ltr`, + cardNumberLabel: "卡號", + inValidCardErrorText: "卡號無效。", + inCompleteCVCErrorText: "您的卡片安全碼不完整。", + inCompleteExpiryErrorText: "您的卡片到期日期不完整。", + enterValidCardNumberErrorText: "請輸入有效的卡號。", + pastExpiryErrorText: "您的卡片到期年份已過期。", + poweredBy: "技術支持:Hyperswitch", + validThruText: "有效期限", + sortCodeText: "排序碼", + cvcTextLabel: "安全碼", + line1Label: "地址第一行", + line1Placeholder: "街道地址", + line1EmptyText: "地址第一行不能為空", + line2Label: "地址第二行", + line2Placeholder: "公寓、單元號等(可選)", + line2EmptyText: "地址第二行不能為空", + cityLabel: "城市", + cityEmptyText: "城市不能為空", + postalCodeLabel: "郵遞區號", + postalCodeEmptyText: "郵遞區號不能為空", + postalCodeInvalidText: "無效的郵遞區號", + stateLabel: "州/省", + stateEmptyText: "州/省不能為空", + accountNumberText: "帳戶號碼", + emailLabel: "電子郵件", + ibanEmptyText: "IBAN不能為空", + emailEmptyText: "電子郵件不能為空", + emailInvalidText: "無效的電子郵件地址", + fullNameLabel: "全名", + fullNamePlaceholder: "名字和姓氏", + countryLabel: "國家", + currencyLabel: "貨幣", + bankLabel: "選擇銀行", + redirectText: "提交訂單後,您將被重定向以安全完成購買。", + bankDetailsText: "提交這些詳細信息後,您將獲得銀行帳戶信息以進行付款。請確保記下這些信息。", + orPayUsing: "或使用以下方式付款", + addNewCard: "添加信用卡/借記卡", + useExisitingSavedCards: "使用已保存的信用卡/借記卡", + saveCardDetails: "保存卡片詳細信息", + addBankAccount: "添加銀行帳戶", + achBankDebitTerms: _ => + `您的ACH借記授權現在將被設置,我們會在未來扣款前確認金額並通知您。`, + sepaDebitTerms: str => + `通過提供您的付款信息並確認此授權書,您授權(A)${str}、債權人和/或我們的支付服務提供商向您的銀行發出指令以扣取您的帳戶資金,(B)您的銀行根據${str}的指令扣取您的帳戶資金。作為您的權利的一部分,根據您與銀行的協議條款,您有權向銀行申請退款。退款必須在帳戶扣款日起的8週內申請。您的權利在您可以從銀行獲得的聲明中進行了解釋。`, + becsDebitTerms: `通過提供您的銀行帳戶詳細信息並確認此付款,您同意此直接借記請求和直接借記請求服務協議,並授權Hyperswitch Payments Australia Pty Ltd ACN 160 180 343,直接借記用戶ID號507156(“Hyperswitch”)通過批量電子清算系統(BECS)代表Hyperswitch Payment Widget(“商戶”)從您的帳戶中扣款,金額由商戶另行通知您。您保證您是上述帳戶的持有人或授權簽署人。`, + cardTerms: str => + `通過提供您的卡片信息,您允許${str}根據其條款從您的卡片中扣款以進行未來的付款。`, + payNowButton: "立即付款", + cardNumberEmptyText: "卡號不能為空", + cardExpiryDateEmptyText: "卡片到期日期不能為空", + cvcNumberEmptyText: "安全碼不能為空", + enterFieldsText: "請填寫所有欄位", + enterValidDetailsText: "請輸入有效的詳細信息", + selectPaymentMethodText: "請選擇一種付款方式並重試", + card: "卡片", + surchargeMsgAmount: (currency, str) => <> + {React.string(`此交易將收取附加費${Utils.nbsp}`)} + {React.string(`${currency} ${str}`)} + {React.string(`${Utils.nbsp}的金額`)} + , + surchargeMsgAmountForCard: (currency, str) => <> + {React.string(`此交易將收取最高附加費${Utils.nbsp}`)} + {React.string(`${currency} ${str}`)} + {React.string(`${Utils.nbsp}的金額`)} + , + surchargeMsgAmountForOneClickWallets: "適用額外費用", + billingNameLabel: "帳單姓名", + billingNamePlaceholder: "名字和姓氏", + cardHolderName: "持卡人姓名", + on: "於", + \"and": "及", + nameEmptyText: str => `請提供您的${str}`, + completeNameEmptyText: str => `請提供您的完整${str}`, + billingDetailsText: "帳單詳細信息", + socialSecurityNumberLabel: "社會安全號碼", + saveWalletDetails: "選擇後,錢包詳細信息將被保存", + morePaymentMethods: "更多付款方式", + useExistingPaymentMethods: "使用已保存的付款方式", + cardNickname: "卡片暱稱", + nicknamePlaceholder: "卡片暱稱(可選)", + cardExpiredText: "此卡已過期", + cardHeader: "卡片信息", + cardBrandConfiguredErrorText: str => `${str} 暫時不支援。`, + currencyNetwork: "貨幣網絡", + expiryPlaceholder: "月 / 年", + dateOfBirth: "出生日期", + vpaIdLabel: "虛擬支付地址(VPA)", + vpaIdEmptyText: "虛擬支付地址不能為空", + vpaIdInvalidText: "無效的虛擬支付地址", + dateofBirthRequiredText: "必須提供出生日期", + dateOfBirthInvalidText: "年齡應大於或等於 18 歲", + dateOfBirthPlaceholderText: "輸入出生日期", + formFundsInfoText: "資金將存入此帳戶", + formFundsCreditInfoText: pmLabel => `您的資金將存入選定的 ${pmLabel}。`, + formEditText: "編輯", + formSaveText: "保存", + formSubmitText: "提交", + formSubmittingText: "提交中", + formSubheaderBillingDetailsText: "輸入您的帳單地址", + formSubheaderCardText: "您的卡片詳細信息", + formSubheaderAccountText: pmLabel => `您的 ${pmLabel}`, + formHeaderReviewText: "審核", + formHeaderReviewTabLayoutText: pmLabel => `審核您的 ${pmLabel} 詳細信息`, + formHeaderBankText: bankTransferType => `輸入 ${bankTransferType} 銀行詳細信息`, + formHeaderWalletText: walletTransferType => `輸入${walletTransferType}錢包詳細信息`, + formHeaderEnterCardText: "輸入卡信息", + formHeaderSelectBankText: "選擇一種銀行方法", + formHeaderSelectWalletText: "選擇一個錢包", + formHeaderSelectAccountText: "選擇一個帳戶進行付款", + formFieldACHRoutingNumberLabel: "路由號碼", + formFieldSepaIbanLabel: "國際銀行帳戶號碼 (IBAN)", + formFieldSepaBicLabel: "銀行識別碼 (可選)", + formFieldPixIdLabel: "Pix ID", + formFieldBankAccountNumberLabel: "銀行帳戶號碼", + formFieldPhoneNumberLabel: "電話號碼", + formFieldCountryCodeLabel: "國家代碼 (可選)", + formFieldBankNameLabel: "銀行名稱 (可選)", + formFieldBankCityLabel: "銀行城市 (可選)", + formFieldCardHoldernamePlaceholder: "您的姓名", + formFieldBankNamePlaceholder: "銀行名稱", + formFieldBankCityPlaceholder: "銀行城市", + formFieldEmailPlaceholder: "您的電子郵件", + formFieldPhoneNumberPlaceholder: "您的電話", + formFieldInvalidRoutingNumber: "路由號碼無效。", + infoCardRefId: `參考編號`, + infoCardErrCode: `錯誤代碼`, + infoCardErrMsg: `錯誤訊息`, + infoCardErrReason: `原因`, + linkRedirectionText: seconds => `在 ${seconds->Int.toString} 秒後重新導向 ...`, + linkExpiryInfo: expiry => `鏈接將於 ${expiry} 到期`, + payoutFromText: merchant => `來自 ${merchant} 的付款`, + payoutStatusFailedMessage: `處理您的付款失敗。請聯絡您的服務提供商了解更多詳情。`, + payoutStatusPendingMessage: `您的付款應在 2-3 個工作日內處理。`, + payoutStatusSuccessMessage: `您的付款成功。資金已存入您選擇的付款方式。`, + payoutStatusFailedText: `付款失敗`, + payoutStatusPendingText: `付款處理中`, + payoutStatusSuccessText: `付款成功`, + pixCNPJInvalidText: `無效的 Pix CNPJ`, + pixCNPJEmptyText: `Pix CNPJ 不能為空`, + pixCNPJLabel: `Pix CNPJ`, + pixCNPJPlaceholder: `輸入 Pix CNPJ`, + pixCPFInvalidText: `無效的 Pix CPF`, + pixCPFEmptyText: `Pix CPF 不能為空`, + pixCPFLabel: `Pix CPF`, + pixCPFPlaceholder: `輸入 Pix CPF`, + pixKeyEmptyText: `Pix 金鑰不能為空`, + pixKeyPlaceholder: `輸入 Pix 金鑰`, + pixKeyLabel: `Pix 金鑰`, + invalidCardHolderNameError: `持卡人姓名不能包含數字`, + invalidNickNameError: `暱稱不能包含超過兩個數字`, +} From c53df8b931d05419ab6dd56eb9193d7581bf4e4a Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Wed, 4 Dec 2024 17:10:26 +0000 Subject: [PATCH 17/22] chore(release): 0.105.0 [skip ci] # [0.105.0](https://github.com/juspay/hyperswitch-web/compare/v0.104.6...v0.105.0) (2024-12-04) ### Features * add traditional chinese locale ([#822](https://github.com/juspay/hyperswitch-web/issues/822)) ([2707923](https://github.com/juspay/hyperswitch-web/commit/27079236edef9bdd776753b67a70c474a794dd72)) --- 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 22b5c5fb0..c12e53603 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +# [0.105.0](https://github.com/juspay/hyperswitch-web/compare/v0.104.6...v0.105.0) (2024-12-04) + + +### Features + +* add traditional chinese locale ([#822](https://github.com/juspay/hyperswitch-web/issues/822)) ([2707923](https://github.com/juspay/hyperswitch-web/commit/27079236edef9bdd776753b67a70c474a794dd72)) + ## [0.104.6](https://github.com/juspay/hyperswitch-web/compare/v0.104.5...v0.104.6) (2024-12-04) ## [0.104.5](https://github.com/juspay/hyperswitch-web/compare/v0.104.4...v0.104.5) (2024-12-03) diff --git a/package-lock.json b/package-lock.json index 36be6536b..547f466c3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "orca-payment-page", - "version": "0.104.6", + "version": "0.105.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "orca-payment-page", - "version": "0.104.6", + "version": "0.105.0", "hasInstallScript": true, "dependencies": { "@glennsl/rescript-fetch": "^0.2.0", diff --git a/package.json b/package.json index 57cb126e8..91eff38dc 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "orca-payment-page", - "version": "0.104.6", + "version": "0.105.0", "main": "index.js", "private": true, "dependencies": { From 659b815b1d9ab005eac3993e4bc55174684898cf Mon Sep 17 00:00:00 2001 From: sakksham7 <130480324+sakksham7@users.noreply.github.com> Date: Thu, 5 Dec 2024 13:53:31 +0530 Subject: [PATCH 18/22] chore: logs added for paze and samsung pay (#812) Co-authored-by: Pritish Budhiraja --- Hyperswitch-React-Demo-App/package.json | 1 - Hyperswitch-React-Demo-App/server.js | 43 +++++++++++-------------- src/App.res | 2 +- src/CardTheme.res | 1 + src/Payments/GPay.res | 8 ++++- src/Payments/PaypalSDK.res | 8 ++++- src/Payments/PazeButton.res | 5 +++ src/Payments/PazeWallet.res | 25 ++++++++++---- src/Payments/PlaidSDKIframe.res | 8 ++++- src/Payments/SamsungPayComponent.res | 5 +++ src/Utilities/ApplePayHelpers.res | 14 +++++--- src/Utilities/Utils.res | 4 --- src/hyper-loader/Elements.res | 40 +++++++++++++++++++++-- src/hyper-loader/Hyper.res | 34 ++++++++++++------- src/hyper-log-catcher/HyperLogger.res | 6 ++-- 15 files changed, 143 insertions(+), 61 deletions(-) diff --git a/Hyperswitch-React-Demo-App/package.json b/Hyperswitch-React-Demo-App/package.json index 475db9f9f..1cf703129 100644 --- a/Hyperswitch-React-Demo-App/package.json +++ b/Hyperswitch-React-Demo-App/package.json @@ -4,7 +4,6 @@ "private": true, "dependencies": { "@juspay-tech/hyper-js": "^1.6.0", - "@juspay-tech/hyperswitch-node": "^1.0.1", "@juspay-tech/react-hyper-js": "^1.0.2", "@testing-library/jest-dom": "^5.16.5", "@testing-library/react": "^12.1.5", diff --git a/Hyperswitch-React-Demo-App/server.js b/Hyperswitch-React-Demo-App/server.js index 514948cef..833639ae5 100644 --- a/Hyperswitch-React-Demo-App/server.js +++ b/Hyperswitch-React-Demo-App/server.js @@ -2,14 +2,11 @@ const fetch = require("node-fetch"); const express = require("express"); const { resolve } = require("path"); const dotenv = require("dotenv"); -const hyper = require("@juspay-tech/hyperswitch-node"); dotenv.config({ path: "./.env" }); const app = express(); const PORT = 5252; -const hyperswitch = hyper(process.env.HYPERSWITCH_SECRET_KEY); - function getUrl(envVar, selfHostedValue) { return process.env[envVar] === selfHostedValue ? "" : process.env[envVar]; } @@ -95,7 +92,7 @@ const paymentData = { country_code: "+91", }, }, -} +}; const profileId = process.env.PROFILE_ID; if (profileId) { @@ -122,29 +119,25 @@ app.get("/create-payment-intent", async (_, res) => { }); async function createPaymentIntent(request) { - if (SERVER_URL) { - const url = - process.env.HYPERSWITCH_SERVER_URL_FOR_DEMO_APP || - process.env.HYPERSWITCH_SERVER_URL; - const apiResponse = await fetch(`${url}/payments`, { - method: "POST", - headers: { - "Content-Type": "application/json", - Accept: "application/json", - "api-key": process.env.HYPERSWITCH_SECRET_KEY, - }, - body: JSON.stringify(request), - }); - const paymentIntent = await apiResponse.json(); + const url = + process.env.HYPERSWITCH_SERVER_URL_FOR_DEMO_APP || + process.env.HYPERSWITCH_SERVER_URL; + const apiResponse = await fetch(`${url}/payments`, { + method: "POST", + headers: { + "Content-Type": "application/json", + Accept: "application/json", + "api-key": process.env.HYPERSWITCH_SECRET_KEY, + }, + body: JSON.stringify(request), + }); + const paymentIntent = await apiResponse.json(); - if (paymentIntent.error) { - console.error("Error - ", paymentIntent.error); - throw new Error(paymentIntent?.error?.message ?? "Something went wrong."); - } - return paymentIntent; - } else { - return await hyperswitch?.paymentIntents?.create(request); + if (paymentIntent.error) { + console.error("Error - ", paymentIntent.error); + throw new Error(paymentIntent?.error?.message ?? "Something went wrong."); } + return paymentIntent; } app.listen(PORT, () => { diff --git a/src/App.res b/src/App.res index b1ff97128..aab35134e 100644 --- a/src/App.res +++ b/src/App.res @@ -57,7 +57,7 @@ let make = () => { switch fullscreenMode { | "paymentloader" => | "plaidSDK" => - | "pazeWallet" => + | "pazeWallet" => | "fullscreen" =>
diff --git a/src/CardTheme.res b/src/CardTheme.res index c5cd8eb1d..ebbff5e54 100644 --- a/src/CardTheme.res +++ b/src/CardTheme.res @@ -97,6 +97,7 @@ let getLocaleObject = async string => { | NL => Js.import(DutchLocale.localeStrings) | SV => Js.import(SwedishLocale.localeStrings) | RU => Js.import(RussianLocale.localeStrings) + | ZH_HANT => Js.import(TraditionalChineseLocale.localeStrings) } let awaitedLocaleValue = await promiseLocale diff --git a/src/Payments/GPay.res b/src/Payments/GPay.res index 2ea74b97d..7ec6ec08a 100644 --- a/src/Payments/GPay.res +++ b/src/Payments/GPay.res @@ -190,7 +190,13 @@ let make = ( syncPayment() } } catch { - | _ => logInfo(Console.log("Error in syncing GooglePay Payment")) + | err => + loggerState.setLogError( + ~value="Error in syncing GooglePay Payment", + ~eventName=GOOGLE_PAY_FLOW, + ~internalMetadata=err->formatException->JSON.stringify, + ~paymentMethod="GOOGLE_PAY", + ) } } Window.addEventListener("message", handleGooglePayMessages) diff --git a/src/Payments/PaypalSDK.res b/src/Payments/PaypalSDK.res index 178526952..82abecc8c 100644 --- a/src/Payments/PaypalSDK.res +++ b/src/Payments/PaypalSDK.res @@ -140,7 +140,13 @@ let make = (~sessionObj: SessionsType.token, ~paymentType: CardThemeType.mode) = } } } catch { - | _err => Utils.logInfo(Console.log("Error loading Paypal")) + | err => + loggerState.setLogError( + ~value="Error loading Paypal", + ~eventName=PAYPAL_SDK_FLOW, + ~internalMetadata=err->Utils.formatException->JSON.stringify, + ~paymentMethod="PAYPAL_SDK", + ) } None }, [stateJson]) diff --git a/src/Payments/PazeButton.res b/src/Payments/PazeButton.res index 9fe799f0e..4ffdfa63a 100644 --- a/src/Payments/PazeButton.res +++ b/src/Payments/PazeButton.res @@ -16,6 +16,11 @@ let make = (~token: SessionsType.token) => { let paymentIntentID = clientSecret->Option.getOr("")->getPaymentId let (showLoader, setShowLoader) = React.useState(() => false) let onClick = _ => { + loggerState.setLogInfo( + ~value="Paze SDK Button Clicked", + ~eventName=PAZE_SDK_FLOW, + ~paymentMethod="PAZE", + ) setShowLoader(_ => true) let metadata = [ diff --git a/src/Payments/PazeWallet.res b/src/Payments/PazeWallet.res index 6f70bce85..e96fa21d2 100644 --- a/src/Payments/PazeWallet.res +++ b/src/Payments/PazeWallet.res @@ -4,7 +4,7 @@ open PazeTypes external digitalWalletSdk: digitalWalletSdk = "DIGITAL_WALLET_SDK" @react.component -let make = () => { +let make = (~logger: HyperLogger.loggerMake) => { open Promise open Utils @@ -97,7 +97,13 @@ let make = () => { resolve() } catch { - | _ => + | err => + logger.setLogError( + ~value=err->formatException->JSON.stringify, + ~eventName=PAZE_SDK_FLOW, + ~paymentMethod="PAZE", + ~logType=ERROR, + ) messageParentWindow([ ("fullscreen", false->JSON.Encode.bool), ("isPaze", true->JSON.Encode.bool), @@ -107,14 +113,21 @@ let make = () => { resolve() } } - + logger.setLogInfo(~value="PAZE SDK Script Loading", ~eventName=PAZE_SDK_FLOW) let pazeScript = Window.createElement("script") pazeScript->Window.elementSrc(pazeScriptURL) pazeScript->Window.elementOnerror(exn => { - let err = exn->Identity.anyTypeToJson->JSON.stringify - Console.log2("PAZE --- errrorrr", err) + logger.setLogError( + ~value=`Error During Loading PAZE SDK Script: ${exn + ->Identity.anyTypeToJson + ->JSON.stringify}`, + ~eventName=PAZE_SDK_FLOW, + ) + }) + pazeScript->Window.elementOnload(_ => { + logger.setLogInfo(~value="PAZE SDK Script Loaded", ~eventName=PAZE_SDK_FLOW) + loadPazeSDK()->ignore }) - pazeScript->Window.elementOnload(_ => loadPazeSDK()->ignore) Window.body->Window.appendChild(pazeScript) } diff --git a/src/Payments/PlaidSDKIframe.res b/src/Payments/PlaidSDKIframe.res index 45b9c1b32..e69a36121 100644 --- a/src/Payments/PlaidSDKIframe.res +++ b/src/Payments/PlaidSDKIframe.res @@ -78,7 +78,13 @@ let make = () => { } messageParentWindow([("fullscreen", false->JSON.Encode.bool)]) } catch { - | e => logInfo(Console.log2("Retrieve Failed", e)) + | err => + logger.setLogError( + ~value="Retrieve failed via Plaid", + ~eventName=PLAID_SDK, + ~internalMetadata=err->formatException->JSON.stringify, + ~paymentMethod="PLAID", + ) } } diff --git a/src/Payments/SamsungPayComponent.res b/src/Payments/SamsungPayComponent.res index 72560487b..b31fee143 100644 --- a/src/Payments/SamsungPayComponent.res +++ b/src/Payments/SamsungPayComponent.res @@ -28,6 +28,11 @@ let make = (~sessionObj: option, ~walletOptions) => { }) let onSamsungPaymentButtonClick = _ => { + loggerState.setLogInfo( + ~value="SamsungPay Button Clicked", + ~eventName=SAMSUNG_PAY, + ~paymentMethod="SAMSUNG_PAY", + ) SamsungPayHelpers.handleSamsungPayClicked( ~sessionObj=sessionObj->Option.getOr(JSON.Encode.null)->getDictFromJson, ~componentName, diff --git a/src/Utilities/ApplePayHelpers.res b/src/Utilities/ApplePayHelpers.res index 3a342cacd..cee2cef9f 100644 --- a/src/Utilities/ApplePayHelpers.res +++ b/src/Utilities/ApplePayHelpers.res @@ -189,10 +189,9 @@ let startApplePaySession = ( let payment = event.payment payment->callBackFunc } - ssn.oncancel = _ev => { + ssn.oncancel = _ => { applePaySessionRef := Nullable.null - logInfo(Console.log("Apple Pay Payment Cancelled")) - logger.setLogInfo( + logger.setLogError( ~value="Apple Pay Payment Cancelled", ~eventName=APPLE_PAY_FLOW, ~paymentMethod="APPLE_PAY", @@ -218,6 +217,7 @@ let useHandleApplePayResponse = ( let options = Recoil.useRecoilValueFromAtom(RecoilAtoms.optionAtom) let {publishableKey} = Recoil.useRecoilValueFromAtom(RecoilAtoms.keys) let paymentMethodListValue = Recoil.useRecoilValueFromAtom(PaymentUtils.paymentMethodListValue) + let logger = Recoil.useRecoilValueFromAtom(RecoilAtoms.loggerAtom) let (stateJson, setStatesJson) = React.useState(_ => JSON.Encode.null) @@ -279,7 +279,13 @@ let useHandleApplePayResponse = ( syncPayment() } } catch { - | _ => logInfo(Console.log("Error in parsing Apple Pay Data")) + | err => + logger.setLogError( + ~value="Error in parsing Apple Pay Data", + ~eventName=APPLE_PAY_FLOW, + ~paymentMethod="APPLE_PAY", + ~internalMetadata=err->formatException->JSON.stringify, + ) } } Window.addEventListener("message", handleApplePayMessages) diff --git a/src/Utilities/Utils.res b/src/Utilities/Utils.res index b52413668..c2c0cd329 100644 --- a/src/Utilities/Utils.res +++ b/src/Utilities/Utils.res @@ -764,10 +764,6 @@ let snakeToTitleCase = str => { ->Array.joinWith(" ") } -let logInfo = log => { - Window.isProd ? () : log -} - let formatIBAN = iban => { let formatted = iban->String.replaceRegExp(%re(`/[^a-zA-Z0-9]/g`), "") let countryCode = formatted->String.substring(~start=0, ~end=2)->String.toUpperCase diff --git a/src/hyper-loader/Elements.res b/src/hyper-loader/Elements.res index c32755c67..911290ffa 100644 --- a/src/hyper-loader/Elements.res +++ b/src/hyper-loader/Elements.res @@ -182,7 +182,11 @@ let make = ( logger.setLogInfo(~value="TrustPay Script Loading", ~eventName=TRUSTPAY_SCRIPT) trustPayScript->Window.elementSrc(trustPayScriptURL) trustPayScript->Window.elementOnerror(err => { - logInfo(Console.log2("ERROR DURING LOADING TRUSTPAY APPLE PAY", err)) + logger.setLogError( + ~value="ERROR DURING LOADING TRUSTPAY APPLE PAY", + ~eventName=TRUSTPAY_SCRIPT, + ~internalMetadata=err->formatException->JSON.stringify, + ) }) trustPayScript->Window.elementOnload(_ => { logger.setLogInfo(~value="TrustPay Script Loaded", ~eventName=TRUSTPAY_SCRIPT) @@ -1173,7 +1177,15 @@ let make = ( mountedIframeRef->Window.iframePostMessage(msg) resolve() }) - ->catch(_ => resolve()) + ->catch(err => { + logger.setLogError( + ~value=`SAMSUNG PAY not ready ${err->formatException->JSON.stringify}`, + ~eventName=SAMSUNG_PAY, + ~paymentMethod="SAMSUNG_PAY", + ~logType=ERROR, + ) + resolve() + }) ->ignore let handleSamsungPayMessages = (event: Types.event) => { @@ -1196,6 +1208,14 @@ let make = ( resolve() }) ->catch(err => { + logger.setLogError( + ~value=`SAMSUNG PAY Initialization fail ${err + ->formatException + ->JSON.stringify}`, + ~eventName=SAMSUNG_PAY, + ~paymentMethod="SAMSUNG_PAY", + ~logType=ERROR, + ) event.source->Window.sendPostMessage( [("samsungPayError", err->anyTypeToJson)]->Dict.fromArray, ) @@ -1210,8 +1230,22 @@ let make = ( "onSamsungPayMessages", ) } catch { - | _ => Console.log("Error loading Samsung Pay") + | err => + logger.setLogError( + ~value=`SAMSUNG PAY Not Ready - ${err->formatException->JSON.stringify}`, + ~eventName=SAMSUNG_PAY, + ~paymentMethod="SAMSUNG_PAY", + ~logType=ERROR, + ) + Console.log("Error loading Samsung Pay") } + } else if wallets.samsungPay === Never { + logger.setLogInfo( + ~value="SAMSUNG PAY is set as never by merchant", + ~eventName=SAMSUNG_PAY, + ~paymentMethod="SAMSUNG_PAY", + ~logType=INFO, + ) } json->resolve diff --git a/src/hyper-loader/Hyper.res b/src/hyper-loader/Hyper.res index e712c61de..f8750ac6a 100644 --- a/src/hyper-loader/Hyper.res +++ b/src/hyper-loader/Hyper.res @@ -139,26 +139,25 @@ let make = (publishableKey, options: option, analyticsInfo: optionOption.getOr(JSON.Encode.null) - ->Utils.getDictFromJson - ->Utils.getBool("isPreloadEnabled", true) + ->getDictFromJson + ->getBool("isPreloadEnabled", true) let shouldUseTopRedirection = options ->Option.getOr(JSON.Encode.null) - ->Utils.getDictFromJson - ->Utils.getBool("shouldUseTopRedirection", false) + ->getDictFromJson + ->getBool("shouldUseTopRedirection", false) let analyticsMetadata = options ->Option.getOr(JSON.Encode.null) - ->Utils.getDictFromJson - ->Utils.getDictFromObj("analytics") - ->Utils.getJsonObjectFromDict("metadata") + ->getDictFromJson + ->getDictFromObj("analytics") + ->getJsonObjectFromDict("metadata") if isPreloadEnabled { preloader() } let analyticsInfoDict = analyticsInfo->Option.flatMap(JSON.Decode.object)->Option.getOr(Dict.make()) - let sessionID = - analyticsInfoDict->getString("sessionID", "hyp_" ++ Utils.generateRandomString(8)) + let sessionID = analyticsInfoDict->getString("sessionID", "hyp_" ++ generateRandomString(8)) let sdkTimestamp = analyticsInfoDict->getString("timeStamp", Date.now()->Float.toString) let logger = HyperLogger.make( ~sessionId=sessionID, @@ -266,7 +265,12 @@ let make = (publishableKey, options: option, analyticsInfo: optionWindow.elementSrc(googlePayScriptURL) googlePayScript->Window.elementOnerror(err => { - Utils.logInfo(Console.log2("ERROR DURING LOADING GOOGLE PAY SCRIPT", err)) + logger.setLogError( + ~value="ERROR DURING LOADING GOOGLE PAY SCRIPT", + ~eventName=GOOGLE_PAY_SCRIPT, + ~internalMetadata=err->formatException->JSON.stringify, + ~paymentMethod="GOOGLE_PAY", + ) }) Window.body->Window.appendChild(googlePayScript) logger.setLogInfo(~value="GooglePay Script Loaded", ~eventName=GOOGLE_PAY_SCRIPT) @@ -279,9 +283,17 @@ let make = (publishableKey, options: option, analyticsInfo: optionWindow.elementSrc(samsungPayScriptUrl) samsungPayScript->Window.elementOnerror(err => { - Console.log2("ERROR LOADING SAMSUNG PAY SCRIPT", err) + logger.setLogError( + ~value="ERROR DURING LOADING SAMSUNG PAY SCRIPT", + ~eventName=SAMSUNG_PAY_SCRIPT, + ~internalMetadata=err->formatException->JSON.stringify, + ~paymentMethod="SAMSUNG_PAY", + ) }) Window.body->Window.appendChild(samsungPayScript) + samsungPayScript->Window.elementOnload(_ => + logger.setLogInfo(~value="SamsungPay Script Loaded", ~eventName=SAMSUNG_PAY_SCRIPT) + ) } let iframeRef = ref([]) diff --git a/src/hyper-log-catcher/HyperLogger.res b/src/hyper-log-catcher/HyperLogger.res index 715ed5609..a0f5851ff 100644 --- a/src/hyper-log-catcher/HyperLogger.res +++ b/src/hyper-log-catcher/HyperLogger.res @@ -86,6 +86,9 @@ type eventName = | EXTERNAL_TAX_CALCULATION | POST_SESSION_TOKENS_CALL | POST_SESSION_TOKENS_CALL_INIT + | PAZE_SDK_FLOW + | SAMSUNG_PAY_SCRIPT + | SAMSUNG_PAY let eventNameToStrMapper = (eventName: eventName) => (eventName :> string) @@ -104,9 +107,6 @@ let toSnakeCaseWithSeparator = (str, separator) => { type maskableDetails = Email | CardDetails type source = Loader | Elements(CardThemeType.mode) | Headless -let logInfo = log => { - Window.isProd ? () : log -} type logFile = { timestamp: string, From a96d87ef51a2b06e5ac8aa28f84e03dd5997c3ea Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Thu, 5 Dec 2024 08:25:25 +0000 Subject: [PATCH 19/22] chore(release): 0.105.1 [skip ci] ## [0.105.1](https://github.com/juspay/hyperswitch-web/compare/v0.105.0...v0.105.1) (2024-12-05) --- CHANGELOG.md | 2 ++ package-lock.json | 4 ++-- package.json | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c12e53603..c69daee52 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,5 @@ +## [0.105.1](https://github.com/juspay/hyperswitch-web/compare/v0.105.0...v0.105.1) (2024-12-05) + # [0.105.0](https://github.com/juspay/hyperswitch-web/compare/v0.104.6...v0.105.0) (2024-12-04) diff --git a/package-lock.json b/package-lock.json index 547f466c3..d2318fc90 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "orca-payment-page", - "version": "0.105.0", + "version": "0.105.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "orca-payment-page", - "version": "0.105.0", + "version": "0.105.1", "hasInstallScript": true, "dependencies": { "@glennsl/rescript-fetch": "^0.2.0", diff --git a/package.json b/package.json index 91eff38dc..fb09ccae7 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "orca-payment-page", - "version": "0.105.0", + "version": "0.105.1", "main": "index.js", "private": true, "dependencies": { From a4691b09f8dba1fa3ebaa8a56b910206296b899d Mon Sep 17 00:00:00 2001 From: Pritish Budhiraja Date: Thu, 5 Dec 2024 16:10:52 +0530 Subject: [PATCH 20/22] fix: re render issue of card nickname (#823) --- src/Hooks/UtilityHooks.res | 11 +++-------- src/Payments/CardPayment.res | 5 ++--- 2 files changed, 5 insertions(+), 11 deletions(-) diff --git a/src/Hooks/UtilityHooks.res b/src/Hooks/UtilityHooks.res index ec1e28674..512fe8ad9 100644 --- a/src/Hooks/UtilityHooks.res +++ b/src/Hooks/UtilityHooks.res @@ -22,24 +22,19 @@ let useHandlePostMessages = (~complete, ~empty, ~paymentType, ~savedMethod=false } let useIsCustomerAcceptanceRequired = ( - ~displaySavedPaymentMethodsCheckbox, + ~options: PaymentType.options, ~isSaveCardsChecked, ~isGuestCustomer, ) => { let paymentMethodListValue = Recoil.useRecoilValueFromAtom(PaymentUtils.paymentMethodListValue) React.useMemo(() => { - if displaySavedPaymentMethodsCheckbox { + if options.displaySavedPaymentMethodsCheckbox { isSaveCardsChecked || paymentMethodListValue.payment_type === SETUP_MANDATE } else { !(isGuestCustomer || paymentMethodListValue.payment_type === NORMAL) } - }, ( - isSaveCardsChecked, - paymentMethodListValue.payment_type, - isGuestCustomer, - displaySavedPaymentMethodsCheckbox, - )) + }, (isSaveCardsChecked, paymentMethodListValue.payment_type, isGuestCustomer, options)) } let useSendEventsToParent = eventsToSendToParent => { diff --git a/src/Payments/CardPayment.res b/src/Payments/CardPayment.res index 2758da9ee..ef6193518 100644 --- a/src/Payments/CardPayment.res +++ b/src/Payments/CardPayment.res @@ -62,7 +62,6 @@ let make = ( cvcError, setCvcError, ) = cvcProps - let {displaySavedPaymentMethodsCheckbox} = Recoil.useRecoilValueFromAtom(RecoilAtoms.optionAtom) let intent = PaymentHelpers.usePaymentIntent(Some(loggerState), Card) let showFields = Recoil.useRecoilValueFromAtom(RecoilAtoms.showCardFieldsAtom) let setComplete = Recoil.useSetRecoilState(RecoilAtoms.fieldsComplete) @@ -120,7 +119,7 @@ let make = ( ) let isCustomerAcceptanceRequired = useIsCustomerAcceptanceRequired( - ~displaySavedPaymentMethodsCheckbox, + ~options, ~isSaveCardsChecked, ~isGuestCustomer, ) @@ -352,7 +351,7 @@ let make = ( CardUtils.getCardType} /> - + {switch ( paymentMethodListValue.mandate_payment, options.terms.card, From 1054e7cd1068b47fe9ab7047dba49ef27c2aafbb Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Thu, 5 Dec 2024 11:27:41 +0000 Subject: [PATCH 21/22] chore(release): 0.105.2 [skip ci] ## [0.105.2](https://github.com/juspay/hyperswitch-web/compare/v0.105.1...v0.105.2) (2024-12-05) ### Bug Fixes * re render issue of card nickname ([#823](https://github.com/juspay/hyperswitch-web/issues/823)) ([a4691b0](https://github.com/juspay/hyperswitch-web/commit/a4691b09f8dba1fa3ebaa8a56b910206296b899d)) --- 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 c69daee52..0f1362387 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## [0.105.2](https://github.com/juspay/hyperswitch-web/compare/v0.105.1...v0.105.2) (2024-12-05) + + +### Bug Fixes + +* re render issue of card nickname ([#823](https://github.com/juspay/hyperswitch-web/issues/823)) ([a4691b0](https://github.com/juspay/hyperswitch-web/commit/a4691b09f8dba1fa3ebaa8a56b910206296b899d)) + ## [0.105.1](https://github.com/juspay/hyperswitch-web/compare/v0.105.0...v0.105.1) (2024-12-05) # [0.105.0](https://github.com/juspay/hyperswitch-web/compare/v0.104.6...v0.105.0) (2024-12-04) diff --git a/package-lock.json b/package-lock.json index d2318fc90..8526311c5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "orca-payment-page", - "version": "0.105.1", + "version": "0.105.2", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "orca-payment-page", - "version": "0.105.1", + "version": "0.105.2", "hasInstallScript": true, "dependencies": { "@glennsl/rescript-fetch": "^0.2.0", diff --git a/package.json b/package.json index fb09ccae7..87455838e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "orca-payment-page", - "version": "0.105.1", + "version": "0.105.2", "main": "index.js", "private": true, "dependencies": { From 77f3c3b2b529da2f301d84d5268e9657ced58653 Mon Sep 17 00:00:00 2001 From: Pritish Budhiraja Date: Thu, 5 Dec 2024 17:19:04 +0530 Subject: [PATCH 22/22] Revert "fix: re render issue of card nickname" (#824) --- src/Hooks/UtilityHooks.res | 11 ++++++++--- src/Payments/CardPayment.res | 5 +++-- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/src/Hooks/UtilityHooks.res b/src/Hooks/UtilityHooks.res index 512fe8ad9..ec1e28674 100644 --- a/src/Hooks/UtilityHooks.res +++ b/src/Hooks/UtilityHooks.res @@ -22,19 +22,24 @@ let useHandlePostMessages = (~complete, ~empty, ~paymentType, ~savedMethod=false } let useIsCustomerAcceptanceRequired = ( - ~options: PaymentType.options, + ~displaySavedPaymentMethodsCheckbox, ~isSaveCardsChecked, ~isGuestCustomer, ) => { let paymentMethodListValue = Recoil.useRecoilValueFromAtom(PaymentUtils.paymentMethodListValue) React.useMemo(() => { - if options.displaySavedPaymentMethodsCheckbox { + if displaySavedPaymentMethodsCheckbox { isSaveCardsChecked || paymentMethodListValue.payment_type === SETUP_MANDATE } else { !(isGuestCustomer || paymentMethodListValue.payment_type === NORMAL) } - }, (isSaveCardsChecked, paymentMethodListValue.payment_type, isGuestCustomer, options)) + }, ( + isSaveCardsChecked, + paymentMethodListValue.payment_type, + isGuestCustomer, + displaySavedPaymentMethodsCheckbox, + )) } let useSendEventsToParent = eventsToSendToParent => { diff --git a/src/Payments/CardPayment.res b/src/Payments/CardPayment.res index ef6193518..2758da9ee 100644 --- a/src/Payments/CardPayment.res +++ b/src/Payments/CardPayment.res @@ -62,6 +62,7 @@ let make = ( cvcError, setCvcError, ) = cvcProps + let {displaySavedPaymentMethodsCheckbox} = Recoil.useRecoilValueFromAtom(RecoilAtoms.optionAtom) let intent = PaymentHelpers.usePaymentIntent(Some(loggerState), Card) let showFields = Recoil.useRecoilValueFromAtom(RecoilAtoms.showCardFieldsAtom) let setComplete = Recoil.useSetRecoilState(RecoilAtoms.fieldsComplete) @@ -119,7 +120,7 @@ let make = ( ) let isCustomerAcceptanceRequired = useIsCustomerAcceptanceRequired( - ~options, + ~displaySavedPaymentMethodsCheckbox, ~isSaveCardsChecked, ~isGuestCustomer, ) @@ -351,7 +352,7 @@ let make = ( CardUtils.getCardType} /> - + {switch ( paymentMethodListValue.mandate_payment, options.terms.card,