Skip to content

Commit

Permalink
Fetch available incentives after linking bank account
Browse files Browse the repository at this point in the history
  • Loading branch information
tillh-stripe committed Dec 4, 2024
1 parent fa657c7 commit 33dc828
Show file tree
Hide file tree
Showing 15 changed files with 96 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -461,7 +461,9 @@ internal class FinancialConnectionsSheetViewModel @Inject constructor(
instantDebits = InstantDebitsResult(
encodedPaymentMethod = paymentMethod,
last4 = url.getQueryParameter(QUERY_PARAM_LAST4),
bankName = url.getQueryParameter(QUERY_BANK_NAME)
bankName = url.getQueryParameter(QUERY_BANK_NAME),
// TODO(tillh-stripe): Pull this from the URL
eligibleForIncentive = false,
),
financialConnectionsSession = null,
token = null
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,24 @@ internal class RealCreateInstantDebitsResult @Inject constructor(
)
}

val incentiveEligibilitySessionId = elementsSessionContext?.incentiveEligibilitySession?.id
val newAccountId = consumerSession?.accountId

val eligibleForIncentive = if (incentiveEligibilitySessionId != null && newAccountId != null) {
val eligibleIncentives = consumerRepository.updateAvailableIncentives(
sessionId = incentiveEligibilitySessionId,
consumerAccount = newAccountId,
)
eligibleIncentives.data.isNotEmpty()
} else {
false
}

