@@ -46,11 +46,18 @@ import com.stripe.android.paymentsheet.paymentdatacollection.ach.BankFormScreenS
4646import com.stripe.android.paymentsheet.paymentdatacollection.ach.USBankAccountFormViewModel.AnalyticsEvent.Finished
4747import com.stripe.android.paymentsheet.paymentdatacollection.ach.di.DaggerUSBankAccountFormComponent
4848import com.stripe.android.paymentsheet.utils.getSetAsDefaultPaymentMethodFromPaymentSelection
49+ import com.stripe.android.ui.core.BillingDetailsCollectionConfiguration
50+ import com.stripe.android.ui.core.elements.BillingAddressCollectionMode
51+ import com.stripe.android.ui.core.elements.BillingAddressElement
4952import com.stripe.android.ui.core.elements.SaveForFutureUseElement
5053import com.stripe.android.ui.core.elements.SetAsDefaultPaymentMethodElement
54+ import com.stripe.android.ui.core.elements.additionalAutomaticTaxFieldsByCountry
5155import com.stripe.android.uicore.elements.AddressElement
56+ import com.stripe.android.uicore.elements.AddressFieldsElement
5257import com.stripe.android.uicore.elements.AutocompleteAddressElement
5358import com.stripe.android.uicore.elements.AutocompleteAddressInteractor
59+ import com.stripe.android.uicore.elements.CountryConfig
60+ import com.stripe.android.uicore.elements.DropdownFieldController
5461import com.stripe.android.uicore.elements.EmailConfig
5562import com.stripe.android.uicore.elements.IdentifierSpec
5663import com.stripe.android.uicore.elements.NameConfig
@@ -81,8 +88,11 @@ internal class USBankAccountFormViewModel @Inject internal constructor(
8188 private val defaultBillingDetails = args.formArgs.billingDetails
8289 private val collectionConfiguration = args.formArgs.billingDetailsCollectionConfiguration
8390
84- private val collectingAddress =
85- args.formArgs.billingDetailsCollectionConfiguration.address == AddressCollectionMode .Full
91+ private val collectingTaxAddress = args.requiresBillingAddressForAutomaticTax &&
92+ collectionConfiguration.address == AddressCollectionMode .Automatic
93+
94+ val collectingAddress = collectionConfiguration.address == AddressCollectionMode .Full ||
95+ collectingTaxAddress
8696
8797 private val collectingPhone =
8898 args.formArgs.billingDetailsCollectionConfiguration.phone == CollectionMode .Always
@@ -171,6 +181,8 @@ internal class USBankAccountFormViewModel @Inject internal constructor(
171181 null
172182 }
173183
184+ private val defaultAddressValues = defaultAddress?.asFormFieldValues() ? : emptyMap()
185+
174186 val sameAsShippingElement = args.formArgs.shippingDetails
175187 ?.toIdentifierMap(defaultBillingDetails)
176188 ?.get(IdentifierSpec .SameAsShipping )
@@ -185,7 +197,7 @@ internal class USBankAccountFormViewModel @Inject internal constructor(
185197 private val autocompleteAddressElement = autocompleteAddressInteractorFactory?.let {
186198 AutocompleteAddressElement (
187199 identifier = IdentifierSpec .Generic (" billing_details[address]" ),
188- initialValues = defaultAddress?.asFormFieldValues() ? : emptyMap() ,
200+ initialValues = defaultAddressValues ,
189201 countryCodes = collectionConfiguration.allowedBillingCountries,
190202 countryElementIdentifier = IdentifierSpec .Country ,
191203 sameAsShippingElement = sameAsShippingElement,
@@ -194,28 +206,64 @@ internal class USBankAccountFormViewModel @Inject internal constructor(
194206 )
195207 }
196208
197- val addressElement = autocompleteAddressElement ? : AddressElement (
198- _identifier = IdentifierSpec .Generic (" billing_details[address]" ),
199- rawValuesMap = defaultAddress?.asFormFieldValues() ? : emptyMap(),
200- countryCodes = collectionConfiguration.allowedBillingCountries,
201- sameAsShippingElement = sameAsShippingElement,
202- shippingValuesMap = args.formArgs.shippingDetails?.toIdentifierMap(args.formArgs.billingDetails),
203- )
209+ val addressElement: AddressFieldsElement = if (collectingTaxAddress) {
210+ BillingAddressElement (
211+ configuration = BillingAddressElement .Configuration (
212+ identifier = IdentifierSpec .Generic (" billing_details[address]" ),
213+ initialValues = defaultAddressValues,
214+ countryCodes = collectionConfiguration.allowedBillingCountries,
215+ countryElementIdentifier = IdentifierSpec .Country ,
216+ autocompleteAddressInteractorFactory = null ,
217+ shippingValues = args.formArgs.shippingDetails?.toIdentifierMap(args.formArgs.billingDetails),
218+ addressCollectionMode = BillingAddressCollectionMode .Country (
219+ additionalFieldsByCountry = additionalAutomaticTaxFieldsByCountry,
220+ ),
221+ collectionConfiguration = BillingDetailsCollectionConfiguration (
222+ collectName = false ,
223+ collectEmail = false ,
224+ collectPhone = false ,
225+ address = BillingDetailsCollectionConfiguration .AddressCollectionMode .Automatic ,
226+ allowedCountries = collectionConfiguration.allowedBillingCountries,
227+ ),
228+ shouldHideCountryOnNoAddressCollection = false ,
229+ ),
230+ countryDropdownFieldController = DropdownFieldController (
231+ config = CountryConfig (collectionConfiguration.allowedBillingCountries),
232+ initialValue = defaultAddressValues[IdentifierSpec .Country ],
233+ ),
234+ sameAsShippingElement = sameAsShippingElement,
235+ )
236+ } else {
237+ autocompleteAddressElement ? : AddressElement (
238+ _identifier = IdentifierSpec .Generic (" billing_details[address]" ),
239+ rawValuesMap = defaultAddressValues,
240+ countryCodes = collectionConfiguration.allowedBillingCountries,
241+ sameAsShippingElement = sameAsShippingElement,
242+ shippingValuesMap = args.formArgs.shippingDetails?.toIdentifierMap(args.formArgs.billingDetails),
243+ )
244+ }
245+
246+ val addressHiddenIdentifiers: StateFlow <Set <IdentifierSpec >> =
247+ (addressElement as ? BillingAddressElement )?.hiddenIdentifiers ? : stateFlowOf(emptySet())
204248
205- val address: StateFlow <Address ?> = addressElement.getFormFieldValueFlow().mapAsStateFlow { formFieldValues ->
206- formFieldValues.takeIf {
207- it.all { value ->
208- value.second.isComplete
249+ val address: StateFlow <Address ?> = combineAsStateFlow(
250+ addressElement.getFormFieldValueFlow(),
251+ addressHiddenIdentifiers,
252+ ) { formFieldValues, hiddenIdentifiers ->
253+ formFieldValues.filterNot { it.first in hiddenIdentifiers }
254+ .takeIf { visibleValues -> visibleValues.all { it.second.isComplete } }
255+ ?.let { values ->
256+ val rawMap = values.associate { it.first to it.second.value }
257+ Address .fromFormFieldValues(rawMap)
209258 }
210- }?.let { values ->
211- val rawMap = values.associate { it.first to it.second.value }
212- Address .fromFormFieldValues(rawMap)
213- }
214259 }
215260
216261 val lastTextFieldIdentifier: StateFlow <IdentifierSpec ?> = if (collectingAddress) {
217- addressElement.getTextFieldIdentifiers().mapAsStateFlow {
218- it.lastOrNull() ? : lastNonAddressTextFieldIdentifier
262+ combineAsStateFlow(
263+ addressElement.getTextFieldIdentifiers(),
264+ addressHiddenIdentifiers,
265+ ) { identifiers, hiddenIdentifiers ->
266+ identifiers.lastOrNull { it !in hiddenIdentifiers } ? : lastNonAddressTextFieldIdentifier
219267 }
220268 } else {
221269 stateFlowOf(lastNonAddressTextFieldIdentifier)
@@ -280,9 +328,7 @@ internal class USBankAccountFormViewModel @Inject internal constructor(
280328 nameController.formFieldValue.mapAsStateFlow { it.isComplete },
281329 emailController.formFieldValue.mapAsStateFlow { it.isComplete },
282330 phoneController.formFieldValue.mapAsStateFlow { it.isComplete },
283- addressElement.getFormFieldValueFlow().mapAsStateFlow { formFieldValues ->
284- formFieldValues.all { it.second.isComplete }
285- }
331+ address.mapAsStateFlow { it != null },
286332 ) { validName, validEmail, validPhone, validAddress ->
287333 val validBaseInfo = if (args.instantDebits) {
288334 validEmail
@@ -291,7 +337,7 @@ internal class USBankAccountFormViewModel @Inject internal constructor(
291337 }
292338
293339 val validAddressInfo = (validPhone || collectionConfiguration.phone != CollectionMode .Always ) &&
294- (validAddress || collectionConfiguration.address != AddressCollectionMode . Full )
340+ (validAddress || collectingAddress. not () )
295341
296342 validBaseInfo && validAddressInfo
297343 }
@@ -874,6 +920,7 @@ internal class USBankAccountFormViewModel @Inject internal constructor(
874920 val sellerBusinessName : String? ,
875921 val forceSetupFutureUseBehavior : Boolean ,
876922 val clientAttributionMetadata : ClientAttributionMetadata ,
923+ val requiresBillingAddressForAutomaticTax : Boolean ,
877924 )
878925
879926 private companion object {
0 commit comments