diff --git a/.env b/.env index 29dda11a..92e6a473 100644 --- a/.env +++ b/.env @@ -1,2 +1,3 @@ ENV_BACKEND_URL="" ENV_LOGGING_URL="" +ENABLE_LOGGING="false" \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 0f136238..ea3acc68 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,49 @@ +## [0.106.11](https://github.com/juspay/hyperswitch-web/compare/v0.106.10...v0.106.11) (2024-12-16) + + +### Bug Fixes + +* samsung pay button rendering fixed ([#838](https://github.com/juspay/hyperswitch-web/issues/838)) ([904d103](https://github.com/juspay/hyperswitch-web/commit/904d10369cae6dd41b211493c932d94dad0943a6)) + +## [0.106.10](https://github.com/juspay/hyperswitch-web/compare/v0.106.9...v0.106.10) (2024-12-12) + + +### Bug Fixes + +* cartes bancaires logo not appearing in firefox ([#837](https://github.com/juspay/hyperswitch-web/issues/837)) ([aa0182b](https://github.com/juspay/hyperswitch-web/commit/aa0182b92018dfb95284198e2610fb40a0b6387e)) + +## [0.106.9](https://github.com/juspay/hyperswitch-web/compare/v0.106.8...v0.106.9) (2024-12-11) + +## [0.106.8](https://github.com/juspay/hyperswitch-web/compare/v0.106.7...v0.106.8) (2024-12-11) + +## [0.106.7](https://github.com/juspay/hyperswitch-web/compare/v0.106.6...v0.106.7) (2024-12-11) + +## [0.106.6](https://github.com/juspay/hyperswitch-web/compare/v0.106.5...v0.106.6) (2024-12-11) + +## [0.106.5](https://github.com/juspay/hyperswitch-web/compare/v0.106.4...v0.106.5) (2024-12-11) + +## [0.106.4](https://github.com/juspay/hyperswitch-web/compare/v0.106.3...v0.106.4) (2024-12-11) + +## [0.106.3](https://github.com/juspay/hyperswitch-web/compare/v0.106.2...v0.106.3) (2024-12-11) + +## [0.106.2](https://github.com/juspay/hyperswitch-web/compare/v0.106.1...v0.106.2) (2024-12-10) + +## [0.106.1](https://github.com/juspay/hyperswitch-web/compare/v0.106.0...v0.106.1) (2024-12-09) + + +### Bug Fixes + +* card validation focus check ([#827](https://github.com/juspay/hyperswitch-web/issues/827)) ([fd15e54](https://github.com/juspay/hyperswitch-web/commit/fd15e54ffd9d1bb4445a78567242d3ebc5a25b90)) + +# [0.106.0](https://github.com/juspay/hyperswitch-web/compare/v0.105.3...v0.106.0) (2024-12-09) + + +### Features + +* added cb regex and typo fix ([#811](https://github.com/juspay/hyperswitch-web/issues/811)) ([e925e33](https://github.com/juspay/hyperswitch-web/commit/e925e33556531eb7142ee0a7b26cdbcacc920b15)) + +## [0.105.3](https://github.com/juspay/hyperswitch-web/compare/v0.105.2...v0.105.3) (2024-12-09) + ## [0.105.2](https://github.com/juspay/hyperswitch-web/compare/v0.105.1...v0.105.2) (2024-12-05) diff --git a/Hyperswitch-React-Demo-App/README.md b/Hyperswitch-React-Demo-App/README.md index 206848bf..c4778757 100644 --- a/Hyperswitch-React-Demo-App/README.md +++ b/Hyperswitch-React-Demo-App/README.md @@ -21,7 +21,26 @@ npm install npm start ``` -This will start the react server running on localhost:4242. Note that the -backend server runs on localhost:5252, but the React UI will be available at -localhost:4242. API requests to your backend are proxied by the +This will start the react server running on localhost:5252. API requests to your backend are proxied by the create-react-app server using the `proxy` setting in `./package.json`. + +## Example config using our Sandbox URL +``` +STATIC_DIR=./dist +HYPERSWITCH_PUBLISHABLE_KEY=pk_snd_*** # Replace with your publishable key +HYPERSWITCH_SECRET_KEY=snd_*** # Replace with your API key +HYPERSWITCH_SERVER_URL=https://sandbox.hyperswitch.io # Our Sandbox server is used +HYPERSWITCH_CLIENT_URL=http://localhost:9050 # Your local running SDK +SELF_SERVER_URL=http://localhost:5252 # Your local running demo server +PROFILE_ID="" +``` + +## Troubleshooting +If your demo application is not working, you can check the following to hopefully find the issue. + +- Make sure you have configured the [.env](.env) file correctly. + - Publishable Key `HYPERSWITCH_PUBLISHABLE_KEY` and API Key `HYPERSWITCH_SECRET_KEY` belong to the server `HYPERSWITCH_SERVER_URL`. If you use our Sandbox URL, use publishable key and API key from the hyperswitch website. If you are using your self-hosted backend, use your locally created publishable key and API Key. + - The URL's must not have a slash at the end. +- Check that you have opened the demo application on the correct port. The default should be [localhost:5252](http://localhost:5252). Check the [webpack.dev.js](./webpack.dev.js) file to see if it is different. +- Make sure you have three terminal windows open and running. If you are running your local backend, it has to be one more. +- Open your browser's development tools (F12 in most browsers) and check the network tab for failed rest calls and the console for errors. diff --git a/README.md b/README.md index 4a3e2f8c..5be2c943 100644 --- a/README.md +++ b/README.md @@ -65,19 +65,20 @@ Ways to get started with Hyperswitch: ### 🛠️ Try it in Local -    Before you start the local setup, you need to understand a few configs - +    You will need to understand and configure a few configurations before starting the local setup. - - #### Env Configs for Demo App - **`HYPERSWITCH_PUBLISHABLE_KEY`:** The publishable key of your Hyperswitch account. This key will start with `pk_dev_` for local development, `pk_snd_` for sandbox, and `pk_prd_` for production. - - **`HYPERSWITCH_SECRET_KEY`:** The API key of your Hyperswitch account that is used to authenticate API requests from your merchant server. On the Hyperswitch Dashboard, locate the "Developers" section, then click on [API Keys](https://app.hyperswitch.io/developer-api-keys). Here, you can generate your API Key. + - **`HYPERSWITCH_SECRET_KEY`:** The API key of your Hyperswitch account that is used to authenticate API requests from your merchant server. - - **`HYPERSWITCH_SERVER_URL`:** The URL of your hosted Hyperswitch backend server. Alternatively, you can use our Sandbox URL (https://sandbox.hyperswitch.io) or specify your backend running locally (e.g., http://localhost:8080). + - **`HYPERSWITCH_SERVER_URL`:** The URL of the Hyperswitch backend server. You may use our Sandbox URL (https://sandbox.hyperswitch.io). To do this, go to the Hyperswitch Dashboard, find the "Developers" section, then click on [API Keys](https://app.hyperswitch.io/dashboard/developer-api-keys). Here you can generate an API key (`HYPERSWITCH_SECRET_KEY`) and copy your publishable key (`HYPERSWITCH_PUBLISHABLE_KEY`).
+Alternatively, you can specify that your backend is running locally (e.g. http://localhost:8080). In this case, you will need to create the API key and publishable key locally. Read this [hyperswitch docs](https://github.com/juspay/hyperswitch/blob/main/docs/try_local_system.md) on how to do this. - - **`HYPERSWITCH_CLIENT_URL`:** The URL of your hosted Hyperswitch SDK. You can also use our Sandbox URL (https://beta.hyperswitch.io/v1) or specify your app running locally (e.g., http://localhost:9050). + - **`HYPERSWITCH_CLIENT_URL`:** The URL of your hosted Hyperswitch SDK (e.g. http://localhost:9050). You may also use our Sandbox URL (https://beta.hyperswitch.io/v1). - - **`SELF_SERVER_URL`:** The URL of the hosted server file for generating client-secret and for fetching urls & configs. (eg: http://localhost:9060/payments) + - **`SELF_SERVER_URL`:** The URL of the hosted server file for generating client-secret and for fetching urls & configs (eg: http://localhost:5252). - #### Env Configs for SDK @@ -106,7 +107,7 @@ Ways to get started with Hyperswitch: ### Setup the repo - 1. First install all the node modules by running the following command + 1. First install all the node modules by running the following command. ```bash npm install @@ -120,7 +121,7 @@ Ways to get started with Hyperswitch: npm run re:start ``` - - On the second terminal, run the following command for starting the server. + - On the second terminal, run the following command for starting the SDK server (by default on http://localhost:9050). ```bash npm run start @@ -136,7 +137,8 @@ Ways to get started with Hyperswitch: npm run start ``` - This will open a demo app where you can test your payments. + Now you can launch the demo app on http://localhost:5252/ where you can test your payments.
+ If you encounter any problems, please refer to the troubleshooting section of the [Hyperswitch-React-Demo-App Readme](./Hyperswitch-React-Demo-App/README.md#troubleshooting). > 💡 Alternatively, you can update `.env` file and use the commands > above @@ -182,7 +184,7 @@ let logEndpoint = : ""; // Set this to true to enable logging -let enableLogging = true; +let ENABLE_LOGGING = true; // Choose from DEBUG, INFO, WARNING, ERROR, SILENT let loggingLevel = "DEBUG"; diff --git a/package-lock.json b/package-lock.json index 8526311c..a2b69d85 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "orca-payment-page", - "version": "0.105.2", + "version": "0.106.11", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "orca-payment-page", - "version": "0.105.2", + "version": "0.106.11", "hasInstallScript": true, "dependencies": { "@glennsl/rescript-fetch": "^0.2.0", diff --git a/package.json b/package.json index 87455838..adf30133 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "orca-payment-page", - "version": "0.105.2", + "version": "0.106.11", "main": "index.js", "private": true, "dependencies": { @@ -17,10 +17,10 @@ }, "scripts": { "build": "webpack --config webpack.common.js", - "build:integ": "cross-env sdkEnv=integ enableLogging=false webpack --config webpack.common.js", + "build:integ": "cross-env sdkEnv=integ webpack --config webpack.common.js", "build:playground": "npm run setup:playground && npm run build", - "build:prod": "cross-env sdkEnv=prod enableLogging=true webpack --config webpack.common.js", - "build:sandbox": "cross-env sdkEnv=sandbox enableLogging=true webpack --config webpack.common.js", + "build:prod": "cross-env sdkEnv=prod webpack --config webpack.common.js", + "build:sandbox": "cross-env sdkEnv=sandbox webpack --config webpack.common.js", "deploy-to-s3": "node ./scripts/pushToS3.js", "postinstall": "cd Hyperswitch-React-Demo-App && npm i", "prepare": "husky install", @@ -29,7 +29,7 @@ "re:format": "rescript format -all", "re:start": "rescript -w", "setup:playground": "npm run postinstall && cd Hyperswitch-React-Demo-App && node promptScript.js", - "start": "cross-env sdkEnv=local enableLogging=false webpack serve --config webpack.dev.js", + "start": "cross-env sdkEnv=local webpack serve --config webpack.dev.js", "start:playground": "npm run setup:playground && npm run start", "test": "cd cypress-tests && npm run cypress:run", "test:hooks": "npx eslint src/" diff --git a/public/icons/orca.svg b/public/icons/orca.svg index dcdab264..17a7c7aa 100644 --- a/public/icons/orca.svg +++ b/public/icons/orca.svg @@ -760,6 +760,27 @@ License) + - + \ No newline at end of file diff --git a/src/CardPattern.res b/src/CardPattern.res index 08c3cb63..ab814e31 100644 --- a/src/CardPattern.res +++ b/src/CardPattern.res @@ -3,7 +3,7 @@ type patterns = { pattern: Re.t, cvcLength: array, length: array, - maxCVCLenth: int, + maxCVCLength: int, pincodeRequired: bool, } type card = {details: array} @@ -11,7 +11,7 @@ let defaultCardPattern = { issuer: "", pattern: %re("/^[0-9]/"), cvcLength: [3], - maxCVCLenth: 3, + maxCVCLength: 3, length: [16], pincodeRequired: false, } @@ -19,44 +19,44 @@ let cardPatterns = [ { issuer: "Maestro", pattern: %re( - "/^(5018|5081|5044|504681|504993|5020|502260|5038|603845|603123|6304|6759|676[1-3]|6220|504834|504817|504645|504775|600206|627741)/" + "/^(5018|5081|5044|504681|504993|5020|502260|5038|5893|603845|603123|6304|6759|676[1-3]|6220|504834|504817|504645|504775|600206|627741)/" ), cvcLength: [3, 4], length: [12, 13, 14, 15, 16, 17, 18, 19], - maxCVCLenth: 4, + maxCVCLength: 4, pincodeRequired: true, }, { issuer: "RuPay", pattern: %re( - "/^(508227|508[5-9]|603741|60698[5-9]|60699|607[0-8]|6079[0-7]|60798[0-4]|60800[1-9]|6080[1-9]|608[1-4]|608500|6521[5-9]|652[2-9]|6530|6531[0-4]|817290|817368|817378|353800)/" + "/^(508227|508[5-9]|603741|60698[5-9]|60699|607[0-8]|6079[0-7]|60798[0-4]|60800[1-9]|6080[1-9]|608[1-4]|608500|6521[5-9]|652[2-9]|6530|6531[0-4]|817290|817368|817378|353800|82)/" ), cvcLength: [3], length: [16], - maxCVCLenth: 3, + maxCVCLength: 3, pincodeRequired: false, }, { issuer: "DinersClub", - pattern: %re("/^(36|38|30[0-5])/"), + pattern: %re("/^(36|38|39|30[0-5])/"), cvcLength: [3], - maxCVCLenth: 3, + maxCVCLength: 3, length: [14, 15, 16, 17, 18, 19], pincodeRequired: false, }, { issuer: "Discover", - pattern: %re("/^(6011|65|64[4-9]|622)/"), + pattern: %re("/^(6011|64[4-9]|65|622126|622[1-9][0-9][0-9]|6229[0-1][0-9]|622925)/"), cvcLength: [3], length: [16], - maxCVCLenth: 3, + maxCVCLength: 3, pincodeRequired: true, }, { issuer: "Mastercard", - pattern: %re("/^5[1-5]/"), + pattern: %re("/^(222[1-9]|22[3-9][0-9]|2[3-6][0-9]{2}|27[0-1][0-9]|2720|5[1-5])/"), cvcLength: [3], - maxCVCLenth: 3, + maxCVCLength: 3, length: [16], pincodeRequired: true, }, @@ -65,7 +65,7 @@ let cardPatterns = [ pattern: %re("/^3[47]/"), cvcLength: [3, 4], length: [14, 15], - maxCVCLenth: 4, + maxCVCLength: 4, pincodeRequired: true, }, { @@ -73,7 +73,17 @@ let cardPatterns = [ pattern: %re("/^4/"), cvcLength: [3], length: [13, 14, 15, 16, 19], - maxCVCLenth: 3, + maxCVCLength: 3, + pincodeRequired: true, + }, + { + issuer: "CartesBancaires", + pattern: %re( + "/^(401(005|006|581)|4021(01|02)|403550|405936|406572|41(3849|4819|50(56|59|62|71|74)|6286|65(37|79)|71[7])|420110|423460|43(47(21|22)|50(48|49|50|51|52)|7875|95(09|11|15|39|98)|96(03|18|19|20|22|72))|4424(48|49|50|51|52|57)|448412|4505(19|60)|45(33|56[6-8]|61|62[^3]|6955|7452|7717|93[02379])|46(099|54(76|77)|6258|6575|98[023])|47(4107|71(73|74|86)|72(65|93)|9619)|48(1091|3622|6519)|49(7|83[5-9]|90(0[1-6]|1[0-6]|2[0-3]|3[0-3]|4[0-3]|5[0-2]|68|9[256789]))|5075(89|90|93|94|97)|51(0726|3([0-7]|8[56]|9(00|38))|5214|62(07|36)|72(22|43)|73(65|66)|7502|7647|8101|9920)|52(0993|1662|3718|7429|9227|93(13|14|31)|94(14|21|30|40|47|55|56|[6-9])|9542)|53(0901|10(28|30)|1195|23(4[4-7])|2459|25(09|34|54|56)|3801|41(02|05|11)|50(29|66)|5324|61(07|15)|71(06|12)|8011)|54(2848|5157|9538|98(5[89]))|55(39(79|93)|42(05|60)|4965|7008|88(67|82)|89(29|4[23])|9618|98(09|10))|56(0408|12(0[2-6]|4[134]|5[04678]))|58(17(0[0-7]|15|2[14]|3[16789]|4[0-9]|5[016]|6[269]|7[3789]|8[0-7]|9[017])|55(0[2-5]|7[7-9]|8[0-2])))/" + ), + cvcLength: [3], + length: [16, 17, 18, 19], + maxCVCLength: 3, pincodeRequired: true, }, { @@ -81,22 +91,22 @@ let cardPatterns = [ pattern: %re("/^(637513)/"), cvcLength: [3], length: [16], - maxCVCLenth: 3, + maxCVCLength: 3, pincodeRequired: false, }, { issuer: "BAJAJ", pattern: %re("/^(203040)/"), cvcLength: [3], - maxCVCLenth: 3, + maxCVCLength: 3, length: [16], pincodeRequired: true, }, { issuer: "JCB", - pattern: %re("/^35/"), + pattern: %re("/^35(2[89]|[3-8][0-9])/"), cvcLength: [3], - maxCVCLenth: 3, + maxCVCLength: 3, length: [16], pincodeRequired: false, }, diff --git a/src/CardSchemeComponent.res b/src/CardSchemeComponent.res index dee03adf..00328cb4 100644 --- a/src/CardSchemeComponent.res +++ b/src/CardSchemeComponent.res @@ -31,7 +31,7 @@ let make = (~cardNumber, ~paymentType, ~cardBrand, ~setCardBrand) => { let enabledCardSchemes = paymentMethodListValue->PaymentUtils.getSupportedCardBrands->Option.getOr([]) - let matchedCardSchemes = cardNumber->CardUtils.getAllMatchedCardSchemes + let matchedCardSchemes = cardNumber->CardUtils.clearSpaces->CardUtils.getAllMatchedCardSchemes let eligibleCardSchemes = CardUtils.getEligibleCoBadgedCardSchemes( ~matchedCardSchemes, @@ -44,7 +44,7 @@ let make = (~cardNumber, ~paymentType, ~cardBrand, ~setCardBrand) => {
cardBrandIcon - + CardUtils.clearSpaces->String.length >= 16}>
diff --git a/src/CardUtils.res b/src/CardUtils.res index 3bb719c6..682e845c 100644 --- a/src/CardUtils.res +++ b/src/CardUtils.res @@ -156,7 +156,7 @@ let getStrFromIndex = (arr: array, index) => { let formatCVCNumber = (val, cardType) => { let clearValue = val->clearSpaces let obj = getobjFromCardPattern(cardType) - clearValue->slice(0, obj.maxCVCLenth) + clearValue->slice(0, obj.maxCVCLength) } let getCurrentMonthAndYear = (dateTimeIsoString: string) => { @@ -176,8 +176,7 @@ let formatCardNumber = (val, cardType) => { let clearValue = val->clearSpaces let formatedCard = switch cardType { | AMEX => `${clearValue->slice(0, 4)} ${clearValue->slice(4, 10)} ${clearValue->slice(10, 15)}` - | DINERSCLUB => - `${clearValue->slice(0, 4)} ${clearValue->slice(4, 10)} ${clearValue->slice(10, 14)}` + | DINERSCLUB | MASTERCARD | DISCOVER | SODEXO @@ -348,7 +347,7 @@ let getCardBrandIcon = (cardType, paymentType) => { | SODEXO => | RUPAY => | JCB => - | CARTESBANCAIRES => + | CARTESBANCAIRES => | UNIONPAY => | INTERAC => | NOTFOUND => @@ -380,7 +379,10 @@ let getExpiryValidity = cardExpiry => { let valid = if currentYear == year->toInt && month->toInt >= currentMonth && month->toInt <= 12 { true } else if ( - year->toInt > currentYear && year->toInt < 2075 && month->toInt >= 1 && month->toInt <= 12 + year->toInt > currentYear && + year->toInt < Date.getFullYear(Js.Date.fromFloat(Date.now())) + 100 && + month->toInt >= 1 && + month->toInt <= 12 ) { true } else { @@ -454,12 +456,27 @@ let generateFontsLink = (fonts: array) => { ->ignore } } + let maxCardLength = cardBrand => { let obj = getobjFromCardPattern(cardBrand) Array.reduce(obj.length, 0, (acc, val) => max(acc, val)) } +let isCardLengthValid = (cardBrand, cardNumberLength) => { + let obj = getobjFromCardPattern(cardBrand) + Array.includes(obj.length, cardNumberLength) +} + let cardValid = (cardNumber, cardBrand) => { + let clearValueLength = cardNumber->clearSpaces->String.length + if cardBrand == "" && (GlobalVars.isInteg || GlobalVars.isSandbox) { + Utils.checkIsTestCardWildcard(cardNumber) + } else { + isCardLengthValid(cardBrand, clearValueLength) && calculateLuhn(cardNumber) + } +} + +let focusCardValid = (cardNumber, cardBrand) => { let clearValueLength = cardNumber->clearSpaces->String.length if cardBrand == "" && (GlobalVars.isInteg || GlobalVars.isSandbox) { Utils.checkIsTestCardWildcard(cardNumber) @@ -468,6 +485,7 @@ let cardValid = (cardNumber, cardBrand) => { (cardBrand === "Visa" && clearValueLength == 16)) && calculateLuhn(cardNumber) } } + let blurRef = (ref: React.ref>) => { ref.current->Nullable.toOption->Option.forEach(input => input->blur)->ignore } @@ -563,13 +581,12 @@ let swapCardOption = (cardOpts: array, dropOpts: array, selected let setCardValid = (cardnumber, setIsCardValid) => { let cardBrand = getCardBrand(cardnumber) + let isCardMaxLength = cardnumber->String.length == maxCardLength(cardBrand) if cardValid(cardnumber, cardBrand) { setIsCardValid(_ => Some(true)) - } else if ( - !cardValid(cardnumber, cardBrand) && cardnumber->String.length == maxCardLength(cardBrand) - ) { + } else if !cardValid(cardnumber, cardBrand) && isCardMaxLength { setIsCardValid(_ => Some(false)) - } else if !(cardnumber->String.length == maxCardLength(cardBrand)) { + } else if !isCardMaxLength { setIsCardValid(_ => None) } } @@ -684,3 +701,6 @@ let getCardBrandInvalidError = (~cardNumber, ~localeString: LocaleStringTypes.lo | cardBrandValue => localeString.cardBrandConfiguredErrorText(cardBrandValue) } } + +let emitExpiryDate = formattedExpiry => + Utils.messageParentWindow([("expiryDate", formattedExpiry->JSON.Encode.string)]) diff --git a/src/Components/SavedCardItem.res b/src/Components/SavedCardItem.res index ee6f5eab..7cd8d3f3 100644 --- a/src/Components/SavedCardItem.res +++ b/src/Components/SavedCardItem.res @@ -72,16 +72,27 @@ let make = ( | None => () } } - React.useEffect(() => { - isActive ? focusCVC() : () - None - }, [isActive]) let isCard = paymentItem.paymentMethod === "card" let isRenderCvv = isCard && paymentItem.requiresCvv let expiryMonth = paymentItem.card.expiryMonth let expiryYear = paymentItem.card.expiryYear + React.useEffect(() => { + open CardUtils + + if isActive { + // * Focus CVC + focusCVC() + + // * Sending card expiry to handle cases where the card expires before the use date. + `${expiryMonth}${String.substring(~start=2, ~end=4, expiryYear)}` + ->formatCardExpiryNumber + ->emitExpiryDate + } + None + }, [isActive]) + let expiryDate = Date.fromString(`${expiryYear}-${expiryMonth}`) expiryDate->Date.setMonth(expiryDate->Date.getMonth + 1) let currentDate = Date.make() diff --git a/src/Payment.res b/src/Payment.res index 19028b56..a0aae0b9 100644 --- a/src/Payment.res +++ b/src/Payment.res @@ -71,7 +71,7 @@ let make = (~paymentMode, ~integrateError, ~logger) => { React.useEffect(() => { let obj = getobjFromCardPattern(cardBrand) - let cvcLength = obj.maxCVCLenth + let cvcLength = obj.maxCVCLength if ( cvcNumberInRange(cvcNumber, cardBrand)->Array.includes(true) && cvcNumber->String.length == cvcLength @@ -88,7 +88,7 @@ let make = (~paymentMode, ~integrateError, ~logger) => { let clearValue = card->clearSpaces setCardValid(clearValue, setIsCardValid) if ( - cardValid(clearValue, cardBrand) && + focusCardValid(clearValue, cardBrand) && (PaymentUtils.checkIsCardSupported(clearValue, supportedCardBrands)->Option.getOr(false) || Utils.checkIsTestCardWildcard(clearValue)) ) { @@ -113,7 +113,7 @@ let make = (~paymentMode, ~integrateError, ~logger) => { 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)]) + emitExpiryDate(formattedExpiry) } setExpiryValid(formattedExpiry, setIsExpiryValid) setCardExpiry(_ => formattedExpiry) @@ -241,7 +241,7 @@ let make = (~paymentMode, ~integrateError, ~logger) => { ~cardNumber, ~month, ~year, - ~cardHolderName="", + ~cardHolderName=None, ~cvcNumber, ~cardBrand=cardNetwork, ) @@ -252,7 +252,7 @@ let make = (~paymentMode, ~integrateError, ~logger) => { ~cardNumber, ~month, ~year, - ~cardHolderName="", + ~cardHolderName=None, ~cvcNumber=localCvcNumber, ~cardBrand=cardNetwork, ) diff --git a/src/Payments/CardPayment.res b/src/Payments/CardPayment.res index 2758da9e..f4ae74a7 100644 --- a/src/Payments/CardPayment.res +++ b/src/Payments/CardPayment.res @@ -142,7 +142,7 @@ let make = ( ~cardNumber, ~month, ~year, - ~cardHolderName="", + ~cardHolderName=None, ~cvcNumber, ~cardBrand=cardNetwork, ~nickname=nickname.value, diff --git a/src/Payments/SamsungPayComponent.res b/src/Payments/SamsungPayComponent.res index b31fee14..4aee673b 100644 --- a/src/Payments/SamsungPayComponent.res +++ b/src/Payments/SamsungPayComponent.res @@ -101,10 +101,11 @@ let make = (~sessionObj: option, ~walletOptions) => { }) None }, [isRenderSamsungPayButton]) - -
Int.toString}px`} - id="samsungpay-container" - className={`w-full flex flex-row justify-center rounded-md [&>*]:w-full [&>button]:!bg-contain`} - /> + +
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/Types/PaymentType.res b/src/Types/PaymentType.res index 346efa08..ac0e8399 100644 --- a/src/Types/PaymentType.res +++ b/src/Types/PaymentType.res @@ -863,7 +863,7 @@ let getCardDetails = (dict, str) => { expiryMonth: getString(json, "expiry_month", ""), expiryYear: getString(json, "expiry_year", ""), cardToken: getString(json, "card_token", ""), - cardHolderName: Some(getString(json, "card_holder_name", "")), + cardHolderName: getOptionString(json, "card_holder_name"), nickname: getString(json, "nick_name", ""), } }) diff --git a/src/Utilities/PaymentBody.res b/src/Utilities/PaymentBody.res index 9b6a9aaa..e5c59717 100644 --- a/src/Utilities/PaymentBody.res +++ b/src/Utilities/PaymentBody.res @@ -35,7 +35,7 @@ let cardPaymentBody = ( ~cardNumber, ~month, ~year, - ~cardHolderName, + ~cardHolderName=None, ~cvcNumber, ~cardBrand, ~nickname="", @@ -44,11 +44,14 @@ let cardPaymentBody = ( ("card_number", cardNumber->CardUtils.clearSpaces->JSON.Encode.string), ("card_exp_month", month->JSON.Encode.string), ("card_exp_year", year->JSON.Encode.string), - ("card_holder_name", cardHolderName->JSON.Encode.string), ("card_cvc", cvcNumber->JSON.Encode.string), ("card_issuer", ""->JSON.Encode.string), ] + cardHolderName + ->Option.map(name => cardBody->Array.push(("card_holder_name", name->JSON.Encode.string))->ignore) + ->ignore + if nickname != "" { cardBody->Array.push(("nick_name", nickname->JSON.Encode.string))->ignore } diff --git a/webpack.common.js b/webpack.common.js index 18a9015f..70f19b55 100644 --- a/webpack.common.js +++ b/webpack.common.js @@ -14,7 +14,7 @@ const getEnvVariable = (variable, defaultValue) => process.env[variable] ?? defaultValue; const sdkEnv = getEnvVariable("sdkEnv", "local"); -const enableLogging = getEnvVariable("enableLogging", "false") === "true"; +const ENABLE_LOGGING = getEnvVariable("ENABLE_LOGGING", "false") === "true"; const envSdkUrl = getEnvVariable("ENV_SDK_URL", ""); const envBackendUrl = getEnvVariable("ENV_BACKEND_URL", ""); const envLoggingUrl = getEnvVariable("ENV_LOGGING_URL", ""); @@ -67,25 +67,28 @@ module.exports = (publicPath = "auto") => { app: "./index.js", HyperLoader: "./src/hyper-loader/HyperLoader.bs.js", }; + + let definePluginValues = { + repoName: JSON.stringify(repoName), + repoVersion: JSON.stringify(repoVersion), + publicPath: JSON.stringify(repoPublicPath), + sdkUrl: JSON.stringify(sdkUrl), + backendEndPoint: JSON.stringify(backendEndPoint), + confirmEndPoint: JSON.stringify(confirmEndPoint), + logEndpoint: JSON.stringify(logEndpoint), + sentryDSN: JSON.stringify(process.env.SENTRY_DSN), + sentryScriptUrl: JSON.stringify(process.env.SENTRY_SCRIPT_URL), + enableLogging: ENABLE_LOGGING, + loggingLevel: JSON.stringify(loggingLevel), + maxLogsPushedPerEventName: JSON.stringify(maxLogsPushedPerEventName), + }; + const plugins = [ new MiniCssExtractPlugin(), new CopyPlugin({ patterns: [{ from: "public" }], }), - new webpack.DefinePlugin({ - repoName: JSON.stringify(repoName), - repoVersion: JSON.stringify(repoVersion), - publicPath: JSON.stringify(repoPublicPath), - sdkUrl: JSON.stringify(sdkUrl), - backendEndPoint: JSON.stringify(backendEndPoint), - confirmEndPoint: JSON.stringify(confirmEndPoint), - logEndpoint: JSON.stringify(logEndpoint), - sentryDSN: JSON.stringify(process.env.SENTRY_DSN), - sentryScriptUrl: JSON.stringify(process.env.SENTRY_SCRIPT_URL), - enableLogging: enableLogging, - loggingLevel: JSON.stringify(loggingLevel), - maxLogsPushedPerEventName: JSON.stringify(maxLogsPushedPerEventName), - }), + new webpack.DefinePlugin(definePluginValues), new HtmlWebpackPlugin({ inject: false, template: "./public/build.html",