Skip to content

Commit d92cd3c

Browse files
cttsai-stripecodex
andcommitted
Use stable automatic-tax billing source signal (MOBILESDK-4667)
Committed-By-Agent: codex Co-authored-by: codex <noreply@openai.com> Committed-By-Agent: codex Co-authored-by: codex <noreply@openai.com> Committed-By-Agent: codex Co-authored-by: codex <noreply@openai.com> Committed-By-Agent: codex Co-authored-by: codex <noreply@openai.com>
1 parent f286cb8 commit d92cd3c

5 files changed

Lines changed: 58 additions & 24 deletions

File tree

paymentsheet/src/main/java/com/stripe/android/lpmfoundations/paymentmethod/PaymentMethodMetadata.kt

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -99,11 +99,13 @@ internal data class PaymentMethodMetadata(
9999
val disableSsdOcrCardScan: Boolean,
100100
val cardArts: List<PaymentMethod.Card.CardArt>,
101101
val shouldUseAutocompleteProxyEndpoints: Boolean,
102-
val requiresBillingAddressForAutomaticTax: Boolean,
103102
val checkoutSessionResponse: CheckoutSessionResponse?,
104103
private val paymentMethodLayout: PaymentSheet.PaymentMethodLayout,
105104
) : Parcelable {
106105

106+
val requiresBillingAddressForAutomaticTax: Boolean
107+
get() = checkoutSessionResponse?.collectsTaxFromBillingAddress == true
108+
107109
fun paymentMethodOrientation(): PaymentMethodOrientation {
108110
return when (paymentMethodLayout) {
109111
PaymentSheet.PaymentMethodLayout.Horizontal -> PaymentMethodOrientation.Horizontal
@@ -383,6 +385,9 @@ internal data class PaymentMethodMetadata(
383385
): PaymentMethodMetadata {
384386
val linkSettings = elementsSession.linkSettings
385387
val cardArts = elementsSession.customer?.paymentMethods?.mapNotNull { it.card?.cardArt }.orEmpty()
388+
val checkoutSessionResponse =
389+
(initializationMode as? PaymentElementLoader.InitializationMode.CheckoutSession)
390+
?.checkoutSessionResponse
386391
return PaymentMethodMetadata(
387392
stripeIntent = elementsSession.stripeIntent,
388393
billingDetailsCollectionConfiguration = configuration.billingDetailsCollectionConfiguration,
@@ -441,10 +446,7 @@ internal data class PaymentMethodMetadata(
441446
disableSsdOcrCardScan = elementsSession.disableSsdOcrCardScan,
442447
cardArts = cardArts,
443448
shouldUseAutocompleteProxyEndpoints = elementsSession.shouldUseAutocompleteProxyEndpoints,
444-
requiresBillingAddressForAutomaticTax = initializationMode.requiresBillingAddressForAutomaticTax(),
445-
checkoutSessionResponse =
446-
(initializationMode as? PaymentElementLoader.InitializationMode.CheckoutSession)
447-
?.checkoutSessionResponse,
449+
checkoutSessionResponse = checkoutSessionResponse,
448450
paymentMethodLayout = paymentMethodLayout,
449451
)
450452
}
@@ -516,7 +518,6 @@ internal data class PaymentMethodMetadata(
516518
disableSsdOcrCardScan = elementsSession.disableSsdOcrCardScan,
517519
cardArts = elementsSession.customer?.paymentMethods?.mapNotNull { it.card?.cardArt }.orEmpty(),
518520
shouldUseAutocompleteProxyEndpoints = elementsSession.shouldUseAutocompleteProxyEndpoints,
519-
requiresBillingAddressForAutomaticTax = false,
520521
checkoutSessionResponse = null,
521522
paymentMethodLayout = PaymentSheet.PaymentMethodLayout.Horizontal,
522523
)

paymentsheet/src/main/java/com/stripe/android/paymentsheet/repositories/CheckoutSessionResponse.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ internal data class CheckoutSessionResponse(
3333
val merchantCountry: String?,
3434
) : StripeModel {
3535

36-
val shouldDisableWalletsForAutomaticTaxBilling: Boolean
36+
val collectsTaxFromBillingAddress: Boolean
3737
get() = automaticTaxEnabled && taxAddressSource == TaxAddressSource.BILLING
3838

3939
enum class TaxAddressSource {

paymentsheet/src/main/java/com/stripe/android/paymentsheet/state/PaymentElementLoader.kt

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ internal interface PaymentElementLoader {
116116
fun walletsDisabledReason(): WalletsDisabledReason? {
117117
val shouldDisable = (this as? CheckoutSession)
118118
?.checkoutSessionResponse
119-
?.shouldDisableWalletsForAutomaticTaxBilling == true
119+
?.collectsTaxFromBillingAddress == true
120120

121121
return if (shouldDisable) {
122122
WalletsDisabledReason.AutomaticTaxBillingAddress
@@ -125,16 +125,6 @@ internal interface PaymentElementLoader {
125125
}
126126
}
127127

128-
/**
129-
* Deliberately narrower than [walletsDisabledReason]: true only while an address is
130-
* still needed, not for the rest of the session once tax is satisfied.
131-
*/
132-
fun requiresBillingAddressForAutomaticTax(): Boolean {
133-
val checkoutSession = this as? CheckoutSession ?: return false
134-
return checkoutSession.checkoutSessionResponse.taxStatus ==
135-
CheckoutSessionResponse.TaxStatus.REQUIRES_BILLING_ADDRESS
136-
}
137-
138128
enum class WalletsDisabledReason {
139129
AutomaticTaxBillingAddress;
140130

paymentsheet/src/test/java/com/stripe/android/lpmfoundations/paymentmethod/PaymentMethodMetadataFactory.kt

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import com.stripe.android.paymentsheet.PaymentSheetFixtures
2121
import com.stripe.android.paymentsheet.addresselement.AddressDetails
2222
import com.stripe.android.paymentsheet.model.PaymentMethodIncentive
2323
import com.stripe.android.paymentsheet.repositories.CheckoutSessionResponse
24+
import com.stripe.android.paymentsheet.repositories.CheckoutSessionResponseFactory
2425
import com.stripe.android.paymentsheet.state.LinkStateResult
2526
import com.stripe.android.ui.core.cbc.CardBrandChoiceEligibility
2627
import com.stripe.android.ui.core.elements.ExternalPaymentMethodSpec
@@ -86,6 +87,15 @@ internal object PaymentMethodMetadataFactory {
8687
checkoutSessionResponse: CheckoutSessionResponse? = null,
8788
paymentMethodLayout: PaymentSheet.PaymentMethodLayout = PaymentSheet.PaymentMethodLayout.Horizontal,
8889
): PaymentMethodMetadata {
90+
val effectiveCheckoutSessionResponse = checkoutSessionResponse ?: if (requiresBillingAddressForAutomaticTax) {
91+
CheckoutSessionResponseFactory.create(
92+
automaticTaxEnabled = true,
93+
taxAddressSource = CheckoutSessionResponse.TaxAddressSource.BILLING,
94+
)
95+
} else {
96+
null
97+
}
98+
8999
return PaymentMethodMetadata(
90100
stripeIntent = stripeIntent,
91101
billingDetailsCollectionConfiguration = billingDetailsCollectionConfiguration,
@@ -157,8 +167,7 @@ internal object PaymentMethodMetadataFactory {
157167
disableSsdOcrCardScan = disableSsdOcrCardScan,
158168
cardArts = cardArts,
159169
shouldUseAutocompleteProxyEndpoints = shouldUseAutocompleteProxyEndpoints,
160-
requiresBillingAddressForAutomaticTax = requiresBillingAddressForAutomaticTax,
161-
checkoutSessionResponse = checkoutSessionResponse,
170+
checkoutSessionResponse = effectiveCheckoutSessionResponse,
162171
paymentMethodLayout = paymentMethodLayout,
163172
)
164173
}

paymentsheet/src/test/java/com/stripe/android/lpmfoundations/paymentmethod/PaymentMethodMetadataTest.kt

Lines changed: 38 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1221,7 +1221,6 @@ internal class PaymentMethodMetadataTest {
12211221
disableSsdOcrCardScan = false,
12221222
cardArts = emptyList(),
12231223
shouldUseAutocompleteProxyEndpoints = false,
1224-
requiresBillingAddressForAutomaticTax = false,
12251224
checkoutSessionResponse = null,
12261225
paymentMethodLayout = PaymentSheet.PaymentMethodLayout.Horizontal,
12271226
)
@@ -1383,7 +1382,6 @@ internal class PaymentMethodMetadataTest {
13831382
disableSsdOcrCardScan = false,
13841383
cardArts = emptyList(),
13851384
shouldUseAutocompleteProxyEndpoints = false,
1386-
requiresBillingAddressForAutomaticTax = false,
13871385
checkoutSessionResponse = null,
13881386
paymentMethodLayout = PaymentSheet.PaymentMethodLayout.Horizontal,
13891387
)
@@ -2176,12 +2174,14 @@ internal class PaymentMethodMetadataTest {
21762174
}
21772175

21782176
@Test
2179-
fun `createForPaymentElement sets requiresBillingAddressForAutomaticTax true when checkout session requires it`() {
2177+
fun `createForPaymentElement requires automatic tax billing address when tax status requires it`() {
21802178
val metadata = createPaymentElementMetadata(
21812179
initializationMode = PaymentElementLoader.InitializationMode.CheckoutSession(
21822180
instancesKey = "key",
21832181
checkoutSessionResponse = CheckoutSessionResponseFactory.create(
21842182
taxStatus = CheckoutSessionResponse.TaxStatus.REQUIRES_BILLING_ADDRESS,
2183+
automaticTaxEnabled = true,
2184+
taxAddressSource = CheckoutSessionResponse.TaxAddressSource.BILLING,
21852185
),
21862186
),
21872187
integrationMetadata = IntegrationMetadata.CheckoutSession(id = "cs_123", instancesKey = "key"),
@@ -2191,12 +2191,46 @@ internal class PaymentMethodMetadataTest {
21912191
}
21922192

21932193
@Test
2194-
fun `createForPaymentElement sets requiresBillingAddressForAutomaticTax false when tax status is ready`() {
2194+
fun `createForPaymentElement requires automatic tax billing address when tax status is ready`() {
21952195
val metadata = createPaymentElementMetadata(
21962196
initializationMode = PaymentElementLoader.InitializationMode.CheckoutSession(
21972197
instancesKey = "key",
21982198
checkoutSessionResponse = CheckoutSessionResponseFactory.create(
21992199
taxStatus = CheckoutSessionResponse.TaxStatus.READY,
2200+
automaticTaxEnabled = true,
2201+
taxAddressSource = CheckoutSessionResponse.TaxAddressSource.BILLING,
2202+
),
2203+
),
2204+
integrationMetadata = IntegrationMetadata.CheckoutSession(id = "cs_123", instancesKey = "key"),
2205+
)
2206+
2207+
assertThat(metadata.requiresBillingAddressForAutomaticTax).isTrue()
2208+
}
2209+
2210+
@Test
2211+
fun `createForPaymentElement does not require automatic tax billing address when automatic tax is disabled`() {
2212+
val metadata = createPaymentElementMetadata(
2213+
initializationMode = PaymentElementLoader.InitializationMode.CheckoutSession(
2214+
instancesKey = "key",
2215+
checkoutSessionResponse = CheckoutSessionResponseFactory.create(
2216+
automaticTaxEnabled = false,
2217+
taxAddressSource = CheckoutSessionResponse.TaxAddressSource.BILLING,
2218+
),
2219+
),
2220+
integrationMetadata = IntegrationMetadata.CheckoutSession(id = "cs_123", instancesKey = "key"),
2221+
)
2222+
2223+
assertThat(metadata.requiresBillingAddressForAutomaticTax).isFalse()
2224+
}
2225+
2226+
@Test
2227+
fun `createForPaymentElement does not require automatic tax billing address when tax uses shipping`() {
2228+
val metadata = createPaymentElementMetadata(
2229+
initializationMode = PaymentElementLoader.InitializationMode.CheckoutSession(
2230+
instancesKey = "key",
2231+
checkoutSessionResponse = CheckoutSessionResponseFactory.create(
2232+
automaticTaxEnabled = true,
2233+
taxAddressSource = CheckoutSessionResponse.TaxAddressSource.SHIPPING,
22002234
),
22012235
),
22022236
integrationMetadata = IntegrationMetadata.CheckoutSession(id = "cs_123", instancesKey = "key"),

0 commit comments

Comments
 (0)