Skip to content
Create account
or
Sign in
The Stripe Docs logo
/
Ask AI
Create account
Sign in
Get started
Payments
Revenue
Platforms and marketplaces
Money management
Developer tools
Overview
About Stripe payments
Upgrade your integration
Payments analytics
Online payments
OverviewFind your use caseManaged Payments
Use Payment Links
Build a checkout page
Build an advanced integration
Build an in-app integration
Payment methods
Add payment methods
Manage payment methods
Faster checkout with Link
Payment interfaces
Payment Links
Checkout
Web Elements
In-app Elements
Payment scenarios
Custom payment flows
Flexible acquiring
Orchestration
In-person payments
Terminal
    Overview
    Accept in-person payments
    Integration design
    Select your reader
    Design an integration
    Quickstart
    Example applications
    Testing
    Terminal setup
    Set up your integration
    Connect to a reader
      Network requirements
    Accepting a payment
    Collect card payments
    Additional payment methods
    Accept offline payments
    Mail order and telephone order payments
    Regional considerations
    During checkout
    Collect tips
    Collect and save payment details for future use
    Flexible authorizations
    After checkout
    Refund transactions
    Provide receipts
    Customize checkout
    Cart display
    Collect on-screen inputs
    Collect swiped data
    Collect tapped data for NFC instruments
    Apps on devices
    Manage readers
    Order, return, replace readers
    Register readers
    Manage locations and zones
    Configure readers
    Monitor Readers
    Encryption
    References
    API references
    Mobile readers
    Smart readers
    SDK migration guide
    Deployment checklist
    Stripe Terminal reader product sheets
Other Stripe products
Financial Connections
Crypto
Climate
HomePaymentsTerminal

Connect to a reader

Connect your application to a Stripe Terminal reader.

Copy page

Note

If you haven’t chosen a reader yet, compare the available Terminal readers and choose one that best suits your needs.

Tap to Pay on Android (TTPA) lets users accept in-person contactless payments with compatible NFC-equipped Android devices. TTPA requires the latest version of the Terminal Android SDK. TTPA supports Visa, Mastercard, and American Express contactless cards and NFC-based mobile wallets (Apple Pay, Google Pay, and Samsung Pay). TTPA is an extension to the Terminal Android SDK and enables payments directly in your Android app.

Follow these steps to connect your app to the Tap to Pay reader on a supported Android device:

  1. Initialize the SDK for TTPA.
  2. Discover readers using the SDK to confirm device compatibility.
  3. Connect to a reader using the SDK to accept payments.
  4. Handle unexpected disconnects to make sure your user can continue to accept payments if the reader disconnects unexpectedly.

If your application runs on a device that doesn’t meet the supported device criteria, the SDK returns a TerminalException that provides additional context in an onFailure callback.

Initialize the SDK

SDK Reference

  • TapToPay (Android)

TTPA operates in a dedicated process to make transactions more secure. In this process, a second instance of your Application is created. To avoid any unexpected errors caused by running your code in this process, you can skip initialization in your Application in this process by checking TapToPay.isInTapToPayProcess().

StripeTerminalApplication.kt
Kotlin
// Substitute with your application name, and remember to keep it the same as your AndroidManifest.xml class StripeTerminalApplication : Application() { override fun onCreate() { super.onCreate() // Skip initialization if running in the TTPA process. if (TapToPay.isInTapToPayProcess()) return // For example, this will be skipped. TerminalApplicationDelegate.onCreate(this) } }

Discover readers

SDK Reference

  • discoverReaders (Android)
  • TapToPayDiscoveryConfiguration (Android)

Use the discoverReaders method to determine hardware support for Tap to Pay on the Android device. discoverReaders verifies the following requirements:

  • The device contains a functioning NFC antenna and chipset.
  • The device has a hardware-backed keystore.
  • The device runs a current version of Android (Android 11 or above).
  • For the non-simulated version of the Tap to Pay reader, the application isn’t debuggable.

Your application must be in the foreground for the Tap to Pay reader service to successfully start.

If your application runs on a device that doesn’t meet the requirements above, the onFailure callback returns with a TerminalException that contains a TerminalErrorCode and additional context. The failures at this stage aren’t actionable by the end user.

Using the non-simulated, production version of the Tap to Pay reader with debuggable applications isn’t supported for security and compliance reasons. To test your integration with the Tap to Pay on Android reader, set TapToPayDiscoveryConfiguration.isSimulated to true during reader discovery. You must set this value to false in the release version of your application.

