Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added fingerprint check validation for card and us bank #4207

Merged
merged 11 commits into from
Nov 1, 2024
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import Foundation
import StripePayments
@_spi(STP) import StripeCore
@_spi(STP) import StripePayments

struct PaymentSheetDeferredValidator {
/// Note: We don't validate amount (for any payment method) because there are use cases where the amount can change slightly between PM collection and confirmation.
Expand Down Expand Up @@ -36,7 +37,7 @@ struct PaymentSheetDeferredValidator {
throw PaymentSheetError.deferredIntentValidationFailed(message: "Your PaymentIntent confirmationMethod (\(paymentIntent.confirmationMethod)) can only be used with PaymentSheet.FlowController.")
}
}

static func validate(setupIntent: STPSetupIntent,
intentConfiguration: PaymentSheet.IntentConfiguration,
paymentMethod: STPPaymentMethod) throws {
Expand All @@ -48,12 +49,41 @@ struct PaymentSheetDeferredValidator {
}
try validatePaymentMethodId(intentPaymentMethod: setupIntent.paymentMethod, paymentMethod: paymentMethod)
}

static func validatePaymentMethodId(intentPaymentMethod: STPPaymentMethod?, paymentMethod: STPPaymentMethod) throws {
joyceqin-stripe marked this conversation as resolved.
Show resolved Hide resolved
guard let intentPaymentMethod = intentPaymentMethod else { return }
guard intentPaymentMethod.stripeId == paymentMethod.stripeId else {
if intentPaymentMethod.type == paymentMethod.type {
switch paymentMethod.type.identifier {
yuki-stripe marked this conversation as resolved.
Show resolved Hide resolved
joyceqin-stripe marked this conversation as resolved.
Show resolved Hide resolved
case "card":
try validateFingerprint(intentFingerprint: intentPaymentMethod.card?.fingerprint, fingerprint: paymentMethod.card?.fingerprint)
return
case "us_bank_account":
try validateFingerprint(intentFingerprint: intentPaymentMethod.usBankAccount?.fingerprint, fingerprint: paymentMethod.usBankAccount?.fingerprint)
return
default:
break
}
}
let errorMessage = """
\nThere is a mismatch between the payment method ID on your Intent: \(intentPaymentMethod.stripeId) and the payment method passed into the `confirmHandler`: \(paymentMethod.stripeId).

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 errorAnalytic = ErrorAnalytic(event: .paymentSheetDeferredIntentPaymentMethodIdMismatch, error: PaymentSheetError.unknown(debugDescription: errorMessage))
joyceqin-stripe marked this conversation as resolved.
Show resolved Hide resolved
STPAnalyticsClient.sharedClient.log(analytic: errorAnalytic)
throw PaymentSheetError.deferredIntentValidationFailed(message: errorMessage)
}
}

static func validateFingerprint(intentFingerprint: String?, fingerprint: String?) throws {
guard let intentFingerprint = intentFingerprint else { return }
guard let fingerprint = fingerprint else { return }
guard intentFingerprint == fingerprint else {
let errorMessage = """
\nThere is a mismatch between the fingerprint of the payment method on your Intent: \(intentFingerprint) and the fingerprint of the payment method passed into the `confirmHandler`: \(fingerprint).

To resolve this issue, you can:
1. Create a new Intent each time before you call the `confirmHandler`, or
Expand All @@ -64,6 +94,7 @@ struct PaymentSheetDeferredValidator {
throw PaymentSheetError.deferredIntentValidationFailed(message: errorMessage)
}
}

}

// MARK: - Validation helpers
Expand Down
Loading