diff --git a/Stripe/STPBINRange.m b/Stripe/STPBINRange.m index 39c3a06c1fd..5890f1b8f75 100644 --- a/Stripe/STPBINRange.m +++ b/Stripe/STPBINRange.m @@ -38,9 +38,9 @@ @implementation STPBINRange @[@"37", @"37", @15, @(STPCardBrandAmex)], // Diners Club - @[@"30", @"30", @14, @(STPCardBrandDinersClub)], + @[@"30", @"30", @16, @(STPCardBrandDinersClub)], @[@"36", @"36", @14, @(STPCardBrandDinersClub)], - @[@"38", @"39", @14, @(STPCardBrandDinersClub)], + @[@"38", @"39", @16, @(STPCardBrandDinersClub)], // Discover @[@"60", @"60", @16, @(STPCardBrandDiscover)], diff --git a/Stripe/STPCardValidator+Private.h b/Stripe/STPCardValidator+Private.h index e06f919c7b1..04ef1252b60 100644 --- a/Stripe/STPCardValidator+Private.h +++ b/Stripe/STPCardValidator+Private.h @@ -13,6 +13,7 @@ NS_ASSUME_NONNULL_BEGIN @interface STPCardValidator (Private) + (NSArray *)cardNumberFormatForBrand:(STPCardBrand)brand; ++ (NSArray *)cardNumberFormatForCardNumber:(NSString *)cardNumber; @end diff --git a/Stripe/STPCardValidator+Private.m b/Stripe/STPCardValidator+Private.m index 3f82477260c..5552b6a7637 100644 --- a/Stripe/STPCardValidator+Private.m +++ b/Stripe/STPCardValidator+Private.m @@ -7,6 +7,7 @@ // #import "STPCardValidator+Private.h" +#import "STPBINRange.h" NS_ASSUME_NONNULL_BEGIN @@ -17,13 +18,21 @@ @implementation STPCardValidator (Private) switch (brand) { case STPCardBrandAmex: return @[@4, @6, @5]; - case STPCardBrandDinersClub: - return @[@4, @6, @4]; default: return @[@4, @4, @4, @4]; } } ++ (NSArray *)cardNumberFormatForCardNumber:(NSString *)cardNumber +{ + STPBINRange *binRange = [STPBINRange mostSpecificBINRangeForNumber:cardNumber]; + if (binRange.brand == STPCardBrandDinersClub && binRange.length == 14) { + return @[@4, @6, @4]; + } + + return [self cardNumberFormatForBrand:binRange.brand]; +} + @end NS_ASSUME_NONNULL_END diff --git a/Stripe/STPFormTextField.m b/Stripe/STPFormTextField.m index af4066daa45..8d71f8510ed 100644 --- a/Stripe/STPFormTextField.m +++ b/Stripe/STPFormTextField.m @@ -133,8 +133,7 @@ - (void)setAutoFormattingBehavior:(STPFormTextFieldAutoFormattingBehavior)autoFo return [inputString copy]; } NSMutableAttributedString *attributedString = [inputString mutableCopy]; - STPCardBrand currentBrand = [STPCardValidator brandForNumber:attributedString.string]; - NSArray *cardNumberFormat = [STPCardValidator cardNumberFormatForBrand:currentBrand]; + NSArray *cardNumberFormat = [STPCardValidator cardNumberFormatForCardNumber:attributedString.string]; NSUInteger index = 0; for (NSNumber *segmentLength in cardNumberFormat) { diff --git a/Stripe/STPPaymentCardTextField.m b/Stripe/STPPaymentCardTextField.m index d6259f0e986..de428f17224 100644 --- a/Stripe/STPPaymentCardTextField.m +++ b/Stripe/STPPaymentCardTextField.m @@ -741,7 +741,7 @@ - (CGFloat)numberFieldCompressedWidth { } STPCardBrand currentBrand = [STPCardValidator brandForNumber:cardNumber]; - NSArray *sortedCardNumberFormat = [[STPCardValidator cardNumberFormatForBrand:currentBrand] sortedArrayUsingSelector:@selector(unsignedIntegerValue)]; + NSArray *sortedCardNumberFormat = [[STPCardValidator cardNumberFormatForCardNumber:cardNumber] sortedArrayUsingSelector:@selector(unsignedIntegerValue)]; NSUInteger fragmentLength = [STPCardValidator fragmentLengthForCardBrand:currentBrand]; NSUInteger maxLength = MAX([[sortedCardNumberFormat lastObject] unsignedIntegerValue], fragmentLength); diff --git a/Stripe/STPPaymentCardTextFieldViewModel.m b/Stripe/STPPaymentCardTextFieldViewModel.m index 58e08bed16c..83e47ab5a70 100644 --- a/Stripe/STPPaymentCardTextFieldViewModel.m +++ b/Stripe/STPPaymentCardTextFieldViewModel.m @@ -38,7 +38,7 @@ - (NSString *)compressedCardNumber { } } else { // use the card number format - NSArray *cardNumberFormat = [STPCardValidator cardNumberFormatForBrand:currentBrand]; + NSArray *cardNumberFormat = [STPCardValidator cardNumberFormatForCardNumber:cardNumber]; NSUInteger index = 0; for (NSNumber *segment in cardNumberFormat) { diff --git a/Tests/Tests/STPCardValidatorTest.m b/Tests/Tests/STPCardValidatorTest.m index 5216450efc6..ff57a325e44 100644 --- a/Tests/Tests/STPCardValidatorTest.m +++ b/Tests/Tests/STPCardValidatorTest.m @@ -44,8 +44,8 @@ + (NSArray *)cardData { @[@(STPCardBrandAmex), @"371449635398431", @(STPCardValidationStateValid)], @[@(STPCardBrandDiscover), @"6011111111111117", @(STPCardValidationStateValid)], @[@(STPCardBrandDiscover), @"6011000990139424", @(STPCardValidationStateValid)], - @[@(STPCardBrandDinersClub), @"30569309025904", @(STPCardValidationStateValid)], - @[@(STPCardBrandDinersClub), @"38520000023237", @(STPCardValidationStateValid)], + @[@(STPCardBrandDinersClub), @"36227206271667", @(STPCardValidationStateValid)], + @[@(STPCardBrandDinersClub), @"3056930009020004", @(STPCardValidationStateValid)], @[@(STPCardBrandJCB), @"3530111333300000", @(STPCardValidationStateValid)], @[@(STPCardBrandJCB), @"3566002020360505", @(STPCardValidationStateValid)], @[@(STPCardBrandUnknown), @"1234567812345678", @(STPCardValidationStateInvalid)], @@ -132,7 +132,7 @@ - (void)testLengthsForCardBrand { @[@(STPCardBrandMasterCard), @[@16]], @[@(STPCardBrandAmex), @[@15]], @[@(STPCardBrandDiscover), @[@16]], - @[@(STPCardBrandDinersClub), @[@14]], + @[@(STPCardBrandDinersClub), @[@14, @16]], @[@(STPCardBrandJCB), @[@16]], @[@(STPCardBrandUnionPay), @[@16]], @[@(STPCardBrandUnknown), @[@16]], diff --git a/Tests/Tests/STPPaymentCardTextFieldViewModelTest.m b/Tests/Tests/STPPaymentCardTextFieldViewModelTest.m index 9da8891acd0..85e54490971 100644 --- a/Tests/Tests/STPPaymentCardTextFieldViewModelTest.m +++ b/Tests/Tests/STPPaymentCardTextFieldViewModelTest.m @@ -102,14 +102,14 @@ - (void)testCompressedCardNumber { self.viewModel.cardNumber = @"12"; XCTAssertEqualObjects(self.viewModel.compressedCardNumber, @"12"); - self.viewModel.cardNumber = @"30569309025904"; - XCTAssertEqualObjects(self.viewModel.compressedCardNumber, @"5904"); - self.viewModel.cardNumber = @"3056930902590"; - XCTAssertEqualObjects(self.viewModel.compressedCardNumber, @"590"); - self.viewModel.cardNumber = @"30569309025"; - XCTAssertEqualObjects(self.viewModel.compressedCardNumber, @"5"); - self.viewModel.cardNumber = @"3056930902"; - XCTAssertEqualObjects(self.viewModel.compressedCardNumber, @"930902"); + self.viewModel.cardNumber = @"36227206271667"; + XCTAssertEqualObjects(self.viewModel.compressedCardNumber, @"1667"); + self.viewModel.cardNumber = @"3622720627166"; + XCTAssertEqualObjects(self.viewModel.compressedCardNumber, @"166"); + self.viewModel.cardNumber = @"36227206271"; + XCTAssertEqualObjects(self.viewModel.compressedCardNumber, @"1"); + self.viewModel.cardNumber = @"3622720627"; + XCTAssertEqualObjects(self.viewModel.compressedCardNumber, @"720627"); } @end