Skip to content
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

Move USBankAccountForm into BankFormElement #9434

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -450,6 +450,7 @@ internal class CustomerSheetViewModel(
* `CustomerSheet` does not implement `Link` so we don't need a coordinator or callback.
*/
linkConfigurationCoordinator = null,
usBankAccountFormArguments = createDefaultUsBankArguments(paymentMethodMetadata.stripeIntent),
onLinkInlineSignupStateChanged = {
throw IllegalStateException(
"`CustomerSheet` does not implement `Link` and should not " +
Expand All @@ -458,9 +459,7 @@ internal class CustomerSheetViewModel(
}
),
) ?: listOf(),
primaryButtonLabel = if (
paymentMethod.code == USBankAccount.code && it.bankAccountSelection == null
) {
primaryButtonLabel = if (paymentMethod.code == USBankAccount.code && it.bankAccountSelection == null) {
UiCoreR.string.stripe_continue_button_label.resolvableString
} else {
R.string.stripe_paymentsheet_save.resolvableString
Expand Down Expand Up @@ -802,8 +801,9 @@ internal class CustomerSheetViewModel(
"`CustomerSheet` does not implement `Link` and should not " +
"receive `InlineSignUpViewState` updates"
)
}
)
},
usBankAccountFormArguments = createDefaultUsBankArguments(stripeIntent),
),
) ?: emptyList()

transition(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.stripe.android.lpmfoundations.luxe

import com.stripe.android.lpmfoundations.paymentmethod.UiDefinitionFactory
import com.stripe.android.paymentsheet.PaymentSheet
import com.stripe.android.paymentsheet.forms.PlaceholderHelper.specsForConfiguration
import com.stripe.android.ui.core.elements.AddressSpec
import com.stripe.android.ui.core.elements.AffirmTextSpec
Expand Down Expand Up @@ -39,7 +40,7 @@ import com.stripe.android.uicore.elements.IdentifierSpec
*
*/
internal class TransformSpecToElements(
private val arguments: UiDefinitionFactory.Arguments,
private val arguments: Arguments,
) {
fun transform(
specs: List<FormItemSpec>,
Expand Down Expand Up @@ -79,4 +80,24 @@ internal class TransformSpecToElements(
}
}
}

data class Arguments(
val initialValues: Map<IdentifierSpec, String?>,
val shippingValues: Map<IdentifierSpec, String?>?,
val merchantName: String,
val billingDetailsCollectionConfiguration: PaymentSheet.BillingDetailsCollectionConfiguration,
val requiresMandate: Boolean,
)
}

