Skip to content

Commit

Permalink
Store instantlyVerified in BankAccount instead
Browse files Browse the repository at this point in the history
  • Loading branch information
tillh-stripe committed Nov 25, 2024
1 parent 00a8114 commit a208f9e
Show file tree
Hide file tree
Showing 22 changed files with 146 additions and 218 deletions.
24 changes: 0 additions & 24 deletions financial-connections/api/financial-connections.api
Original file line number Diff line number Diff line change
Expand Up @@ -277,30 +277,6 @@ public final class com/stripe/android/financialconnections/FinancialConnectionsS
public synthetic fun newArray (I)[Ljava/lang/Object;
}

public final class com/stripe/android/financialconnections/FinancialConnectionsSheetInternalResult$Canceled$Creator : android/os/Parcelable$Creator {
public fun <init> ()V
public final fun createFromParcel (Landroid/os/Parcel;)Lcom/stripe/android/financialconnections/FinancialConnectionsSheetInternalResult$Canceled;
public synthetic fun createFromParcel (Landroid/os/Parcel;)Ljava/lang/Object;
public final fun newArray (I)[Lcom/stripe/android/financialconnections/FinancialConnectionsSheetInternalResult$Canceled;
public synthetic fun newArray (I)[Ljava/lang/Object;
}

public final class com/stripe/android/financialconnections/FinancialConnectionsSheetInternalResult$Completed$Creator : android/os/Parcelable$Creator {
public fun <init> ()V
public final fun createFromParcel (Landroid/os/Parcel;)Lcom/stripe/android/financialconnections/FinancialConnectionsSheetInternalResult$Completed;
public synthetic fun createFromParcel (Landroid/os/Parcel;)Ljava/lang/Object;
public final fun newArray (I)[Lcom/stripe/android/financialconnections/FinancialConnectionsSheetInternalResult$Completed;
public synthetic fun newArray (I)[Ljava/lang/Object;
}

public final class com/stripe/android/financialconnections/FinancialConnectionsSheetInternalResult$Failed$Creator : android/os/Parcelable$Creator {
public fun <init> ()V
public final fun createFromParcel (Landroid/os/Parcel;)Lcom/stripe/android/financialconnections/FinancialConnectionsSheetInternalResult$Failed;
public synthetic fun createFromParcel (Landroid/os/Parcel;)Ljava/lang/Object;
public final fun newArray (I)[Lcom/stripe/android/financialconnections/FinancialConnectionsSheetInternalResult$Failed;
public synthetic fun newArray (I)[Ljava/lang/Object;
}

public final class com/stripe/android/financialconnections/FinancialConnectionsSheetRedirectActivity : androidx/appcompat/app/AppCompatActivity {
public static final field $stable I
public fun <init> ()V
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,9 +129,7 @@ class FinancialConnectionsSheet internal constructor(
callback: FinancialConnectionsSheetResultCallback
): FinancialConnectionsSheet {
return FinancialConnectionsSheet(
FinancialConnectionsSheetForDataLauncher(activity) {
callback.onFinancialConnectionsSheetResult(it.toPublicResult())
}
FinancialConnectionsSheetForDataLauncher(activity, callback)
)
}

Expand All @@ -147,9 +145,7 @@ class FinancialConnectionsSheet internal constructor(
callback: FinancialConnectionsSheetResultCallback
): FinancialConnectionsSheet {
return FinancialConnectionsSheet(
FinancialConnectionsSheetForDataLauncher(fragment) {
callback.onFinancialConnectionsSheetResult(it.toPublicResult())
}
FinancialConnectionsSheetForDataLauncher(fragment, callback)
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ fun rememberFinancialConnectionsSheet(
): FinancialConnectionsSheet {
val activityResultLauncher = rememberLauncherForActivityResult(
FinancialConnectionsSheetForDataContract()
) { callback(it.toPublicResult()) }
) { callback(it) }
return remember {
FinancialConnectionsSheet(
FinancialConnectionsSheetForDataLauncher(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
package com.stripe.android.financialconnections

import android.os.Parcelable
import androidx.annotation.RestrictTo
import com.stripe.android.financialconnections.FinancialConnectionsSheetInternalResult.Canceled
import com.stripe.android.financialconnections.FinancialConnectionsSheetInternalResult.Completed
import com.stripe.android.financialconnections.FinancialConnectionsSheetInternalResult.Failed
import com.stripe.android.financialconnections.model.FinancialConnectionsSession
import kotlinx.parcelize.Parcelize

Expand All @@ -18,7 +14,7 @@ sealed class FinancialConnectionsSheetResult : Parcelable {
*/
@Parcelize
data class Completed(
val financialConnectionsSession: FinancialConnectionsSession,
val financialConnectionsSession: FinancialConnectionsSession
) : FinancialConnectionsSheetResult()

/**
Expand All @@ -36,33 +32,3 @@ sealed class FinancialConnectionsSheetResult : Parcelable {
val error: Throwable
) : FinancialConnectionsSheetResult()
}

@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
sealed class FinancialConnectionsSheetInternalResult : Parcelable {

@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
@Parcelize
data class Completed(
val financialConnectionsSession: FinancialConnectionsSession,
val manualEntryUsesMicrodeposits: Boolean,
) : FinancialConnectionsSheetInternalResult()

@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
@Parcelize
data object Canceled : FinancialConnectionsSheetInternalResult()

@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
@Parcelize
data class Failed(
val error: Throwable
) : FinancialConnectionsSheetInternalResult()
}

@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
fun FinancialConnectionsSheetInternalResult.toPublicResult(): FinancialConnectionsSheetResult {
return when (this) {
is Canceled -> FinancialConnectionsSheetResult.Canceled
is Failed -> FinancialConnectionsSheetResult.Failed(error)
is Completed -> FinancialConnectionsSheetResult.Completed(financialConnectionsSession)
}
}
Original file line number Diff line number Diff line change
@@ -1,15 +1,8 @@
package com.stripe.android.financialconnections

import androidx.annotation.RestrictTo

/**
* Callback that is invoked when a [FinancialConnectionsSheetResult] is available.
*/
fun interface FinancialConnectionsSheetResultCallback {
fun onFinancialConnectionsSheetResult(financialConnectionsSheetResult: FinancialConnectionsSheetResult)
}

@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
fun interface FinancialConnectionsSheetInternalResultCallback {
fun onFinancialConnectionsSheetResult(financialConnectionsSheetResult: FinancialConnectionsSheetInternalResult)
}
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ import com.stripe.android.financialconnections.model.FinancialConnectionsSession
import com.stripe.android.financialconnections.model.FinancialConnectionsSessionManifest
import com.stripe.android.financialconnections.model.FinancialConnectionsSessionManifest.Pane
import com.stripe.android.financialconnections.model.SynchronizeSessionResponse
import com.stripe.android.financialconnections.model.update
import com.stripe.android.financialconnections.navigation.topappbar.TopAppBarStateUpdate
import com.stripe.android.financialconnections.presentation.FinancialConnectionsViewModel
import com.stripe.android.financialconnections.ui.FinancialConnectionsSheetNativeActivity
Expand Down Expand Up @@ -297,13 +298,11 @@ internal class FinancialConnectionsSheetViewModel @Inject constructor(
viewModelScope.launch {
kotlin.runCatching {
fetchFinancialConnectionsSession(state.sessionSecret)
}.onSuccess {
}.onSuccess { session ->
val updatedSession = session.update(state.manifest)
finishWithResult(
state = state,
result = Completed(
financialConnectionsSession = it,
manualEntryUsesMicrodeposits = state.manifest?.manualEntryUsesMicrodeposits ?: false,
)
result = Completed(financialConnectionsSession = updatedSession)
)
}.onFailure { error ->
finishWithResult(stateFlow.value, Failed(error))
Expand All @@ -323,12 +322,12 @@ internal class FinancialConnectionsSheetViewModel @Inject constructor(
kotlin.runCatching {
fetchFinancialConnectionsSessionForToken(clientSecret = state.sessionSecret)
}.onSuccess { (las, token) ->
val updatedSession = las.update(state.manifest)
finishWithResult(
state = state,
result = Completed(
financialConnectionsSession = las,
financialConnectionsSession = updatedSession,
token = token,
manualEntryUsesMicrodeposits = state.manifest?.manualEntryUsesMicrodeposits ?: false,
)
)
}.onFailure { error ->
Expand Down Expand Up @@ -465,8 +464,7 @@ internal class FinancialConnectionsSheetViewModel @Inject constructor(
bankName = url.getQueryParameter(QUERY_BANK_NAME)
),
financialConnectionsSession = null,
token = null,
manualEntryUsesMicrodeposits = false,
token = null
)
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,13 @@ internal sealed class FinancialConnectionsSheetActivityResult : Parcelable {
* @param financialConnectionsSession The financial connections session connected
*/
@Parcelize
data class Completed constructor(
data class Completed(
// Instant Debits sessions: return payment method id and bank details.
val instantDebits: InstantDebitsResult? = null,
// non-Link sessions: return full LinkedAccountSession
val financialConnectionsSession: FinancialConnectionsSession? = null,
// Bank account Token sessions: session + token.
val token: Token? = null,
// Temporary field to expose to callers whether the session used microdeposits.
val manualEntryUsesMicrodeposits: Boolean,
val token: Token? = null
) : FinancialConnectionsSheetActivityResult()

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ import android.content.Context
import android.content.Intent
import androidx.activity.result.contract.ActivityResultContract
import com.stripe.android.financialconnections.FinancialConnectionsSheetActivity
import com.stripe.android.financialconnections.FinancialConnectionsSheetInternalResult
import com.stripe.android.financialconnections.FinancialConnectionsSheetResult
import com.stripe.android.financialconnections.launcher.FinancialConnectionsSheetActivityResult.Companion.EXTRA_RESULT

internal class FinancialConnectionsSheetForDataContract :
ActivityResultContract<FinancialConnectionsSheetActivityArgs.ForData, FinancialConnectionsSheetInternalResult>() {
ActivityResultContract<FinancialConnectionsSheetActivityArgs.ForData, FinancialConnectionsSheetResult>() {

override fun createIntent(
context: Context,
Expand All @@ -23,31 +23,30 @@ internal class FinancialConnectionsSheetForDataContract :
override fun parseResult(
resultCode: Int,
intent: Intent?
): FinancialConnectionsSheetInternalResult {
): FinancialConnectionsSheetResult {
return intent
?.getParcelableExtra<FinancialConnectionsSheetActivityResult>(EXTRA_RESULT)
?.toResult()
?: FinancialConnectionsSheetInternalResult.Failed(
?.toExposedResult()
?: FinancialConnectionsSheetResult.Failed(
IllegalArgumentException("Failed to retrieve a ConnectionsSheetResult.")
)
}

private fun FinancialConnectionsSheetActivityResult.toResult(): FinancialConnectionsSheetInternalResult =
private fun FinancialConnectionsSheetActivityResult.toExposedResult(): FinancialConnectionsSheetResult =
when (this) {
is FinancialConnectionsSheetActivityResult.Canceled -> FinancialConnectionsSheetInternalResult.Canceled
is FinancialConnectionsSheetActivityResult.Failed -> FinancialConnectionsSheetInternalResult.Failed(
is FinancialConnectionsSheetActivityResult.Canceled -> FinancialConnectionsSheetResult.Canceled
is FinancialConnectionsSheetActivityResult.Failed -> FinancialConnectionsSheetResult.Failed(
error
)

is FinancialConnectionsSheetActivityResult.Completed ->
when (financialConnectionsSession) {
null -> FinancialConnectionsSheetInternalResult.Failed(
null -> FinancialConnectionsSheetResult.Failed(
IllegalArgumentException("financialConnectionsSession not set.")
)

else -> FinancialConnectionsSheetInternalResult.Completed(
financialConnectionsSession = financialConnectionsSession,
manualEntryUsesMicrodeposits = manualEntryUsesMicrodeposits,
else -> FinancialConnectionsSheetResult.Completed(
financialConnectionsSession = financialConnectionsSession
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import androidx.activity.result.ActivityResultRegistry
import androidx.annotation.RestrictTo
import androidx.fragment.app.Fragment
import com.stripe.android.financialconnections.FinancialConnectionsSheet
import com.stripe.android.financialconnections.FinancialConnectionsSheetInternalResultCallback
import com.stripe.android.financialconnections.FinancialConnectionsSheetResultCallback
import org.jetbrains.annotations.TestOnly

@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
Expand All @@ -16,7 +16,7 @@ class FinancialConnectionsSheetForDataLauncher(

constructor(
activity: ComponentActivity,
callback: FinancialConnectionsSheetInternalResultCallback
callback: FinancialConnectionsSheetResultCallback
) : this(
activity.registerForActivityResult(
FinancialConnectionsSheetForDataContract()
Expand All @@ -27,7 +27,7 @@ class FinancialConnectionsSheetForDataLauncher(

constructor(
fragment: Fragment,
callback: FinancialConnectionsSheetInternalResultCallback
callback: FinancialConnectionsSheetResultCallback
) : this(
fragment.registerForActivityResult(
FinancialConnectionsSheetForDataContract()
Expand All @@ -40,7 +40,7 @@ class FinancialConnectionsSheetForDataLauncher(
constructor(
fragment: Fragment,
registry: ActivityResultRegistry,
callback: FinancialConnectionsSheetInternalResultCallback
callback: FinancialConnectionsSheetResultCallback
) : this(
fragment.registerForActivityResult(
FinancialConnectionsSheetForDataContract(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ data class BankAccount(

@SerialName(value = "bank_name") val bankName: String? = null,

@SerialName(value = "routing_number") val routingNumber: String? = null
@SerialName(value = "routing_number") val routingNumber: String? = null,

// Whether the account is to be verified with microdeposits.
// This field isn't part of the API response and is being set later on.
val usesMicrodeposits: Boolean = true,

) : PaymentAccount()
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package com.stripe.android.financialconnections.model

/**
* Updates the [FinancialConnectionsSession] with any data from the [FinancialConnectionsSessionManifest]
* that's not already present.
*/
internal fun FinancialConnectionsSession.update(
manifest: FinancialConnectionsSessionManifest?,
): FinancialConnectionsSession {
val manualEntryUsesMicrodeposits = manifest?.manualEntryUsesMicrodeposits ?: false
return copy(
paymentAccount = paymentAccount?.setUsesMicrodepositsIfNeeded(manualEntryUsesMicrodeposits),
)
}

/**
* Updates the [FinancialConnectionsSession] with the [usesMicrodeposits] value if the linked account is
* a [BankAccount].
*/
internal fun FinancialConnectionsSession.update(
usesMicrodeposits: Boolean,
): FinancialConnectionsSession {
return copy(
paymentAccount = paymentAccount?.setUsesMicrodepositsIfNeeded(usesMicrodeposits),
)
}

private fun PaymentAccount.setUsesMicrodepositsIfNeeded(
usesMicrodeposits: Boolean,
): PaymentAccount {
return when (this) {
is BankAccount -> copy(usesMicrodeposits = usesMicrodeposits)
is FinancialConnectionsAccount -> this
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ import com.stripe.android.financialconnections.launcher.FinancialConnectionsShee
import com.stripe.android.financialconnections.model.BankAccount
import com.stripe.android.financialconnections.model.FinancialConnectionsSession
import com.stripe.android.financialconnections.model.FinancialConnectionsSessionManifest.Pane
import com.stripe.android.financialconnections.model.update
import com.stripe.android.financialconnections.navigation.Destination
import com.stripe.android.financialconnections.navigation.NavigationManager
import com.stripe.android.financialconnections.navigation.destination
Expand Down Expand Up @@ -334,7 +335,7 @@ internal class FinancialConnectionsSheetNativeViewModel @Inject constructor(
if (state.isLinkWithStripe) {
handleInstantDebitsCompletion(session)
} else {
handleFinancialConnectionsCompletion(session, state.manualEntryUsesMicrodeposits)
handleFinancialConnectionsCompletion(session)
}
}

Expand Down Expand Up @@ -364,21 +365,21 @@ internal class FinancialConnectionsSheetNativeViewModel @Inject constructor(
}
}

private fun handleFinancialConnectionsCompletion(
session: FinancialConnectionsSession,
manualEntryUsesMicrodeposits: Boolean,
) {
private fun handleFinancialConnectionsCompletion(session: FinancialConnectionsSession) {
FinancialConnections.emitEvent(
name = Name.SUCCESS,
metadata = Metadata(
manualEntry = session.paymentAccount is BankAccount,
)
)

val usesMicrodeposits = stateFlow.value.manualEntryUsesMicrodeposits
val updatedSession = session.update(usesMicrodeposits = usesMicrodeposits)

finishWithResult(
Completed(
financialConnectionsSession = session,
token = session.parsedToken,
manualEntryUsesMicrodeposits = manualEntryUsesMicrodeposits,
financialConnectionsSession = updatedSession,
token = updatedSession.parsedToken,
)
)
}
Expand All @@ -391,7 +392,6 @@ internal class FinancialConnectionsSheetNativeViewModel @Inject constructor(
val result = if (instantDebits != null) {
Completed(
instantDebits = instantDebits,
manualEntryUsesMicrodeposits = false,
)
} else {
Failed(
Expand Down
Loading

0 comments on commit a208f9e

Please sign in to comment.