DiscoverReadersActivity.kt
Kotlin
var discoverCancelable: Cancelable? = null fun onDiscoverReaders() { val isApplicationDebuggable = 0 != applicationInfo.flags and ApplicationInfo.FLAG_DEBUGGABLE val config = TapToPayDiscoveryConfiguration(isSimulated = isApplicationDebuggable) // Save this cancelable to an instance variable discoverCancelable = Terminal.getInstance().discoverReaders( config, object : DiscoveryListener { override fun onUpdateDiscoveredReaders(readers: List<Reader>) { // Automatically connect to supported mobile readers } }, object : Callback { override fun onSuccess() { // Placeholder for handling successful operation } override fun onFailure(e: TerminalException) { // Placeholder for handling exception } } ) } override fun onStop() { super.onStop() // If you're leaving the activity or fragment without selecting a reader, // make sure you cancel the discovery process or the SDK will be stuck in // a discover readers phase discoverCancelable?.cancel( object : Callback { override fun onSuccess() { // Placeholder for handling successful operation } override fun onFailure(e: TerminalException) { // Placeholder for handling exception } } ) }

To check if a device meets the Tap to Pay hardware and OS requirements at runtime, use the Terminal.supportsReadersOfType function. As part of initializing the Terminal SDK, this function requires your end-user to accept permission requests to access the location and bluetooth. This function takes approximately 10 milliseconds to run on most devices.

Connect to a reader

SDK Reference

  • connectReader (Android)
  • TapToPayConnectionConfiguration (Android)

To accept Tap to Pay payments, provide the discovered reader from the previous step to the connectReader method.

connectReader verifies the following requirements:

  • The device has a stable connection to the internet.
  • The device isn’t rooted and the device bootloader is locked and unchanged.
  • The device uses Google Mobile Services.
  • The device runs a current version of Android (Android 11 or above).
  • The application uses a supported version of the Tap to Pay SDK (currently 2.20.0 or above).

If your application runs on a device that doesn’t meet the requirements above, the onFailure callback returns with a TerminalException that contains a TerminalErrorCode and additional context. The end user can take action on some of the failure reasons. For example:

  • STRIPE_API_CONNECTION_ERROR: The user can connect to a stable internet source.
  • TAP_TO_PAY_UNSUPPORTED_ANDROID_VERSION: The user can upgrade their operating system, if an update is available from the device manufacturer.

You must register your reader to a location upon connection. To do so, create and use a TapToPayConnectionConfiguration with the locationId set to the relevant location ID when connecting.

ConnectReaderActivity.kt
Kotlin
val tapToPayReaderListener = yourTapToPayReaderListener val autoReconnectOnUnexpectedDisconnect = true val config = TapToPayConnectionConfiguration(
"{{LOCATION_ID}}"
, autoReconnectOnUnexpectedDisconnect, tapToPayReaderListener ), Terminal.getInstance().connectReader( firstReader, config, object : ReaderCallback { override fun onSuccess(reader: Reader) { // Placeholder for handling successful operation } override fun onFailure(e: TerminalException) { // Placeholder for handling exception } } )

Handle unexpected disconnects

SDK Reference

  • TapToPayReaderListener (Android)

Unexpected disconnects might occur between your app and the reader. For example, the Tap to Pay reader might unexpectedly disconnect because:

  • Android OS terminates the Tap to Pay reader service due to memory constraints.
  • The device loses internet connectivity.

There are two ways you can handle this:

Automatically attempt reconnection

Stripe automatically attempts reconnection by default when an unexpected disconnect occurs. Set up TapToPayReaderListener for auto reconnect callbacks in your app.

ConnectReaderActivity.kt
Kotlin
val tapToPayReaderListener = yourTapToPayReaderListener val autoReconnectOnUnexpectedDisconnect = true Terminal.getInstance().connectReader( reader, TapToPayConnectionConfiguration(
"{{LOCATION_ID}}"
, autoReconnectOnUnexpectedDisconnect, tapToPayReaderListener ), readerCallback, )

When the SDK automatically attempts reconnection, the following occurs:

  1. When a disconnect occurs, the SDK automatically attempts to reconnect and notifies you through onReaderReconnectStarted. Make sure your app announces that the connection was lost and a reconnection is in progress.
    • You can use the Cancelable object to stop the reconnection attempt at any time.
  2. If the SDK successfully reconnects to the reader, Stripe notifies you through onReaderReconnectSucceeded. Make sure your app announces that the connection was restored and to continue normal operations.
  3. If the SDK can’t reconnect to the reader, Stripe notifies you through both onReaderReconnectFailed and TapToPayReaderListener.onDisconnect. Make sure your app announces that an unexpected disconnect occurred.
CustomTapToPayReaderListener.kt
Kotlin
class CustomTapToPayReaderListener : TapToPayReaderListener { override fun onReaderReconnectStarted(reader: Reader, cancelReconnect: Cancelable, reason: DisconnectReason) { // 1. Notified at the start of a reconnection attempt // Use cancelable to stop reconnection at any time } override fun onReaderReconnectSucceeded(reader: Reader) { // 2. Notified when reader reconnection succeeds // App is now connected } override fun onReaderReconnectFailed(reader: Reader) { // 3. Notified when reader reconnection fails // App is now disconnected } }

Handle the disconnect manually

To handle reader disconnects yourself, you can set autoReconnectOnUnexpectedDisconnect as false and implement the TapToPayReaderListener.onDisconnect callback. This allows your app to reconnect to the Tap to Pay reader and, when appropriate, notify the user of what went wrong and how they can enable access to Tap to Pay. End users can resolve certain errors, such as internet connectivity issues.

ReaderActivity.kt
Kotlin
class ReaderActivity : AppCompatActivity(), TapToPayReaderListener { // ... override fun onDisconnect(reason: DisconnectReason) { // Consider displaying a UI to notify the user and start rediscovering readers } // ... }

Next steps

You’ve connected your application to the reader. Next, collect your first Stripe Terminal payment.

The BBPOS and Chipper™ name and logo are trademarks or registered trademarks of BBPOS Limited in the United States and/or other countries. The Verifone® name and logo are either trademarks or registered trademarks of Verifone in the United States and/or other countries. Use of the trademarks does not imply any endorsement by BBPOS or Verifone.

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