Terminal
JavaScript

Getting started with the JavaScript SDK

Set up the Stripe Terminal JavaScript SDK so you can begin accepting in-person payments with a Verifone P400 reader and your website.

Getting started with the JavaScript SDK requires four steps:

  1. Install the SDK and client library on your checkout page
  2. Set up the connection token endpoint on your backend and web application
  3. Initialize the SDK in your web application
  4. Connect to the simulated reader

Step 1: Install the SDK and client library Client-side Server-side

Client-side

To get started, include this script on your checkout page. This script must always load directly from https://js.stripe.com for compatibility with the latest reader software. Do not include the script in a bundle or host a copy yourself; this could break your integration without warning.

<script src="https://js.stripe.com/terminal/v1/"></script>

Using the Terminal JS SDK as a module

We also provide an npm package that makes it easier to load and use the Terminal JS SDK as a module. For more information, check out the project on GitHub.

Server-side

Use our official libraries for access to the Stripe API from your application:

# Available as a gem gem install stripe
# If you use bundler, you can add this line to your Gemfile gem 'stripe'
# Install through pip pip install --upgrade stripe
# Or find the Stripe package on http://pypi.python.org/pypi/stripe/
# Find the version you want to pin: # https://github.com/stripe/stripe-python/blob/master/CHANGELOG.md # Specify that version in your requirements.txt file stripe>=2.48.0,<3.0
# Install the PHP library via Composer composer require stripe/stripe-php
# Or download the source directly: https://github.com/stripe/stripe-php/releases
/* For Gradle, add the following dependency to your build.gradle and replace {VERSION} with the version number you want to use from - https://mvnrepository.com/artifact/com.stripe/stripe-java or - https://github.com/stripe/stripe-java/releases/latest */ implementation "com.stripe:stripe-java:{VERSION}"
<!-- For Maven, add the following dependency to your POM and replace {VERSION} with the version number you want to use from - https://mvnrepository.com/artifact/com.stripe/stripe-java or - https://github.com/stripe/stripe-java/releases/latest --> <dependency> <groupId>com.stripe</groupId> <artifactId>stripe-java</artifactId> <version>{VERSION}</version> </dependency>
# For other environments, manually install the following JARs: # - The Stripe JAR from https://github.com/stripe/stripe-java/releases/latest # - Google Gson from https://github.com/google/gson
# Install via npm npm install --save stripe
# Make sure your project is using Go Modules go mod init # Install stripe-go go get -u github.com/stripe/stripe-go/v71
// Then import the package import ( "github.com/stripe/stripe-go/v71" )
# Install via dotnet dotnet add package Stripe.net dotnet restore
# Or install via NuGet PM> Install-Package Stripe.net

Step 2: 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.

