diff --git a/src/CardPattern.res b/src/CardPattern.res index 08c3cb63..1706eeb0 100644 --- a/src/CardPattern.res +++ b/src/CardPattern.res @@ -19,7 +19,7 @@ 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], @@ -29,7 +29,7 @@ let cardPatterns = [ { 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], @@ -38,7 +38,7 @@ let cardPatterns = [ }, { issuer: "DinersClub", - pattern: %re("/^(36|38|30[0-5])/"), + pattern: %re("/^(36|38|39|30[0-5])/"), cvcLength: [3], maxCVCLenth: 3, length: [14, 15, 16, 17, 18, 19], @@ -46,7 +46,7 @@ let cardPatterns = [ }, { 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, @@ -54,7 +54,7 @@ let cardPatterns = [ }, { 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, length: [16], @@ -94,7 +94,7 @@ let cardPatterns = [ }, { issuer: "JCB", - pattern: %re("/^35/"), + pattern: %re("/^35(2[89]|[3-8][0-9])/"), cvcLength: [3], maxCVCLenth: 3, length: [16], diff --git a/src/CardUtils.res b/src/CardUtils.res index 3bb719c6..9d0b9beb 100644 --- a/src/CardUtils.res +++ b/src/CardUtils.res @@ -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 @@ -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) } } diff --git a/src/Payment.res b/src/Payment.res index 19028b56..253b8939 100644 --- a/src/Payment.res +++ b/src/Payment.res @@ -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)) ) {