Skip to content

Commit

Permalink
Don't allow expiration dates >50 years out (stripe#3545)
Browse files Browse the repository at this point in the history
## Summary
Don't allow card numbers with expiration dates more than 50 years out.

## Motivation
Matches the behavior on Android/Web, also specified in [our testing
docs](https://docs.stripe.com/testing?testing-method=card-numbers#invalid-data).

## Testing
Added tests, tested manually in PS Example. Removed "expired card"
server-side confirmation tests, these are no longer valid now that the
expiration date is validated client-side.

## Changelog
Added
  • Loading branch information
davidme-stripe authored Apr 30, 2024
1 parent 11c735b commit 3f2c3ab
Show file tree
Hide file tree
Showing 12 changed files with 94 additions and 98 deletions.
10 changes: 6 additions & 4 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,15 @@
### PaymentSheet
* [Added] Support for Multibanco with PaymentIntents.
* [Fixed] Fixed an issue where STPPaymentHandler sometimes reported errors using `unexpectedErrorCode` instead of a more specific error when customers fail a next action.
* [Fixed] Expiration dates more than 50 years in the past (e.g. `95`) are now blocked.

### Payments
* [Added] Support for Multibanco bindings.
* [Fixed] Expiration dates more than 50 years in the past (e.g. `95`) are now blocked.

## 23.27.1 2024-04-22
### Payments
* [Fixed] An issue where the PrivacyInfo.xcprivacy was not bundled with StripePayments when installing with Cocoapods.
* [Fixed] An issue where the PrivacyInfo.xcprivacy was not bundled with StripePayments when installing with Cocoapods.

### Apple Pay
* [Changed] Apple Pay additionalEnabledApplePayNetworks are now in front of the supported network list.
Expand Down Expand Up @@ -84,7 +86,7 @@

## 23.21.2 2024-02-05
### Payments
* [Changed] We now auto append `mandate_data` when using Klarna with a SetupIntent. If you are interested in using Klarna with SetupIntents you sign up for the beta [here](https://stripe.com/docs/payments/klarna/accept-a-payment).
* [Changed] We now auto append `mandate_data` when using Klarna with a SetupIntent. If you are interested in using Klarna with SetupIntents you sign up for the beta [here](https://stripe.com/docs/payments/klarna/accept-a-payment).

## 23.21.1 2024-01-22
### Payments
Expand All @@ -93,7 +95,7 @@
## 23.21.0 2024-01-16
### PaymentSheet
* [Fixed] Fixed a few design issues on visionOS.
* [Added] Added billing details and type properties to [`PaymentSheet.FlowController.PaymentOptionDisplayData`](https://stripe.dev/stripe-ios/stripepaymentsheet/documentation/stripepaymentsheet/paymentsheet/flowcontroller/paymentoptiondisplaydata).
* [Added] Added billing details and type properties to [`PaymentSheet.FlowController.PaymentOptionDisplayData`](https://stripe.dev/stripe-ios/stripepaymentsheet/documentation/stripepaymentsheet/paymentsheet/flowcontroller/paymentoptiondisplaydata).

## 23.20.0 2023-12-18
### PaymentSheet
Expand Down Expand Up @@ -237,7 +239,7 @@
## 23.12.0 2023-07-31
### PaymentSheet
* [Added] Enable SEPA Debit and iDEAL for SetupIntents and PaymentIntents with setup_future_usage. Note: PaymentSheet doesn't display saved SEPA Debit payment methods yet.
* [Added] Add removeSavedPaymentMethodMessage to PaymentSheet.Configuration and CustomerSheet.Configuration.
* [Added] Add removeSavedPaymentMethodMessage to PaymentSheet.Configuration and CustomerSheet.Configuration.

### Identity
* [Added] Supports [phone verification](https://stripe.com/docs/identity/phone) in Identity mobile SDK.
Expand Down
8 changes: 8 additions & 0 deletions Stripe/StripeiOSTests/CardExpiryDateTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -70,4 +70,12 @@ class CardExpiryDateTests: XCTestCase {
XCTAssertTrue(sut.expired(now: aMonthAfter))
}

func test_90s_not_allowed() throws {
let sutPast = CardExpiryDate(month: 2, year: 1995)
let sutFuture = CardExpiryDate(month: 2, year: 2095)

XCTAssertTrue(sutPast.expired())
XCTAssertTrue(sutFuture.expired())
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,14 @@ class STPCardExpiryInputTextFieldValidatorTests: XCTestCase {
XCTFail("Invalid month+year should be invalid")
}

let nineties = "01/95"
validator.inputValue = nonsensical
if case .invalid(let errorMessage) = validator.validationState {
XCTAssertEqual(errorMessage, "Your card's expiration date is invalid.")
} else {
XCTFail("The 90s are over")
}

validator.inputValue = "2"
if case .incomplete(let description) = validator.validationState {
XCTAssertEqual(description, "Your card's expiration date is incomplete.")
Expand Down
4 changes: 2 additions & 2 deletions Stripe/StripeiOSTests/STPCardFormViewTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ class STPCardFormViewTests: XCTestCase {
let cardFormView = STPCardFormView(billingAddressCollection: .automatic, cbcEnabledOverride: true)
let cardParams = STPPaymentMethodCardParams()
cardParams.number = "5555552500001001"
cardParams.expYear = 2080
cardParams.expYear = 2050
cardParams.expMonth = 12
cardParams.cvc = "123"
cardParams.networks = .init(preferred: "cartes_bancaires")
Expand All @@ -166,7 +166,7 @@ class STPCardFormViewTests: XCTestCase {
let cardFormView = STPCardFormView(billingAddressCollection: .automatic, cbcEnabledOverride: true)
let cardParams = STPPaymentMethodCardParams()
cardParams.number = "5555552500001001"
cardParams.expYear = 2080
cardParams.expYear = 2050
cardParams.expMonth = 12
cardParams.cvc = "1234"
let billingDetails = STPPaymentMethodBillingDetails(postalCode: "12345", countryCode: "US")
Expand Down
12 changes: 8 additions & 4 deletions Stripe/StripeiOSTests/STPCardValidatorTest.swift
Original file line number Diff line number Diff line change
Expand Up @@ -274,10 +274,14 @@ class STPCardValidatorTest: XCTestCase {
("8", "15", .valid),
("9", "15", .valid),
("11", "16", .valid),
("11", "99", .valid),
("01", "99", .valid),
("1", "99", .valid),
("11", "99", .invalid),
("01", "99", .invalid),
("11", "50", .valid),
("01", "50", .valid),
("1", "50", .valid),
("1", "99", .invalid),
("00", "99", .invalid),
("00", "50", .invalid),
("12", "14", .invalid),
("7", "15", .invalid),
("12", "00", .invalid),
Expand All @@ -294,7 +298,7 @@ class STPCardValidatorTest: XCTestCase {
inCurrentYear: 15,
currentMonth: 8
)
XCTAssertEqual(state, test.2)
XCTAssertEqual(state, test.2, "Failed to validate \(test.0)/\(test.1)")
}
}

Expand Down
2 changes: 1 addition & 1 deletion Stripe/StripeiOSTests/STPPaymentCardTextFieldKVOTest.m
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ - (void)setUp {
- (void)testIsValidKVO {
id observer = OCMClassMock([UIViewController class]);
self.sut.numberField.text = @"4242424242424242";
self.sut.expirationField.text = @"10/99";
self.sut.expirationField.text = @"10/50";
self.sut.postalCodeField.text = @"90210";
XCTAssertFalse(self.sut.isValid);

Expand Down
Loading

0 comments on commit 3f2c3ab

Please sign in to comment.