curl https://api.stripe.com/v1/terminal/connection_tokens \ -u sk_test_4eC39HqLyjWDarjtT1zdp7dc: \ -X POST
# Set your secret key. Remember to switch to your live secret key in production! # See your keys here: https://dashboard.stripe.com/account/apikeys Stripe.api_key = 'sk_test_4eC39HqLyjWDarjtT1zdp7dc' # In a new endpoint on your server, create a ConnectionToken and return the # `secret` to your app. The SDK needs the `secret` to connect to a reader. connection_token = Stripe::Terminal::ConnectionToken.create
# Set your secret key. Remember to switch to your live secret key in production! # See your keys here: https://dashboard.stripe.com/account/apikeys stripe.api_key = 'sk_test_4eC39HqLyjWDarjtT1zdp7dc' # In a new endpoint on your server, create a ConnectionToken and return the # `secret` to your app. The SDK needs the `secret` to connect to a reader. connection_token = stripe.terminal.ConnectionToken.create()
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys \Stripe\Stripe::setApiKey('sk_test_4eC39HqLyjWDarjtT1zdp7dc'); // In a new endpoint on your server, create a ConnectionToken and return the // `secret` to your app. The SDK needs the `secret` to connect to a reader. $connectionToken = \Stripe\Terminal\ConnectionToken::create();
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys Stripe.apiKey = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"; // In a new endpoint on your server, create a ConnectionToken and return the // `secret` to your app. The SDK needs the `secret` to connect to a reader. ConnectionTokenCreateParams params = ConnectionTokenCreateParams.builder() .build(); ConnectionToken connectionToken = ConnectionToken.create(params);
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys const stripe = require('stripe')('sk_test_4eC39HqLyjWDarjtT1zdp7dc'); // In a new endpoint on your server, create a ConnectionToken and return the // `secret` to your app. The SDK needs the `secret` to connect to a reader. let connectionToken = stripe.terminal.connectionTokens.create();
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys stripe.Key = "sk_test_4eC39HqLyjWDarjtT1zdp7dc" // In a new endpoint on your server, create a ConnectionToken and return the // `secret` to your app. The SDK needs the `secret` to connect to a reader. params := &stripe.TerminalConnectionTokenParams{} ct, _ := connectiontoken.New(params)
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys StripeConfiguration.ApiKey = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"; // In a new endpoint on your server, create a ConnectionToken and return the // `secret` to your app. The SDK needs the `secret` to connect to a reader. var options = new ConnectionTokenCreateOptions{}; var service = new ConnectionTokenService(); var connectionToken = service.Create(options);

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
from flask import jsonify @app.route('/connection_token', methods=['POST']) def secret(): token = # ... Create or retrieve the ConnectionToken return jsonify(secret=token.secret)
<?php $token = # ... Create or retrieve the ConnectionToken echo json_encode(array('secret' => $token->secret)); ?>
import java.util.HashMap; import java.util.Map; import com.stripe.model.ConnectionToken; import com.google.gson.Gson; import static spark.Spark.post; public class StripeJavaQuickStart { public static void main(String[] args) { Gson gson = new Gson(); post("/connection_token", (request, response) -> { ConnectionToken token = // ... Fetch or create the ConnectionToken Map<String, String> map = new HashMap(); map.put("secret", token.getSecret()); return map; }, gson::toJson); } }
const express = require('express'); const app = express(); app.post('/connection_token', async (req, res) => { const token = // ... Fetch or create the ConnectionToken res.json({secret: token.secret}); }); app.listen(3000, () => { console.log('Running on port 3000'); });
package main import ( "encoding/json" "net/http" ) type TokenData struct { Secret string `json:"secret"` } func main() { http.HandleFunc("/connection_token", func(w http.ResponseWriter, r *http.Request) { token := // ... Fetch or create the ConnectionToken data := TokenData{ Secret: token.secret, } w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) json.NewEncoder(w).Encode(data) }) http.ListenAndServe(":3000", nil) }
using System; using Microsoft.AspNetCore.Mvc; namespace StripeExampleApi.Controllers { [Route("connection_token")] [ApiController] public class StripeApiController : Controller { [HttpPost] public ActionResult Post() { var token = // ... Fetch or create the ConnectionToken return Json(new {secret = token.Secret}); } } }

Client-side

To give the SDK access to this endpoint, create a function in your web application that requests a ConnectionToken from your backend and returns the secret from the ConnectionToken object.

function fetchConnectionToken() { // Your backend should call /v1/terminal/connection_tokens and return the JSON response from Stripe return fetch('https://{YOUR_BACKEND_URL}/connection_token', { method: "POST" }) .then(function(response) { return response.json(); }) .then(function(data) { return data.secret; }); }
async function fetchConnectionToken() { // Your backend should call /v1/terminal/connection_tokens and return the JSON response from Stripe const response = await fetch('https://{YOUR_BACKEND_URL}/connection_token', { method: "POST" }); const data = await response.json(); return data.secret; }

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.

Step 3: Initialize the SDK Client-side

The StripeTerminal object made available by the SDK exposes a generic interface for discovering readers, connecting to a reader, and creating payments. To initialize a StripeTerminal instance in your JavaScript application, provide the ConnectionToken function implemented in Step 2.

You must also provide a function to handle unexpected disconnects from the reader, onUnexpectedReaderDisconnect. In this function, your app should notify the user that the reader disconnected. You can also include a way to attempt to reconnect to a reader. For more information, see Handling disconnects.

var terminal = StripeTerminal.create({ onFetchConnectionToken: fetchConnectionToken, onUnexpectedReaderDisconnect: unexpectedDisconnect, }); function unexpectedDisconnect() { // You might want to display UI to notify the user and start re-discovering readers }
const terminal = StripeTerminal.create({ onFetchConnectionToken: fetchConnectionToken, onUnexpectedReaderDisconnect: unexpectedDisconnect, }); function unexpectedDisconnect() { // You might want to display UI to notify the user and start re-discovering readers }

Step 4: 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.

// Handler for a "Connect Reader" button function connectReaderHandler() { var config = {simulated: true}; terminal.discoverReaders(config).then(function(discoverResult) { if (discoverResult.error) { console.log('Failed to discover: ', discoverResult.error); } else if (discoverResult.discoveredReaders.length === 0) { console.log('No available readers.'); } else { // Just select the first reader here. var selectedReader = discoverResult.discoveredReaders[0]; terminal.connectReader(selectedReader).then(function(connectResult) { if (connectResult.error) { console.log('Failed to connect: ', connectResult.error); } else { console.log('Connected to reader: ', connectResult.reader.label); } }); } }); }
// Handler for a "Connect Reader" button async function connectReaderHandler() { const config = {simulated: true}; const discoverResult = await terminal.discoverReaders(config); if (discoverResult.error) { console.log('Failed to discover: ', discoverResult.error); } else if (discoverResult.discoveredReaders.length === 0) { console.log('No available readers.'); } else { // Just select the first reader here. const selectedReader = discoverResult.discoveredReaders[0]; const connectResult = await terminal.connectReader(selectedReader); if (connectResult.error) { console.log('Failed to connect: ', connectResult.error); } else { console.log('Connected to reader: ', connectResult.reader.label); } } }

Simulated reader configuration

The simulated reader supports a small amount of configuration, enabling you to test different flows within your point of sale application such as different card brands or error scenarios like a declined charge.

Currently, the simulated reader configuration API is only available in our JavaScript SDK. The simulator configuration accepts either a testCardNumber or a testPaymentMethod options. To enable this behavior, insert this line of code before you call collectPaymentMethod:

terminal.setSimulatorConfiguration({testCardNumber: '4242424242424242'});

For more details about the configuration options API, see the Stripe Terminal JavaScript API reference.

Supported browsers

The Stripe Terminal JavaScript SDK strives to support all recent versions of major browsers. We support:

  • Internet Explorer 11 and Edge on Windows.
  • Firefox on desktop platforms.
  • Chrome and Safari on all platforms.
  • The Android native browser on Android 4.4 and later.

If you have issues with the Stripe Terminal JavaScript SDK on a specific browser, please email support-terminal@stripe.com.

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