-
Notifications
You must be signed in to change notification settings - Fork 664
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
Support networking relink flows #10000
Changes from all commits
c95a46a
110ded4
149f6be
aa2a906
2e4c151
1555ddb
ea50ed9
0854f7b
a5cc2df
6656e2e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
package com.stripe.android.financialconnections.domain | ||
|
||
import com.stripe.android.financialconnections.repository.CoreAuthorizationPendingNetworkingRepairRepository | ||
import javax.inject.Inject | ||
|
||
internal fun interface IsNetworkingRelinkSession { | ||
operator fun invoke(): Boolean | ||
} | ||
|
||
internal class RealIsNetworkingRelinkSession @Inject constructor( | ||
private val pendingRepairRepository: CoreAuthorizationPendingNetworkingRepairRepository, | ||
) : IsNetworkingRelinkSession { | ||
|
||
override fun invoke(): Boolean { | ||
return pendingRepairRepository.get() != null | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
package com.stripe.android.financialconnections.domain | ||
|
||
import com.stripe.android.financialconnections.FinancialConnectionsSheet | ||
import com.stripe.android.financialconnections.di.APPLICATION_ID | ||
import com.stripe.android.financialconnections.model.FinancialConnectionsAuthorizationSession | ||
import com.stripe.android.financialconnections.repository.FinancialConnectionsManifestRepository | ||
import javax.inject.Inject | ||
import javax.inject.Named | ||
|
||
internal class RepairAuthorizationSession @Inject constructor( | ||
private val repository: FinancialConnectionsManifestRepository, | ||
private val configuration: FinancialConnectionsSheet.Configuration, | ||
@Named(APPLICATION_ID) private val applicationId: String, | ||
) { | ||
|
||
suspend operator fun invoke( | ||
coreAuthorization: String | ||
): FinancialConnectionsAuthorizationSession { | ||
return repository.repairAuthorizationSession( | ||
clientSecret = configuration.financialConnectionsSessionClientSecret, | ||
coreAuthorization = coreAuthorization, | ||
applicationId = applicationId, | ||
) | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -24,6 +24,7 @@ import com.stripe.android.financialconnections.presentation.Async | |
import com.stripe.android.financialconnections.presentation.Async.Uninitialized | ||
import com.stripe.android.financialconnections.presentation.FinancialConnectionsViewModel | ||
import com.stripe.android.financialconnections.repository.AccountUpdateRequiredContentRepository | ||
import com.stripe.android.financialconnections.repository.CoreAuthorizationPendingNetworkingRepairRepository | ||
import dagger.assisted.Assisted | ||
import dagger.assisted.AssistedFactory | ||
import dagger.assisted.AssistedInject | ||
|
@@ -33,6 +34,7 @@ internal class AccountUpdateRequiredViewModel @AssistedInject constructor( | |
@Assisted initialState: AccountUpdateRequiredState, | ||
nativeAuthFlowCoordinator: NativeAuthFlowCoordinator, | ||
private val updateRequiredContentRepository: AccountUpdateRequiredContentRepository, | ||
private val pendingRepairRepository: CoreAuthorizationPendingNetworkingRepairRepository, | ||
private val navigationManager: NavigationManager, | ||
private val eventTracker: FinancialConnectionsAnalyticsTracker, | ||
private val updateLocalManifest: UpdateLocalManifest, | ||
|
@@ -60,7 +62,7 @@ internal class AccountUpdateRequiredViewModel @AssistedInject constructor( | |
val referrer = state.referrer | ||
when (val type = requireNotNull(state.payload()?.type)) { | ||
is Type.Repair -> { | ||
handleUnsupportedRepairAction(referrer) | ||
openBankAuthRepair(type.institution, type.authorization, referrer) | ||
} | ||
is Type.Supportability -> { | ||
openPartnerAuth(type.institution, referrer) | ||
|
@@ -69,15 +71,31 @@ internal class AccountUpdateRequiredViewModel @AssistedInject constructor( | |
} | ||
} | ||
|
||
private fun handleUnsupportedRepairAction(referrer: Pane) { | ||
eventTracker.logError( | ||
extraMessage = "Updating a repair account, but repairs are not supported in Mobile.", | ||
error = UnclassifiedError("UpdateRepairAccountError"), | ||
logger = logger, | ||
pane = PANE, | ||
) | ||
// Fall back to the institution picker for now | ||
navigationManager.tryNavigateTo(InstitutionPicker(referrer)) | ||
private fun openBankAuthRepair( | ||
institution: FinancialConnectionsInstitution?, | ||
authorization: String?, | ||
referrer: Pane, | ||
) { | ||
if (institution != null && authorization != null) { | ||
updateLocalManifest { | ||
it.copy(activeInstitution = institution) | ||
} | ||
|
||
pendingRepairRepository.set(authorization) | ||
navigationManager.tryNavigateTo(Destination.BankAuthRepair(referrer)) | ||
} else { | ||
val missingAuth = authorization == null | ||
val missingInstitution = institution == null | ||
eventTracker.logError( | ||
extraMessage = "Unable to open repair flow " + | ||
"(missing auth: $missingAuth, missing institution: $missingInstitution).", | ||
error = UnclassifiedError("UpdateRepairAccountError"), | ||
logger = logger, | ||
pane = PANE, | ||
) | ||
// Fall back to the institution picker | ||
navigationManager.tryNavigateTo(InstitutionPicker(referrer)) | ||
Comment on lines
+96
to
+97
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. is this considered an error? should we log anything? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I’ll combing a few |
||
} | ||
} | ||
|
||
private fun openPartnerAuth( | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,10 +9,13 @@ import com.stripe.android.financialconnections.analytics.FinancialConnectionsAna | |
import com.stripe.android.financialconnections.analytics.FinancialConnectionsAnalyticsTracker | ||
import com.stripe.android.financialconnections.analytics.logError | ||
import com.stripe.android.financialconnections.di.FinancialConnectionsSheetNativeComponent | ||
import com.stripe.android.financialconnections.domain.CachedPartnerAccount | ||
import com.stripe.android.financialconnections.domain.GetCachedAccounts | ||
import com.stripe.android.financialconnections.domain.GetOrFetchSync | ||
import com.stripe.android.financialconnections.domain.IsNetworkingRelinkSession | ||
import com.stripe.android.financialconnections.domain.NativeAuthFlowCoordinator | ||
import com.stripe.android.financialconnections.domain.PollAttachPaymentAccount | ||
import com.stripe.android.financialconnections.model.FinancialConnectionsSessionManifest | ||
import com.stripe.android.financialconnections.model.FinancialConnectionsSessionManifest.Pane | ||
import com.stripe.android.financialconnections.model.LinkAccountSessionPaymentAccount | ||
import com.stripe.android.financialconnections.model.PaymentAccountParams | ||
|
@@ -41,7 +44,8 @@ internal class AttachPaymentViewModel @AssistedInject constructor( | |
private val getCachedAccounts: GetCachedAccounts, | ||
private val navigationManager: NavigationManager, | ||
private val getOrFetchSync: GetOrFetchSync, | ||
private val logger: Logger | ||
private val logger: Logger, | ||
private val isNetworkingRelinkSession: IsNetworkingRelinkSession, | ||
) : FinancialConnectionsViewModel<AttachPaymentState>(initialState, nativeAuthFlowCoordinator) { | ||
|
||
init { | ||
|
@@ -60,15 +64,8 @@ internal class AttachPaymentViewModel @AssistedInject constructor( | |
params = PaymentAccountParams.LinkedAccount(requireNotNull(id)) | ||
) | ||
} | ||
if (manifest.isNetworkingUserFlow == true && manifest.accountholderIsLinkConsumer == true) { | ||
result.networkingSuccessful?.let { | ||
successContentRepository.set( | ||
message = PluralId( | ||
value = R.plurals.stripe_success_pane_desc_link_success, | ||
count = accounts.size | ||
) | ||
) | ||
} | ||
if (result.networkingSuccessful == true) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This was broken before, since There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🤦 |
||
setSuccessMessageIfNecessary(manifest, accounts) | ||
} | ||
eventTracker.track( | ||
PollAttachPaymentsSucceeded( | ||
|
@@ -91,6 +88,20 @@ internal class AttachPaymentViewModel @AssistedInject constructor( | |
) | ||
} | ||
|
||
private fun setSuccessMessageIfNecessary( | ||
manifest: FinancialConnectionsSessionManifest, | ||
accounts: List<CachedPartnerAccount>, | ||
) { | ||
if (manifest.canSetCustomLinkSuccessMessage && !isNetworkingRelinkSession()) { | ||
successContentRepository.set( | ||
message = PluralId( | ||
value = R.plurals.stripe_success_pane_desc_link_success, | ||
count = accounts.size | ||
) | ||
) | ||
} | ||
} | ||
|
||
private fun logErrors() { | ||
onAsync( | ||
AttachPaymentState::linkPaymentAccount, | ||
|
@@ -132,3 +143,6 @@ internal class AttachPaymentViewModel @AssistedInject constructor( | |
internal data class AttachPaymentState( | ||
val linkPaymentAccount: Async<LinkAccountSessionPaymentAccount> = Uninitialized | ||
) | ||
|
||
private val FinancialConnectionsSessionManifest.canSetCustomLinkSuccessMessage: Boolean | ||
get() = isNetworkingUserFlow == true && accountholderIsLinkConsumer == true |
This file was deleted.
This file was deleted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We have multiple screens where we want to know if we’re in a networking relink flow. This is easier to inject and test than using the full
CoreAuthorizationPendingNetworkingRepairRepository
.