@@ -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,36 +197,70 @@ 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 sameAsShippingElement = sameAsShippingElement,
191203 interactorFactory = it,
192204 shippingValuesMap = args.formArgs.shippingDetails?.toIdentifierMap(args.formArgs.billingDetails),
193205 )
194206 }
195207
196- val addressElement = autocompleteAddressElement ? : AddressElement (
197- _identifier = IdentifierSpec .Generic (" billing_details[address]" ),
198- rawValuesMap = defaultAddress?.asFormFieldValues() ? : emptyMap(),
199- countryCodes = collectionConfiguration.allowedBillingCountries,
200- sameAsShippingElement = sameAsShippingElement,
201- shippingValuesMap = args.formArgs.shippingDetails?.toIdentifierMap(args.formArgs.billingDetails),
202- )
208+ val addressElement: AddressFieldsElement = if (collectingTaxAddress) {
209+ BillingAddressElement (
210+ identifier = IdentifierSpec .Generic (" billing_details[address]" ),
211+ rawValuesMap = defaultAddressValues,
212+ countryCodes = collectionConfiguration.allowedBillingCountries,
213+ countryDropdownFieldController = DropdownFieldController (
214+ config = CountryConfig (collectionConfiguration.allowedBillingCountries),
215+ initialValue = defaultAddressValues[IdentifierSpec .Country ],
216+ ),
217+ countryElementIdentifier = IdentifierSpec .Country ,
218+ autocompleteAddressInteractorFactory = null ,
219+ sameAsShippingElement = sameAsShippingElement,
220+ shippingValuesMap = args.formArgs.shippingDetails?.toIdentifierMap(args.formArgs.billingDetails),
221+ addressCollectionMode = BillingAddressCollectionMode .Country (
222+ additionalFieldsByCountry = additionalAutomaticTaxFieldsByCountry,
223+ ),
224+ collectionConfiguration = BillingDetailsCollectionConfiguration (
225+ collectName = false ,
226+ collectEmail = false ,
227+ collectPhone = false ,
228+ address = BillingDetailsCollectionConfiguration .AddressCollectionMode .Automatic ,
229+ allowedCountries = collectionConfiguration.allowedBillingCountries,
230+ ),
231+ shouldHideCountryOnNoAddressCollection = false ,
232+ )
233+ } else {
234+ autocompleteAddressElement ? : AddressElement (
235+ _identifier = IdentifierSpec .Generic (" billing_details[address]" ),
236+ rawValuesMap = defaultAddressValues,
237+ countryCodes = collectionConfiguration.allowedBillingCountries,
238+ sameAsShippingElement = sameAsShippingElement,
239+ shippingValuesMap = args.formArgs.shippingDetails?.toIdentifierMap(args.formArgs.billingDetails),
240+ )
241+ }
242+
243+ val addressHiddenIdentifiers: StateFlow <Set <IdentifierSpec >> =
244+ (addressElement as ? BillingAddressElement )?.hiddenIdentifiers ? : stateFlowOf(emptySet())
203245
204- val address: StateFlow <Address ?> = addressElement.getFormFieldValueFlow().mapAsStateFlow { formFieldValues ->
205- formFieldValues.takeIf {
206- it.all { value ->
207- value.second.isComplete
246+ val address: StateFlow <Address ?> = combineAsStateFlow(
247+ addressElement.getFormFieldValueFlow(),
248+ addressHiddenIdentifiers,
249+ ) { formFieldValues, hiddenIdentifiers ->
250+ formFieldValues.filterNot { it.first in hiddenIdentifiers }
251+ .takeIf { visibleValues -> visibleValues.all { it.second.isComplete } }
252+ ?.let { values ->
253+ val rawMap = values.associate { it.first to it.second.value }
254+ Address .fromFormFieldValues(rawMap)
208255 }
209- }?.let { values ->
210- val rawMap = values.associate { it.first to it.second.value }
211- Address .fromFormFieldValues(rawMap)
212- }
213256 }
214257
215258 val lastTextFieldIdentifier: StateFlow <IdentifierSpec ?> = if (collectingAddress) {
216- addressElement.getTextFieldIdentifiers().mapAsStateFlow {
217- it.lastOrNull() ? : lastNonAddressTextFieldIdentifier
259+ combineAsStateFlow(
260+ addressElement.getTextFieldIdentifiers(),
261+ addressHiddenIdentifiers,
262+ ) { identifiers, hiddenIdentifiers ->
263+ identifiers.lastOrNull { it !in hiddenIdentifiers } ? : lastNonAddressTextFieldIdentifier
218264 }
219265 } else {
220266 stateFlowOf(lastNonAddressTextFieldIdentifier)
@@ -279,9 +325,7 @@ internal class USBankAccountFormViewModel @Inject internal constructor(
279325 nameController.formFieldValue.mapAsStateFlow { it.isComplete },
280326 emailController.formFieldValue.mapAsStateFlow { it.isComplete },
281327 phoneController.formFieldValue.mapAsStateFlow { it.isComplete },
282- addressElement.getFormFieldValueFlow().mapAsStateFlow { formFieldValues ->
283- formFieldValues.all { it.second.isComplete }
284- }
328+ address.mapAsStateFlow { it != null },
285329 ) { validName, validEmail, validPhone, validAddress ->
286330 val validBaseInfo = if (args.instantDebits) {
287331 validEmail
@@ -290,7 +334,7 @@ internal class USBankAccountFormViewModel @Inject internal constructor(
290334 }
291335
292336 val validAddressInfo = (validPhone || collectionConfiguration.phone != CollectionMode .Always ) &&
293- (validAddress || collectionConfiguration.address != AddressCollectionMode . Full )
337+ (validAddress || collectingAddress. not () )
294338
295339 validBaseInfo && validAddressInfo
296340 }
@@ -873,6 +917,7 @@ internal class USBankAccountFormViewModel @Inject internal constructor(
873917 val sellerBusinessName : String? ,
874918 val forceSetupFutureUseBehavior : Boolean ,
875919 val clientAttributionMetadata : ClientAttributionMetadata ,
920+ val requiresBillingAddressForAutomaticTax : Boolean ,
876921 )
877922
878923 private companion object {
0 commit comments