Sign in
Create account
Sign in
Home
Payments
Business operations
Financial services
Developer tools
Security
All products
Home
Payments
Business operations
Home
Payments
Business operations
Financial services
Developer tools
Support
Overview
Overview
Sample integration
Example applications
Designing an integration
Integrate your application and readers
Getting started
JavaScript
iOS
Android
Readers
Reader setup
Connecting to a reader
Fleet management
Creating reader locations
Using reader locations
Placing orders
Setting a custom splash screen
Transactions
Collecting payments
Connect platforms
Saving cards
Refunds
Checkout experience
Cart display
Receipts
Beta
Beta migration guide
Testing
Checklist
Testing
terminal
·
HomePaymentsIn-person payments

Getting started with the iOS SDK

Set up the Stripe Terminal iOS SDK so that you can begin accepting in-person payments.

SDK Reference

If you’re looking for a more detailed reference with all available methods, objects, and errors, consult our our full SDK reference.

Getting started with the iOS SDK requires five steps:

  1. Install the SDK in your app
  2. Configure your app
  3. Set up the connection token endpoint in your app and backend
  4. Initialize the SDK in your app
  5. Connect your app to the simulated reader

Just getting started with Terminal? Check out our example applications to get your own integration set up quickly.

Install the SDK
Client-side

The Stripe Terminal iOS SDK is compatible with apps supporting iOS 9 and above, and can be installed with CocoaPods or by manually integrating the framework.

  1. If you haven’t already done so, install a recent version of CocoaPods.

  2. If you don’t have an existing Podfile, run the following command to create one:

    Terminal
    pod init
  3. Add this line to your Podfile:

    Podfile
    pod 'StripeTerminal', '1.4.0'
  4. Run the following command:

    Terminal
    pod install
  5. From now on, use the .xcworkspace file to open your project in Xcode, instead of the .xcodeproj file.

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 or subscribe to the Github Releases RSS feed.

For information on migrating from beta versions of the iOS SDK, see the Stripe Terminal Beta Migration Guide.

Configure your app
Client-side

To prepare your app to work with the Stripe Terminal SDK, make a few changes to your Info.plist file in Xcode.

  1. Enable location services with the following key-value pair.

    Privacy – Location When In Use Usage Description
    KeyNSLocationWhenInUseUsageDescription
    ValueLocation access is required in order to accept payments.

    To reduce fraud risks associated with payments, and to minimize disputes, Stripe needs to know where payments occur. If the SDK can’t determine the location of the iOS device, payments are disabled until location access is restored.

  2. Ensure that your app runs in the background and remains connected to the reader.

    Required background modes
    KeyUIBackgroundModes
    Valuebluetooth-central (Uses Bluetooth LE accessories)

    Setting the bluetooth-central background mode lets the reader remain in standby mode when your app is backgrounded, or when the iOS device is locked. Without this value, standby fails. When your app is running in the background, the reader can turn off automatically to conserve power.

  3. Pass app validation checks when submitting to the App Store.

    Privacy – Bluetooth Peripheral Usage Description
    KeyNSBluetoothPeripheralUsageDescription
    ValueBluetooth access is required in order to connect to supported card readers.

    This is an example—you can rephrase the prompt for user permission in your app.

  4. iOS 13 SDK and later: Allow your app to display a Bluetooth permission dialog.

    Privacy - Bluetooth Always Usage Description
    KeyNSBluetoothAlwaysUsageDescription
    ValueThis app uses Bluetooth to connect to supported card readers.

    iOS 13 introduces new, more granular permissions surrounding an app’s use of Bluetooth peripherals. Any apps that use the device’s Bluetooth APIs must include this key in their Info.plist file, or else they will crash on first launch.

Save your app’s Info.plist. Now it’s configured correctly and ready for use with the Stripe Terminal SDK.

Set up the ConnectionToken endpoint
Server-side
Client-side

Server-side

To connect to a reader, your backend needs to give the SDK permission to use the reader with your Stripe account, by providing it with the secret from a ConnectionToken. Your backend should only create connection tokens for clients that it trusts.

Terminal
curl https://api.stripe.com/v1/terminal/connection_tokens \ -u
sk_test_4eC39HqLyjWDarjtT1zdp7dc
: \ -X "POST"

Obtain the secret from the ConnectionToken on your server and pass it to the client side.

post '/connection_token' do token = # ... Create or retrieve the ConnectionToken {secret: token.secret}.to_json end

The ConnectionToken’s secret lets you connect to any Stripe Terminal reader and take payments with your Stripe account. Be sure to authenticate the endpoint for creating connection tokens.

Client-side

To give the SDK access to this endpoint, implement the ConnectionTokenProvider protocol in your app, which defines a single function that requests a ConnectionToken from your backend.

