Manage payment methods in settings
Use the Payment Method Settings Sheet to let your customers manage their payment methods in your app settings page.
Note
The Payment Method Settings Sheet is intended for use on an app settings page. For checkout and payments, use theIn-app Payments, which also has built-in support for saving and displaying payment methods and supports more payment methods than the Payment Method Settings Sheet.
Note
In code, this component is referenced as CustomerSheet for historical reasons. Throughout the documentation, when you seeCustomerSheet in code examples, this refers to the Payment Method Settings Sheet.
The Payment Method Settings Sheet is a prebuilt UI component that lets your customers manage their saved payment methods. You can use the Payment Method Settings Sheet UI outside of a checkout flow and the appearance and styling is customisable to match the appearance and aesthetic of your app. Customers can add and remove payment methods, which get saved to the customer object and set their default payment method stored locally on the device. Use both the In-app Payments and the Payment Method Settings Sheet to provide customers a consistent end-to-end solution for saved payment methods.

The CustomerSession object grants the SDK temporary access to the Customer and provides additional configuration options. These configuration options allow you to customise the behaviour of CustomerSheet. A complete list of features exposed on the CustomerSession are in our API docs.
Set up Stripe
First, you need a Stripe account. Register now.
To install the SDK, add stripe-android to the dependencies block of your app/build.gradle file:
Note
For details on the latest SDK release and past versions, see the Releases page on GitHub. To receive notifications when a new release is published, watch releases for the repository.
Configure the SDK with your Stripe publishable key so that it can make requests to the Stripe API, such as in your Application subclass:
Enable payment methods
View your payment methods settings and enable the payment methods you want to support. You need at least one payment method enabled to create a SetupIntent.
By default, Stripe enables cards and other prevalent payment methods that can help you reach more customers, but we recommend turning on additional payment methods that are relevant for your business and customers. See Payment method support for product and payment method support, and our pricing page for fees.
Note
At this time, Payment Method Settings Sheet only supports cards and US bank accounts.
Add Customer endpointsServer-side
Create two endpoints on your server: one for fetching a CustomerSession client secret, and one to create a SetupIntent for saving a new payment method to the Customer.
- Create an endpoint to return a Customer ID and a CustomerSession client secret.
 
Note
Integrations with legacy customer ephemeral keys results in saved payment methods having an allow_ value of unspecified. To display these payment methods in addition to payment methods saved while using Customer Sessions, set payment_ to ["unspecified", "always"]. For more information, see CustomerSessions.
- Create an endpoint to return a SetupIntent configured with the Customer ID.
 
