@@ -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,62 @@ 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+ identifier = IdentifierSpec .Generic (" billing_details[address]" ),
212+ rawValuesMap = defaultAddressValues,
213+ countryCodes = collectionConfiguration.allowedBillingCountries,
214+ countryDropdownFieldController = DropdownFieldController (
215+ config = CountryConfig (collectionConfiguration.allowedBillingCountries),
216+ initialValue = defaultAddressValues[IdentifierSpec .Country ],
217+ ),
218+ countryElementIdentifier = IdentifierSpec .Country ,
219+ autocompleteAddressInteractorFactory = null ,
220+ sameAsShippingElement = sameAsShippingElement,
221+ shippingValuesMap = args.formArgs.shippingDetails?.toIdentifierMap(args.formArgs.billingDetails),
222+ addressCollectionMode = BillingAddressCollectionMode .Country (
223+ additionalFieldsByCountry = additionalAutomaticTaxFieldsByCountry,
224+ ),
225+ collectionConfiguration = BillingDetailsCollectionConfiguration (
226+ collectName = false ,
227+ collectEmail = false ,
228+ collectPhone = false ,
229+ address = BillingDetailsCollectionConfiguration .AddressCollectionMode .Automatic ,
230+ allowedCountries = collectionConfiguration.allowedBillingCountries,
231+ ),
232+ shouldHideCountryOnNoAddressCollection = false ,
233+ )
234+ } else {
235+ autocompleteAddressElement ? : AddressElement (
236+ _identifier = IdentifierSpec .Generic (" billing_details[address]" ),
237+ rawValuesMap = defaultAddressValues,
238+ countryCodes = collectionConfiguration.allowedBillingCountries,
239+ sameAsShippingElement = sameAsShippingElement,
240+ shippingValuesMap = args.formArgs.shippingDetails?.toIdentifierMap(args.formArgs.billingDetails),
241+ )
242+ }
243+
244+ val addressHiddenIdentifiers: StateFlow <Set <IdentifierSpec >> =
245+ (addressElement as ? BillingAddressElement )?.hiddenIdentifiers ? : stateFlowOf(emptySet())
204246
205- val address: StateFlow <Address ?> = addressElement.getFormFieldValueFlow().mapAsStateFlow { formFieldValues ->
206- formFieldValues.takeIf {
207- it.all { value ->
208- value.second.isComplete
247+ val address: StateFlow <Address ?> = combineAsStateFlow(
248+ addressElement.getFormFieldValueFlow(),
249+ addressHiddenIdentifiers,
250+ ) { formFieldValues, hiddenIdentifiers ->
251+ formFieldValues.filterNot { it.first in hiddenIdentifiers }
252+ .takeIf { visibleValues -> visibleValues.all { it.second.isComplete } }
253+ ?.let { values ->
254+ val rawMap = values.associate { it.first to it.second.value }
255+ Address .fromFormFieldValues(rawMap)
209256 }
210- }?.let { values ->
211- val rawMap = values.associate { it.first to it.second.value }
212- Address .fromFormFieldValues(rawMap)
213- }
214257 }
215258
216259 val lastTextFieldIdentifier: StateFlow <IdentifierSpec ?> = if (collectingAddress) {
217- addressElement.getTextFieldIdentifiers().mapAsStateFlow {
218- it.lastOrNull() ? : lastNonAddressTextFieldIdentifier
260+ combineAsStateFlow(
261+ addressElement.getTextFieldIdentifiers(),
262+ addressHiddenIdentifiers,
263+ ) { identifiers, hiddenIdentifiers ->
264+ identifiers.lastOrNull { it !in hiddenIdentifiers } ? : lastNonAddressTextFieldIdentifier
219265 }
220266 } else {
221267 stateFlowOf(lastNonAddressTextFieldIdentifier)
@@ -280,9 +326,7 @@ internal class USBankAccountFormViewModel @Inject internal constructor(
280326 nameController.formFieldValue.mapAsStateFlow { it.isComplete },
281327 emailController.formFieldValue.mapAsStateFlow { it.isComplete },
282328 phoneController.formFieldValue.mapAsStateFlow { it.isComplete },
283- addressElement.getFormFieldValueFlow().mapAsStateFlow { formFieldValues ->
284- formFieldValues.all { it.second.isComplete }
285- }
329+ address.mapAsStateFlow { it != null },
286330 ) { validName, validEmail, validPhone, validAddress ->
287331 val validBaseInfo = if (args.instantDebits) {
288332 validEmail
@@ -291,7 +335,7 @@ internal class USBankAccountFormViewModel @Inject internal constructor(
291335 }
292336
293337 val validAddressInfo = (validPhone || collectionConfiguration.phone != CollectionMode .Always ) &&
294- (validAddress || collectionConfiguration.address != AddressCollectionMode . Full )
338+ (validAddress || collectingAddress. not () )
295339
296340 validBaseInfo && validAddressInfo
297341 }
@@ -874,6 +918,7 @@ internal class USBankAccountFormViewModel @Inject internal constructor(
874918 val sellerBusinessName : String? ,
875919 val forceSetupFutureUseBehavior : Boolean ,
876920 val clientAttributionMetadata : ClientAttributionMetadata ,
921+ val requiresBillingAddressForAutomaticTax : Boolean ,
877922 )
878923
879924 private companion object {
0 commit comments