discoverReaders
to search for readers, with the simulated option set to true.
### Discover readers
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. To use the simulated reader, call `discoverReaders` to search for readers, with the simulated option set to true. To discover intended readers more easily, filter by location.
### Connect to the simulated reader
When `discoverReaders` returns a result, call `connectInternetReader` to connect to the simulated reader.
### Connect to the simulated reader
When `discoverReaders` returns a result, call `connectBluetoothReader` to connect to the simulated reader.
### Create a PaymentIntent
Create a [PaymentIntent](https://docs.stripe.com/api/payment_intents.md) object using the SDK. A PaymentIntent tracks the customer’s payment lifecycle, keeping track of any failed payment attempts and ensuring the customer is only charged once.
### Collect payment method details
Call `collectPaymentMethod` with the PaymentIntent’s client secret to collect a payment method. When connected to the simulated reader calling this method immediately updates the PaymentIntent object with a [simulated test card](https://docs.stripe.com/terminal/references/testing.md#simulated-test-cards). When connected to a physical reader the connected reader waits for a card to be presented.
### Confirm the payment
After successfully collecting payment method data, call `confirmPaymentIntent` with the updated PaymentIntent to confirm the payment. A successful call results in a PaymentIntent with a status of `requires_capture` for manual capture or `succeeded` for automatic capture.
### Create an endpoint to capture the PaymentIntent
Create an endpoint on your back end that accepts a PaymentIntent ID and sends a request to the Stripe API to capture it.
### Capture the PaymentIntent
If you defined `capture_method` as `manual` during PaymentIntent creation, the SDK returns an authorized but not captured PaymentIntent to your application. When the PaymentIntent status is `requires_capture`, notify your back end to capture the PaymentIntent.
For connected accounts, before manually capturing a payment, inspect the PaymentIntent’s ‘application_fee_amount’ and modify it if needed.
### Run the application
Run your server and go to [localhost:4242](http://localhost:4242).
### Make a test payment
Use [amounts](https://docs.stripe.com/terminal/references/testing.md#physical-test-cards) ending in the following special values to test your integration.
| Scenario | Card Number |
| ------------------------------- | ---------------- |
| Payment succeeds | 4242424242424242 |
| Payment requires authentication | 4000002500003155 |
| Payment is declined | 4000000000009995 |
### Install the Stripe Node library
Install the package and import it in your code. Alternatively, if you’re starting from scratch and need a package.json file, download the project files using the Download link in the code editor.
Install the library:
Or download the stripe-node library source code directly
[from GitHub](https://github.com/stripe/stripe-node).
### Install the Stripe Ruby library
Install the Stripe ruby gem and require it in your code. Alternatively, if you’re starting from scratch and need a Gemfile, download the project files using the link in the code editor.
Install the gem:
Add this line to your Gemfile:
Or download the stripe-ruby gem source code directly
[from GitHub](https://github.com/stripe/stripe-ruby).
### Install the Stripe Java library
Add the dependency to your build and import the library. Alternatively, if you’re starting from scratch and need a sample pom.xml file (for Maven), download the project files using the link in the code editor.
Add the following dependency to your POM and replace {VERSION} with the version number you want to use.
Add the dependency to your build.gradle file and replace {VERSION} with the version number you want to use.
Download the JAR directly
[from GitHub](https://github.com/stripe/stripe-java/releases/latest).
### Install the Stripe Python package
Install the Stripe package and import it in your code. Alternatively, if you’re starting from scratch and need a requirements.txt file, download the project files using the link in the code editor.
Install the package through pip:
Download the stripe-python library source code directly
[from GitHub](https://github.com/stripe/stripe-python/releases).
### Install the Stripe PHP library
Install the library with composer and initialize with your secret API key. Alternatively, if you’re starting from scratch and need a composer.json file, download the files using the link in the code editor.
Install the library:
Or download the stripe-php library source code directly
[from GitHub](https://github.com/stripe/stripe-php).
### Set up your server
Add the dependency to your build and import the library. Alternatively, if you’re starting from scratch and need a go.mod file, download the project files using the link in the code editor.
Make sure to initialize with Go Modules:
Or download the stripe-go module source code directly
[from GitHub](https://github.com/stripe/stripe-go).
### Install the Stripe.net library
Install the package with .NET or NuGet. Alternatively, if you’re starting from scratch, download the files which contains a configured .csproj file.
Install the library:
Install the library:
Or download the Stripe.net library source code directly
[from GitHub](https://github.com/stripe/stripe-dotnet).
### Install the Stripe libraries
Install the packages and import them in your code. Alternatively, if you’re starting from scratch and need a `package.json` file, download the project files using the link in the code editor.
Install the libraries:
The Stripe Terminal SDK requires local network access. When using macOS, you must explicitly allow your browser apps access to local network devices. For more information, see the [Stripe Support article](https://support.stripe.com/questions/ensuring-stripe-terminal-javascript-sdk-functionality-on-macos-15).
### Create a ConnectionToken endpoint
To connect to a reader, your back end needs to give the SDK permission to use it with your Stripe account by providing it with the secret from a [ConnectionToken](https://docs.stripe.com/api/terminal/connection_tokens.md). Create connection tokens only for trusted clients, and [pass a location ID](https://docs.stripe.com/terminal/fleet/locations-and-zones.md#connection-tokens) when creating a connection token to control access to readers. If you’re using Connect, [scope the connection token](https://docs.stripe.com/terminal/features/connect.md) to the relevant connected accounts.
### Install the SDK
### Create locations for your readers
[Create locations](https://docs.stripe.com/terminal/fleet/locations-and-zones.md) to organize your readers. Locations group readers and allow them to automatically download the reader configuration needed for their region of use. You must assign a location to each reader when you [register it](https://docs.stripe.com/terminal/fleet/register-readers.md), which you can do using the API or the Dashboard.
### Fetch ConnectionToken
To give the SDK access to this endpoint, create a function in your web application that requests a ConnectionToken from your back end and returns the secret from the ConnectionToken object.
### Configure permissions
Add a check to make sure that the `ACCESS_FINE_LOCATION` permission is enabled in your app.
To prepare your app to work with the Stripe Terminal SDK, make a few changes to your Info.plist file in Xcode.
Enable location services with the following key-value pair.
Make sure that your app runs in the background and remains connected to Bluetooth readers.
Pass app validation checks when submitting to the App Store.
Allow your app to display a Bluetooth permission dialog.
### Set up the context provider
Pass the `onFetchConnectionToken` function to `StripeTerminalProvider` as a prop.
### Initialize the SDK
To initialize a `StripeTerminal` instance in your React Native application, call the initialize method from `useStripeTerminal` hook. You must call the `initialize` method from a component nested within `StripeTerminalProvider` and not from the component that contains the `StripeTerminalProvider`.
### Discover readers
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. To use the simulated reader, call `discoverReaders` to search for readers, with the simulated option set to true.
### Discover readers
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. To use the simulated reader, call `discoverReaders` to search for readers, with the simulated option set to true. To discover intended readers more easily, filter by location.
### Connect to the simulated reader
When `discoverReaders` returns a result, call `connectReader` to connect to the simulated reader.
### Connect to the simulated reader
When `discoverReaders` returns a result, call `connectBluetoothReader` to connect to the simulated reader.
### Create a PaymentIntent
Add an endpoint on your server that creates a PaymentIntent. A PaymentIntent tracks the customer’s payment lifecycle, keeping track of any failed payment attempts and ensuring they’re only charged once. Return the PaymentIntent’s client secret in the response. If you’re using Connect, you can also specify [connected account information](https://docs.stripe.com/terminal/features/connect.md) based on your platform’s charge logic.
### Fetch the PaymentIntent
Make a request to your server for a PaymentIntent to initiate the payment process.
### Collect payment method details
Call `collectPaymentMethod` with the PaymentIntent’s client secret to collect a payment method. When connected to the simulated reader calling this method immediately updates the PaymentIntent object with a [simulated test card](https://docs.stripe.com/terminal/references/testing.md#simulated-test-cards). When connected to a physical reader the connected reader waits for a card to be presented.
### Process the payment
After successfully collecting payment method data, call `processPayment` with the updated PaymentIntent to process the payment. A successful call results in a PaymentIntent with a status of `requires_capture` for manual capture or `succeeded` for automatic capture.
### Create an endpoint to capture the PaymentIntent
Create an endpoint on your back end that accepts a PaymentIntent ID and sends a request to the Stripe API to capture it.
### Capture the PaymentIntent
If you defined `capture_method` as `manual` during PaymentIntent creation, the SDK returns an authorized but not captured PaymentIntent to your application. When the PaymentIntent status is `requires_capture`, notify your back end to capture the PaymentIntent.
For connected accounts, before manually capturing a payment, inspect the PaymentIntent’s ‘application_fee_amount’ and modify it if needed.
### Run the application
Run your server and go to [localhost:4242](http://localhost:4242).
### Use a test card number to try your integration
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. To enable this behavior, insert this line of code before you call `collectPaymentMethod.`
| Scenario | Card Number |
| ------------------------------- | ---------------- |
| Payment succeeds | 4242424242424242 |
| Payment requires authentication | 4000002500003155 |
| Payment is declined | 4000000000009995 |
```javascript
const express = require("express");
const app = express();
const { resolve } = require("path");
const stripe = require("stripe")("<