If you only plan to use the payment method for future payments when your customer is present during the checkout flow, set the usage parameter to on_session to improve authorisation rates.
Create a Customer session providerClient-side
A CustomerSessionProvider enables a CustomerSheet to communicate with Stripe using CustomerSession objects. On the client, create a CustomerSessionProvider that can create a CustomerSession client secret and a SetupIntent client secret from your server.
import com.stripe.android.customersheet.CustomerSheet import com.stripe.android.customersheet.ExperimentalCustomerSheetApi @OptIn(ExperimentalCustomerSheetApi::class) class MyCustomerSessionProvider : CustomerSheet.CustomerSessionProvider() { val myBackend = // .... override suspend fun providesCustomerSessionClientSecret(): Result<CustomerSheet.CustomerSessionClientSecret> { return myBackend.getCustomerSessionClientSecret().fold( onSuccess = { response -> Result.success( CustomerSessionClientSecret.create( customerId = response.customerId, clientSecret = response.customerSessionClientSecret, ) ) }, onFailure = { exception -> Result.failure(exception) } ) } override suspend fun provideSetupIntentClientSecret(customerId: String): Result<String> { return myBackend.getSetupIntentClientSecret(customerId).fold( onSuccess = { response -> Result.success(response.setupIntentClientSecret) }, onFailure = { exception -> Result.failure(exception) } ) } }
import android.app.Application import androidx.lifecycle.AndroidViewModel class CheckoutViewModel( application: Application ) : AndroidViewModel(application) { val customerSessionProvider = MyCustomerSessionProvider() }
Configure the sheet
Next, initialise the Payment Method Settings Sheet using the CustomerSheet class with yourCustomerSessionProvider then callconfigure with aCustomerSheet.Configuration. Always callconfigure before callingpresent andretrievePaymentOptionSelection.
import android.os.Bundle import androidx.activity.ComponentActivity import androidx.activity.compose.setContent import androidx.activity.viewModels import com.stripe.android.customersheet.CustomerSheet import com.stripe.android.customersheet.ExperimentalCustomerSheetApi import com.stripe.android.customersheet.rememberCustomerSheet @OptIn(ExperimentalCustomerSheetApi::class) class CheckoutActivity : ComponentActivity() { private val viewModel by viewModels<CheckoutViewModel>() override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) val configuration = CustomerSheet.Configuration.builder(merchantDisplayName = "{{YOUR BUSINESS NAME}}") .build() setContent { val customerSheet = rememberCustomerSheet( customerSessionProvider = viewModel.customerSessionProvider, callback = viewModel::handleResult // Implemented in next step ) LaunchedEffect(customerSheet) { customerSheet.configure(configuration = configuration) } } } }
Present the sheet
Present the Payment Method Settings Sheet using CustomerSheet. When the customer dismisses the sheet, theCustomerSheet calls the completion block with aCustomerSheetResult.
import android.os.Bundle import androidx.activity.ComponentActivity import androidx.activity.compose.setContent import androidx.activity.viewModels import androidx.compose.foundation.Image import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.material.Text import androidx.compose.material.TextButton import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp import com.stripe.android.customersheet.CustomerSheet import com.stripe.android.customersheet.ExperimentalCustomerSheetApi import com.stripe.android.customersheet.rememberCustomerSheet import com.stripe.android.uicore.image.rememberDrawablePainter @OptIn(ExperimentalCustomerSheetApi::class) class CheckoutActivity : ComponentActivity() { private val viewModel by viewModels<CheckoutViewModel>() override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) val configuration = CustomerSheet.Configuration.builder(merchantDisplayName = "{{YOUR BUSINESS NAME}}") .headerTextForSelectionScreen("Manage your payment method") .build() setContent { val customerSheet = rememberCustomerSheet( customerSessionProvider = viewModel.customerSessionProvider, customerAdapter = viewModel.customerAdapter, callback = viewModel::handleResult ) LaunchedEffect(customerSheet) { customerSheet.configure(configuration = configuration) viewModel.handleResult(customerSheet.retrievePaymentOptionSelection()) } val paymentOption by viewModel.paymentOption.collectAsState() Row( modifier = Modifier.fillMaxWidth(), verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.SpaceBetween, ) { val icon = paymentOption?.icon() if (icon != null) { Image( painter = rememberDrawablePainter( drawable = icon ), contentDescription = "Payment Method Icon", modifier = Modifier.height(32.dp) ) } TextButton( onClick = { customerSheet.present() } ) { Text( text = paymentOption?.label ?: "Select" ) } } } } }
import android.app.Application import androidx.lifecycle.AndroidViewModel import com.stripe.android.customersheet.ExperimentalCustomerSheetApi import com.stripe.android.paymentsheet.model.PaymentOption import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.update @OptIn(ExperimentalCustomerSheetApi::class) class CheckoutViewModel( application: Application ) : AndroidViewModel(application) { val customerSessionProvider = // ... private val _paymentOption = MutableStateFlow<PaymentOption?>(null) val paymentOption: StateFlow<PaymentOption?> = _paymentOption fun handleResult(result: CustomerSheetResult) { when (result) { is CustomerSheetResult.Selected -> { // Configure your UI based on the payment option _paymentOption.update { result.selection?.paymentOption } } is CustomerSheetResult.Canceled -> { // Configure your UI based on the payment option _paymentOption.update { result.selection?.paymentOption } } is CustomerSheetResult.Failed -> { // Show the error in your UI } } } }
- If the customer selects a payment method, the result is 
CustomerSheetResult.. The associated value is the selectedSelected PaymentOptionSelection, or null if the user deleted the previously-selected payment method. The full payment method details are available in thePaymentOptionSelection’spaymentMethodvalue. - If the customer cancels the sheet, the result is 
CustomerSheetResult.. The associated value is the customer’s originalCanceled PaymentOptionSelection, or null if the customer hasn’t selected a payment method before or has deleted the originally selected payment method. - If an error occurs, the result is 
CustomerSheetResult..Failed  
OptionalEnable Google Pay
Set up your integration
To use Google Pay, first enable the Google Pay API by adding the following to the <application> tag of your AndroidManifest.xml:
<application> ... <meta-data android:name="com.google.android.gms.wallet.api.enabled" android:value="true" /> </application>
For more details, see Google Pay’s Set up Google Pay API for Android.
Add Google Pay
To add Google Pay to your integration, pass true to googlePayEnabled when initialising CustomerSheet.Configuration with CustomerSheet.Configuration.Builder.
OptionalEnable ACH payments
To enable ACH debit payments include Financial Connections as a dependency for your app.
The Stripe Android SDK is open source and fully documented.
To install the SDK, add financial-connections to the dependencies block of your app/build.gradle file:
Note
For details on the latest SDK release and past versions, see the Releases page on GitHub. To receive notifications when a new release is published, watch releases for the repository.
OptionalFetch the selected payment method
To fetch the default payment method without presenting the Payment Method Settings Sheet, callretrievePaymentOptionSelection() onCustomerSheet.
class CheckoutActivity : ComponentActivity() { private val viewModel by viewModels<CheckoutViewModel>() override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstance) val configuration = ... setContent { val customerSheet = ... LaunchedEffect(Unit) { customerSheet.configure(configuration = configuration) val result = customerSheet.retrievePaymentOptionSelection() viewModel.handleResult(result) } ... } } }
OptionalCustomise the sheet
Appearance
Customise the colours, fonts, and other appearance attributes to match the look and feel of your app by using the appearance API.
Note
retrievePaymentMethods can filter out saved payment methods from being shown, but won’t impact the type of payment methods that are addable.
Default billing details
To set default values for billing details collected in the customer sheet, configure the defaultBillingDetails property. The CustomerSheet pre-populates its fields with the values that you provide.
val configuration = CustomerSheet.Configuration.Builder() .defaultBillingDetails( PaymentSheet.BillingDetails( address = PaymentSheet.Address( country = "US", ), email = "foo@bar.com" ) ) .build()
Billing details collection
Use billingDetailsCollectionConfiguration to specify how you want to collect billing details in the payment sheet.
You can collect your customer’s name, email address, phone number, and address.
To attach values that aren’t collected by CustomerSheet, add them to the defaultBillingDetails property and set billingDetailsCollectionConfiguration. to true. Make sure that you complete this step if you don’t plan to collect values required by the payment method.
val configuration = CustomerSheet.Configuration.Builder() .defaultBillingDetails( PaymentSheet.BillingDetails( email = "foo@bar.com" ) ) .billingDetailsCollectionConfiguration( PaymentSheet.BillingDetailsCollectionConfiguration( name = PaymentSheet.BillingDetailsCollectionConfiguration.AddressCollectionMode.Always, email = PaymentSheet.BillingDetailsCollectionConfiguration.AddressCollectionMode.Never, address = PaymentSheet.BillingDetailsCollectionConfiguration.AddressCollectionMode.Full, attachDefaultsToPaymentMethod = true, ) ) .build()
Note
Consult with your legal team regarding laws that apply to you collecting information. Only collect phone numbers if you need them for the transaction.