Skip to content
Create account
or
Sign in
The Stripe Docs logo
/
Ask AI
Create account
Sign in
Get started
Payments
Finance automation
Platforms and marketplaces
Money management
Developer tools
Get started
Payments
Finance automation
Get started
Payments
Finance automation
Platforms and marketplaces
Money management
OverviewExplore all products
Start building
Start developing
Sample projects
About the APIs
Build with LLMs
Use Stripe without code
Set up Stripe
Create an account
Web Dashboard
Mobile Dashboard
Migrate to Stripe
Manage fraud risk
Understand fraud
Radar fraud protection
Manage disputes
Verify identities
    Overview
    Get started
    Verify identity documents
    Handle verification outcomes
    Access verification results
    Review verification results
    Verification Flows
    More verification checks
    Verification checks
    Adding selfie checks
    About the APIs
    Verification Sessions
    Go live
    Before going live
    Supported use cases
    Explaining Identity
HomeGet startedVerify identities

Verify your users’ identity documents

Create sessions and collect identity documents.

Copy page

This guide explains how to use Stripe Identity to securely collect and verify identity documents.

Before you begin

  1. Activate your account.
  2. Fill out your Stripe Identity application.
  3. (Optional) Customize your brand settings on the branding settings page.

 

Note

To get access to the Identity Android SDK, visit the Identity Settings page and click Enable.

To verify the identity of your users on Android, present a verification sheet in your application. This guide includes the following steps:

  1. Set up Stripe.
  2. Add a server endpoint.
  3. Present the verification sheet.
  4. Handle verification events.

The steps in this guide are fully implemented in the example app and example backend server.

Set up
Server-side
Client-side

Note

If you intend to use this SDK with Stripe’s Identity service, you must not modify this SDK. Using a modified version of this SDK with Stripe’s Identity service, without Stripe’s written authorization, is a breach of your agreement with Stripe and might result in your Stripe account being shut down.

Install the SDK Client-side

The Stripe Android SDK is open source and fully documented.

To install the SDK, add identity to the dependencies block of your app/build.gradle file:

