diff --git a/CHANGELOG.md b/CHANGELOG.md index d80ffb03cf6..7ecbcc6e7f4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,11 @@ ## XX.XX.XX - 2023-XX-XX +### PaymentSheet + +* [ADDED] PaymentSheet now supports the following payment methods for PaymentIntents: + * [7281](https://github.com/stripe/stripe-android/pull/7281) OXXO + ## 20.30.1 - 2023-09-11 ### Financial Connections diff --git a/payments-ui-core/res/drawable/stripe_ic_paymentsheet_pm_oxxo.xml b/payments-ui-core/res/drawable/stripe_ic_paymentsheet_pm_oxxo.xml new file mode 100644 index 00000000000..b3bfb31362b --- /dev/null +++ b/payments-ui-core/res/drawable/stripe_ic_paymentsheet_pm_oxxo.xml @@ -0,0 +1,22 @@ + + + + + + diff --git a/payments-ui-core/res/values/donottranslate.xml b/payments-ui-core/res/values/donottranslate.xml index 9b3ded3fd3d..b479f95ae16 100644 --- a/payments-ui-core/res/values/donottranslate.xml +++ b/payments-ui-core/res/values/donottranslate.xml @@ -24,6 +24,7 @@ Zip BLIK Alipay + OXXO diff --git a/payments-ui-core/src/main/assets/lpms.json b/payments-ui-core/src/main/assets/lpms.json index cae7a87bfbc..b2d011b0c24 100644 --- a/payments-ui-core/src/main/assets/lpms.json +++ b/payments-ui-core/src/main/assets/lpms.json @@ -993,5 +993,23 @@ "light_theme_png": "https://js.stripe.com/v3/fingerprinted/img/payment-methods/icon-pm-alipay@3x-d216a94882c3c5422274faaec75a3c81.png" }, "fields": [] + }, + { + "type": "oxxo", + "async": true, + "fields": [ + { + "type": "name", + "api_path": { + "v1": "billing_details[name]" + } + }, + { + "type": "email", + "api_path": { + "v1": "billing_details[email]" + } + } + ] } ] diff --git a/payments-ui-core/src/main/java/com/stripe/android/paymentsheet/forms/PaymentMethodRequirements.kt b/payments-ui-core/src/main/java/com/stripe/android/paymentsheet/forms/PaymentMethodRequirements.kt index 13578b7a7ac..4bbe8f38cde 100644 --- a/payments-ui-core/src/main/java/com/stripe/android/paymentsheet/forms/PaymentMethodRequirements.kt +++ b/payments-ui-core/src/main/java/com/stripe/android/paymentsheet/forms/PaymentMethodRequirements.kt @@ -271,3 +271,9 @@ internal val AlipayRequirement = PaymentMethodRequirements( siRequirements = null, confirmPMFromCustomer = false, ) + +internal val OxxoRequirement = PaymentMethodRequirements( + piRequirements = setOf(Delayed), + siRequirements = null, + confirmPMFromCustomer = false, +) diff --git a/payments-ui-core/src/main/java/com/stripe/android/ui/core/forms/resources/LpmRepository.kt b/payments-ui-core/src/main/java/com/stripe/android/ui/core/forms/resources/LpmRepository.kt index 380d5c70912..f428076c19e 100644 --- a/payments-ui-core/src/main/java/com/stripe/android/ui/core/forms/resources/LpmRepository.kt +++ b/payments-ui-core/src/main/java/com/stripe/android/ui/core/forms/resources/LpmRepository.kt @@ -30,6 +30,7 @@ import com.stripe.android.paymentsheet.forms.GrabPayRequirement import com.stripe.android.paymentsheet.forms.IdealRequirement import com.stripe.android.paymentsheet.forms.KlarnaRequirement import com.stripe.android.paymentsheet.forms.MobilePayRequirement +import com.stripe.android.paymentsheet.forms.OxxoRequirement import com.stripe.android.paymentsheet.forms.P24Requirement import com.stripe.android.paymentsheet.forms.PaymentMethodRequirements import com.stripe.android.paymentsheet.forms.PaypalRequirement @@ -72,7 +73,6 @@ class LpmRepository constructor( private val lpmInitialFormData: LpmInitialFormData = LpmInitialFormData.Instance, private val lpmPostConfirmData: LuxePostConfirmActionRepository = LuxePostConfirmActionRepository.Instance ) { - fun fromCode(code: PaymentMethodCode?) = lpmInitialFormData.fromCode(code) fun values(): List = lpmInitialFormData.values() @@ -543,6 +543,17 @@ class LpmRepository constructor( requirement = AlipayRequirement, formSpec = LayoutSpec(sharedDataSpec.fields), ) + PaymentMethod.Type.Oxxo.code -> SupportedPaymentMethod( + code = "oxxo", + requiresMandate = false, + displayNameResource = R.string.stripe_paymentsheet_payment_method_oxxo, + iconResource = R.drawable.stripe_ic_paymentsheet_pm_oxxo, + lightThemeIconUrl = null, + darkThemeIconUrl = null, + tintIconOnSelection = false, + requirement = OxxoRequirement, + formSpec = LayoutSpec(sharedDataSpec.fields), + ) else -> null } diff --git a/paymentsheet-example/src/main/java/com/stripe/android/paymentsheet/example/playground/activity/PaymentSheetPlaygroundActivity.kt b/paymentsheet-example/src/main/java/com/stripe/android/paymentsheet/example/playground/activity/PaymentSheetPlaygroundActivity.kt index 71bdd33a2ce..01b26de4a1f 100644 --- a/paymentsheet-example/src/main/java/com/stripe/android/paymentsheet/example/playground/activity/PaymentSheetPlaygroundActivity.kt +++ b/paymentsheet-example/src/main/java/com/stripe/android/paymentsheet/example/playground/activity/PaymentSheetPlaygroundActivity.kt @@ -882,7 +882,7 @@ class PaymentSheetPlaygroundActivity : AppCompatActivity() { /** * Modify this list if you want to change the countries displayed in the playground. */ - country.code.value in setOf("US", "GB", "AU", "FR", "IN", "SG", "MY") + country.code.value in setOf("US", "GB", "AU", "FR", "IN", "SG", "MY", "MX") }.map { country -> /** * Modify this statement to change the default currency associated with each @@ -910,6 +910,9 @@ class PaymentSheetPlaygroundActivity : AppCompatActivity() { "MY" -> { country to "MYR" } + "MX" -> { + country to "MXN" + } else -> { country to "USD" } @@ -918,6 +921,6 @@ class PaymentSheetPlaygroundActivity : AppCompatActivity() { // List was created from: https://stripe.com/docs/currencies /** Modify this list if you want to change the currencies displayed in the playground **/ - private val stripeSupportedCurrencies = listOf("AUD", "EUR", "GBP", "USD", "INR", "PLN", "SGD", "MYR") + private val stripeSupportedCurrencies = listOf("AUD", "EUR", "GBP", "USD", "INR", "PLN", "SGD", "MYR", "MXN") } } diff --git a/paymentsheet/src/androidTest/java/com/stripe/android/paymentsheet/PaymentSheetPage.kt b/paymentsheet/src/androidTest/java/com/stripe/android/paymentsheet/PaymentSheetPage.kt index aa15fd4fa6c..0599a8ee563 100644 --- a/paymentsheet/src/androidTest/java/com/stripe/android/paymentsheet/PaymentSheetPage.kt +++ b/paymentsheet/src/androidTest/java/com/stripe/android/paymentsheet/PaymentSheetPage.kt @@ -33,6 +33,12 @@ internal class PaymentSheetPage( .performClick() } + fun clickViewWithText(text: String) { + composeTestRule.onNode(hasText(text)) + .performScrollTo() + .performClick() + } + fun waitForText(text: String, substring: Boolean = false) { composeTestRule.waitUntil(timeoutMillis = 5_000) { composeTestRule diff --git a/paymentsheet/src/test/resources/oxxo-support.csv b/paymentsheet/src/test/resources/oxxo-support.csv new file mode 100644 index 00000000000..6332f325fab --- /dev/null +++ b/paymentsheet/src/test/resources/oxxo-support.csv @@ -0,0 +1,49 @@ +lpm, hasCustomer, allowsDelayedPayment, intentSetupFutureUsage, intentHasShipping, intentLpms, supportCustomerSavedCard, formExists, formType, supportsAdding +oxxo, true, true, off_session, false, card/oxxo, false, false, not available, false +oxxo, true, true, off_session, false, card/eps/oxxo, false, false, not available, false +oxxo, true, false, off_session, false, card/oxxo, false, false, not available, false +oxxo, true, false, off_session, false, card/eps/oxxo, false, false, not available, false +oxxo, true, true, on_session, false, card/oxxo, false, false, not available, false +oxxo, true, true, on_session, false, card/eps/oxxo, false, false, not available, false +oxxo, true, false, on_session, false, card/oxxo, false, false, not available, false +oxxo, true, false, on_session, false, card/eps/oxxo, false, false, not available, false +oxxo, true, true, null, false, card/oxxo, false, true, oneTime, true +oxxo, true, true, null, false, card/eps/oxxo, false, true, oneTime, true +oxxo, true, false, null, false, card/oxxo, false, false, not available, false +oxxo, true, false, null, false, card/eps/oxxo, false, false, not available, false +oxxo, false, true, off_session, false, card/oxxo, false, false, not available, false +oxxo, false, true, off_session, false, card/eps/oxxo, false, false, not available, false +oxxo, false, false, off_session, false, card/oxxo, false, false, not available, false +oxxo, false, false, off_session, false, card/eps/oxxo, false, false, not available, false +oxxo, false, true, on_session, false, card/oxxo, false, false, not available, false +oxxo, false, true, on_session, false, card/eps/oxxo, false, false, not available, false +oxxo, false, false, on_session, false, card/oxxo, false, false, not available, false +oxxo, false, false, on_session, false, card/eps/oxxo, false, false, not available, false +oxxo, false, true, null, false, card/oxxo, false, true, oneTime, true +oxxo, false, true, null, false, card/eps/oxxo, false, true, oneTime, true +oxxo, false, false, null, false, card/oxxo, false, false, not available, false +oxxo, false, false, null, false, card/eps/oxxo, false, false, not available, false +oxxo, true, true, off_session, true, card/oxxo, false, false, not available, false +oxxo, true, true, off_session, true, card/eps/oxxo, false, false, not available, false +oxxo, true, false, off_session, true, card/oxxo, false, false, not available, false +oxxo, true, false, off_session, true, card/eps/oxxo, false, false, not available, false +oxxo, true, true, on_session, true, card/oxxo, false, false, not available, false +oxxo, true, true, on_session, true, card/eps/oxxo, false, false, not available, false +oxxo, true, false, on_session, true, card/oxxo, false, false, not available, false +oxxo, true, false, on_session, true, card/eps/oxxo, false, false, not available, false +oxxo, true, true, null, true, card/oxxo, false, true, oneTime, true +oxxo, true, true, null, true, card/eps/oxxo, false, true, oneTime, true +oxxo, true, false, null, true, card/oxxo, false, false, not available, false +oxxo, true, false, null, true, card/eps/oxxo, false, false, not available, false +oxxo, false, true, off_session, true, card/oxxo, false, false, not available, false +oxxo, false, true, off_session, true, card/eps/oxxo, false, false, not available, false +oxxo, false, false, off_session, true, card/oxxo, false, false, not available, false +oxxo, false, false, off_session, true, card/eps/oxxo, false, false, not available, false +oxxo, false, true, on_session, true, card/oxxo, false, false, not available, false +oxxo, false, true, on_session, true, card/eps/oxxo, false, false, not available, false +oxxo, false, false, on_session, true, card/oxxo, false, false, not available, false +oxxo, false, false, on_session, true, card/eps/oxxo, false, false, not available, false +oxxo, false, true, null, true, card/oxxo, false, true, oneTime, true +oxxo, false, true, null, true, card/eps/oxxo, false, true, oneTime, true +oxxo, false, false, null, true, card/oxxo, false, false, not available, false +oxxo, false, false, null, true, card/eps/oxxo, false, false, not available, false