Getting Started with the iOS SDK Beta

    Set up the Stripe Terminal iOS SDK so that you can begin accepting in-person payments. The iOS SDK is compatible with apps supporting iOS 9 and above.

    Set up the iOS SDK in just a few 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

    Step 1: Install the SDK

    1. If you haven't already done so, install a recent version of CocoaPods.
    2. If you don't have an existing Podfile, create one. Run the following command:
      pod init
    3. Add this line to your Podfile:
      pod 'StripeTerminal', '1.0.0-rc1'
    4. Run the following command:
      pod install

    From now on, use the .xcworkspace file to open your project in Xcode, instead of the .xcodeproj file. You can always update to the latest version of the SDK with pod update StripeTerminal.

    Step 2: Configure your app

    Make a few updates to your app in Xcode to prepare it for working with the Stripe Terminal SDK. First, enable location services. Add the following key-value pair to your app’s Info.plist file.

    Privacy – Location When In Use Usage Description

    • Key: NSLocationWhenInUseUsageDescription
    • Value: “Location access is required in order to accept payments.”
      • This is an example—you can rephrase the prompt for user permission in your app.

    To ensure that your app runs in the background and remains connected to the reader, add this key-value pair to the file:

    Required background modes

    • Key: UIBackgroundModes
    • Value: “bluetooth-central” (Uses Bluetooth LE accessories)
      • This is an example—you can rephrase the prompt for user permission in your app.

    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.

    Next, add the following key-value pairs to pass app validation checks when submitting to the App Store.

    Privacy – Bluetooth Peripheral Usage Description

    • Key: NSBluetoothPeripheralUsageDescription
    • Value: “Bluetooth 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.

    Privacy – Microphone Usage Description

    • Key: NSMicrophoneUsageDescription
    • Value: “Microphone 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.

    Although Stripe currently doesn’t support any audio-jack card readers, you still need to add a microphone usage description to your Info.plist to pass App Store validation, as our underlying hardware SDK accesses these APIs. Since the SDK never uses microphone access, your users won’t be prompted for microphone permission.

    Step 3: Set up the connection token endpoint

    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 a connection token. Your backend should only create connection tokens for clients that it trusts.

    curl https://api.stripe.com/v1/terminal/connection_tokens \
      -u sk_test_4eC39HqLyjWDarjtT1zdp7dc: \
      -X POST
    
    
    # Set your secret key: remember to change this to your live secret key in production
    # See your keys here: https://dashboard.stripe.com/account/apikeys
    Stripe.api_key = 'sk_test_4eC39HqLyjWDarjtT1zdp7dc'
    
    # Using Sinatra
    post 'terminal_connection_token' do
      token = Stripe::Terminal::ConnectionToken.create
      token.to_json
    end
    
    # Set your secret key: remember to change this to your live secret key in production
    # See your keys here: https://dashboard.stripe.com/account/apikeys
    stripe.api_key = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"
    
    # Flask
    from flask import Flask, jsonify, request
    @app.route('terminal_connection_token', methods=['POST'])
    def terminal_connection_token():
        token = stripe.terminal.ConnectionToken.create()
        return jsonify(token)
    
    // Set your secret key: remember to change this to your live secret key in production
    // See your keys here: https://dashboard.stripe.com/account/apikeys
    var stripe = require("stripe")("sk_test_4eC39HqLyjWDarjtT1zdp7dc");
    
    // Using Express
    app.post('terminal_connection_token', async (req, res) => {
      try{
        const token = await stripe.terminal.connectionTokens.create();
        res.status(200).json(token);
      }catch(err){
        res.status(500).end();
      };
    });
    
    // Set your secret key: remember to change this to your live secret key in production
    // See your keys here: https://dashboard.stripe.com/account/apikeys
    Stripe.apiKey = "sk_test_4eC39HqLyjWDarjtT1zdp7dc";
    
    // Using Spark framework (http://sparkjava.com)
    post(new Route("terminal_connection_token") {
        @Override
        public Object handle(final Request request,
                             final Response response) {
            try {
                Map<String, Object> params = new HashMap<String, Object>();
                ConnectionToken token = ConnectionToken.create(params);
                return token.getRawJson();
            } catch (StripeException e) {
                response.status(500);
                return e;
            }
        }
    });
    
    // Set your secret key: remember to change this to your live secret key in production
    // See your keys here: https://dashboard.stripe.com/account/apikeys
    stripe.Key = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"
    
    // net/http
    func terminalConnectionTokenHandler(w http.ResponseWriter, r *http.Request, customerId string) {
        token, err := New(&stripe.TerminalConnectionTokenParams{})
        if err != nil {
            log.Printf("Stripe bindings call failed, %v\n", err)
            w.WriteHeader(500)
            return
        }
        w.Write(token.RawJSON)
    }
    

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

    import StripeTerminal
    import Alamofire
    
    class APIClient: ConnectionTokenProvider {
    
        // Your backend should call v1/terminal/connection_tokens and return the JSON response from Stripe
        func fetchConnectionToken(_ completion: @escaping ConnectionTokenCompletionBlock) {
            let url = yourBackendUrl.appendingPathComponent("connection_token")
            let params = [:] // whatever parameters necessary for your backend to authenticate the client
            Alamofire.request(url, method: .get, parameters: params)
                .responseJSON { responseJSON in
                    switch responseJSON.result {
                    case .success(let json):
                        let json = value as! [String: AnyObject]
                        completion(json["secret"], nil)
                    case .failure(let error):
                        completion(nil, error)
                    }
            }
        }
    }

    This function is called whenever the SDK is initialized. It’s also called when a new 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 token from your backend, connecting to a reader fails with the error from your server.

    Step 4: Initialize the SDK

    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.

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        // Your app's API client can implement ConnectionTokenProvider.
        Terminal.setTokenProvider(apiClient)
        // ...
        return true
    }
    

    SDK updates

    Stripe periodically releases updates to the Stripe Terminal iOS SDK and Stripe Terminal Android SDK, which can include new functionality, bug fixes, and security updates. Update your integrated version of the Stripe Terminal iOS and Android SDKs as soon as new versions are available. The Stripe Terminal JavaScript SDK is updated automatically.

    Next steps

    Congratulations! You integrated the Stripe Terminal SDK into your app. Next, either continue your software integration by using the simulated reader, or learn about physical readers and connecting to one.

    Questions?

    We're always happy to help with code or other questions you might have! Search our documentation, contact support, or connect with our sales team. You can also chat live with other developers in #stripe on freenode.

    Was this page helpful? Yes No

    Send

    Thank you for helping improve Stripe's documentation. If you need help or have any questions, please consider contacting support.

    On this page