diff --git a/CHANGELOG.md b/CHANGELOG.md index e309b70db22..c4fe66c68af 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ ### All SDKs * [CHANGED][6608](https://github.com/stripe/stripe-android/pull/6608) Added a `stripe` prefix to our string resources to avoid name conflicts. * [FIXED][6602](https://github.com/stripe/stripe-android/pull/6602) Fixed an issue which caused a compiler error (duplicate class) when including payments *and* identity SDKs. +* [FIXED][6611](https://github.com/stripe/stripe-android/pull/6611) Fixed an issue where countries might be filtered out on old Android versions (notably Kosovo). ## 20.24.0 - 2023-04-24 diff --git a/payments-ui-core/src/main/java/com/stripe/android/ui/core/elements/AddressSpec.kt b/payments-ui-core/src/main/java/com/stripe/android/ui/core/elements/AddressSpec.kt index 376ea44ead7..2845dfcf316 100644 --- a/payments-ui-core/src/main/java/com/stripe/android/ui/core/elements/AddressSpec.kt +++ b/payments-ui-core/src/main/java/com/stripe/android/ui/core/elements/AddressSpec.kt @@ -1,6 +1,7 @@ package com.stripe.android.ui.core.elements import androidx.annotation.RestrictTo +import com.stripe.android.core.model.CountryUtils import com.stripe.android.ui.core.R import com.stripe.android.uicore.address.AddressRepository import com.stripe.android.uicore.elements.AddressElement @@ -12,7 +13,6 @@ import com.stripe.android.uicore.elements.IdentifierSpec import com.stripe.android.uicore.elements.SameAsShippingController import com.stripe.android.uicore.elements.SameAsShippingElement import com.stripe.android.uicore.elements.SectionElement -import com.stripe.android.uicore.elements.supportedBillingCountries import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable import kotlinx.serialization.Transient @@ -30,7 +30,7 @@ data class AddressSpec( override val apiPath: IdentifierSpec = IdentifierSpec.Generic("billing_details[address]"), @SerialName("allowed_country_codes") - val allowedCountryCodes: Set = supportedBillingCountries, + val allowedCountryCodes: Set = CountryUtils.supportedBillingCountries, @SerialName("display_fields") val displayFields: Set = emptySet(), diff --git a/payments-ui-core/src/main/java/com/stripe/android/ui/core/elements/CardBillingSpec.kt b/payments-ui-core/src/main/java/com/stripe/android/ui/core/elements/CardBillingSpec.kt index 2c1a3637f00..b92458cc240 100644 --- a/payments-ui-core/src/main/java/com/stripe/android/ui/core/elements/CardBillingSpec.kt +++ b/payments-ui-core/src/main/java/com/stripe/android/ui/core/elements/CardBillingSpec.kt @@ -1,6 +1,7 @@ package com.stripe.android.ui.core.elements import androidx.annotation.RestrictTo +import com.stripe.android.core.model.CountryUtils import com.stripe.android.ui.core.CardBillingDetailsCollectionConfiguration import com.stripe.android.ui.core.R import com.stripe.android.uicore.address.AddressRepository @@ -8,7 +9,6 @@ import com.stripe.android.uicore.elements.IdentifierSpec import com.stripe.android.uicore.elements.SameAsShippingController import com.stripe.android.uicore.elements.SameAsShippingElement import com.stripe.android.uicore.elements.SectionElement -import com.stripe.android.uicore.elements.supportedBillingCountries import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable @@ -18,7 +18,7 @@ data class CardBillingSpec( @SerialName("api_path") override val apiPath: IdentifierSpec = IdentifierSpec.Generic("card_billing"), @SerialName("allowed_country_codes") - val allowedCountryCodes: Set = supportedBillingCountries, + val allowedCountryCodes: Set = CountryUtils.supportedBillingCountries, @SerialName("collection_mode") val collectionMode: CardBillingDetailsCollectionConfiguration.AddressCollectionMode = CardBillingDetailsCollectionConfiguration.AddressCollectionMode.Automatic, diff --git a/payments-ui-core/src/main/java/com/stripe/android/ui/core/elements/CountrySpec.kt b/payments-ui-core/src/main/java/com/stripe/android/ui/core/elements/CountrySpec.kt index 8fcaa3f0a63..eb438af3adf 100644 --- a/payments-ui-core/src/main/java/com/stripe/android/ui/core/elements/CountrySpec.kt +++ b/payments-ui-core/src/main/java/com/stripe/android/ui/core/elements/CountrySpec.kt @@ -1,11 +1,11 @@ package com.stripe.android.ui.core.elements import androidx.annotation.RestrictTo +import com.stripe.android.core.model.CountryUtils import com.stripe.android.uicore.elements.CountryConfig import com.stripe.android.uicore.elements.CountryElement import com.stripe.android.uicore.elements.DropdownFieldController import com.stripe.android.uicore.elements.IdentifierSpec -import com.stripe.android.uicore.elements.supportedBillingCountries import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable @@ -21,7 +21,7 @@ data class CountrySpec( override val apiPath: IdentifierSpec = IdentifierSpec.Country, @SerialName("allowed_country_codes") - val allowedCountryCodes: Set = supportedBillingCountries + val allowedCountryCodes: Set = CountryUtils.supportedBillingCountries ) : FormItemSpec() { fun transform( initialValues: Map diff --git a/payments-ui-core/src/main/java/com/stripe/android/ui/core/forms/LinkCardForm.kt b/payments-ui-core/src/main/java/com/stripe/android/ui/core/forms/LinkCardForm.kt index 4de2b7a5075..16d8bb665ad 100644 --- a/payments-ui-core/src/main/java/com/stripe/android/ui/core/forms/LinkCardForm.kt +++ b/payments-ui-core/src/main/java/com/stripe/android/ui/core/forms/LinkCardForm.kt @@ -1,16 +1,16 @@ package com.stripe.android.ui.core.forms import androidx.annotation.RestrictTo +import com.stripe.android.core.model.CountryUtils import com.stripe.android.ui.core.elements.CardBillingSpec import com.stripe.android.ui.core.elements.CardDetailsSectionSpec import com.stripe.android.ui.core.elements.LayoutSpec import com.stripe.android.uicore.elements.IdentifierSpec -import com.stripe.android.uicore.elements.supportedBillingCountries @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP) val LinkCardForm = LayoutSpec( listOf( CardDetailsSectionSpec(IdentifierSpec.Generic("card_details_section")), - CardBillingSpec(allowedCountryCodes = supportedBillingCountries) + CardBillingSpec(allowedCountryCodes = CountryUtils.supportedBillingCountries) ) ) diff --git a/stripe-core/src/main/java/com/stripe/android/core/model/CountryUtils.kt b/stripe-core/src/main/java/com/stripe/android/core/model/CountryUtils.kt index 5af4ea687a2..df974070572 100644 --- a/stripe-core/src/main/java/com/stripe/android/core/model/CountryUtils.kt +++ b/stripe-core/src/main/java/com/stripe/android/core/model/CountryUtils.kt @@ -7,19 +7,41 @@ import java.util.Locale @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP) // For paymentsheet -- this still auto-completes object CountryUtils { + + // This comes from: stripe-js-v3/blob/master/src/lib/shared/checkoutSupportedCountries.js + @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP) + val supportedBillingCountries = setOf( + "AD", "AE", "AF", "AG", "AI", "AL", "AM", "AO", "AQ", "AR", "AT", "AU", "AW", "AX", + "AZ", "BA", "BB", "BD", "BE", "BF", "BG", "BH", "BI", "BJ", "BL", "BM", "BN", "BO", + "BQ", "BR", "BS", "BT", "BV", "BW", "BY", "BZ", "CA", "CD", "CF", "CG", "CH", "CI", + "CK", "CL", "CM", "CN", "CO", "CR", "CV", "CW", "CY", "CZ", "DE", "DJ", "DK", "DM", + "DO", "DZ", "EC", "EE", "EG", "EH", "ER", "ES", "ET", "FI", "FJ", "FK", "FO", "FR", + "GA", "GB", "GD", "GE", "GF", "GG", "GH", "GI", "GL", "GM", "GN", "GP", "GQ", "GR", + "GS", "GT", "GU", "GW", "GY", "HK", "HN", "HR", "HT", "HU", "ID", "IE", "IL", "IM", + "IN", "IO", "IQ", "IS", "IT", "JE", "JM", "JO", "JP", "KE", "KG", "KH", "KI", "KM", + "KN", "KR", "KW", "KY", "KZ", "LA", "LB", "LC", "LI", "LK", "LR", "LS", "LT", "LU", + "LV", "LY", "MA", "MC", "MD", "ME", "MF", "MG", "MK", "ML", "MM", "MN", "MO", "MQ", + "MR", "MS", "MT", "MU", "MV", "MW", "MX", "MY", "MZ", "NA", "NC", "NE", "NG", "NI", + "NL", "NO", "NP", "NR", "NU", "NZ", "OM", "PA", "PE", "PF", "PG", "PH", "PK", "PL", + "PM", "PN", "PR", "PS", "PT", "PY", "QA", "RE", "RO", "RS", "RU", "RW", "SA", "SB", + "SC", "SE", "SG", "SH", "SI", "SJ", "SK", "SL", "SM", "SN", "SO", "SR", "SS", "ST", + "SV", "SX", "SZ", "TA", "TC", "TD", "TF", "TG", "TH", "TJ", "TK", "TL", "TM", "TN", + "TO", "TR", "TT", "TV", "TW", "TZ", "UA", "UG", "US", "UY", "UZ", "VA", "VC", "VE", + "VG", "VN", "VU", "WF", "WS", "XK", "YE", "YT", "ZA", "ZM", "ZW" + ) + private val CARD_POSTAL_CODE_COUNTRIES = setOf( "US", "GB", "CA" ) - private fun localizedCountries(currentLocale: Locale) = - Locale.getISOCountries().map { code -> - Country( - CountryCode.create(code), - Locale("", code).getDisplayCountry(currentLocale) - ) - } + private fun localizedCountries(currentLocale: Locale) = supportedBillingCountries.map { code -> + Country( + CountryCode.create(code), + Locale("", code).getDisplayCountry(currentLocale) + ) + } @JvmSynthetic fun getDisplayCountry(countryCode: CountryCode, currentLocale: Locale): String = diff --git a/stripe-core/src/test/java/com/stripe/android/core/model/CountryUtilsTest.kt b/stripe-core/src/test/java/com/stripe/android/core/model/CountryUtilsTest.kt index 6967b753ec3..89d86246732 100644 --- a/stripe-core/src/test/java/com/stripe/android/core/model/CountryUtilsTest.kt +++ b/stripe-core/src/test/java/com/stripe/android/core/model/CountryUtilsTest.kt @@ -64,6 +64,17 @@ class CountryUtilsTest { .isEqualTo("Deutschland") } + @Test + fun countryIsAvailableEvenWhenNotReturnedFrom_getISOCountries() { + // https://github.com/stripe/stripe-android/issues/6501 + // We used to use Locale.getISOCountries instead of our hardcoded set. + // Some countries (notably Kosovo) wasn't available on some older Android versions. + assertThat(CountryUtils.getDisplayCountry(CountryCode.create("XK"), Locale.US)) + .isEqualTo("Kosovo") + val country = CountryUtils.getCountryByCode(CountryCode.create("XK"), Locale.US) + assertThat(country).isEqualTo(Country("XK", "Kosovo")) + } + @Test fun `getOrderedCountriesLocaleLanguage() in the language of the current locale`() { val currentLocale = Locale("de", "DE") diff --git a/stripe-ui-core/api/stripe-ui-core.api b/stripe-ui-core/api/stripe-ui-core.api index 7f3554f36fb..e4dd861dc8e 100644 --- a/stripe-ui-core/api/stripe-ui-core.api +++ b/stripe-ui-core/api/stripe-ui-core.api @@ -78,9 +78,6 @@ public final class com/stripe/android/uicore/elements/AddressElementUIKt { public final class com/stripe/android/uicore/elements/AddressTextFieldUIKt { } -public final class com/stripe/android/uicore/elements/BillingSpecKt { -} - public final class com/stripe/android/uicore/elements/CheckboxElementUIKt { } diff --git a/stripe-ui-core/src/main/java/com/stripe/android/uicore/elements/BillingSpec.kt b/stripe-ui-core/src/main/java/com/stripe/android/uicore/elements/BillingSpec.kt deleted file mode 100644 index 69ec7c6abce..00000000000 --- a/stripe-ui-core/src/main/java/com/stripe/android/uicore/elements/BillingSpec.kt +++ /dev/null @@ -1,25 +0,0 @@ -package com.stripe.android.uicore.elements - -import androidx.annotation.RestrictTo - -// This comes from: stripe-js-v3/blob/master/src/lib/shared/checkoutSupportedCountries.js -@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP) -val supportedBillingCountries = setOf( - "AD", "AE", "AF", "AG", "AI", "AL", "AM", "AO", "AQ", "AR", "AT", "AU", "AW", "AX", - "AZ", "BA", "BB", "BD", "BE", "BF", "BG", "BH", "BI", "BJ", "BL", "BM", "BN", "BO", - "BQ", "BR", "BS", "BT", "BV", "BW", "BY", "BZ", "CA", "CD", "CF", "CG", "CH", "CI", - "CK", "CL", "CM", "CN", "CO", "CR", "CV", "CW", "CY", "CZ", "DE", "DJ", "DK", "DM", - "DO", "DZ", "EC", "EE", "EG", "EH", "ER", "ES", "ET", "FI", "FJ", "FK", "FO", "FR", - "GA", "GB", "GD", "GE", "GF", "GG", "GH", "GI", "GL", "GM", "GN", "GP", "GQ", "GR", - "GS", "GT", "GU", "GW", "GY", "HK", "HN", "HR", "HT", "HU", "ID", "IE", "IL", "IM", - "IN", "IO", "IQ", "IS", "IT", "JE", "JM", "JO", "JP", "KE", "KG", "KH", "KI", "KM", - "KN", "KR", "KW", "KY", "KZ", "LA", "LB", "LC", "LI", "LK", "LR", "LS", "LT", "LU", - "LV", "LY", "MA", "MC", "MD", "ME", "MF", "MG", "MK", "ML", "MM", "MN", "MO", "MQ", - "MR", "MS", "MT", "MU", "MV", "MW", "MX", "MY", "MZ", "NA", "NC", "NE", "NG", "NI", - "NL", "NO", "NP", "NR", "NU", "NZ", "OM", "PA", "PE", "PF", "PG", "PH", "PK", "PL", - "PM", "PN", "PR", "PS", "PT", "PY", "QA", "RE", "RO", "RS", "RU", "RW", "SA", "SB", - "SC", "SE", "SG", "SH", "SI", "SJ", "SK", "SL", "SM", "SN", "SO", "SR", "SS", "ST", - "SV", "SX", "SZ", "TA", "TC", "TD", "TF", "TG", "TH", "TJ", "TK", "TL", "TM", "TN", - "TO", "TR", "TT", "TV", "TW", "TZ", "UA", "UG", "US", "UY", "UZ", "VA", "VC", "VE", - "VG", "VN", "VU", "WF", "WS", "XK", "YE", "YT", "ZA", "ZM", "ZW" -) diff --git a/stripe-ui-core/src/test/java/com/stripe/android/uicore/elements/CountryConfigTest.kt b/stripe-ui-core/src/test/java/com/stripe/android/uicore/elements/CountryConfigTest.kt index 6deefb3a84f..ced00882064 100644 --- a/stripe-ui-core/src/test/java/com/stripe/android/uicore/elements/CountryConfigTest.kt +++ b/stripe-ui-core/src/test/java/com/stripe/android/uicore/elements/CountryConfigTest.kt @@ -1,6 +1,7 @@ package com.stripe.android.uicore.elements import com.google.common.truth.Truth.assertThat +import com.stripe.android.core.model.CountryUtils import com.stripe.android.uicore.R import org.junit.Test import java.util.Locale @@ -62,7 +63,7 @@ class CountryConfigTest { locale = Locale.US ).displayItems val supportedCountries = CountryConfig( - onlyShowCountryCodes = supportedBillingCountries, + onlyShowCountryCodes = CountryUtils.supportedBillingCountries, locale = Locale.US ).displayItems @@ -79,10 +80,10 @@ class CountryConfigTest { assertThat( defaultCountries.size - ).isEqualTo(249) + ).isEqualTo(235) assertThat( supportedCountries.size - ).isEqualTo(233) + ).isEqualTo(235) } }