Skip to content

Commit

Permalink
Merge branch 'main' into feature/three_ds_partB
Browse files Browse the repository at this point in the history
  • Loading branch information
prafulkoppalkar authored May 27, 2024
2 parents 070d7bd + f085bfb commit baeafe1
Show file tree
Hide file tree
Showing 15 changed files with 138 additions and 33 deletions.
36 changes: 36 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,39 @@
# [0.55.0](https://github.com/juspay/hyperswitch-web/compare/v0.54.2...v0.55.0) (2024-05-23)


### Features

* unsupported card networks validation ([#370](https://github.com/juspay/hyperswitch-web/issues/370)) ([05f527a](https://github.com/juspay/hyperswitch-web/commit/05f527abb475bdaf29912fd452a3b0f4b0b3bb55))

## [0.54.2](https://github.com/juspay/hyperswitch-web/compare/v0.54.1...v0.54.2) (2024-05-23)


### Bug Fixes

* sdk button redirect issue ([#398](https://github.com/juspay/hyperswitch-web/issues/398)) ([dd78d56](https://github.com/juspay/hyperswitch-web/commit/dd78d5611100e23025e19d1563e1ff1e5434a692))

## [0.54.1](https://github.com/juspay/hyperswitch-web/compare/v0.54.0...v0.54.1) (2024-05-22)


### Bug Fixes

* saved method checkbox condition updated ([#395](https://github.com/juspay/hyperswitch-web/issues/395)) ([8642913](https://github.com/juspay/hyperswitch-web/commit/8642913f5ba4be1c441499f15da2aab64870b209))

# [0.54.0](https://github.com/juspay/hyperswitch-web/compare/v0.53.3...v0.54.0) (2024-05-22)


### Features

* isolate paymentElementCreate message ([#387](https://github.com/juspay/hyperswitch-web/issues/387)) ([0fdfacd](https://github.com/juspay/hyperswitch-web/commit/0fdfacd5826cebc16bb0a807d0539c42055e30f5))

## [0.53.3](https://github.com/juspay/hyperswitch-web/compare/v0.53.2...v0.53.3) (2024-05-22)


### Bug Fixes

* added patch for revert to generate tag ([#385](https://github.com/juspay/hyperswitch-web/issues/385)) ([4a0d92f](https://github.com/juspay/hyperswitch-web/commit/4a0d92f775fafd21e892e58a12151cbd58f7a170))
* reverse core lib issue ([#386](https://github.com/juspay/hyperswitch-web/issues/386)) ([28f9067](https://github.com/juspay/hyperswitch-web/commit/28f90670d61c18828f7e24007f9c898bf3ad2acc))

## [0.53.2](https://github.com/juspay/hyperswitch-web/compare/v0.53.1...v0.53.2) (2024-05-22)


Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 5 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "orca-payment-page",
"version": "0.53.2",
"version": "0.55.0",
"main": "index.js",
"private": true,
"dependencies": {
Expand Down Expand Up @@ -145,6 +145,10 @@
{
"type": "chore",
"release": "patch"
},
{
"type": "revert",
"release": "patch"
}
]
}
Expand Down
1 change: 1 addition & 0 deletions src/CardUtils.res
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ type cardIssuer =
type cardProps = (
option<bool>,
(option<bool> => option<bool>) => unit,
option<bool>,
string,
JsxEvent.Form.t => unit,
JsxEvent.Focus.t => unit,
Expand Down
2 changes: 2 additions & 0 deletions src/Components/DynamicFields.res
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ let make = (
let defaultCardProps = (
None,
_ => (),
None,
"",
_ => (),
_ => (),
Expand Down Expand Up @@ -154,6 +155,7 @@ let make = (
let (
isCardValid,
setIsCardValid,
_,
cardNumber,
changeCardNumber,
handleCardBlur,
Expand Down
12 changes: 0 additions & 12 deletions src/Components/PayNowButton.res
Original file line number Diff line number Diff line change
Expand Up @@ -21,21 +21,9 @@ let make = () => {
let confirmPayload = sdkHandleConfirmPayment->PaymentBody.confirmPayloadForSDKButton
let buttonText = sdkHandleConfirmPayment.buttonText->Option.getOr(localeString.payNowButton)

let handleMessage = (event: Types.event) => {
let json = event.data->Identity.anyTypeToJson->getStringFromJson("")->safeParse
let dict = json->getDictFromJson
switch dict->Dict.get("submitSuccessful") {
| Some(_) =>
setIsPayNowButtonDisable(_ => false)
setShowLoader(_ => false)
| None => ()
}
}

let handleOnClick = _ => {
setIsPayNowButtonDisable(_ => true)
setShowLoader(_ => true)
EventListenerManager.addSmartEventListener("message", handleMessage, "onSubmitSuccessful")
handlePostMessage([("handleSdkConfirm", confirmPayload)])
}

Expand Down
12 changes: 10 additions & 2 deletions src/Components/SavedMethods.res
Original file line number Diff line number Diff line change
Expand Up @@ -176,8 +176,16 @@ let make = (
let conditionsForShowingSaveCardCheckbox = React.useMemo(() => {
!isGuestCustomer &&
paymentMethodListValue.payment_type === NEW_MANDATE &&
displaySavedPaymentMethodsCheckbox
}, (isGuestCustomer, paymentMethodListValue.payment_type, displaySavedPaymentMethodsCheckbox))
displaySavedPaymentMethodsCheckbox &&
savedMethods->Array.some(ele => {
ele.paymentMethod === "card" && ele.requiresCvv
})
}, (
isGuestCustomer,
paymentMethodListValue.payment_type,
displaySavedPaymentMethodsCheckbox,
savedMethods,
))

<div className="flex flex-col overflow-auto h-auto no-scrollbar animate-slowShow">
{if savedCardlength === 0 && (loadSavedCards === PaymentType.LoadingSavedCards || !showFields) {
Expand Down
58 changes: 54 additions & 4 deletions src/Payment.res
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ let make = (~paymentMode, ~integrateError, ~logger) => {
let showFields = Recoil.useRecoilValueFromAtom(showCardFieldsAtom)
let selectedOption = Recoil.useRecoilValueFromAtom(selectedOptionAtom)
let paymentToken = Recoil.useRecoilValueFromAtom(paymentTokenAtom)
let paymentMethodListValue = Recoil.useRecoilValueFromAtom(PaymentUtils.paymentMethodListValue)

let {iframeId} = keys

Expand Down Expand Up @@ -43,6 +44,7 @@ let make = (~paymentMode, ~integrateError, ~logger) => {
let (isExpiryValid, setIsExpiryValid) = React.useState(_ => None)
let (isCVCValid, setIsCVCValid) = React.useState(_ => None)
let (isZipValid, setIsZipValid) = React.useState(_ => None)
let (isCardSupported, setIsCardSupported) = React.useState(_ => None)

let (cardBrand, maxCardLength) = React.useMemo(() => {
let brand = getCardBrand(cardNumber)
Expand All @@ -51,6 +53,46 @@ let make = (~paymentMode, ~integrateError, ~logger) => {
!showFields && isNotBancontact ? (cardScheme, maxLength) : (brand, maxLength)
}, (cardNumber, cardScheme, showFields))

let supportedCardBrands = React.useMemo(() => {
let cardPaymentMethod =
paymentMethodListValue.payment_methods->Array.find(ele => ele.payment_method === "card")

switch cardPaymentMethod {
| Some(cardPaymentMethod) =>
let cardNetworks = cardPaymentMethod.payment_method_types->Array.map(ele => ele.card_networks)
let cardNetworkNames =
cardNetworks->Array.map(ele =>
ele->Array.map(
val => val.card_network->CardUtils.getCardStringFromType->String.toLowerCase,
)
)
Some(
cardNetworkNames
->Array.reduce([], (acc, ele) => acc->Array.concat(ele))
->Utils.getUniqueArray,
)
| None => None
}
}, [paymentMethodListValue])

let checkIsCardSupported = cardNumber => {
let cardBrand = cardNumber->CardUtils.getCardBrand
let clearValue = cardNumber->clearSpaces
if cardValid(clearValue, cardBrand) {
switch supportedCardBrands {
| Some(brands) => Some(brands->Array.includes(cardBrand->String.toLowerCase))
| None => Some(true)
}
} else {
None
}
}

React.useEffect(() => {
setIsCardSupported(_ => checkIsCardSupported(cardNumber))
None
}, (supportedCardBrands, cardNumber))

let cardType = React.useMemo1(() => {
cardBrand->getCardType
}, [cardBrand])
Expand Down Expand Up @@ -92,7 +134,7 @@ let make = (~paymentMode, ~integrateError, ~logger) => {
let card = val->formatCardNumber(cardType)
let clearValue = card->clearSpaces
setCardValid(clearValue, setIsCardValid)
if cardValid(clearValue, cardBrand) {
if cardValid(clearValue, cardBrand) && checkIsCardSupported(clearValue)->Option.getOr(false) {
handleInputFocus(~currentRef=cardRef, ~destinationRef=expiryRef)
}
if card->String.length > 6 && cardNumber->pincodeVisibility {
Expand Down Expand Up @@ -153,7 +195,7 @@ let make = (~paymentMode, ~integrateError, ~logger) => {
let handleCardBlur = ev => {
let cardNumber = ReactEvent.Focus.target(ev)["value"]
if cardNumberInRange(cardNumber)->Array.includes(true) && calculateLuhn(cardNumber) {
setIsCardValid(_ => Some(true))
setIsCardValid(_ => checkIsCardSupported(cardNumber))
} else if cardNumber->String.length == 0 {
setIsCardValid(_ => None)
} else {
Expand Down Expand Up @@ -336,9 +378,16 @@ let make = (~paymentMode, ~integrateError, ~logger) => {
}, (cardNumber, cvcNumber, cardExpiry, isCVCValid, isExpiryValid, isCardValid))

React.useEffect(() => {
setCardError(_ => isCardValid->Option.getOr(true) ? "" : localeString.inValidCardErrorText)
let cardError = if isCardSupported->Option.getOr(true) && isCardValid->Option.getOr(true) {
""
} else if isCardSupported->Option.getOr(true) {
localeString.inValidCardErrorText
} else {
localeString.cardBrandConfiguredErrorText(cardBrand)
}
setCardError(_ => cardError)
None
}, [isCardValid])
}, [isCardValid, isCardSupported])

React.useEffect(() => {
setCvcError(_ => isCVCValid->Option.getOr(true) ? "" : localeString.inCompleteCVCErrorText)
Expand Down Expand Up @@ -366,6 +415,7 @@ let make = (~paymentMode, ~integrateError, ~logger) => {
let cardProps: CardUtils.cardProps = (
isCardValid,
setIsCardValid,
isCardSupported,
cardNumber,
changeCardNumber,
handleCardBlur,
Expand Down
26 changes: 20 additions & 6 deletions src/Payments/CardPayment.res
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ let make = (
let (
isCardValid,
setIsCardValid,
isCardSupported,
cardNumber,
changeCardNumber,
handleCardBlur,
Expand Down Expand Up @@ -99,7 +100,14 @@ let make = (

let areRequiredFieldsValid = Recoil.useRecoilValueFromAtom(RecoilAtoms.areRequiredFieldsValid)

let complete = isAllValid(isCardValid, isCVCValid, isExpiryValid, true, "payment")
let complete = isAllValid(
isCardValid,
isCardSupported,
isCVCValid,
isExpiryValid,
true,
"payment",
)
let empty = cardNumber == "" || cardExpiry == "" || cvcNumber == ""
React.useEffect(() => {
setComplete(_ => complete)
Expand Down Expand Up @@ -152,8 +160,13 @@ let make = (
defaultCardBody
}
if confirm.doSubmit {
let validFormat = (isBancontact || complete) && areRequiredFieldsValid
if validFormat && (showFields || isBancontact) && isCardBrandValid {
let validFormat =
(isBancontact ||
(isCVCValid->Option.getOr(false) &&
isCardValid->Option.getOr(false) &&
isCardSupported->Option.getOr(false) &&
isExpiryValid->Option.getOr(false))) && areRequiredFieldsValid
if validFormat && (showFields || isBancontact) {
intent(
~bodyArr={
(isBancontact ? banContactBody : cardBody)
Expand All @@ -179,12 +192,13 @@ let make = (
setCvcError(_ => localeString.cvcNumberEmptyText)
setUserError(localeString.enterFieldsText)
}
if isCardSupported->Option.getOr(true)->not {
setCardError(_ => localeString.cardBrandConfiguredErrorText(cardBrand))
setUserError(localeString.cardBrandConfiguredErrorText(cardBrand))
}
if !validFormat {
setUserError(localeString.enterValidDetailsText)
}
if !isCardBrandValid {
setUserError(localeString.cardBrandConfiguredErrorText(cardBrand))
}
}
}
}, (
Expand Down
1 change: 1 addition & 0 deletions src/RenderPaymentMethods.res
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ let make = (
let (
isCardValid,
setIsCardValid,
_,
cardNumber,
changeCardNumber,
handleCardBlur,
Expand Down
1 change: 1 addition & 0 deletions src/SingleLineCardPayment.res
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ let make = (
let (
isCardValid,
setIsCardValid,
_,
cardNumber,
changeCardNumber,
handleCardBlur,
Expand Down
2 changes: 1 addition & 1 deletion src/Utilities/PaymentBody.res
Original file line number Diff line number Diff line change
Expand Up @@ -162,11 +162,11 @@ let paymentTypeBody = paymentType =>

let confirmPayloadForSDKButton = (sdkHandleConfirmPayment: PaymentType.sdkHandleConfirmPayment) =>
[
("redirect", "always"->JSON.Encode.string),
(
"confirmParams",
[
("return_url", sdkHandleConfirmPayment.confirmParams.return_url->JSON.Encode.string),
("redirect", "always"->JSON.Encode.string), // *As in the case of SDK Button we are not returning the promise back so it will always redirect
]->Utils.getJsonFromArrayOfJson,
),
]->Utils.getJsonFromArrayOfJson
Expand Down
2 changes: 2 additions & 0 deletions src/Utilities/Utils.res
Original file line number Diff line number Diff line change
Expand Up @@ -460,12 +460,14 @@ let sortBasedOnPriority = (sortArr: array<string>, priorityArr: array<string>) =

let isAllValid = (
card: option<bool>,
cardSupported: option<bool>,
cvc: option<bool>,
expiry: option<bool>,
zip: bool,
paymentMode: string,
) => {
card->getBoolValue &&
cardSupported->getBoolValue &&
cvc->getBoolValue &&
expiry->getBoolValue &&
(paymentMode == "payment" || zip)
Expand Down
2 changes: 1 addition & 1 deletion src/orca-loader/Elements.res
Original file line number Diff line number Diff line change
Expand Up @@ -1042,10 +1042,10 @@ let make = (
fetchCustomerPaymentMethods(mountedIframeRef, false, componentType)
}
fetchSessionTokens(mountedIframeRef)
mountedIframeRef->Window.iframePostMessage(message)
resolve()
})
->ignore
mountedIframeRef->Window.iframePostMessage(message)
}

let paymentElement = LoaderPaymentElement.make(
Expand Down
6 changes: 2 additions & 4 deletions webpack.common.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,7 @@ const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const CopyPlugin = require("copy-webpack-plugin");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const TerserPlugin = require("terser-webpack-plugin");
const BundleAnalyzerPlugin =
require("webpack-bundle-analyzer").BundleAnalyzerPlugin;
const BundleAnalyzerPlugin = require("webpack-bundle-analyzer").BundleAnalyzerPlugin;
const { sentryWebpackPlugin } = require("@sentry/webpack-plugin");

const sdkEnv = process.env.sdkEnv ?? "local";
Expand All @@ -20,8 +19,7 @@ let repoVersion = require("./package.json").version;
let majorVersion = "v" + repoVersion.split(".")[0];

let repoName = require("./package.json").name;
let repoPublicPath =
sdkEnv === "local" ? "" : `/${repoVersion}/${majorVersion}`;
let repoPublicPath = sdkEnv === "local" ? "" : `/${repoVersion}/${majorVersion}`;

let sdkUrl;

Expand Down

0 comments on commit baeafe1

Please sign in to comment.