Skip to content

Commit

Permalink
Don't use a filter on isReady calls for Google Pay (#9580)
Browse files Browse the repository at this point in the history
* Don't use a filter on isReady calls for Google Pay

* Fix a few tests
  • Loading branch information
porter-stripe authored Nov 11, 2024
1 parent 488ac3f commit eed35fc
Show file tree
Hide file tree
Showing 2 changed files with 96 additions and 26 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,8 @@ class GooglePayJsonFactory internal constructor(
.put(
createCardPaymentMethod(
billingAddressParameters,
allowCreditCards
allowCreditCards,
forIsReadyToPayRequest = true
)
)
)
Expand Down Expand Up @@ -263,9 +264,10 @@ class GooglePayJsonFactory internal constructor(
@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
fun createCardPaymentMethod(
billingAddressParameters: BillingAddressParameters?,
allowCreditCards: Boolean?
allowCreditCards: Boolean?,
forIsReadyToPayRequest: Boolean = false
): JSONObject {
val cardPaymentMethodParams = createBaseCardPaymentMethodParams()
val cardPaymentMethodParams = createBaseCardPaymentMethodParams(forIsReadyToPayRequest = forIsReadyToPayRequest)
.apply {
if (billingAddressParameters?.isRequired == true) {
put("billingAddressRequired", true)
Expand All @@ -290,13 +292,20 @@ class GooglePayJsonFactory internal constructor(
.put("tokenizationSpecification", googlePayConfig.tokenizationSpecification)
}

private fun createBaseCardPaymentMethodParams(): JSONObject {
val acceptedCardBrands = DEFAULT_CARD_NETWORKS
.plus(listOf(JCB_CARD_NETWORK).takeIf { isJcbEnabled } ?: emptyList())
.filter {
val cardBrand = networkStringToCardBrandMap[it] ?: CardBrand.Unknown
cardBrandFilter.isAccepted(cardBrand)
}
private fun createBaseCardPaymentMethodParams(forIsReadyToPayRequest: Boolean = false): JSONObject {
val acceptedCardBrands = if (forIsReadyToPayRequest) {
// Use all card networks for isReadyToPayRequest
DEFAULT_CARD_NETWORKS.plus(listOf(JCB_CARD_NETWORK).takeIf { isJcbEnabled } ?: emptyList())
} else {
// Apply filtering for actual payment request
DEFAULT_CARD_NETWORKS
.plus(listOf(JCB_CARD_NETWORK).takeIf { isJcbEnabled } ?: emptyList())
.filter {
val cardBrand = networkStringToCardBrandMap[it] ?: CardBrand.Unknown
cardBrandFilter.isAccepted(cardBrand)
}
}

return JSONObject()
.put("allowedAuthMethods", JSONArray(ALLOWED_AUTH_METHODS))
.put("allowedCardNetworks", JSONArray(acceptedCardBrands))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -327,16 +327,15 @@ class GooglePayJsonFactoryTest {
cardBrandFilter = customCardBrandFilter
)

val isReadyToPayRequestJson = factory.createIsReadyToPayRequest()
val createCardPaymentMethodRequestJson = factory.createCardPaymentMethod(
billingAddressParameters = null,
allowCreditCards = true
)

val allowedCardNetworks = isReadyToPayRequestJson
.getJSONArray("allowedPaymentMethods")
.getJSONObject(0)
val allowedCardNetworks = createCardPaymentMethodRequestJson
.getJSONObject("parameters")
.getJSONArray("allowedCardNetworks")
.let {
StripeJsonUtils.jsonArrayToList(it)
}
.optJSONArray("allowedCardNetworks")
.let { StripeJsonUtils.jsonArrayToList(it) }

assertThat(allowedCardNetworks)
.containsExactly("MASTERCARD", "VISA")
Expand Down Expand Up @@ -365,11 +364,12 @@ class GooglePayJsonFactoryTest {
cardBrandFilter = customCardBrandFilter
)

val isReadyToPayRequestJson = factory.createIsReadyToPayRequest()
val createCardPaymentMethodRequestJson = factory.createCardPaymentMethod(
billingAddressParameters = null,
allowCreditCards = true
)

val allowedCardNetworks = isReadyToPayRequestJson
.getJSONArray("allowedPaymentMethods")
.getJSONObject(0)
val allowedCardNetworks = createCardPaymentMethodRequestJson
.getJSONObject("parameters")
.optJSONArray("allowedCardNetworks")
.let { StripeJsonUtils.jsonArrayToList(it) }
Expand Down Expand Up @@ -499,9 +499,48 @@ class GooglePayJsonFactoryTest {
cardBrandFilter = customCardBrandFilter
)

val createCardPaymentMethodRequestJson = factory.createCardPaymentMethod(
billingAddressParameters = null,
allowCreditCards = true
)

val allowedCardNetworks = createCardPaymentMethodRequestJson
.getJSONObject("parameters")
.optJSONArray("allowedCardNetworks")
.let { StripeJsonUtils.jsonArrayToList(it) }

// JCB should not be included even though JCB is enabled, because it's filtered out
assertThat(allowedCardNetworks)
.containsExactly("AMEX", "DISCOVER", "MASTERCARD", "VISA")
}

@Test
fun `createIsReadyToPayRequest should include all card networks regardless of filter`() {
// Create a CardBrandFilter that only accepts Visa and Mastercard
val customCardBrandFilter = object : CardBrandFilter {
override fun isAccepted(cardBrand: CardBrand): Boolean {
return cardBrand == CardBrand.Visa || cardBrand == CardBrand.MasterCard
}

override fun describeContents(): Int {
throw IllegalStateException("describeContents should not be called.")
}

override fun writeToParcel(p0: Parcel, p1: Int) {
throw IllegalStateException("writeToParcel should not be called.")
}
}

val factory = GooglePayJsonFactory(
googlePayConfig = googlePayConfig,
isJcbEnabled = true,
cardBrandFilter = customCardBrandFilter
)

// Test isReadyToPayRequest
val isReadyToPayRequestJson = factory.createIsReadyToPayRequest()

val allowedCardNetworks = isReadyToPayRequestJson
val isReadyAllowedCardNetworks = isReadyToPayRequestJson
.getJSONArray("allowedPaymentMethods")
.getJSONObject(0)
.getJSONObject("parameters")
Expand All @@ -510,8 +549,30 @@ class GooglePayJsonFactoryTest {
StripeJsonUtils.jsonArrayToList(it)
}

// JCB should not be included even though JCB is enabled, because it's filtered out
assertThat(allowedCardNetworks)
.containsExactly("AMEX", "DISCOVER", "MASTERCARD", "VISA")
// isReadyToPayRequest should include all card networks
assertThat(isReadyAllowedCardNetworks)
.containsExactly("AMEX", "DISCOVER", "MASTERCARD", "VISA", "JCB")

// Test regular payment request
val paymentDataRequestJson = factory.createPaymentDataRequest(
transactionInfo = GooglePayJsonFactory.TransactionInfo(
currencyCode = "USD",
totalPriceStatus = GooglePayJsonFactory.TransactionInfo.TotalPriceStatus.Final,
totalPrice = 100
)
)

val paymentDataAllowedCardNetworks = paymentDataRequestJson
.getJSONArray("allowedPaymentMethods")
.getJSONObject(0)
.getJSONObject("parameters")
.getJSONArray("allowedCardNetworks")
.let {
StripeJsonUtils.jsonArrayToList(it)
}

// Regular payment request should only include filtered card networks
assertThat(paymentDataAllowedCardNetworks)
.containsExactly("MASTERCARD", "VISA")
}
}

0 comments on commit eed35fc

Please sign in to comment.