Android basic integrationDeprecated
Accept cards with the Android SDK's prebuilt UI.
Note
We created an improved payments UI for mobile apps with support for additional payment methods. We recommend using it for your integration instead of this one.
If you want to migrate but are unable to, please let us know.
Use this integration if you want a prebuilt UI that:
- Accepts credit cards and other payment methods
- Saves and displays cards for reuse
- Can be customized to fit your app’s look and feel using an Android theme
- Launches full-screen activities to collect payment details, shipping address, and shipping method
- Allows your customer to choose Google Pay as a payment method
These activities can also be used individually. This integration requires both server and client-side steps to implement.
Note
Check out the example Basic Integration app and backend for a full implementation of this guide.
Set up StripeClient-sideServer-side
First, you need a Stripe account. Register now.
Server-side
This integration requires endpoints on your server that talk to the Stripe API. Use our official libraries for access to the Stripe API from your server:
Client-side
The Stripe Android SDK is open source and fully documented.
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:
Set up an ephemeral keyClient-sideServer-side
In order for the SDK to save and retrieve credit cards for later use, create a single Stripe Customer object for each of your users. When you create a new user or account on your server, create a corresponding Customer object at the same time, even if you don’t collect payment information from your users when they sign up. This ensures that your application has a matching Customer for each user.
For security, the Customer API is not directly accessible from the client. Instead, your server provides the SDK with an ephemeral key—a short-lived API key with restricted access to the Customer API. You can think of an ephemeral key as a session, authorizing the SDK to retrieve and update a specific Customer object s for the duration of the session.
Server-side
To provide an ephemeral key to the SDK, expose a new API endpoint on your backend. This endpoint should create an ephemeral key for the current Stripe customer, and return the key’s unmodified response as JSON. When the SDK requests an ephemeral key, it will specify the version of the Stripe API that it expects the response to come from. Your endpoint must accept an api_ parameter, and use the specified API version when creating the ephemeral key. This ensures that the SDK always receives the correct ephemeral key response from your backend. Consult our Example Backend to see this in practice.
Client-side
After you’ve added an ephemeral key endpoint to your backend, you’ll need a way for your Android app to communicate with this endpoint. In your app, make your API client class implement the EphemeralKeyProvider interface, which defines a single method, createEphemeralKey(). When implementing this method, pass the apiVersion parameter along to your ephemeral keys endpoint. Refer to our example app to see this in practice.
Set up a CustomerSessionClient-side
After creating an EphemeralKeyProvider, initialize a CustomerSession. A CustomerSession talks to your backend to retrieve an ephemeral key for your Customer with its EphemeralKeyProvider, and uses that key to manage retrieving and updating the Customer’s payment methods on your behalf.
You can also use CustomerSession with your own custom UI to retrieve or refresh the Customer, and list their payment methods, attach a payment method, or detach a payment method.
To reduce load times, preload your customer’s information by initializing CustomerSession before they enter your payment flow.
If your current user logs out of the app, clear the current CustomerSession singleton by calling CustomerSession.. When a new user logs in, re-initialize the instance. On your backend, create and return a new ephemeral key for the Customer object associated with the new user.
Set up a PaymentSessionClient-side
The core of this integration is the PaymentSession class. It uses CustomerSession to launch full-screen activities to collect and store payment information, and can also be used to collect shipping info. Think of it as the data source for your checkout activity—it handles asynchronously retrieving the data you need, and notifies its PaymentSessionListener when your UI should change.
To work with PaymentSession, you’ll need to:
- Create a
PaymentSessionConfigobject - Implement a
PaymentSessionListener
PaymentSessionConfig
The PaymentSessionConfig object is created using a Builder. All of the Builder’s fields are optional. See the API reference for details on each method.
PaymentSessionListener
After creating the PaymentSessionConfig, you’ll need to implement PaymentSessionListener.
This method should also check for whether or not the payment data is complete, according to the PaymentSessionConfig specified. If you receive an update for which PaymentSessionData#isPaymentReadyToCharge() returns true, you can immediately send a message to your server to complete the charge.
void onCommunicatingStateChanged(boolean isCommunicating)
This method is called whenever the network communication state has changed. We recommend showing a spinner or infinite progress bar when it is set to true
void onError(int errorCode, @Nullable String errorMessage)
This method is called whenever an error occurs when connecting to the Stripe API. Make sure users can see the error messages, so display them in an alert dialog.
Initialize a PaymentSession
Having created your PaymentSessionConfig and PaymentSessionListener, you can now initialize the PaymentSession. In the below example, we use anonymous classes to create our listener and config for simplicity.
Collect the customer's payment and shipping detailsClient-side
Once the PaymentSession has been initialized, you can use it to make the following calls.
void presentPaymentMethodSelection()
This method starts the PaymentMethodsActivity to allow the customer to choose a saved payment method, using CustomerSession as its data source. If the Add new card button is tapped, or there are no existing payment methods, AddPaymentMethodActivity is launched to add a credit card.
void presentShippingFlow()
This method presents the PaymentFlowActivity to allow the user to enter shipping information, if such information is required according to your PaymentSessionConfig.
Complete the paymentClient-sideServer-side
Once PaymentSession#isPaymentReadyToCharge() returns true, submit the payment to Stripe using a Payment Intent. Stripe uses this payment object to track and handle all the states of the payment—even when the bank requires customer intervention, like additional card authentication—until the payment completes.
Server-side
On your server, make an endpoint that creates a PaymentIntent with an amount and currency and returns its client secret to your client.
Always decide how much to charge on the server side, a trusted environment, as opposed to the client. This prevents malicious customers from being able to choose their own prices.
Client-side
- Request a
PaymentIntentfrom your server - Assemble a ConfirmPaymentIntentParams object with the
PaymentIntentclient secret from your server and the id ofPaymentSessionData#paymentMethodobtained fromPaymentSessionListenerImpl#onPaymentSessionDataChanged(). - Call the Stripe confirmPayment method to confirm the payment.
When the payment completes, onSuccess is called and the value of the returned PaymentIntent’s status is Succeeded. Any other value indicates the payment was not successful. Inspect lastPaymentError to determine the cause. End the payment session by calling PaymentSession#onCompleted().
Manage PaymentSession in a host ActivityClient-side
To get updates for the PaymentSessionData object and to handle state during Activity lifecycle, you’ll need to hook up your PaymentSession instance to a few key parts of your host Activity lifecycle. The first is in onActivityResult()
This is all you need to do to get updates from the various activities launched by PaymentSession. Any updates to the data are reported to the PaymentSessionListener argument to PaymentSession#init().
Test the integration
Several test cards are available for you to use in a sandbox to make sure this integration is ready. Use them with any CVC and an expiration date in the future.
| Number | Description |
|---|---|
| Succeeds and immediately processes the payment. | |
| Requires authentication. Stripe triggers a modal asking for the customer to authenticate. | |
Always fails with a decline code of insufficient_. |
For the full list of test cards see our guide on testing.
OptionalHandle post-payment events
Stripe sends a payment_intent.succeeded event when the payment completes. Use the Dashboard, a custom webhook, or a partner solution to receive these events and run actions, like sending an order confirmation email to your customer, logging the sale in a database, or starting a shipping workflow.
Listen for these events rather than waiting on a callback from the client. On the client, the customer could close the browser window or quit the app before the callback executes, and malicious clients could manipulate the response. Setting up your integration to listen for asynchronous events also helps you accept more payment methods in the future. Learn about the differences between all supported payment methods.
Receive events and run business actions
There are a few options for receiving and running business actions.
Manually
Use the Stripe Dashboard to view all your Stripe payments, send email receipts, handle payouts, or retry failed payments.
Custom code
Build a webhook handler to listen for events and build custom asynchronous payment flows. Test and debug your webhook integration locally with the Stripe CLI.
Prebuilt apps
Handle common business events, like automation or marketing and sales, by integrating a partner application.
OptionalUse individual activitiesClient-side
The full-screen activities that Basic Integration displays are also available to use individually, without using PaymentSession.
AddPaymentMethodActivity
Use AddPaymentMethodActivity to collect card details from your customer. To launch the activity, use AddPaymentMethodActivityStarter#startForResult().
PaymentMethodsActivity
Use PaymentMethodsActivity to display the customer’s payment methods and allow them to select one or add new ones. First, follow the steps to set up an ephemeral key and CustomerSession. Then, use PaymentMethodsActivityStarter#startForResult() to launch the activity.
In your host Activity or Fragment, implement Activity#onActivityResult and handle the result.
OptionalCustomize the UIClient-side
The full-screen activities can be customized to fit your app’s look and feel by defining a StripeDefaultTheme theme that extends StripeBaseTheme. See below for an example as well as explanation of how each theme attribute is applied.
<?xml version="1.0" encoding="utf-8"?> <resources> <style name="StripeDefaultTheme" parent="StripeBaseTheme"> <!-- Applied to toolbar background --> <item name="colorPrimary">@color/primary</item> <!-- Applied to status bar --> <item name="colorPrimaryDark">@color/primaryDark</item> <!-- Applied to inactive Shipping Method name and amount --> <item name="android:textColorPrimary">@color/text</item> <!-- Applied to inactive Shipping Method description --> <item name="android:textColorSecondary">@color/textPrimary</item> <!-- Applied to Shipping Information drop-down items; add Payment Method footer text color --> <item name="android:textColor">@color/textPrimary</item> <!-- Applied to toolbar foreground/text --> <item name="titleTextColor">@color/title</item> <!-- Applied to selected Payment Method; active field; links; add new Payment Method call-to-action --> <item name="colorAccent">@color/accent</item> <!-- Applied to: Payment Method icon; inactive form field highlight --> <item name="colorControlNormal">@color/accent</item> <!-- Applied to form field text --> <item name="android:editTextColor">@color/textPrimary</item> <item name="editTextColor">@color/textPrimary</item> </style> </resources>
For more information on Android themes, see the Android Styles and Themes guide.