return InstantDebitsResult(
encodedPaymentMethod = paymentMethod,
bankName = paymentDetails.bankName,
last4 = paymentDetails.last4,
eligibleForIncentive = eligibleForIncentive,
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -56,5 +56,6 @@ internal sealed class FinancialConnectionsSheetActivityResult : Parcelable {
internal data class InstantDebitsResult(
val encodedPaymentMethod: String,
val last4: String?,
val bankName: String?
val bankName: String?,
val eligibleForIncentive: Boolean,
) : Parcelable
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ class FinancialConnectionsSheetForInstantDebitsContract :
encodedPaymentMethod = instantDebits.encodedPaymentMethod,
last4 = instantDebits.last4,
bankName = instantDebits.bankName,
eligibleForIncentive = instantDebits.eligibleForIncentive,
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,14 @@ import kotlinx.parcelize.Parcelize
sealed class FinancialConnectionsSheetInstantDebitsResult : Parcelable {
/**
* The customer completed the connections session.
* @param paymentMethodId The payment method id, that can be used to confirm the payment.
* @param last4 The last 4 digits of the bank account.
* @param bankName The name of the bank.
*/
@Parcelize
@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
data class Completed(
val encodedPaymentMethod: String,
val last4: String?,
val bankName: String?
val bankName: String?,
val eligibleForIncentive: Boolean,
) : FinancialConnectionsSheetInstantDebitsResult()

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.stripe.android.financialconnections.model

import com.stripe.android.model.LinkConsumerIncentive
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable

@Serializable
internal data class UpdateAvailableIncentives(
@SerialName("data") val data: List<LinkConsumerIncentive>,
)
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ internal const val KeyConsumerSession = "ConsumerSession"

@Parcelize
internal data class CachedConsumerSession(
val accountId: String?,
val emailAddress: String,
val phoneNumber: String,
val clientSecret: String,
Expand All @@ -28,6 +29,7 @@ internal interface ConsumerSessionRepository : ConsumerSessionProvider {
fun storeNewConsumerSession(
consumerSession: ConsumerSession?,
publishableKey: String?,
accountId: String? = null,
)

fun updateConsumerSession(
Expand All @@ -46,8 +48,9 @@ internal class RealConsumerSessionRepository @Inject constructor(
override fun storeNewConsumerSession(
consumerSession: ConsumerSession?,
publishableKey: String?,
accountId: String?,
) {
savedStateHandle[KeyConsumerSession] = consumerSession?.toCached(publishableKey)
savedStateHandle[KeyConsumerSession] = consumerSession?.toCached(publishableKey, accountId)
}

override fun updateConsumerSession(consumerSession: ConsumerSession) {
Expand All @@ -58,7 +61,9 @@ internal class RealConsumerSessionRepository @Inject constructor(

private fun ConsumerSession.toCached(
publishableKey: String?,
accountId: String? = null,
) = CachedConsumerSession(
accountId = accountId,
emailAddress = emailAddress,
phoneNumber = getRedactedPhoneNumber(),
clientSecret = clientSecret,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import com.stripe.android.core.frauddetection.FraudDetectionDataRepository
import com.stripe.android.financialconnections.FinancialConnectionsSheet.ElementsSessionContext
import com.stripe.android.financialconnections.FinancialConnectionsSheet.ElementsSessionContext.BillingDetails
import com.stripe.android.financialconnections.domain.IsLinkWithStripe
import com.stripe.android.financialconnections.model.UpdateAvailableIncentives
import com.stripe.android.financialconnections.repository.api.FinancialConnectionsConsumersApiService
import com.stripe.android.financialconnections.repository.api.ProvideApiRequestOptions
import com.stripe.android.financialconnections.utils.toConsumerBillingAddressParams
Expand Down Expand Up @@ -69,6 +70,11 @@ internal interface FinancialConnectionsConsumerSessionRepository {
billingPhone: String?,
): SharePaymentDetails

suspend fun updateAvailableIncentives(
sessionId: String,
consumerAccount: String,
): UpdateAvailableIncentives

companion object {
operator fun invoke(
consumersApiService: ConsumersApiService,
Expand Down Expand Up @@ -238,6 +244,16 @@ private class FinancialConnectionsConsumerSessionRepositoryImpl(
).getOrThrow()
}

override suspend fun updateAvailableIncentives(
sessionId: String,
consumerAccount: String,
): UpdateAvailableIncentives {
return financialConnectionsConsumersApiService.updateAvailableIncentives(
sessionId = sessionId,
consumerAccount = consumerAccount,
)
}

private suspend fun postConsumerSession(
email: String,
clientSecret: String
Expand Down Expand Up @@ -266,6 +282,10 @@ private class FinancialConnectionsConsumerSessionRepositoryImpl(
signup: ConsumerSessionSignup,
) {
logger.debug("SYNC_CACHE: updating local consumer session from signUp")
consumerSessionRepository.storeNewConsumerSession(signup.consumerSession, signup.publishableKey)
consumerSessionRepository.storeNewConsumerSession(
consumerSession = signup.consumerSession,
publishableKey = signup.publishableKey,
accountId = signup.accountId,
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package com.stripe.android.financialconnections.repository.api

import androidx.annotation.RestrictTo
import com.stripe.android.core.networking.ApiRequest
import com.stripe.android.financialconnections.model.UpdateAvailableIncentives
import com.stripe.android.financialconnections.network.FinancialConnectionsRequestExecutor
import com.stripe.android.financialconnections.utils.filterNotNullValues
import com.stripe.android.model.ConsumerSessionLookup
Expand All @@ -15,6 +16,11 @@ internal interface FinancialConnectionsConsumersApiService {
requestSurface: String,
): ConsumerSessionLookup

suspend fun updateAvailableIncentives(
sessionId: String,
consumerAccount: String,
): UpdateAvailableIncentives

companion object {
operator fun invoke(
requestExecutor: FinancialConnectionsRequestExecutor,
Expand Down Expand Up @@ -59,6 +65,24 @@ private class FinancialConnectionsConsumersApiServiceImpl(
)
}

override suspend fun updateAvailableIncentives(
sessionId: String,
consumerAccount: String,
): UpdateAvailableIncentives {
val request = apiRequestFactory.createPost(
consumerSessionsUrl,
apiOptions,
mapOf(
"session_id" to sessionId,
"consumer_account" to consumerAccount,
).filterNotNullValues()
)
return requestExecutor.execute(
request,
UpdateAvailableIncentives.serializer()
)
}

private companion object {
/**
* @return `https://api.stripe.com/v1/connections/link_account_sessions/consumer_sessions`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ sealed interface CollectBankAccountForInstantDebitsResult : Parcelable {
val intent: StripeIntent?,
val paymentMethod: PaymentMethod,
val last4: String?,
val bankName: String?
val bankName: String?,
val eligibleForIncentive: Boolean,
) : CollectBankAccountForInstantDebitsResult

@Parcelize
Expand Down Expand Up @@ -51,7 +52,8 @@ internal fun CollectBankAccountResultInternal.toInstantDebitsResult(): CollectBa
intent = response.intent,
paymentMethod = response.instantDebitsData.paymentMethod,
last4 = response.instantDebitsData.last4,
bankName = response.instantDebitsData.bankName
bankName = response.instantDebitsData.bankName,
eligibleForIncentive = response.instantDebitsData.eligibleForIncentive,
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ data class CollectBankAccountResponseInternal(
data class InstantDebitsData(
val paymentMethod: PaymentMethod,
val last4: String?,
val bankName: String?
val bankName: String?,
val eligibleForIncentive: Boolean,
) : StripeModel
}
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,7 @@ internal class CollectBankAccountViewModel @Inject constructor(
paymentMethod = it,
last4 = result.last4,
bankName = result.bankName,
eligibleForIncentive = result.eligibleForIncentive,
)
},
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import kotlinx.serialization.Serializable
@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
@Serializable
data class ConsumerSessionSignup(
@SerialName("account_id")
val accountId: String,
@SerialName("consumer_session")
val consumerSession: ConsumerSession,
@SerialName("publishable_key")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,19 @@ package com.stripe.android.model
import androidx.annotation.RestrictTo
import com.stripe.android.core.model.StripeModel
import kotlinx.parcelize.Parcelize
import kotlinx.serialization.Serializable

@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
@Parcelize
@Serializable
data class LinkConsumerIncentive(
val incentiveParams: IncentiveParams,
val incentiveDisplayText: String?,
) : StripeModel {

@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
@Parcelize
@Serializable
data class IncentiveParams(
val paymentMethod: String,
) : StripeModel
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,7 @@ internal class USBankAccountFormViewModel @Inject internal constructor(
financialConnectionsSessionId = null,
mandateText = buildMandateText(isVerifyWithMicrodeposits = false),
isVerifyingWithMicrodeposits = false,
eligibleForIncentive = result.eligibleForIncentive,
)
)
}
Expand Down

0 comments on commit 33dc828

Please sign in to comment.