APIClient.swift
import StripeTerminal // Example API client class for communicating with your backend class APIClient: ConnectionTokenProvider { // For simplicity, this example class is a singleton static let shared = APIClient() // Fetches a ConnectionToken from your backend func fetchConnectionToken(_ completion: @escaping ConnectionTokenCompletionBlock) { let config = URLSessionConfiguration.default let session = URLSession(configuration: config) guard let url = URL(string: "https://{YOUR BACKEND URL}/connection_token") else { fatalError("Invalid backend URL") } var request = URLRequest(url: url) request.httpMethod = "POST" let task = session.dataTask(with: request) { (data, response, error) in if let data = data { do { // Warning: casting using `as? [String: String]` looks simpler, but isn't safe: let json = try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any] if let secret = json?["secret"] as? String { completion(secret, nil) } else { let error = NSError(domain: "com.stripe-terminal-ios.example", code: 2000, userInfo: [NSLocalizedDescriptionKey: "Missing `secret` in ConnectionToken JSON response"]) completion(nil, error) } } catch { completion(nil, error) } } else { let error = NSError(domain: "com.stripe-terminal-ios.example", code: 1000, userInfo: [NSLocalizedDescriptionKey: "No data in response from ConnectionToken endpoint"]) completion(nil, error) } } task.resume() } }

This function is called whenever the SDK needs to authenticate with Stripe or the Reader. It’s also called when a new connection token is needed to connect to a reader (for example, when your app disconnects from a reader). If the SDK is unable to retrieve a new connection token from your backend, connecting to a reader fails with the error from your server.

Do not cache or hardcode the connection token. The SDK manages the connection token’s lifecycle.

Initialize the SDK
Client-side

The Terminal class made available by the Stripe Terminal SDK exposes a generic interface for discovering readers, connecting to a reader, creating payments, and updating reader software.

To get started, provide your ConnectionTokenProvider implemented in Step 3. You can only call setTokenProvider once in your app, and must call it before accessing Terminal.shared. We recommend calling setTokenProvider in your AppDelegate’s application:didFinishLaunchingWithOptions method. Alternatively, you can use dispatch_once in Objective-C, or a static constructor in Swift.

AppDelegate.swift
import UIKit import StripeTerminal @UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate { func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool { Terminal.setTokenProvider(APIClient.shared) // ... return true } // ... }

Connect to the simulated reader
Client-side

The Stripe Terminal SDK comes with a built-in simulated card reader, so you can develop and test your app without connecting to physical hardware. Whether your integration is complete or you’re just starting out, use the simulated reader to emulate all the Terminal flows in your app: connecting to a reader, updating reader software, and collecting payments.

Note that the simulated reader does not provide a UI. After connecting to it in your app, you can see it working when calls to the Stripe SDK succeed.

To use the simulated reader, call discoverReaders to search for readers, with the simulated option set to true. When discoverReaders returns a result, call connectReader to connect to the simulated reader.

ReaderDiscoveryViewController.swift
import UIKit import StripeTerminal class ReaderDiscoveryViewController: UIViewController, DiscoveryDelegate { var discoverCancelable: Cancelable? // ... // Action for a "Discover Readers" button func discoverReadersAction() { let config = DiscoveryConfiguration( discoveryMethod: .bluetoothScan, simulated: true ) self.discoverCancelable = Terminal.shared.discoverReaders(config, delegate: self) { error in if let error = error { print("discoverReaders failed: \(error)") } else { print("discoverReaders succeeded") } }) } // ... // MARK: DiscoveryDelegate // This delegate method can get called multiple times throughout the discovery process. // You might want to update a UITableView and display all available readers. // Here, we're automatically connecting to the first reader we discover. func terminal(_ terminal: Terminal, didUpdateDiscoveredReaders readers: [Reader]) { // Select the first reader we discover guard let selectedReader = readers.first else { return } // Only connect if we aren't currently connected. guard terminal.connectionStatus == .notConnected else { return } Terminal.shared.connectReader(selectedReader) { reader, error in if let reader = reader { print("Successfully connected to reader: \(reader)") } else if let error = error { print("connectReader failed: \(error)") } }) } }

SDK updates

Stripe periodically releases updates to the Stripe Terminal JavaScript SDK, the Stripe Terminal iOS SDK, and the Stripe Terminal Android SDK, which can include new functionality, bug fixes, and security updates. Update your integrated version of the Stripe Terminal JavaScript, iOS, or Android SDK as soon as a new version is available.

Next steps

  • Collecting payments
  • Reader setup
Was this page helpful?
Questions? Contact us.
Developer tutorials on YouTube.
You can unsubscribe at any time. Read our privacy policy.
On this page
Install the SDK
Configure your app
Set up the ConnectionToken endpoint
Initialize the SDK
Connect to the simulated reader
SDK updates