From 5bb8089449f1dbd1558a6cf3501fe05f9d3cf6ae Mon Sep 17 00:00:00 2001 From: Ali <> Date: Tue, 7 Feb 2023 23:14:09 +0400 Subject: [PATCH] Update card validation (cherry picked from commit 5c71c08b6e9442b009ca3b71e784a1f8e2ebe4a1) --- .../PublicHeaders/Stripe/STPCardValidator.h | 4 ++-- submodules/Stripe/Sources/STPBINRange.m | 3 ++- submodules/Stripe/Sources/STPCardParams.m | 2 +- submodules/Stripe/Sources/STPCardValidator.m | 22 +++++++++++++++---- .../STPPaymentCardTextFieldViewModel.m | 2 +- 5 files changed, 24 insertions(+), 9 deletions(-) diff --git a/submodules/Stripe/PublicHeaders/Stripe/STPCardValidator.h b/submodules/Stripe/PublicHeaders/Stripe/STPCardValidator.h index f6bc671b50..23b906db0d 100755 --- a/submodules/Stripe/PublicHeaders/Stripe/STPCardValidator.h +++ b/submodules/Stripe/PublicHeaders/Stripe/STPCardValidator.h @@ -79,7 +79,7 @@ NS_ASSUME_NONNULL_BEGIN * @return STPCardValidationStateValid if the year is valid, STPCardValidationStateInvalid if the year is invalid, or STPCardValidationStateIncomplete if the year is a substring of a valid year (e.g. @"1" or @"2"). */ + (STPCardValidationState)validationStateForExpirationYear:(NSString *)expirationYear - inMonth:(NSString *)expirationMonth; + inMonth:(NSString *)expirationMonth cardBrand:(STPCardBrand)cardBrand; /** * The max CVC length for a card brand (for context, American Express CVCs are 4 digits, while all others are 3). @@ -109,7 +109,7 @@ NS_ASSUME_NONNULL_BEGIN + (STPCardValidationState)validationStateForExpirationYear:(NSString *)expirationYear inMonth:(NSString *)expirationMonth inCurrentYear:(NSInteger)currentYear - currentMonth:(NSInteger)currentMonth; + currentMonth:(NSInteger)currentMonth cardBrand:(STPCardBrand)cardBrand; + (STPCardValidationState)validationStateForCard:(STPCardParams *)card inCurrentYear:(NSInteger)currentYear currentMonth:(NSInteger)currentMonth; diff --git a/submodules/Stripe/Sources/STPBINRange.m b/submodules/Stripe/Sources/STPBINRange.m index 2939effddf..29d9a2b9ba 100755 --- a/submodules/Stripe/Sources/STPBINRange.m +++ b/submodules/Stripe/Sources/STPBINRange.m @@ -66,7 +66,8 @@ @[@"492937", @"492937", @13, @(STPCardBrandVisa)], @[@"492939", @"492939", @13, @(STPCardBrandVisa)], @[@"492960", @"492960", @13, @(STPCardBrandVisa)], - @[@"2", @"2", @16, @(STPCardBrandOther)], + @[@"8600", @"8600", @16, @(STPCardBrandOther)], + @[@"9860", @"9860", @16, @(STPCardBrandOther)], ]; NSMutableArray *binRanges = [NSMutableArray array]; for (NSArray *range in ranges) { diff --git a/submodules/Stripe/Sources/STPCardParams.m b/submodules/Stripe/Sources/STPCardParams.m index 329271d0b3..14b8300d53 100755 --- a/submodules/Stripe/Sources/STPCardParams.m +++ b/submodules/Stripe/Sources/STPCardParams.m @@ -101,7 +101,7 @@ NSString *ioValueString = [(NSString *)*ioValue stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]; NSString *monthString = [@(self.expMonth) stringValue]; - if ([STPCardValidator validationStateForExpirationYear:ioValueString inMonth:monthString] != STPCardValidationStateValid) { + if ([STPCardValidator validationStateForExpirationYear:ioValueString inMonth:monthString cardBrand:[STPCardValidator brandForNumber:self.number]] != STPCardValidationStateValid) { return [self.class handleValidationErrorForParameter:@"expYear" error:outError]; } return YES; diff --git a/submodules/Stripe/Sources/STPCardValidator.m b/submodules/Stripe/Sources/STPCardValidator.m index 2d8d5ae371..93b8310f6b 100755 --- a/submodules/Stripe/Sources/STPCardValidator.m +++ b/submodules/Stripe/Sources/STPCardValidator.m @@ -75,7 +75,7 @@ static NSString * _Nonnull stringByRemovingCharactersFromSet(NSString * _Nonnull } } -+ (STPCardValidationState)validationStateForExpirationYear:(NSString *)expirationYear inMonth:(NSString *)expirationMonth inCurrentYear:(NSInteger)currentYear currentMonth:(NSInteger)currentMonth { ++ (STPCardValidationState)validationStateForExpirationYear:(NSString *)expirationYear inMonth:(NSString *)expirationMonth inCurrentYear:(NSInteger)currentYear currentMonth:(NSInteger)currentMonth cardBrand:(STPCardBrand)cardBrand { NSInteger moddedYear = currentYear % 100; @@ -91,6 +91,15 @@ static NSString * _Nonnull stringByRemovingCharactersFromSet(NSString * _Nonnull case 1: return STPCardValidationStateIncomplete; case 2: { + switch (cardBrand) { + case STPCardBrandVisa: + case STPCardBrandMasterCard: + case STPCardBrandOther: + return STPCardValidationStateValid; + default: + break; + } + if (sanitizedYear.integerValue == moddedYear) { return sanitizedMonth.integerValue >= currentMonth ? STPCardValidationStateValid : STPCardValidationStateInvalid; } else { @@ -104,11 +113,11 @@ static NSString * _Nonnull stringByRemovingCharactersFromSet(NSString * _Nonnull + (STPCardValidationState)validationStateForExpirationYear:(NSString *)expirationYear - inMonth:(NSString *)expirationMonth { + inMonth:(NSString *)expirationMonth cardBrand:(STPCardBrand)cardBrand { return [self validationStateForExpirationYear:expirationYear inMonth:expirationMonth inCurrentYear:[self currentYear] - currentMonth:[self currentMonth]]; + currentMonth:[self currentMonth] cardBrand:cardBrand]; } @@ -165,7 +174,12 @@ static NSString * _Nonnull stringByRemovingCharactersFromSet(NSString * _Nonnull STPCardValidationState expYearValidation = [self validationStateForExpirationYear:expYearString inMonth:expMonthString inCurrentYear:currentYear - currentMonth:currentMonth]; + currentMonth:currentMonth cardBrand:[STPCardValidator brandForNumber:card.number]]; + if (expMonthValidation == STPCardValidationStateInvalid || expYearValidation == STPCardValidationStateInvalid) { + expMonthValidation = STPCardValidationStateValid; + expYearValidation = STPCardValidationStateValid; + } + STPCardBrand brand = [self brandForNumber:card.number]; STPCardValidationState cvcValidation = [self validationStateForCVC:card.cvc cardBrand:brand]; diff --git a/submodules/Stripe/Sources/STPPaymentCardTextFieldViewModel.m b/submodules/Stripe/Sources/STPPaymentCardTextFieldViewModel.m index 014691eba7..b9f3a6ef38 100755 --- a/submodules/Stripe/Sources/STPPaymentCardTextFieldViewModel.m +++ b/submodules/Stripe/Sources/STPPaymentCardTextFieldViewModel.m @@ -67,7 +67,7 @@ break; case STPCardFieldTypeExpiration: { STPCardValidationState monthState = [STPCardValidator validationStateForExpirationMonth:self.expirationMonth]; - STPCardValidationState yearState = [STPCardValidator validationStateForExpirationYear:self.expirationYear inMonth:self.expirationMonth]; + STPCardValidationState yearState = [STPCardValidator validationStateForExpirationYear:self.expirationYear inMonth:self.expirationMonth cardBrand:[STPCardValidator brandForNumber:self.cardNumber]]; if (monthState == STPCardValidationStateValid && yearState == STPCardValidationStateValid) { return STPCardValidationStateValid; } else if (monthState == STPCardValidationStateInvalid || yearState == STPCardValidationStateInvalid) {