Skip to content

Commit a11abfb

Browse files
committed
Add Link warmup pane for deferred intents
1 parent 475ad81 commit a11abfb

File tree

5 files changed

+76
-18
lines changed

5 files changed

+76
-18
lines changed

StripeFinancialConnections/StripeFinancialConnections/Source/Native/Consent/ConsentDataSource.swift

+51-4
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,12 @@ protocol ConsentDataSource: AnyObject {
1414
var merchantLogo: [String]? { get }
1515
var analyticsClient: FinancialConnectionsAnalyticsClient { get }
1616

17-
func markConsentAcquired() -> Promise<FinancialConnectionsSessionManifest>
17+
func markConsentAcquired() -> Future<ConsentAcquiredResult>
18+
}
19+
20+
struct ConsentAcquiredResult {
21+
var manifest: FinancialConnectionsSessionManifest
22+
var customNextPane: FinancialConnectionsSessionManifest.NextPane?
1823
}
1924

2025
final class ConsentDataSourceImplementation: ConsentDataSource {
@@ -25,24 +30,66 @@ final class ConsentDataSourceImplementation: ConsentDataSource {
2530
private let apiClient: FinancialConnectionsAPIClient
2631
private let clientSecret: String
2732
let analyticsClient: FinancialConnectionsAnalyticsClient
33+
private let elementsSessionContext: ElementsSessionContext?
34+
35+
private var isLinkWithStripe: Bool {
36+
manifest.isLinkWithStripe ?? false
37+
}
2838

2939
init(
3040
manifest: FinancialConnectionsSessionManifest,
3141
consent: FinancialConnectionsConsent,
3242
merchantLogo: [String]?,
3343
apiClient: FinancialConnectionsAPIClient,
3444
clientSecret: String,
35-
analyticsClient: FinancialConnectionsAnalyticsClient
45+
analyticsClient: FinancialConnectionsAnalyticsClient,
46+
elementsSessionContext: ElementsSessionContext?
3647
) {
3748
self.manifest = manifest
3849
self.consent = consent
3950
self.merchantLogo = merchantLogo
4051
self.apiClient = apiClient
4152
self.clientSecret = clientSecret
4253
self.analyticsClient = analyticsClient
54+
self.elementsSessionContext = elementsSessionContext
4355
}
4456

45-
func markConsentAcquired() -> Promise<FinancialConnectionsSessionManifest> {
46-
return apiClient.markConsentAcquired(clientSecret: clientSecret)
57+
func markConsentAcquired() -> Future<ConsentAcquiredResult> {
58+
return apiClient.markConsentAcquired(clientSecret: clientSecret).chained { [weak self] manifest in
59+
let promise = Promise<ConsentAcquiredResult>()
60+
61+
guard let self, self.isLinkWithStripe, self.manifest.accountholderCustomerEmailAddress == nil else {
62+
let result = ConsentAcquiredResult(manifest: manifest, customNextPane: nil)
63+
return Promise(value: result)
64+
}
65+
66+
guard let email = elementsSessionContext?.prefillDetails?.email else {
67+
let result = ConsentAcquiredResult(manifest: manifest, customNextPane: nil)
68+
return Promise(value: result)
69+
}
70+
71+
apiClient.consumerSessionLookup(
72+
emailAddress: email,
73+
clientSecret: clientSecret
74+
).observe { lookupResult in
75+
let customNextPane = lookupResult.hasConsumer ? FinancialConnectionsSessionManifest.NextPane.networkingLinkLoginWarmup : nil
76+
let result = ConsentAcquiredResult(manifest: manifest, customNextPane: customNextPane)
77+
promise.resolve(with: result)
78+
}
79+
80+
return promise
81+
}
82+
}
83+
}
84+
85+
private extension Swift.Result<LookupConsumerSessionResponse, any Error> {
86+
87+
var hasConsumer: Bool {
88+
switch self {
89+
case .success(let lookup):
90+
return lookup.exists
91+
case .failure:
92+
return false
93+
}
4794
}
4895
}

StripeFinancialConnections/StripeFinancialConnections/Source/Native/Consent/ConsentViewController.swift

+4-3
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@ protocol ConsentViewControllerDelegate: AnyObject {
1919
)
2020
func consentViewController(
2121
_ viewController: ConsentViewController,
22-
didConsentWithManifest manifest: FinancialConnectionsSessionManifest
22+
didConsentWithManifest manifest: FinancialConnectionsSessionManifest,
23+
customNextPane: FinancialConnectionsSessionManifest.NextPane?
2324
)
2425
}
2526

@@ -146,8 +147,8 @@ class ConsentViewController: UIViewController {
146147
.observe(on: .main) { [weak self] result in
147148
guard let self = self else { return }
148149
switch result {
149-
case .success(let manifest):
150-
self.delegate?.consentViewController(self, didConsentWithManifest: manifest)
150+
case .success(let result):
151+
self.delegate?.consentViewController(self, didConsentWithManifest: result.manifest, customNextPane: result.customNextPane)
151152
case .failure(let error):
152153
// we display no errors on failure
153154
self.dataSource

StripeFinancialConnections/StripeFinancialConnections/Source/Native/NativeFlowController.swift

+10-6
Original file line numberDiff line numberDiff line change
@@ -614,7 +614,8 @@ extension NativeFlowController: ConsentViewControllerDelegate {
614614

615615
func consentViewController(
616616
_ viewController: ConsentViewController,
617-
didConsentWithManifest manifest: FinancialConnectionsSessionManifest
617+
didConsentWithManifest manifest: FinancialConnectionsSessionManifest,
618+
customNextPane: FinancialConnectionsSessionManifest.NextPane?
618619
) {
619620
delegate?.nativeFlowController(
620621
self,
@@ -623,7 +624,7 @@ extension NativeFlowController: ConsentViewControllerDelegate {
623624

624625
dataManager.manifest = manifest
625626

626-
let nextPane = manifest.nextPane
627+
let nextPane = customNextPane ?? manifest.nextPane
627628
if nextPane == .networkingLinkLoginWarmup {
628629
presentPaneAsSheet(nextPane)
629630
} else {
@@ -1279,7 +1280,8 @@ private func CreatePaneViewController(
12791280
merchantLogo: dataManager.merchantLogo,
12801281
apiClient: dataManager.apiClient,
12811282
clientSecret: dataManager.clientSecret,
1282-
analyticsClient: dataManager.analyticsClient
1283+
analyticsClient: dataManager.analyticsClient,
1284+
elementsSessionContext: dataManager.elementsSessionContext
12831285
)
12841286
let consentViewController = ConsentViewController(dataSource: consentDataSource)
12851287
consentViewController.delegate = nativeFlowController
@@ -1366,9 +1368,10 @@ private func CreatePaneViewController(
13661368
case .networkingLinkVerification:
13671369
let accountholderCustomerEmailAddress = dataManager.manifest.accountholderCustomerEmailAddress
13681370
let consumerSessionEmailAddress = dataManager.consumerSession?.emailAddress
1369-
if let accountholderCustomerEmailAddress = consumerSessionEmailAddress ?? accountholderCustomerEmailAddress {
1371+
let prefillEmailAddress = dataManager.elementsSessionContext?.prefillDetails?.email
1372+
if let email = consumerSessionEmailAddress ?? accountholderCustomerEmailAddress ?? prefillEmailAddress {
13701373
let networkingLinkVerificationDataSource = NetworkingLinkVerificationDataSourceImplementation(
1371-
accountholderCustomerEmailAddress: accountholderCustomerEmailAddress,
1374+
accountholderCustomerEmailAddress: email,
13721375
manifest: dataManager.manifest,
13731376
apiClient: dataManager.apiClient,
13741377
clientSecret: dataManager.clientSecret,
@@ -1492,7 +1495,8 @@ private func CreatePaneViewController(
14921495
apiClient: dataManager.apiClient,
14931496
clientSecret: dataManager.clientSecret,
14941497
analyticsClient: dataManager.analyticsClient,
1495-
nextPaneOrDrawerOnSecondaryCta: parameters?.nextPaneOrDrawerOnSecondaryCta
1498+
nextPaneOrDrawerOnSecondaryCta: parameters?.nextPaneOrDrawerOnSecondaryCta,
1499+
elementsSessionContext: dataManager.elementsSessionContext
14961500
)
14971501
let networkingLinkWarmupViewController = NetworkingLinkLoginWarmupViewController(
14981502
dataSource: networkingLinkWarmupDataSource,

StripeFinancialConnections/StripeFinancialConnections/Source/Native/NetworkingLinkLoginWarmup/NetworkingLinkLoginWarmupDataSource.swift

+9-1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import Foundation
1111
protocol NetworkingLinkLoginWarmupDataSource: AnyObject {
1212
var manifest: FinancialConnectionsSessionManifest { get }
1313
var analyticsClient: FinancialConnectionsAnalyticsClient { get }
14+
var email: String? { get }
1415

1516
func disableNetworking() -> Future<FinancialConnectionsSessionManifest>
1617
}
@@ -22,19 +23,26 @@ final class NetworkingLinkLoginWarmupDataSourceImplementation: NetworkingLinkLog
2223
private let clientSecret: String
2324
let analyticsClient: FinancialConnectionsAnalyticsClient
2425
private let nextPaneOrDrawerOnSecondaryCta: String?
26+
private let elementsSessionContext: ElementsSessionContext?
27+
28+
var email: String? {
29+
manifest.accountholderCustomerEmailAddress ?? elementsSessionContext?.prefillDetails?.email
30+
}
2531

2632
init(
2733
manifest: FinancialConnectionsSessionManifest,
2834
apiClient: FinancialConnectionsAPIClient,
2935
clientSecret: String,
3036
analyticsClient: FinancialConnectionsAnalyticsClient,
31-
nextPaneOrDrawerOnSecondaryCta: String?
37+
nextPaneOrDrawerOnSecondaryCta: String?,
38+
elementsSessionContext: ElementsSessionContext?
3239
) {
3340
self.manifest = manifest
3441
self.apiClient = apiClient
3542
self.clientSecret = clientSecret
3643
self.analyticsClient = analyticsClient
3744
self.nextPaneOrDrawerOnSecondaryCta = nextPaneOrDrawerOnSecondaryCta
45+
self.elementsSessionContext = elementsSessionContext
3846
}
3947

4048
func disableNetworking() -> Future<FinancialConnectionsSessionManifest> {

StripeFinancialConnections/StripeFinancialConnections/Source/Native/NetworkingLinkLoginWarmup/NetworkingLinkLoginWarmupViewController.swift

+2-4
Original file line numberDiff line numberDiff line change
@@ -70,10 +70,8 @@ final class NetworkingLinkLoginWarmupViewController: SheetViewController {
7070
"The subtitle/description of a screen where users are informed that they can sign-in-to Link."
7171
),
7272
contentView: NetworkingLinkLoginWarmupBodyView(
73-
// `accountholderCustomerEmailAddress` should always be non-null, and
74-
// since the email is only used as a visual, it's not worth to throw an error
75-
// if it is null
76-
email: dataSource.manifest.accountholderCustomerEmailAddress ?? "you"
73+
// `email` should always be non-null, and since the email is only used as a visual, it's not worth to throw an error if it is null
74+
email: dataSource.email ?? "you"
7775
)
7876
),
7977
footerView: PaneLayoutView.createFooterView(

0 commit comments

Comments
 (0)