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
Products and prices
Invoicing
Subscriptions
Quotes
In-person payments
    Overview
    What is Terminal
    Design an integration
    Example applications
    Quickstart
    Accept an in-person payment
    Set up your reader
    Set up your integration
    Connect to a reader
    Collect payments
    Regional considerations
    Supported card brands
    Terminal payments features
    Multiparty payments with Connect
    Collect tips
    Save cards for future use
    Refund transactions
    Provide receipts
    Cart display
    Incremental authorizations
    Extended authorizations
    Operate offline
    Deploy at scale
    Order hardware
    Manage locations
    Configure readers
    References
    API references
    Bluetooth readers
    Smart readers
    SDK migration guide
    Testing
    Deployment checklist
    Stripe Terminal reader product sheets
Multiparty payments
After the payment
Add payment methods
Payment Links
Stripe Checkout
Stripe Elements
About the APIs
Regulation support
Implementation guides
Testing
Terminal
·
HomePaymentsIn-person payments

Connect to a reader

Connect your application to a Stripe Terminal reader.

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

Bluetooth-connected readers are Bluetooth LE devices. They collect payment details, but rely on a paired mobile device for communication with Stripe.

Follow these steps to connect your app to a Terminal reader using Bluetooth:

  • Discover readers
  • Connect to a reader

Don’t use mobile device settings to pair with your reader. Pairing the reader through device settings makes the reader unavailable to connect to your app.

Discover readers
Client-side

First, turn on the reader. Then, from your app, search for nearby Bluetooth-connected readers using the discoverReaders method.

ReaderDiscoveryViewController.swift
import StripeTerminal class ReaderDiscoveryViewController: UIViewController, DiscoveryDelegate { var discoverCancelable: Cancelable? // ... // Action for a "Discover Readers" button func discoverReadersAction() { let config = DiscoveryConfiguration( discoveryMethod: .bluetoothScan, simulated: false ) self.discoverCancelable = Terminal.shared.discoverReaders(config, delegate: self) { error in if let error = error { print("discoverReaders failed: \(error)") } else { print("discoverReaders succeeded") } } } // ... // MARK: DiscoveryDelegate func terminal(_ terminal: Terminal, didUpdateDiscoveredReaders readers: [Reader]) { // In your app, display the discovered reader(s) to the user. // Call `connectBluetoothReader` after the user selects a reader to connect to. } }

Bluetooth proximity * BBPOS Chipper 2X BT only

Bluetooth proximity filters search results to return the closest reader. When discovered, the reader flashes multicolored lights, making it easy for your user to identify the discovered reader among many other readers. After the SDK discovers a reader, it won’t switch to a closer reader unless you turn off the discovered reader.

Note that when using Bluetooth proximity, the SDK returns the reader to your app’s callback twice. The first time, your app receives a Reader object populated with only the reader’s serial number. After a short delay, your app receives the same Reader object populated with new information, such as the reader’s battery level.

We recommend displaying the discovered reader in your app’s UI, letting the user either confirm connection to the reader or cancel if they don’t want to connect to this reader.

Bluetooth scan

Bluetooth scan searches for all nearby readers and returns a list of discovered readers to your app. As the discovery process continues, the SDK continues to invoke the DiscoveryDelegate.didUpdateDiscoveredReaders method with the latest list of nearby readers.

With the Bluetooth scan discovery method, you can set a timeout to scan for a set period of time. This is useful for managing battery life or triggering an error message if no devices are found.

In your mobile application, we recommend displaying an auto-updating list of discovered readers, with serial numbers or labels to help users identify their reader.

Connect to a reader
Client-side

To connect to a discovered reader, call the connectBluetoothReader method from your app. As soon as the SDK connects to the reader, the reader’s status light shines solid blue.

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

ReaderDiscoveryViewController.swift
// Call `connectBluetoothReader` with the selected reader and a connection config // to register to a location as set by your app. let connectionConfig = BluetoothConnectionConfiguration(locationId:
"{{LOCATION_ID}}"
) Terminal.shared.connectBluetoothReader(selectedReader, delegate: readerDelegate, connectionConfig: connectionConfig) { reader, error in if let reader = reader { print("Successfully connected to reader: \(reader)") } else if let error = error { print("connectBluetoothReader failed: \(error)") } }

For your app to run in the background and remain connected to the reader, configure your app to include the required background mode.

Don’t program your app to call disconnectReader to conserve power. The reader efficiently handles power management using its standby mode.

Handle unexpected disconnects

SDK Reference

- TerminalDelegate (iOS)

Unexpected disconnects can sometimes occur between your app and the reader. For example, the reader can disconnect from your app if it’s out of range or runs out of battery. Or, you can simulate an unexpected disconnect while testing by powering off the reader.

You can handle disconnects in two ways:

1. Handle the disconnect immediately

For this option, your app must implement the didReportUnexpectedReaderDisconnect callback to manually handle when a reader disconnects. This is the default behavior of the SDK.

In your implementation of this callback, display a UI to notify the user that the reader disconnected.

The reader can disconnect from your app if it goes out of range or runs out of battery. To simulate an unexpected disconnect while testing, power off the reader.

