diff --git a/StripePaymentSheet/StripePaymentSheetTests/PaymentSheet/PaymentSheetDeferredValidatorTests.swift b/StripePaymentSheet/StripePaymentSheetTests/PaymentSheet/PaymentSheetDeferredValidatorTests.swift index 9c0832c34b5..7db9571ee9f 100644 --- a/StripePaymentSheet/StripePaymentSheetTests/PaymentSheet/PaymentSheetDeferredValidatorTests.swift +++ b/StripePaymentSheet/StripePaymentSheetTests/PaymentSheet/PaymentSheetDeferredValidatorTests.swift @@ -107,6 +107,86 @@ final class PaymentSheetDeferredValidatorTests: XCTestCase { XCTAssertNotNil(analyticEvent?["error_code"] as? String) } + func testPaymentIntentMatchedCardFingerprint() throws { + let testCard = STPPaymentMethod._testCard() + var paymentMethodJson = STPPaymentMethod.paymentMethodJson + paymentMethodJson["id"] = "pm_mismatch_id" + paymentMethodJson["card"] = testCard.card + let testCardPi = STPFixtures.makePaymentIntent(paymentMethodJson: paymentMethodJson) + XCTAssertNoThrow(try PaymentSheetDeferredValidator.validatePaymentMethod(intentPaymentMethod: testCardPi.paymentMethod, + paymentMethod: testCard)) + } + + func testPaymentIntentMismatchedCardFingerprint() throws { + let testCard = STPPaymentMethod._testCard() + var paymentMethodJson = STPPaymentMethod.paymentMethodJson + paymentMethodJson["id"] = "pm_mismatch_id" + paymentMethodJson["card"] = ["fingerprint": "mismatch_fingerprint"] + let testCardPi = STPFixtures.makePaymentIntent(paymentMethodJson: paymentMethodJson) + guard let intentPaymentMethod = testCardPi.paymentMethod else { + return + } + guard let intentPaymentMethodFingerprint = intentPaymentMethod.card?.fingerprint else { + return + } + guard let testCardFingerprint = testCard.card?.fingerprint else { + return + } + XCTAssertThrowsError(try PaymentSheetDeferredValidator.validatePaymentMethod(intentPaymentMethod: testCardPi.paymentMethod, + paymentMethod: testCard)) { error in + XCTAssertEqual("\(error)", """ + An error occurred in PaymentSheet. \nThere is a mismatch between the fingerprint of the payment method on your Intent: \(intentPaymentMethodFingerprint) and the fingerprint of the payment method passed into the `confirmHandler`: \(testCardFingerprint). + + To resolve this issue, you can: + 1. Create a new Intent each time before you call the `confirmHandler`, or + 2. Update the existing Intent with the desired `paymentMethod` before calling the `confirmHandler`. + """) + } + let analyticEvent = STPAnalyticsClient.sharedClient._testLogHistory.last + XCTAssertEqual(analyticEvent?["event"] as? String, STPAnalyticEvent.paymentSheetDeferredIntentPaymentMethodMismatch.rawValue) + XCTAssertNotNil(analyticEvent?["error_code"] as? String) + } + + func testPaymentIntentMatchedUSBankAccountFingerprint() throws { + let testUSBankAccount = STPPaymentMethod._testUSBankAccount() + var paymentMethodJson = STPPaymentMethod.usBankAccountJson + paymentMethodJson["id"] = "pm_mismatch_id" + paymentMethodJson["us_bank_account"] = testUSBankAccount.usBankAccount + let testUSBankAccountPi = STPFixtures.makePaymentIntent(paymentMethodJson: paymentMethodJson) + XCTAssertNoThrow(try PaymentSheetDeferredValidator.validatePaymentMethod(intentPaymentMethod: testUSBankAccountPi.paymentMethod, + paymentMethod: testUSBankAccount)) + } + + func testPaymentIntentMismatchedUSBankAccountFingerprint() throws { + let testUSBankAccount = STPPaymentMethod._testUSBankAccount() + var paymentMethodJson = STPPaymentMethod.usBankAccountJson + paymentMethodJson["id"] = "pm_mismatch_id" + paymentMethodJson["us_bank_account"] = ["fingerprint": "mismatch_fingerprint"] + let testUSBankAccountPi = STPFixtures.makePaymentIntent(paymentMethodJson: paymentMethodJson) + guard let intentPaymentMethod = testUSBankAccountPi.paymentMethod else { + return + } + guard let intentPaymentMethodFingerprint = intentPaymentMethod.card?.fingerprint else { + return + } + guard let testUSBankAccountFingerprint = testUSBankAccount.usBankAccount?.fingerprint else { + return + } + XCTAssertThrowsError(try PaymentSheetDeferredValidator.validatePaymentMethod(intentPaymentMethod: testUSBankAccountPi.paymentMethod, + paymentMethod: testUSBankAccount)) { error in + XCTAssertEqual("\(error)", """ + An error occurred in PaymentSheet. \nThere is a mismatch between the fingerprint of the payment method on your Intent: \(intentPaymentMethodFingerprint) and the fingerprint of the payment method passed into the `confirmHandler`: \(testUSBankAccountFingerprint). + + To resolve this issue, you can: + 1. Create a new Intent each time before you call the `confirmHandler`, or + 2. Update the existing Intent with the desired `paymentMethod` before calling the `confirmHandler`. + """) + } + let analyticEvent = STPAnalyticsClient.sharedClient._testLogHistory.last + XCTAssertEqual(analyticEvent?["event"] as? String, STPAnalyticEvent.paymentSheetDeferredIntentPaymentMethodMismatch.rawValue) + XCTAssertNotNil(analyticEvent?["error_code"] as? String) + } + func testPaymentIntentNilPaymentMethod() throws { let testCard = STPPaymentMethod._testCard() let nilPaymentMethodPi = STPFixtures.makePaymentIntent() diff --git a/StripePaymentSheet/StripePaymentSheetTests/PaymentSheet/STPFixtures+PaymentSheet.swift b/StripePaymentSheet/StripePaymentSheetTests/PaymentSheet/STPFixtures+PaymentSheet.swift index fd15db852e4..c7167d4d47b 100644 --- a/StripePaymentSheet/StripePaymentSheetTests/PaymentSheet/STPFixtures+PaymentSheet.swift +++ b/StripePaymentSheet/StripePaymentSheetTests/PaymentSheet/STPFixtures+PaymentSheet.swift @@ -159,6 +159,7 @@ extension STPPaymentMethod { "card": [ "last4": "4242", "brand": "visa", + "fingerprint": "B8XXs2y2JsVBtB9f", ], ])! } diff --git a/StripePaymentSheet/StripePaymentSheetTests/PaymentSheet/SavedPaymentMethodManagerTest.swift b/StripePaymentSheet/StripePaymentSheetTests/PaymentSheet/SavedPaymentMethodManagerTest.swift index f6f591cdedc..d6699b8b498 100644 --- a/StripePaymentSheet/StripePaymentSheetTests/PaymentSheet/SavedPaymentMethodManagerTest.swift +++ b/StripePaymentSheet/StripePaymentSheetTests/PaymentSheet/SavedPaymentMethodManagerTest.swift @@ -169,9 +169,31 @@ extension STPPaymentMethod { "card": [ "last4": "4242", "brand": "visa", + "fingerprint": "B8XXs2y2JsVBtB9f", ], ] } + + static var usBankAccountJson: [String: Any] { + return [ + "id": "pm_123", + "type": "us_bank_account", + "us_bank_account": [ + "account_holder_type": "individual", + "account_type": "checking", + "bank_name": "STRIPE TEST BANK", + "fingerprint": "ickfX9sbxIyAlbuh", + "last4": "6789", + "networks": [ + "preferred": "ach", + "supported": [ + "ach", + ], + ] as [String: Any], + "routing_number": "110000000", + ] as [String: Any], + ] + } static var paymentMethodsJson: [String: Any] = [ "data": [