Sign in
An image of the Stripe logo
Create account
Sign in
Home
Payments
Business operations
Financial services
Developer tools
No-code
All products
Home
Payments
Business operations
Home
Payments
Business operations
Financial services
Developer tools
Support
Overview
Online payments
    Overview
    How cards work
    Quickstart
    Accept a payment
    Add funds to your balance
    Faster checkout with Link
    More payment scenarios
    US and Canadian cards
Products and prices
Invoicing
Subscriptions
Quotes
In-person payments
Multiparty payments
After the payment
Add payment methods
Payment Links
Stripe Checkout
Stripe Elements
About the APIs
Regulation support
Implementation guides
Testing
Payments
·
HomePaymentsOnline payments

Accept a payment

Securely accept payments online.

Integrate Stripe’s prebuilt payment UI into the checkout of your Android app with the PaymentSheet class.

Set up Stripe
Server-side
Client-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 the official libraries for access to the Stripe API from your server:

Command Line
# For detailed setup, see our quickstarts at https://stripe.com/docs/development/quickstart bundle add stripe

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:

build.gradle
apply plugin: 'com.android.application' android { ... } dependencies { // ... // Stripe Android SDK implementation 'com.stripe:stripe-android:20.21.1' }

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.

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 PaymentIntent.

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 integration options for product and payment method support, and our pricing page for fees.

Add an endpoint
Server-side

This integration uses three Stripe API objects:

  1. A PaymentIntent. Stripe uses this to represent your intent to collect payment from a customer, tracking your charge attempts and payment state changes throughout the process.

  2. A Customer (optional). To set up a payment method for future payments, it must be attached to a Customer. Create a Customer object when your customer creates an account with your business. If your customer is making a payment as a guest, you can create a Customer object before payment and associate it with your own internal representation of the customer’s account later.

  3. A Customer Ephemeral Key (optional). Information on the Customer object is sensitive, and can’t be retrieved directly from an app. An Ephemeral Key grants the SDK temporary access to the Customer.

If you never save cards to a Customer and don’t allow returning Customers to reuse saved cards, you can omit the Customer and Customer Ephemeral Key objects from your integration.

For security reasons, your app can’t create these objects. Instead, add an endpoint on your server that:

  1. Retrieves the Customer, or creates a new one.
  2. Creates an Ephemeral Key for the Customer.
  3. Creates a PaymentIntent, with the amount, currency, customer, and automatic_payment_methods enabled.
  4. Returns the Payment Intent’s client secret, the Ephemeral Key’s secret, the Customer’s id, and your publishable key to your app.
Interested in creating the PaymentIntent at the end of the checkout flow?

We’re building an integration that lets you present the payment sheet before creating a PaymentIntent. If you’re interested in providing feedback and getting early access, please contact us.

The payment methods shown to customers during the checkout process are also included on the PaymentIntent. You can let Stripe pull payment methods from your Dashboard settings or you can list them manually. Regardless of the option you choose, know that the currency passed in the PaymentIntent filters the payment methods shown to the customer. For example, if you pass eur on the PaymentIntent and have OXXO enabled in the Dashboard, OXXO won’t be shown to the customer because OXXO doesn’t support eur payments.

Unless your integration requires a code-based option for offering payment methods, Stripe recommends the automated option. This is because Stripe evaluates the currency, payment method restrictions, and other parameters to determine the list of supported payment methods. Payment methods that increase conversion and that are most relevant to the currency and customer’s location are prioritized.

You can find a running implementation of this endpoint available on Glitch for quick testing.

Note that with automatic_payment_methods enabled, the PaymentIntent is created using the payment methods you configured in the Dashboard. If you don’t want to use the Dashboard or if you want to specify payment methods manually, you can list them using the payment_method_types attribute.

Command Line
# Create a Customer (skip this and get the existing Customer ID if this is a returning customer) curl https://api.stripe.com/v1/customers \ -u
sk_test_4eC39HqLyjWDarjtT1zdp7dc
: \ -X "POST" # Create an Ephemeral Key for the Customer curl https://api.stripe.com/v1/ephemeral_keys \ -u
sk_test_4eC39HqLyjWDarjtT1zdp7dc
: \ -H "Stripe-Version: 2022-11-15" \ -X "POST" \ -d "customer"="{{CUSTOMER_ID}}" \ # Create a PaymentIntent curl https://api.stripe.com/v1/payment_intents \ -u
sk_test_4eC39HqLyjWDarjtT1zdp7dc
: \ -X "POST" \ -d "customer"="{{CUSTOMER_ID}}" \ -d "amount"=1099 \ -d "currency"="eur" \ -d "automatic_payment_methods[enabled]"=true \

Collect payment details
Client-side

Before displaying the mobile Payment Element, your checkout page should:

  • Show the products being purchased and the total amount
  • Collect any required shipping information using the Address Element
  • Include a checkout button to present Stripe’s UI

Initialize a PaymentSheet instance inside onCreate of your checkout Activity, passing a method to handle the result.

import com.stripe.android.paymentsheet.PaymentSheet class CheckoutActivity : AppCompatActivity() { lateinit var paymentSheet: PaymentSheet override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) paymentSheet = PaymentSheet(this, ::onPaymentSheetResult) } fun onPaymentSheetResult(paymentSheetResult: PaymentSheetResult) { // implemented in the next steps } }

Next, fetch the PaymentIntent client secret, Ephemeral Key secret, Customer ID, and publishable key from the endpoint you created in the previous step. Set the publishable key using PaymentConfiguration and store the others for use when you present the PaymentSheet.

import com.stripe.android.paymentsheet.PaymentSheet // Add the following lines to build.gradle to use this example's networking library: // implementation 'com.github.kittinunf.fuel:fuel:2.3.1' // implementation 'com.github.kittinunf.fuel:fuel-json:2.3.1' import com.github.kittinunf.fuel.httpPost import com.github.kittinunf.fuel.json.responseJson class CheckoutActivity : AppCompatActivity() { lateinit var paymentSheet: PaymentSheet lateinit var customerConfig: PaymentSheet.CustomerConfiguration lateinit var paymentIntentClientSecret: String override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) paymentSheet = PaymentSheet(this, ::onPaymentSheetResult) "Your backend endpoint/payment-sheet".httpPost().responseJson { _, _, result -> if (result is Success) { val responseJson = result.get().obj() paymentIntentClientSecret = responseJson.getString("paymentIntent") customerConfig = PaymentSheet.CustomerConfiguration( responseJson.getString("customer"), responseJson.getString("ephemeralKey") ) val publishableKey = responseJson.getString("publishableKey") PaymentConfiguration.init(this, publishableKey) } } } fun onPaymentSheetResult(paymentSheetResult: PaymentSheetResult) { // implemented in the next steps } }

When the customer taps your checkout button, call presentWithPaymentIntent to present the payment sheet. After the customer completes the payment, the sheet dismisses and the PaymentSheetResultCallback is called with a PaymentSheetResult.

// ... class CheckoutActivity : AppCompatActivity() { lateinit var paymentSheet: PaymentSheet lateinit var customerConfig: PaymentSheet.CustomerConfiguration lateinit var paymentIntentClientSecret: String // ... fun presentPaymentSheet() { paymentSheet.presentWithPaymentIntent( paymentIntentClientSecret, PaymentSheet.Configuration( merchantDisplayName = "My merchant name", customer = customerConfig, // Set `allowsDelayedPaymentMethods` to true if your business // can handle payment methods that complete payment after a delay, like SEPA Debit and Sofort. allowsDelayedPaymentMethods = true ) ) } fun onPaymentSheetResult(paymentSheetResult: PaymentSheetResult) { when(paymentSheetResult) { is PaymentSheetResult.Canceled -> { print("Canceled") } is PaymentSheetResult.Failed -> { print("Error: ${paymentSheetResult.error}") } is PaymentSheetResult.Completed -> { // Display for example, an order confirmation screen print("Completed") } } } }

Setting allowsDelayedPaymentMethods to true allows delayed payment methods like SEPA Debit and Sofort. For these payment methods, the final payment status isn’t known when the PaymentSheet completes, and instead succeeds or fails later. If you allow this, inform the customer that you confirmed their order and only fulfill their order (for example, ship their product) when you receive payment.

Handle post-payment events
Server-side

Stripe sends a payment_intent.succeeded event when the payment completes. Use the Dashboard webhook tool or follow the webhook guide to receive these events and run actions, such as 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 is what enables you to accept different types of payment methods with a single integration.

In addition to handling the payment_intent.succeeded event, we recommend handling two other events when collecting payments with the Payment Element:

EventDescriptionAction
payment_intent.succeededSent when a customer has successfully completed a payment.Send the customer an order confirmation and fulfill their order.
payment_intent.processingSent when a customer successfully initiated a payment, but the payment has yet to complete. This event is most commonly sent when a bank debit is initiated. It’s followed by either a payment_intent.succeeded or payment_intent.payment_failed event in the future.Send the customer an order confirmation that indicates their payment is pending. For digital goods, you may want to fulfill the order before waiting for payment to complete.
payment_intent.payment_failedSent when a customer attempted a payment, but the payment failed.If a payment transitioned from processing to payment_failed, offer the customer another attempt to pay.

Test the integration

Use test payment details and the test redirect page to verify your integration. Click the tabs below to view details for each payment method.

Payment methodScenarioHow to test
Credit cardThe card payment succeeds and doesn’t require authentication.Fill out the credit card form using the credit card number 4242 4242 4242 4242 with any expiration, CVC, and postal code.
Credit cardThe card payment requires authentication.Fill out the credit card form using the credit card number 4000 0025 0000 3155 with any expiration, CVC, and postal code.
Credit cardThe card is declined with a decline code like insufficient_funds.Fill out the credit card form using the credit card number 4000 0000 0000 9995 with any expiration, CVC, and postal code.

OptionalEnable Google Pay

OptionalEnable card scanning

OptionalEnable ACH payments

OptionalCustomize the sheet

OptionalComplete payment in your UI

Have feedback on the mobile SDK?

Provide your email address if you’re interested in sharing feedback with us and getting early access to mobile features.
Read our privacy policy.
Signed up successfully!
Thank you! We'll be in touch soon.
Was this page helpful?
Questions? Contact us.
Watch our developer tutorials.
Check out our product changelog.
Powered by Markdoc
You can unsubscribe at any time. Read our privacy policy.
Code quickstart
On this page
Set up Stripe
Enable payment methods
Add an endpoint
Collect payment details
Handle post-payment events
Test the integration
Enable Google Pay
Enable card scanning
Enable ACH payments
Customize the sheet
Complete payment in your UI
Related Guides
Elements Appearance API
More payment scenarios
How cards work
Stripe Shell
Test mode
Welcome to the Stripe Shell! Stripe Shell is a browser-based shell with the Stripe CLI pre-installed. Login to your Stripe account and press Control + Backtick on your keyboard to start managing your Stripe resources in test mode. - View supported Stripe commands: - Find webhook events: - Listen for webhook events: - Call Stripe APIs: stripe [api resource] [operation] (e.g. )
The Stripe Shell is best experienced on desktop.
$