ReaderViewController.swift
import StripeTerminal class ReaderViewController: UIViewController, TerminalDelegate { override func viewDidLoad() { super.viewDidLoad() Terminal.shared.delegate = self } // ... // MARK: TerminalDelegate func terminal(_ terminal: Terminal, didReportUnexpectedReaderDisconnect reader: Reader) { // Consider displaying a UI to notify the user and start rediscovering readers } }

2. Automatically attempt reconnection

For this option, your app must set autoReconnectOnUnexpectedDisconnect as true on the BluetoothConnectionConfiguration and implement the callbacks found in the ReconnectionDelegate. You must also pass a autoReconnectionDelegate to your BluetoothConnectionConfiguration.

let connectionConfig = BluetoothConnectionConfiguration(locationId: presentLocationId, autoReconnectOnUnexpectedDisconnect: true, autoReconnectionDelegate: yourReconnectionDelegate) Terminal.shared.connectBluetoothReader(reader, delegate: readerDelegate, connectionConfig: connectionConfig, completion: connectCompletion)

If you automatically attempt reconnection, the following occurs:

  1. When a disconnect occurs, the SDK automatically attempts to reconnect and notifies you through didStartReaderReconnect. 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, you’ll be notified through didSucceedReaderReconnect. 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, you’ll be notified through didFailReaderReconnect. Make sure your app announces that an unexpected disconnect occurred.
ReaderViewController.swift
import StripeTerminal extension ReaderViewController: ReconnectionDelegate { // MARK: ReconnectionDelegate func terminal(_ terminal: Terminal, didStartReaderReconnect cancelable: Cancelable) { // 1. Notified at the start of a reconnection attempt // Use cancelable to stop reconnection at any time } func terminalDidSucceedReaderReconnect(_ terminal: Terminal) { // 2. Notified when reader reconnection succeeds // App is now connected } func terminalDidFailReaderReconnect(_ terminal: Terminal) { // 3. Notified when reader reconnection fails // App is now disconnected } }

Automatic reconnection on application start

Stripe Terminal doesn’t automatically reconnect to a reader when your application starts. Instead, you can build a reconnection flow by storing reader IDs and attempting to connect to a known reader on startup.

  1. When you successfully connect to a reader, save its serial number in a persistent data storage location, such as the UserDefaults API (iOS).
  2. When your app launches, check the persistent data storage location for a saved serial number. If one is found, call the discoverReaders method so your application can try to find that reader again.
  3. If the saved serial number matches any of the discovered readers, try connecting to that reader with the matching reader object returned from the call to discoverReaders. If the previously connected reader isn’t found, stop the discovery process.

Display some UI during the discovery and connection process to indicate that an automatic reconnection is happening.

Update reader software
Client-side

SDK Reference

- SCPBluetoothReaderDelegate

You must support updating the Bluetooth reader from your application. The reader cannot update itself. These updates include regional configurations that keep you up to date with card network and issuer requirements, as well as potential security updates. Required updates will start installing on connection to the reader and must complete before the reader can be used.

Installing updates requires that the reader’s battery is charged to more than 50%.

Required updates

If there are immediately required updates for the reader, they will be installed when connecting to it. The connection process will not complete until the required update has been installed.

When a required update starts installing, your application’s BluetoothReaderDelegate will receive didStartInstallingRequiredUpdate with a ReaderSoftwareUpdate object containing the update details. This will include an estimate of total update duration, estimatedUpdateTime.

Your application should notify users that an update is being installed, and display the progress in your UI so it’s clear why the connection process is taking longer than normal.

ReaderViewController.swift
import UIKit import StripeTerminal class ReaderViewController: UIViewController, BluetoothReaderDelegate { // ... // MARK: BluetoothReaderDelegate func reader(_ reader: Reader, didStartInstallingUpdate update: ReaderSoftwareUpdate, cancelable: Cancelable?) { // Show UI communicating that a required update has started installing } func reader(_ reader: Reader, didReportReaderSoftwareUpdateProgress progress: Float) { // Update the progress of the install } func reader(_ reader: Reader, didFinishInstallingUpdate update: ReaderSoftwareUpdate?, error: Error?) { // Report success or failure of the update } // ... }

You can cancel required updates using the Cancelable object. However, this will result in a failed connection to the reader. For incremental-only updates no Cancelable is provided as these updates can not be canceled.

Optional updates

Optional updates can be deferred, but will become required updates if not installed by a certain date. Optional updates will be announced to your BluetoothReaderDelegate at any time the reader is connected but not performing a transaction. If an optional update is available, your application’s BluetoothReaderDelegate will receive the didReportAvailableUpdate callback with the ReaderSoftwareUpdate object containing the update details. This update is also stored on the reader object as reader.availableUpdate, and is the update that will be installed when calling Terminal.installAvailableUpdate. The update object includes an estimate of update duration (estimatedUpdateTime) and the future date at which the update must be installed (requiredAt).

In your application, you should notify users that an update is available, and display a prompt to optionally continue with the update.

To proceed with the update, call installAvailableUpdate, which will install the update previously reported via didReportAvailableUpdate.

As the update proceeds, block the user from leaving the page in your app, and instruct the user to keep the reader in range and powered on until the update is complete. We recommend also providing your user with a visual indicator of the update’s progress. The BluetoothReaderDelegate reports the updates progress via the didReportReaderSoftwareUpdateProgress method.

When an optional update’s requiredAt date has passed, the update will not be installed until the reader is disconnected and reconnected.

ReaderViewController.swift
import UIKit import StripeTerminal class ReaderViewController: UIViewController, BluetoothReaderDelegate { // ... // MARK: BluetoothReaderDelegate func reader(_ reader: Reader, didReportAvailableUpdate update: ReaderSoftwareUpdate) { // An update is available for the connected reader. Show this update in your application. // This update can be installed using `Terminal.shared.installAvailableUpdate`. } }

See Testing Bluetooth reader updates to learn more about making sure your application handles the different update types that a reader can have.

Next steps

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

  • Collect payments

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?
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.
On this page
Discover readers
Connect to a reader
Update reader software
See also
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.
$