Skip to content

Commit

Permalink
[BANKCON-14524] Allow pay by bank when linkCardBrand criteria is met …
Browse files Browse the repository at this point in the history
…& dedupe instant debits
  • Loading branch information
mats-stripe committed Sep 25, 2024
1 parent d94be4c commit ccd9427
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -165,12 +165,29 @@ extension PaymentSheet {
// External Payment Methods
+ elementsSession.externalPaymentMethods.map { PaymentMethodType.external($0) }

if
elementsSession.orderedPaymentMethodTypes.contains(.link),
!elementsSession.orderedPaymentMethodTypes.contains(.USBankAccount),
!intent.isDeferredIntent,
// We should manually add Instant Debits as a payment method when:
// - Link is an available payment method.
// - US Bank Account is *not* an available payment method.
// - Not a deferred intent flow.
// - Link Funding Sources contains Bank Account.
var eligibleForInstantDebits: Bool {
elementsSession.orderedPaymentMethodTypes.contains(.link) &&
!elementsSession.orderedPaymentMethodTypes.contains(.USBankAccount) &&
!intent.isDeferredIntent &&
elementsSession.linkFundingSources?.contains(.bankAccount) == true
{
}

// We should manually add Link Card Brand as a payment method when:
// - Link Funding Sources contains Bank Account.
// - US Bank Account is *not* an available payment method.
// - Link Card Brand is the Link Mode
var eligibleForLinkCardBrand: Bool {
elementsSession.linkFundingSources?.contains(.bankAccount) == true &&
!elementsSession.orderedPaymentMethodTypes.contains(.USBankAccount) &&
elementsSession.linkSettings?.linkMode == .linkCardBrand
}

if eligibleForInstantDebits {
let availabilityStatus = configurationSatisfiesRequirements(
requirements: [.financialConnectionsSDK],
configuration: configuration,
Expand All @@ -179,6 +196,16 @@ extension PaymentSheet {
if availabilityStatus == .supported {
recommendedPaymentMethodTypes.append(.instantDebits)
}
// Else if here so we don't show both Instant Debits and Link Card Brand together.
} else if eligibleForLinkCardBrand {
let availabilityStatus = configurationSatisfiesRequirements(
requirements: [.financialConnectionsSDK],
configuration: configuration,
intent: intent
)
if availabilityStatus == .supported {
recommendedPaymentMethodTypes.append(.linkCardBrand)
}
}

if let merchantPaymentMethodOrder = configuration.paymentMethodOrder?.map({ $0.lowercased() }) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -340,6 +340,8 @@ class PaymentSheetPaymentMethodTypeTest: XCTestCase {
XCTAssertEqual(elementsSession.orderedPaymentMethodTypes, [.klarna, .card])
}

// MARK: - Payment Method Types

func testPaymentIntentFilteredPaymentMethodTypes() {
let intent = Intent._testPaymentIntent(paymentMethodTypes: [.card, .klarna, .przelewy24])
var configuration = PaymentSheet.Configuration()
Expand Down Expand Up @@ -407,6 +409,23 @@ class PaymentSheetPaymentMethodTypeTest: XCTestCase {
XCTAssertEqual(types, [.stripe(.card)])
}

func testPaymentMethodTypesLinkCardBrand() {
let intent = Intent._testPaymentIntent(paymentMethodTypes: [.card])
let configuration = PaymentSheet.Configuration()
let types = PaymentSheet.PaymentMethodType.filteredPaymentMethodTypes(
from: intent,
elementsSession: ._testValue(
intent: intent,
linkMode: .linkCardBrand,
linkFundingSources: [.card, .bankAccount]
),
configuration: configuration
)
XCTAssertEqual(types, [.stripe(.card), .linkCardBrand])
}

// MARK: Other

func testUnknownPMTypeIsUnsupported() {
let setupIntent = STPFixtures.makeSetupIntent(paymentMethodTypes: [.unknown])
let paymentMethod = STPPaymentMethod.type(from: "luxe_bucks")
Expand Down Expand Up @@ -518,7 +537,7 @@ extension STPFixtures {
captureMethod: String = "automatic",
confirmationMethod: String = "automatic",
shippingProvided: Bool = false,
paymentMethodJson: [String:Any]? = nil
paymentMethodJson: [String: Any]? = nil
) -> STPPaymentIntent {
var json = STPTestUtils.jsonNamed(STPTestJSONPaymentIntent)!
if let setupFutureUsage = setupFutureUsage {
Expand All @@ -539,7 +558,7 @@ extension STPFixtures {
}
if let paymentMethodJson = paymentMethodJson {
json["payment_method"] = paymentMethodJson

}
if let paymentMethodOptions = paymentMethodOptions {
json["payment_method_options"] = paymentMethodOptions.dictionaryValue
Expand All @@ -550,7 +569,7 @@ extension STPFixtures {
static func makeSetupIntent(
paymentMethodTypes: [STPPaymentMethodType] = [.card],
usage: String = "off_session",
paymentMethodJson: [String:Any]? = nil
paymentMethodJson: [String: Any]? = nil
) -> STPSetupIntent {
var json = STPTestUtils.jsonNamed(STPTestJSONSetupIntent)!
json["usage"] = usage
Expand All @@ -559,7 +578,7 @@ extension STPFixtures {
}
if let paymentMethodJson = paymentMethodJson {
json["payment_method"] = paymentMethodJson

}
return STPSetupIntent.decodedObject(fromAPIResponse: json)!
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ extension STPElementsSession {
customerSessionData: [String: Any]? = nil,
cardBrandChoiceData: [String: Any]? = nil,
isLinkPassthroughModeEnabled: Bool? = nil,
linkMode: LinkSettings.LinkMode? = nil,
linkFundingSources: Set<LinkSettings.FundingSource> = [],
disableLinkSignup: Bool? = nil
) -> STPElementsSession {
var json = STPTestUtils.jsonNamed("ElementsSession")!
Expand Down Expand Up @@ -70,6 +72,12 @@ extension STPElementsSession {
json[jsonDict: "link_settings"]!["link_passthrough_mode_enabled"] = isLinkPassthroughModeEnabled
}

if let linkMode {
json[jsonDict: "link_settings"]!["link_mode"] = linkMode.rawValue
}

json[jsonDict: "link_settings"]!["link_funding_sources"] = linkFundingSources.map(\.rawValue)

if let disableLinkSignup {
json[jsonDict: "link_settings"]!["link_mobile_disable_signup"] = disableLinkSignup
}
Expand All @@ -78,7 +86,11 @@ extension STPElementsSession {
return elementsSession
}

static func _testValue(intent: Intent) -> STPElementsSession {
static func _testValue(
intent: Intent,
linkMode: LinkSettings.LinkMode? = nil,
linkFundingSources: Set<LinkSettings.FundingSource> = []
) -> STPElementsSession {
let paymentMethodTypes: [String] = {
switch intent {
case .paymentIntent(let paymentIntent):
Expand All @@ -89,7 +101,11 @@ extension STPElementsSession {
return intentConfig.paymentMethodTypes ?? []
}
}()
return STPElementsSession._testValue(paymentMethodTypes: paymentMethodTypes)
return STPElementsSession._testValue(
paymentMethodTypes: paymentMethodTypes,
linkMode: linkMode,
linkFundingSources: linkFundingSources
)
}
}

Expand Down

0 comments on commit ccd9427

Please sign in to comment.