diff --git a/CHANGELOG.md b/CHANGELOG.md
index 914d3f2caf1..3dbf0019ff2 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,9 @@
## XX.XX.XX - 2023-XX-XX
+### Payments
+* [ADDED][7431](https://github.com/stripe/stripe-android/pull/7431) Added bindings support for MobilePay. See [private beta information](https://stripe.com/docs/payments/mobilepay).
+
## 20.32.1 - 2023-10-09
### PaymentSheet
diff --git a/example/AndroidManifest.xml b/example/AndroidManifest.xml
index e8d856293f6..f60c7f3f5b2 100644
--- a/example/AndroidManifest.xml
+++ b/example/AndroidManifest.xml
@@ -81,6 +81,7 @@
+
diff --git a/example/res/values/strings.xml b/example/res/values/strings.xml
index 0a8ab8d83ea..c6b66584cd5 100644
--- a/example/res/values/strings.xml
+++ b/example/res/values/strings.xml
@@ -35,6 +35,7 @@
Cash App Pay
Revolut Pay
Swish
+ MobilePay
Card Brands
Card number
Possible Card Brands
diff --git a/example/src/main/java/com/stripe/example/activity/LauncherActivity.kt b/example/src/main/java/com/stripe/example/activity/LauncherActivity.kt
index 97335fc6b3a..6f24beeb11b 100644
--- a/example/src/main/java/com/stripe/example/activity/LauncherActivity.kt
+++ b/example/src/main/java/com/stripe/example/activity/LauncherActivity.kt
@@ -185,6 +185,10 @@ class LauncherActivity : AppCompatActivity() {
activity.getString(R.string.swish_example),
SwishExampleActivity::class.java
),
+ Item(
+ activity.getString(R.string.mobilepay_example),
+ MobilePayExampleActivity::class.java
+ ),
// This is for internal use so as not to confuse the user.
Item(
"StripeImage Example",
diff --git a/example/src/main/java/com/stripe/example/activity/MobilePayExampleActivity.kt b/example/src/main/java/com/stripe/example/activity/MobilePayExampleActivity.kt
new file mode 100644
index 00000000000..d7b1b08c137
--- /dev/null
+++ b/example/src/main/java/com/stripe/example/activity/MobilePayExampleActivity.kt
@@ -0,0 +1,90 @@
+package com.stripe.example.activity
+
+import android.os.Bundle
+import androidx.activity.compose.setContent
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.size
+import androidx.compose.material.Button
+import androidx.compose.material.CircularProgressIndicator
+import androidx.compose.material.Divider
+import androidx.compose.material.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.livedata.observeAsState
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.unit.dp
+import com.google.accompanist.themeadapter.material.MdcTheme
+import com.stripe.android.model.PaymentMethodCreateParams
+
+class MobilePayExampleActivity : StripeIntentActivity() {
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+
+ setContent {
+ val isProcessing by viewModel.inProgress.observeAsState(initial = false)
+ val status by viewModel.status.observeAsState(initial = "")
+
+ MobilePayScreen(
+ isProcessing = isProcessing,
+ status = status,
+ onButtonPressed = { payWithMobilePay() },
+ )
+ }
+ }
+
+ private fun payWithMobilePay() {
+ val params = PaymentMethodCreateParams.createMobilePay()
+
+ createAndConfirmPaymentIntent(
+ country = "FR",
+ currency = "EUR",
+ paymentMethodCreateParams = params,
+ supportedPaymentMethods = "mobilepay",
+ )
+ }
+}
+
+@Composable
+private fun MobilePayScreen(
+ isProcessing: Boolean,
+ status: String,
+ onButtonPressed: () -> Unit,
+) {
+ MdcTheme {
+ Column(modifier = Modifier.fillMaxSize()) {
+ Row(verticalAlignment = Alignment.CenterVertically) {
+ Button(
+ onClick = onButtonPressed,
+ enabled = !isProcessing,
+ modifier = Modifier.padding(16.dp),
+ ) {
+ Text("Pay with MobilePay")
+ }
+
+ if (isProcessing) {
+ CircularProgressIndicator(modifier = Modifier.size(24.dp))
+ }
+ }
+
+ if (status.isNotBlank()) {
+ Divider(
+ modifier = Modifier
+ .fillMaxWidth()
+ .padding(horizontal = 16.dp),
+ )
+
+ Text(
+ text = status,
+ modifier = Modifier
+ .fillMaxWidth()
+ .padding(16.dp),
+ )
+ }
+ }
+ }
+}
diff --git a/payments-core/api/payments-core.api b/payments-core/api/payments-core.api
index bf044fc3f94..c8c75a40983 100644
--- a/payments-core/api/payments-core.api
+++ b/payments-core/api/payments-core.api
@@ -3971,6 +3971,9 @@ public final class com/stripe/android/model/PaymentMethodCreateParams : android/
public static final fun createKlarna ()Lcom/stripe/android/model/PaymentMethodCreateParams;
public static final fun createKlarna (Lcom/stripe/android/model/PaymentMethod$BillingDetails;)Lcom/stripe/android/model/PaymentMethodCreateParams;
public static final fun createKlarna (Lcom/stripe/android/model/PaymentMethod$BillingDetails;Ljava/util/Map;)Lcom/stripe/android/model/PaymentMethodCreateParams;
+ public static final fun createMobilePay ()Lcom/stripe/android/model/PaymentMethodCreateParams;
+ public static final fun createMobilePay (Lcom/stripe/android/model/PaymentMethod$BillingDetails;)Lcom/stripe/android/model/PaymentMethodCreateParams;
+ public static final fun createMobilePay (Lcom/stripe/android/model/PaymentMethod$BillingDetails;Ljava/util/Map;)Lcom/stripe/android/model/PaymentMethodCreateParams;
public static final fun createOxxo (Lcom/stripe/android/model/PaymentMethod$BillingDetails;)Lcom/stripe/android/model/PaymentMethodCreateParams;
public static final fun createOxxo (Lcom/stripe/android/model/PaymentMethod$BillingDetails;Ljava/util/Map;)Lcom/stripe/android/model/PaymentMethodCreateParams;
public static final fun createP24 (Lcom/stripe/android/model/PaymentMethod$BillingDetails;)Lcom/stripe/android/model/PaymentMethodCreateParams;
@@ -4194,6 +4197,10 @@ public final class com/stripe/android/model/PaymentMethodCreateParams$Companion
public final fun createKlarna (Lcom/stripe/android/model/PaymentMethod$BillingDetails;)Lcom/stripe/android/model/PaymentMethodCreateParams;
public final fun createKlarna (Lcom/stripe/android/model/PaymentMethod$BillingDetails;Ljava/util/Map;)Lcom/stripe/android/model/PaymentMethodCreateParams;
public static synthetic fun createKlarna$default (Lcom/stripe/android/model/PaymentMethodCreateParams$Companion;Lcom/stripe/android/model/PaymentMethod$BillingDetails;Ljava/util/Map;ILjava/lang/Object;)Lcom/stripe/android/model/PaymentMethodCreateParams;
+ public final fun createMobilePay ()Lcom/stripe/android/model/PaymentMethodCreateParams;
+ public final fun createMobilePay (Lcom/stripe/android/model/PaymentMethod$BillingDetails;)Lcom/stripe/android/model/PaymentMethodCreateParams;
+ public final fun createMobilePay (Lcom/stripe/android/model/PaymentMethod$BillingDetails;Ljava/util/Map;)Lcom/stripe/android/model/PaymentMethodCreateParams;
+ public static synthetic fun createMobilePay$default (Lcom/stripe/android/model/PaymentMethodCreateParams$Companion;Lcom/stripe/android/model/PaymentMethod$BillingDetails;Ljava/util/Map;ILjava/lang/Object;)Lcom/stripe/android/model/PaymentMethodCreateParams;
public final fun createOxxo (Lcom/stripe/android/model/PaymentMethod$BillingDetails;)Lcom/stripe/android/model/PaymentMethodCreateParams;
public final fun createOxxo (Lcom/stripe/android/model/PaymentMethod$BillingDetails;Ljava/util/Map;)Lcom/stripe/android/model/PaymentMethodCreateParams;
public static synthetic fun createOxxo$default (Lcom/stripe/android/model/PaymentMethodCreateParams$Companion;Lcom/stripe/android/model/PaymentMethod$BillingDetails;Ljava/util/Map;ILjava/lang/Object;)Lcom/stripe/android/model/PaymentMethodCreateParams;
diff --git a/payments-core/src/main/java/com/stripe/android/model/PaymentMethodCreateParams.kt b/payments-core/src/main/java/com/stripe/android/model/PaymentMethodCreateParams.kt
index 7ff161dd1b7..0d3f25e9da7 100644
--- a/payments-core/src/main/java/com/stripe/android/model/PaymentMethodCreateParams.kt
+++ b/payments-core/src/main/java/com/stripe/android/model/PaymentMethodCreateParams.kt
@@ -1048,6 +1048,19 @@ data class PaymentMethodCreateParams internal constructor(
)
}
+ @JvmStatic
+ @JvmOverloads
+ fun createMobilePay(
+ billingDetails: PaymentMethod.BillingDetails? = null,
+ metadata: Map? = null
+ ): PaymentMethodCreateParams {
+ return PaymentMethodCreateParams(
+ type = PaymentMethod.Type.MobilePay,
+ billingDetails = billingDetails,
+ metadata = metadata
+ )
+ }
+
@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
fun createLink(
paymentDetailsId: String,
diff --git a/payments-core/src/test/java/com/stripe/android/ApiKeyFixtures.kt b/payments-core/src/test/java/com/stripe/android/ApiKeyFixtures.kt
index c67f0fbe300..757a0cf6c04 100644
--- a/payments-core/src/test/java/com/stripe/android/ApiKeyFixtures.kt
+++ b/payments-core/src/test/java/com/stripe/android/ApiKeyFixtures.kt
@@ -32,4 +32,6 @@ internal object ApiKeyFixtures {
"pk_test_51KmkHbGoesj9fw9QAZJlz1qY4dns8nFmLKc7rXiWKAIj8QU7NPFPwSY1h8mqRaFRKQ9njs9pVJoo2jhN6ZKSDA4h00mjcbGF7b"
const val SWISH_PUBLISHABLE_KEY =
"pk_test_51JtgfQKG6vc7r7YCU0qQNOkDaaHrEgeHgGKrJMNfuWwaKgXMLzPUA1f8ZlCNPonIROLOnzpUnJK1C1xFH3M3Mz8X00Q6O4GfUt"
+ const val MOBILE_PAY_PUBLISHABLE_KEY =
+ "pk_test_51JtgfQKG6vc7r7YCU0qQNOkDaaHrEgeHgGKrJMNfuWwaKgXMLzPUA1f8ZlCNPonIROLOnzpUnJK1C1xFH3M3Mz8X00Q6O4GfUt"
}
diff --git a/payments-core/src/test/java/com/stripe/android/PaymentMethodEndToEndTest.kt b/payments-core/src/test/java/com/stripe/android/PaymentMethodEndToEndTest.kt
index 1bd0a49ec7e..ac96ca5b9c1 100644
--- a/payments-core/src/test/java/com/stripe/android/PaymentMethodEndToEndTest.kt
+++ b/payments-core/src/test/java/com/stripe/android/PaymentMethodEndToEndTest.kt
@@ -465,4 +465,13 @@ internal class PaymentMethodEndToEndTest {
val paymentMethod = stripe.createPaymentMethodSynchronous(params)
assertThat(paymentMethod.type).isEqualTo(PaymentMethod.Type.Swish)
}
+
+ @Test
+ fun createPaymentMethod_withMobilePay_shouldCreateObject() {
+ val params = PaymentMethodCreateParamsFixtures.MOBILE_PAY
+ val stripe = Stripe(context, ApiKeyFixtures.MOBILE_PAY_PUBLISHABLE_KEY)
+
+ val paymentMethod = stripe.createPaymentMethodSynchronous(params)
+ assertThat(paymentMethod.type).isEqualTo(PaymentMethod.Type.MobilePay)
+ }
}
diff --git a/payments-core/src/test/java/com/stripe/android/model/PaymentMethodCreateParamsFixtures.kt b/payments-core/src/test/java/com/stripe/android/model/PaymentMethodCreateParamsFixtures.kt
index fd8159c71ec..b70be47bcab 100644
--- a/payments-core/src/test/java/com/stripe/android/model/PaymentMethodCreateParamsFixtures.kt
+++ b/payments-core/src/test/java/com/stripe/android/model/PaymentMethodCreateParamsFixtures.kt
@@ -125,6 +125,10 @@ internal object PaymentMethodCreateParamsFixtures {
billingDetails = BILLING_DETAILS,
)
+ internal val MOBILE_PAY = PaymentMethodCreateParams.createMobilePay(
+ billingDetails = BILLING_DETAILS,
+ )
+
@JvmStatic
fun createWith(metadata: Map): PaymentMethodCreateParams {
return PaymentMethodCreateParams.create(
diff --git a/paymentsheet-example/src/androidTest/java/com/stripe/android/lpm/TestMobilePay.kt b/paymentsheet-example/src/androidTest/java/com/stripe/android/lpm/TestMobilePay.kt
new file mode 100644
index 00000000000..888bc8eac43
--- /dev/null
+++ b/paymentsheet-example/src/androidTest/java/com/stripe/android/lpm/TestMobilePay.kt
@@ -0,0 +1,37 @@
+package com.stripe.android.lpm
+
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import com.stripe.android.BasePlaygroundTest
+import com.stripe.android.paymentsheet.example.playground.settings.Country
+import com.stripe.android.paymentsheet.example.playground.settings.CountrySettingsDefinition
+import com.stripe.android.paymentsheet.example.playground.settings.Currency
+import com.stripe.android.paymentsheet.example.playground.settings.CurrencySettingsDefinition
+import com.stripe.android.paymentsheet.example.playground.settings.SupportedPaymentMethodsSettingsDefinition
+import com.stripe.android.test.core.TestParameters
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(AndroidJUnit4::class)
+internal class TestMobilePay : BasePlaygroundTest() {
+ private val testParameters = TestParameters.create(
+ paymentMethodCode = "mobilepay",
+ ) { settings ->
+ settings[CountrySettingsDefinition] = Country.FR
+ settings[CurrencySettingsDefinition] = Currency.EUR
+ settings[SupportedPaymentMethodsSettingsDefinition] = listOf("card", "mobilepay")
+ }
+
+ @Test
+ fun testMobilePay() {
+ testDriver.confirmNewOrGuestComplete(
+ testParameters = testParameters,
+ )
+ }
+
+ @Test
+ fun testMobilePayInCustomFlow() {
+ testDriver.confirmCustom(
+ testParameters = testParameters,
+ )
+ }
+}