# Deployment checklist Use this checklist to help ensure a smooth deployment of Stripe Terminal. As you complete each item and check it off, the state of each checkbox is stored within your browser’s cache. You can refer back to this page at any time to see what you’ve completed so far. Stripe Terminal requires integrating hardware and software to bring Stripe to the physical world. As you develop your integration, refer to this checklist to make sure you cover all the critical steps. It’s fine to go out of order, but understanding the full scope of a Terminal integration helps you connect all the pieces. After following the integration guides for Stripe Terminal, check that your application is set up correctly. - [ ] Set up the Connection Token endpoint correctly (SDK only) To handle the Connection Token lifecycle, set up an endpoint on your backend server, which uses your Stripe secret API key to create a Connection Token for your client application. Follow [best practices](https://docs.stripe.com/keys-best-practices.md) and never expose, embed, or hardcode your secret key in your client application (this can prevent reconnecting to a reader). Authenticate this endpoint to control who can access your readers. For smart readers, pass a `location` when you create a Connection Token to restrict access to readers assigned to that [Location](https://docs.stripe.com/terminal/fleet/locations-and-zones.md). For mobile readers and Tap to Pay readers, you associate the reader with a location at [connection time](https://docs.stripe.com/terminal/payments/connect-reader.md?reader-type=bluetooth). > #### Don't provision Connection Tokens directly from your client application > > Provisioning tokens directly from your clienat application requires embedding your Stripe secret API key in client-side code, which exposes it to end users and creates a significant security risk. Always create Connection Tokens from your backend server. Learn about more [best practices for managing secret API keys](https://docs.stripe.com/keys-best-practices.md). - [ ] Verify your network meets Terminal requirements Before deploying smart readers, confirm your network meets [Terminal network requirements](https://docs.stripe.com/terminal/network-requirements.md). Key requirements include: - WiFi networks must be password protected, using WPA/WPA2/WPA3-Personal or WPA2/WPA3 EAP-PEAP Enterprise encryption - Your network must support IPv4 (IPv6-only networks aren’t supported, but dual-stack is supported) - Your firewall must allow outbound traffic to all [required Stripe endpoints](https://docs.stripe.com/ips.md). Blocked endpoints are a common cause of reader connectivity failures that can be difficult to diagnose. - For SDK integrations, the reader and your point of sale device must be on the same local network, and your DHCP configuration must allow readers to retain the same IP address for at least an entire workday. If the WiFi signal is weak or unreliable, consider using Ethernet with the [S700/S710 hub](https://docs.stripe.com/terminal/payments/stripe-reader-s700-s710/accessories.md#s700-s710-hub) or [WisePOS E dock](https://docs.stripe.com/terminal/payments/setup-reader/bbpos-wisepos-e.md#ethernet). After connecting a smart reader, run the built-in [diagnostics](https://docs.stripe.com/terminal/readers/stripe-reader-s700-s710.md#diagnostics) to verify DNS resolution, Stripe connectivity, and signal strength. - [ ] Test your integration end-to-end Use the [simulated reader](https://docs.stripe.com/terminal/references/testing.md) to test your full payment flow in test mode before deploying physical hardware. Test successful payments, declined cards, and interrupted connections. When you’re ready for live testing, use physical [test cards](https://docs.stripe.com/terminal/references/testing.md#physical-test-cards) with a real reader. Order test cards and devices early to avoid delays. - [ ] Capture PaymentIntents If you defined the PaymentIntent [capture_method](https://docs.stripe.com/api/payment_intents/object.md#payment_intent_object-capture_method) as `manual`, the payment is authorized but not captured when the SDK returns a processed PaymentIntent to your application. To complete collection of funds, you must [capture the PaymentIntent](https://docs.stripe.com/terminal/payments/collect-card-payment.md#capture-payment). When your application receives a processed PaymentIntent from the SDK, make sure it notifies your backend to capture the PaymentIntent. - [ ] Handle payment errors and declines Your application must [handle errors](https://docs.stripe.com/terminal/payments/collect-card-payment.md?terminal-sdk-platform=server-driven#handle-errors) like declined payments, network timeouts, and reader disconnections during a transaction. Make sure you: - Display clear error messages to the operator when a payment fails. - Allow retrying a payment without requiring the customer to re-present their card (when possible). - Handle the case where a capture request fails after a successful authorization, to avoid un-captured funds. - If a network interruption occurs mid-payment, use the same PaymentIntent ID to [retrieve its status](https://docs.stripe.com/api/payment_intents/retrieve.md) and determine whether to retry or resume. Reusing the same PaymentIntent avoids double charging the customer. - [ ] Make sure you can provide receipts to customers Provide your customer with the option to receive a paper or email [receipt](https://docs.stripe.com/terminal/features/receipts.md). You can use Stripe’s prebuilt receipts, or use receipt data from the Stripe API to build custom receipts that are on-brand for your business. Test that you receive a receipt when you create a live mode payment using your application. If you provide your customers with [custom receipts](https://docs.stripe.com/terminal/features/receipts.md#custom), save a copy of each receipt as dispute evidence. If you use Stripe’s prebuilt receipts, a copy of the receipt is saved automatically and available in the Dashboard. - [ ] Set up a process to reconcile payments with your internal orders system [Reconcile payments](https://docs.stripe.com/terminal/payments/collect-card-payment.md#reconciling) with your internal orders system on your server at the end of a day’s activity to avoid unintended authorizations or un-captured funds: - A user abandoning your application’s checkout flow early can result in an un-captured PaymentIntent, which might appear to the cardholder as an unintended authorization. - Similarly, the request from your application notifying your backend to capture the PaymentIntent might fail, resulting in incomplete collection of funds. - [ ] Set up webhooks for Terminal events Configure [webhooks](https://docs.stripe.com/webhooks.md) to listen for Terminal-related events and keep your system in sync with Stripe. For all integrations, important events include: - `payment_intent.succeeded` and `payment_intent.payment_failed` for payment outcomes - `charge.refunded` for refund notifications For [server-driven integrations](https://docs.stripe.com/terminal/payments/setup-integration.md?terminal-sdk-platform=server-driven), webhooks are required to receive action results asynchronously: - `terminal.reader.action_succeeded` and `terminal.reader.action_failed` for reader action outcomes - [ ] Support reader software updates Stripe and our hardware partners periodically release reader software updates that can include new features, bug fixes, and required security patches. - **Smart readers** ([Stripe Reader S700/S710](https://docs.stripe.com/terminal/payments/setup-reader/stripe-reader-s700-s710.md), [BBPOS WisePOS E](https://docs.stripe.com/terminal/payments/setup-reader/bbpos-wisepos-e.md)) update automatically when connected to the internet. No action is required from your application, but updates can cause readers to restart. Avoid scheduling updates during business hours by configuring [update windows](https://docs.stripe.com/terminal/fleet/reboot-time.md). - **Mobile readers (SDK only)** ([Stripe Reader M2](https://docs.stripe.com/terminal/payments/setup-reader/stripe-m2.md), [BBPOS WisePad 3](https://docs.stripe.com/terminal/payments/setup-reader/bbpos-wisepad3.md)) update when they connect to your application through the Terminal SDK. Your app must support displaying update progress and must not interrupt the update process. Block navigation during updates and display a progress indicator. The Terminal SDK notifies your application of [optional updates](https://docs.stripe.com/terminal/payments/connect-reader.md?terminal-sdk-platform=ios&reader-type=bluetooth#optional-updates) that eventually become [required updates](https://docs.stripe.com/terminal/payments/connect-reader.md?terminal-sdk-platform=ios&reader-type=bluetooth#required-updates). Install optional updates as soon as possible when they become available. Failing to install a required update can prevent a reader from accepting payments. - [ ] Support registering readers in the field For smart readers like the [Stripe Reader S700/S710](https://docs.stripe.com/terminal/readers/stripe-reader-s700-s710.md) and [BBPOS WisePOS E](https://docs.stripe.com/terminal/readers/bbpos-wisepos-e.md), you must [register the reader](https://docs.stripe.com/terminal/fleet/register-readers.md) to your account before you can connect your application to the reader. How you handle reader registration depends on your use case: - **Deployment size**: For smaller deployments, [register each reader](https://docs.stripe.com/terminal/fleet/register-readers.md) in the Stripe Dashboard. For larger deployments that require shipping readers to various locations, make sure site managers can add new readers to your company’s Stripe account. Build a workflow into your application to let others register readers to your Stripe account. The endpoint for [registering a reader](https://docs.stripe.com/api/terminal/readers/create.md) must be called server-side. If you support registering readers from your client application, the app must communicate with your backend to register the reader. - **Using Connect**: If you use Connect [direct charges](https://docs.stripe.com/connect/direct-charges.md), use the `Stripe-Account` header to register the reader to the connected account. With [destination charges](https://docs.stripe.com/connect/destination-charges.md), register new readers [to the platform account](https://docs.stripe.com/terminal/features/connect.md). - [ ] Use Locations to group your readers Create a Terminal [Location](https://docs.stripe.com/api/terminal/locations/create.md) object for each physical operating site at which your business accepts in-person payments. You must register each reader to a location to ensure that it downloads the proper regional configuration. For smart readers, support specifying a location while [registering the reader](https://docs.stripe.com/terminal/fleet/register-readers.md#smart-readers). For Bluetooth readers, support specifying a location while [connecting to the reader](https://docs.stripe.com/terminal/fleet/register-readers.md#bluetooth-readers). - [ ] Support discovering multiple readers and provide helpful UI (SDK only) Make sure your application can display an updating list of discovered readers, with the label and/or serial number of each. Refer to our [example applications](https://docs.stripe.com/terminal/example-applications.md) for a sample UI. - **Local network**: If your smart reader and point of sale device are on the same LAN, include instructions in your application for verifying both devices are on the correct network. - **Bluetooth** ([Stripe Reader M2](https://docs.stripe.com/terminal/payments/setup-reader/stripe-m2.md), [BBPOS WisePad 3](https://docs.stripe.com/terminal/payments/setup-reader/bbpos-wisepad3.md)): Mobile readers use [Bluetooth scan](https://docs.stripe.com/terminal/payments/connect-reader.md?reader-type=bluetooth#discover-readers) to discover nearby readers. This is supported on iOS, Android, and React Native SDKs. Display an auto-updating list of discovered readers with serial numbers, and allow users to cancel the discovery process. If Bluetooth is unstable due to interference in your operating environment, consider [USB connectivity](https://docs.stripe.com/terminal/payments/connect-reader.md?reader-type=usb) as a more reliable alternative (generally available on Android SDK; contact us for access on iOS SDK). - [ ] Use the latest SDK release and establish a process to stay current (SDK only) Stripe periodically releases updates which can include new functionality, bug fixes, and security updates. Update your SDK as soon as a new version is available. The currently available SDKs are: - [Stripe Terminal Android SDK](https://github.com/stripe/stripe-terminal-android/releases) - [Stripe Terminal iOS SDK](https://github.com/stripe/stripe-terminal-ios/releases) - [Stripe Terminal JavaScript SDK](https://docs.stripe.com/terminal/references/api/js-sdk.md#changelog) - [Stripe Terminal React Native SDK](https://github.com/stripe/stripe-terminal-react-native) - [ ] Set a custom admin menu passcode The default admin menu passcode for your smart readers is `07139`. For security, you should set your own [custom 5 digit passcode](https://docs.stripe.com/terminal/fleet/admin-menu-passcode.md). - [ ] Plan for connectivity interruptions Determine how your application handles situations where the reader or your point of sale device loses internet connectivity: - If reliable connectivity isn’t guaranteed at your deployment locations, consider enabling [offline mode](https://docs.stripe.com/terminal/features/operate-offline/overview.md). Offline mode is supported on both smart readers (Stripe Reader S700/S710, BBPOS WisePOS E) and mobile readers (Stripe Reader M2, BBPOS WisePad 3) using SDK integrations. Understand the risks and limitations of offline payments before enabling. - If you don’t use offline mode, make sure your application displays a clear message when connectivity is lost and prevents payment attempts until the connection is restored. - For SDK integrations, handle [reader disconnection events](https://docs.stripe.com/terminal/payments/connect-reader.md?reader-type=bluetooth#handle-disconnects) and provide a reconnection flow. For mobile readers and Tap to Pay readers, the SDK supports automatic reconnection by default. Make sure your app displays appropriate status messages during reconnection attempts. The BBPOS and Chipper™ name and logo are trademarks or registered trademarks of BBPOS Limited in the United States 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 doesn’t imply any endorsement by BBPOS or Verifone.