build.gradle.kts
Kotlin
plugins { id("com.android.application") } android { ... } dependencies { // ... // Stripe Identity Android SDK implementation("com.stripe:identity:21.14.0") }

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.

Use TFLite in Google Play to reduce binary size Client-side

Identity Android SDK uses a portable TFLite runtime to execute AI models. If your application is released through Google Play, you can use the Google Play runtime to reduce SDK size by about 1.2mb.

build.gradle
Groovy
dependencies { // ... // Stripe Identity Android SDK implementation('com.stripe:identity:21.14.0') { exclude group: 'com.stripe', module: 'ml-core-default' // exclude the default TFLite runtime } implementation('com.stripe:ml-core-googleplay:21.14.0') // include the Google Play TFLite runtime }

Set up material theme Client-side

The Stripe Identity Android SDK requires the hosting activity to use material theme. To enable material theme:

  1. Open your project’s app/src/main/AndroidManifest.xml.
  2. Make sure the android:theme applied to the application is a child of one of the material themes(for example, Theme.MaterialComponents.DayNight).

See more details about material theme here.

Install Stripe on your server Server-side

First, register for a Stripe account.

Then install the libraries for access to the Stripe API from your application:

Command Line
Ruby
# Available as a gem sudo gem install stripe
Gemfile
Ruby
# If you use bundler, you can add this line to your Gemfile gem 'stripe'

Add a server endpoint
Server-side

Create a VerificationSession

A VerificationSession is the programmatic representation of the verification. It contains details about the type of verification, such as what check to perform. You can expand the verified outputs field to see details of the data that was verified.

Simplify your integration

You can use verification flows for re-usable configuration, which is passed to the verification_flow parameter. Read more in the Verification flows guide.

You need a server-side endpoint to create the VerificationSession. Creating the VerificationSession server-side prevents malicious users from overriding verification options and incurring processing charges on your account. Add authentication to this endpoint by including a user reference in the session metadata or storing the session ID in your database.

For security, don’t create a VerificationSession object that’s directly accessible from the mobile client. Instead, your server provides the SDK with an ephemeral key — a short-lived API key with restricted access to the VerificationSession. You can think of an ephemeral key as a session, authorizing the SDK to retrieve and update a specific VerificationSession object for the duration of the session.

After successfully creating a VerificationSession and ephemeral key, send the VerificationSession ID and ephemeral key secret to the client to show the document upload sheet.

Note

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

server.js
Node
// Set your secret key. Remember to switch to your live secret key in production. // See your keys here: https://dashboard.stripe.com/apikeys const stripe = require('stripe')(
'sk_test_BQokikJOvBiI2HlWgH4olfQ2'
); // In the route handler for /create-verification-session: // Authenticate your user. // Create the session. const verificationSession = await stripe.identity.verificationSessions.create({ type: 'document', provided_details: { email: 'user@example.com', }, metadata: { user_id: '{{USER_ID}}', }, }); // Create an ephemeral key for the VerificationSession const ephemeralKey = await stripe.ephemeralKeys.create( {verification_session: verificationSession.id}, {apiVersion: '2025-04-30.basil'} ); // Return only the ID and ephemeral key secret to the frontend. const verficationSessionId = verificationSession.id; const ephemeralKeySecret = ephemeralKey.secret;

Caution

The ephemeral key secret is bound to the VerificationSession and lets your app collect sensitive verification information such as document and selfie image files. It’s single-use and expires after 1 hour. Don’t store it, log it, embed it in a URL, or expose it to anyone other than the user. Make sure that you have TLS enabled on any endpoint that returns the ephemeral key secret. Send only the ephemeral key secret to your app to avoid exposing verification configuration or results.

Test your endpoint by starting your web server (for example, localhost:4242) and sending a POST request with curl to create a VerificationSession:

Command Line
curl -X POST -is "http://localhost:4242/create-verification-session" -d ""

The response in your terminal looks like this:

Command Line
HTTP/1.1 200 OK Content-Type: application/json { id: "vs_QdfQQ6xfGNJR7ogV6", ephemeral_key_secret: "ek_YWNjdF8xRm..." }

Present the verification sheet
Client-side

Set up a button to present a verification sheet. After tapping the button, your user can capture and upload a picture of their passport, driver’s license, or national ID.

Before getting started, your verification page should:

  • Explain to the user why they need to verify their identity.
  • Include a verify identity button to present Stripe’s UI.

Add a button

Start by creating an Activity with a button that has a tap action and a loading indicator. Make sure MyHostingActivity inherits AppCompatActivity and uses a theme, inheriting Theme.MaterialComponents.

MyHostingActivity.kt
Kotlin
class MyHostingActivity : AppCompatActivity() { // binding has a button and a loading indicator private val binding by lazy { MyHostingActivityBinding.inflate(layoutInflater) } }

Import the Stripe Identity SDK

Import the Identity SDK to your activity, initialize it in the onCreate method (This registers an ActivityResultLauncher on this AppCompatActivity or Fragment).

MyHostingActivity.kt
Kotlin
import com.stripe.android.identity.IdentityVerificationSheet class MyHostingActivity : AppCompatActivity() { // binding has a button and a loading indicator private val binding by lazy { MyHostingActivityBinding.inflate(layoutInflater) } lateinit var identityVerificationSheet: IdentityVerificationSheet override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(binding.root) identityVerificationSheet = IdentityVerificationSheet.create( this, IdentityVerificationSheet.Configuration( // Pass your square brand logo by creating it from local resource or // Uri.parse("https://path/to/your/brandlogo.jpg") brandLogo = logoUri ) ) { verificationResult-> when (verificationResult) { is Completed -> { // The user has completed uploading their documents. // Let them know that the verification is processing. ... Log.d(TAG, "Verification Completed!") } is Canceled -> { // The user did not complete uploading their documents. // You should allow them to try again. ... Log.d(TAG, "Verification Canceled!") } is Failed -> { // If the flow fails, you should display the localized error // message to your user using throwable.getLocalizedMessage() ... Log.d(TAG, "Verification Failed!") } } } } }

Add an action to the Verify button

Now that you have a button and an endpoint to create a VerificationSession, modify the button so that it presents the document upload sheet when tapped the document upload sheet when tapped.

Add a call to:

  • Fetch the VerificationSession ID and ephemeral key secret from your endpoint.
  • Instantiate an IdentityVerificationSheet with your brand logo and present it to the user.
  • Handle the VerificationFlowResult to know if the user completed the verification flow.
MyHostingActivity.kt
Kotlin
import com.stripe.android.identity.* class MyHostingActivity : AppCompatActivity() { // binding has a button and a loading indicator private val binding by lazy { MyHostingActivityBinding.inflate(layoutInflater) } lateinit var identityVerificationSheet: IdentityVerificationSheet override fun onCreate(savedInstanceState: Bundle?) { ... binding.button.setOnClickListener(::onButtonClick) } fun onButtonClick() { // show loading UI // Request the session ID with Fuel or other network libraries Fuel.post("https://{{YOUR_SERVER_BASE_URL}}/create-verification-session") .responseString { _, _, result -> when (result) { is Result.Failure -> { // show error UI } is Result.Success -> { val responseJson = JSONObject(result.value) try { // start verification session identityVerificationSheet.present( verificationSessionId = responseJson.getString("id"), ephemeralKeySecret = responseJson.getString("ephemeral_key_secret") ) } catch (t: Throwable) { // show error UI } } } } } }

Test the verification sheet

Test that the verify button presents a document upload sheet:

  • Tap the Verify Identity button.
  • Ensure no error messages are shown.

If your integration isn’t working:

  1. Put a breakpoint where you fetch the VerificationSession ID and ephemeral key secret.
  2. Verify that no network errors exist and that the endpoint is returning a VerificationSession ID and ephemeral key secret.

Handle verification events

Document checks are typically completed as soon as the user redirects back to your site and you can retrieve the result from the API immediately. In some rare cases, the document verification isn’t ready yet and must continue asynchronously. In these cases, you’re notified through webhooks when the verification result is ready. After the processing completes, the VerificationSession status changes from processing to verified.

Stripe sends the following events when the session status changes:

Event nameDescriptionNext steps
identity.verification_session.verifiedProcessing of all the verification checks have completed, and they’re all successfully verified.Trigger relevant actions in your application.
identity.verification_session.requires_inputProcessing of all the verification checks have completed, and at least one of the checks failed.Trigger relevant actions in your application and potentially allow your user to retry the verification.

Use a webhook handler to receive these events and automate actions like sending a confirmation email, updating the verification results in your database, or completing an onboarding step. You can also view verification events in the Dashboard.

Receive events and run business actions

With code

Build a webhook handler to listen for events and build custom asynchronous verification flows. Test and debug your webhook integration locally with the Stripe CLI.

Build a custom webhook

Without code

Use the Dashboard to view all your verifications, inspect collected data, and understand verification failures.

View your test verifications in the Dashboard

Was this page helpful?
YesNo
Need help? Contact Support.
Join our early access program.
Check out our changelog.
Questions? Contact Sales.
LLM? Read llms.txt.
Powered by Markdoc
Products Used
Identity