internal fun TransformSpecToElements(arguments: UiDefinitionFactory.Arguments): TransformSpecToElements {
return TransformSpecToElements(
arguments = TransformSpecToElements.Arguments(
initialValues = arguments.initialValues,
shippingValues = arguments.shippingValues,
merchantName = arguments.merchantName,
billingDetailsCollectionConfiguration = arguments.billingDetailsCollectionConfiguration,
requiresMandate = arguments.requiresMandate,
)
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,14 @@ import com.stripe.android.model.PaymentMethodCreateParams
import com.stripe.android.model.PaymentMethodExtraParams
import com.stripe.android.paymentsheet.PaymentSheet
import com.stripe.android.paymentsheet.addresselement.toIdentifierMap
import com.stripe.android.paymentsheet.paymentdatacollection.ach.USBankAccountFormArguments
import com.stripe.android.ui.core.cbc.CardBrandChoiceEligibility
import com.stripe.android.ui.core.elements.SharedDataSpec
import com.stripe.android.uicore.elements.FormElement
import com.stripe.android.uicore.elements.IdentifierSpec

internal sealed interface UiDefinitionFactory {
class Arguments(
data class Arguments(
val cardAccountRangeRepositoryFactory: CardAccountRangeRepository.Factory,
val linkConfigurationCoordinator: LinkConfigurationCoordinator?,
val initialValues: Map<IdentifierSpec, String?>,
Expand All @@ -28,6 +29,7 @@ internal sealed interface UiDefinitionFactory {
val cbcEligibility: CardBrandChoiceEligibility,
val billingDetailsCollectionConfiguration: PaymentSheet.BillingDetailsCollectionConfiguration,
val requiresMandate: Boolean,
val usBankAccountFormArguments: USBankAccountFormArguments,
val onLinkInlineSignupStateChanged: (InlineSignupViewState) -> Unit,
val cardBrandFilter: CardBrandFilter,
) {
Expand All @@ -43,6 +45,7 @@ internal sealed interface UiDefinitionFactory {
private val onLinkInlineSignupStateChanged: (InlineSignupViewState) -> Unit,
private val paymentMethodCreateParams: PaymentMethodCreateParams? = null,
private val paymentMethodExtraParams: PaymentMethodExtraParams? = null,
private val usBankAccountFormArguments: USBankAccountFormArguments,
) : Factory {
override fun create(
metadata: PaymentMethodMetadata,
Expand All @@ -62,6 +65,7 @@ internal sealed interface UiDefinitionFactory {
saveForFutureUseInitialValue = false,
billingDetailsCollectionConfiguration = metadata.billingDetailsCollectionConfiguration,
requiresMandate = requiresMandate,
usBankAccountFormArguments = usBankAccountFormArguments,
onLinkInlineSignupStateChanged = onLinkInlineSignupStateChanged,
cardBrandFilter = metadata.cardBrandFilter,
)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
package com.stripe.android.lpmfoundations.paymentmethod.bank

import androidx.compose.runtime.Composable
import androidx.lifecycle.viewmodel.compose.viewModel
import com.stripe.android.lpmfoundations.paymentmethod.PaymentMethodMetadata
import com.stripe.android.model.PaymentMethod
import com.stripe.android.paymentsheet.forms.FormArgumentsFactory
import com.stripe.android.paymentsheet.model.PaymentSelection.New
import com.stripe.android.paymentsheet.paymentdatacollection.FormArguments
import com.stripe.android.paymentsheet.paymentdatacollection.ach.USBankAccountEmitters
import com.stripe.android.paymentsheet.paymentdatacollection.ach.USBankAccountForm
import com.stripe.android.paymentsheet.paymentdatacollection.ach.USBankAccountFormArguments
import com.stripe.android.paymentsheet.paymentdatacollection.ach.USBankAccountFormViewModel
import com.stripe.android.ui.core.elements.RenderableFormElement
import com.stripe.android.uicore.elements.IdentifierSpec
import com.stripe.android.uicore.forms.FormFieldEntry
import com.stripe.android.uicore.utils.stateFlowOf
import kotlinx.coroutines.flow.StateFlow

internal class BankFormElement(
private val formArgs: FormArguments,
private val usBankAccountFormArgs: USBankAccountFormArguments,
) : RenderableFormElement(
allowsUserInteraction = true,
identifier = IdentifierSpec.Generic("bank_form")
) {

override fun getFormFieldValueFlow(): StateFlow<List<Pair<IdentifierSpec, FormFieldEntry>>> {
return stateFlowOf(emptyList())
}

@Composable
override fun ComposeUI(enabled: Boolean) {
val viewModel = viewModel<USBankAccountFormViewModel>(
factory = USBankAccountFormViewModel.Factory {
makeViewModelArgs()
},
)

USBankAccountEmitters(
viewModel = viewModel,
usBankAccountFormArgs = usBankAccountFormArgs,
)

USBankAccountForm(
viewModel = viewModel,
formArgs = formArgs,
usBankAccountFormArgs = usBankAccountFormArgs,
)
}

private fun makeViewModelArgs(): USBankAccountFormViewModel.Args {
return USBankAccountFormViewModel.Args(
instantDebits = usBankAccountFormArgs.instantDebits,
linkMode = usBankAccountFormArgs.linkMode,
formArgs = formArgs,
hostedSurface = usBankAccountFormArgs.hostedSurface,
showCheckbox = usBankAccountFormArgs.showCheckbox,
isCompleteFlow = usBankAccountFormArgs.isCompleteFlow,
isPaymentFlow = usBankAccountFormArgs.isPaymentFlow,
stripeIntentId = usBankAccountFormArgs.stripeIntentId,
clientSecret = usBankAccountFormArgs.clientSecret,
onBehalfOf = usBankAccountFormArgs.onBehalfOf,
savedPaymentMethod = usBankAccountFormArgs.draftPaymentSelection as? New.USBankAccount,
shippingDetails = usBankAccountFormArgs.shippingDetails,
)
}

companion object {

fun create(
usBankAccountFormArgs: USBankAccountFormArguments,
metadata: PaymentMethodMetadata,
): BankFormElement {
val formArgs = FormArgumentsFactory.create(
paymentMethodCode = if (usBankAccountFormArgs.instantDebits) {
PaymentMethod.Type.Link.code
} else {
PaymentMethod.Type.USBankAccount.code
},
metadata = metadata,
)

return BankFormElement(
formArgs = formArgs,
usBankAccountFormArgs = usBankAccountFormArgs,
)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package com.stripe.android.lpmfoundations.paymentmethod.bank

import com.stripe.android.lpmfoundations.luxe.FormElementsBuilder
import com.stripe.android.lpmfoundations.paymentmethod.PaymentMethodMetadata
import com.stripe.android.lpmfoundations.paymentmethod.UiDefinitionFactory
import com.stripe.android.paymentsheet.PaymentSheet
import com.stripe.android.uicore.elements.FormElement

internal object BankFormElementsFactory {

fun create(
metadata: PaymentMethodMetadata,
arguments: UiDefinitionFactory.Arguments,
): List<FormElement> {
val bankFormElement = BankFormElement.create(
usBankAccountFormArgs = arguments.usBankAccountFormArguments,
metadata = metadata,
)

return FormElementsBuilder(arguments.stripBillingDetails())
.element(bankFormElement)
.build()
}
}

private fun UiDefinitionFactory.Arguments.stripBillingDetails(): UiDefinitionFactory.Arguments {
return copy(
billingDetailsCollectionConfiguration = PaymentSheet.BillingDetailsCollectionConfiguration(
name = PaymentSheet.BillingDetailsCollectionConfiguration.CollectionMode.Never,
phone = PaymentSheet.BillingDetailsCollectionConfiguration.CollectionMode.Never,
email = PaymentSheet.BillingDetailsCollectionConfiguration.CollectionMode.Never,
address = PaymentSheet.BillingDetailsCollectionConfiguration.AddressCollectionMode.Never,
attachDefaultsToPaymentMethod = false,
)
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import com.stripe.android.lpmfoundations.paymentmethod.AddPaymentMethodRequireme
import com.stripe.android.lpmfoundations.paymentmethod.PaymentMethodDefinition
import com.stripe.android.lpmfoundations.paymentmethod.PaymentMethodMetadata
import com.stripe.android.lpmfoundations.paymentmethod.UiDefinitionFactory
import com.stripe.android.lpmfoundations.paymentmethod.bank.BankFormElementsFactory
import com.stripe.android.model.PaymentMethod
import com.stripe.android.uicore.elements.FormElement
import com.stripe.android.ui.core.R as PaymentsUiCoreR
Expand Down Expand Up @@ -40,11 +41,10 @@ private object InstantDebitsUiDefinitionFactory : UiDefinitionFactory.Simple {
)
}

// Instant Debits uses its own mechanism, not these form elements.
override fun createFormElements(
metadata: PaymentMethodMetadata,
arguments: UiDefinitionFactory.Arguments,
): List<FormElement> {
return emptyList()
return BankFormElementsFactory.create(metadata, arguments)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import com.stripe.android.lpmfoundations.paymentmethod.AddPaymentMethodRequireme
import com.stripe.android.lpmfoundations.paymentmethod.PaymentMethodDefinition
import com.stripe.android.lpmfoundations.paymentmethod.PaymentMethodMetadata
import com.stripe.android.lpmfoundations.paymentmethod.UiDefinitionFactory
import com.stripe.android.lpmfoundations.paymentmethod.bank.BankFormElementsFactory
import com.stripe.android.model.PaymentMethod
import com.stripe.android.uicore.elements.FormElement
import com.stripe.android.ui.core.R as PaymentsUiCoreR
Expand Down Expand Up @@ -40,11 +41,10 @@ private object LinkCardBrandDefinitionFactory : UiDefinitionFactory.Simple {
)
}

// Link Card Brand uses its own mechanism, not these form elements.
override fun createFormElements(
metadata: PaymentMethodMetadata,
arguments: UiDefinitionFactory.Arguments,
): List<FormElement> {
return emptyList()
return BankFormElementsFactory.create(metadata, arguments)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import com.stripe.android.lpmfoundations.paymentmethod.AddPaymentMethodRequireme
import com.stripe.android.lpmfoundations.paymentmethod.PaymentMethodDefinition
import com.stripe.android.lpmfoundations.paymentmethod.PaymentMethodMetadata
import com.stripe.android.lpmfoundations.paymentmethod.UiDefinitionFactory
import com.stripe.android.lpmfoundations.paymentmethod.bank.BankFormElementsFactory
import com.stripe.android.model.PaymentMethod
import com.stripe.android.ui.core.R
import com.stripe.android.uicore.elements.FormElement
Expand Down Expand Up @@ -46,9 +47,10 @@ private object UsBankAccountUiDefinitionFactory : UiDefinitionFactory.Simple {
)
}

// US Bank Account uses it's own mechanism, not these form elements.
override fun createFormElements(
metadata: PaymentMethodMetadata,
arguments: UiDefinitionFactory.Arguments,
): List<FormElement> = emptyList()
arguments: UiDefinitionFactory.Arguments
): List<FormElement> {
return BankFormElementsFactory.create(metadata, arguments)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import com.stripe.android.paymentsheet.forms.FormArgumentsFactory
import com.stripe.android.paymentsheet.forms.FormFieldValues
import com.stripe.android.paymentsheet.model.PaymentSelection
import com.stripe.android.paymentsheet.paymentdatacollection.FormArguments
import com.stripe.android.paymentsheet.paymentdatacollection.ach.USBankAccountFormArguments
import com.stripe.android.paymentsheet.ui.transformToPaymentSelection
import com.stripe.android.paymentsheet.viewmodels.BaseSheetViewModel
import com.stripe.android.uicore.elements.FormElement
Expand All @@ -21,6 +22,7 @@ internal class FormHelper(
private val paymentMethodMetadata: PaymentMethodMetadata,
private val newPaymentSelectionProvider: () -> NewOrExternalPaymentSelection?,
private val selectionUpdater: (PaymentSelection?) -> Unit,
private val usBankAccountFormArgumentsFactory: (PaymentMethodCode) -> USBankAccountFormArguments,
private val linkConfigurationCoordinator: LinkConfigurationCoordinator,
private val onLinkInlineSignupStateChanged: (InlineSignupViewState) -> Unit,
) {
Expand All @@ -37,6 +39,14 @@ internal class FormHelper(
viewModel.newPaymentSelection
},
linkConfigurationCoordinator = viewModel.linkHandler.linkConfigurationCoordinator,
usBankAccountFormArgumentsFactory = { code ->
USBankAccountFormArguments.create(
viewModel = viewModel,
paymentMethodMetadata = paymentMethodMetadata,
hostedSurface = "payment_element",
selectedPaymentMethodCode = code,
)
},
onLinkInlineSignupStateChanged = linkInlineHandler::onStateUpdated,
selectionUpdater = {
viewModel.updateSelection(it)
Expand All @@ -48,6 +58,8 @@ internal class FormHelper(
fun formElementsForCode(code: String): List<FormElement> {
val currentSelection = newPaymentSelectionProvider()?.takeIf { it.getType() == code }

val usBankAccountFormArguments = usBankAccountFormArgumentsFactory(code)

return paymentMethodMetadata.formElementsForCode(
code = code,
uiDefinitionFactoryArgumentsFactory = UiDefinitionFactory.Arguments.Factory.Default(
Expand All @@ -56,6 +68,7 @@ internal class FormHelper(
onLinkInlineSignupStateChanged = onLinkInlineSignupStateChanged,
paymentMethodCreateParams = currentSelection?.getPaymentMethodCreateParams(),
paymentMethodExtraParams = currentSelection?.getPaymentMethodExtraParams(),
usBankAccountFormArguments = usBankAccountFormArguments,
),
) ?: emptyList()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,7 @@ import com.stripe.android.cards.DefaultCardAccountRangeRepositoryFactory
import com.stripe.android.core.injection.INITIAL_VALUES
import com.stripe.android.core.injection.SHIPPING_VALUES
import com.stripe.android.lpmfoundations.luxe.TransformSpecToElements
import com.stripe.android.lpmfoundations.paymentmethod.UiDefinitionFactory
import com.stripe.android.paymentsheet.PaymentSheet
import com.stripe.android.ui.core.cbc.CardBrandChoiceEligibility
import com.stripe.android.uicore.elements.IdentifierSpec
import dagger.Module
import dagger.Provides
Expand All @@ -18,31 +16,16 @@ import javax.inject.Named
internal object FormControllerModule {
@Provides
fun provideTransformSpecToElements(
context: Context,
merchantName: String,
@Named(INITIAL_VALUES) initialValues: Map<IdentifierSpec, String?>,
@Named(SHIPPING_VALUES) shippingValues: Map<IdentifierSpec, String?>?
) = TransformSpecToElements(
arguments = UiDefinitionFactory.Arguments(
arguments = TransformSpecToElements.Arguments(
initialValues = initialValues,
shippingValues = shippingValues,
saveForFutureUseInitialValue = false,
merchantName = merchantName,
cardAccountRangeRepositoryFactory = DefaultCardAccountRangeRepositoryFactory(context.applicationContext),
cbcEligibility = CardBrandChoiceEligibility.Ineligible,
billingDetailsCollectionConfiguration = PaymentSheet.BillingDetailsCollectionConfiguration(),
requiresMandate = false,
/*
* `FormController` is only used by `AddressElement` now so it does not require a
* `LinkConfigurationCoordinator` instance or a callback for reacting to `InlineSignUpViewState` changes.
*/
linkConfigurationCoordinator = null,
onLinkInlineSignupStateChanged = {
throw IllegalStateException(
"`InlineSignUpViewState` updates should not be received by `FormController`!"
)
},
cardBrandFilter = DefaultCardBrandFilter
)
)
}
Loading
Loading