Skip to content
Create account
or
Sign in
The Stripe Docs logo
/
Ask AI
Create account
Sign in
Get started
Payments
Revenue
Platforms and marketplaces
Money management
Developer tools
Overview
About Stripe payments
Upgrade your integration
Payments analytics
Online payments
OverviewFind your use caseManaged Payments
Use Payment Links
Build a checkout page
Build an advanced integration
Build an in-app integration
Payment methods
Add payment methods
Manage payment methods
Faster checkout with Link
Payment interfaces
Payment Links
Checkout
Web Elements
In-app Elements
Payment scenarios
Custom payment flows
Flexible acquiring
Orchestration
In-person payments
Terminal
    Overview
    Accept in-person payments
    Integration design
    Select your reader
    Design an integration
    Quickstart
    Example applications
    Testing
    Terminal setup
    Set up your integration
    Connect to a reader
    Accepting a payment
    Collect card payments
    Additional payment methods
    Accept offline payments
      Collect card payments
    Mail order and telephone order payments
    Regional considerations
    During checkout
    Collect tips
    Collect and save payment details for future use
    Flexible authorizations
    After checkout
    Refund transactions
    Provide receipts
    Customize checkout
    Cart display
    Collect on-screen inputs
    Collect swiped data
    Collect tapped data for NFC instruments
    Apps on devices
    Manage readers
    Order, return, replace readers
    Register readers
    Manage locations and zones
    Configure readers
    Monitor Readers
    Encryption
    References
    API references
    Mobile readers
    Smart readers
    SDK migration guide
    Deployment checklist
    Stripe Terminal reader product sheets
Other Stripe products
Financial Connections
Crypto
Climate
HomePaymentsTerminalAccept offline payments

Collect card payments while offline

Collect card payments when you have internet connectivity issues.

Copy page

The Terminal SDK allows your application to continue collecting payments using a smart reader without an Internet connection.

If you’re using a separate POS device with a Stripe smart reader, you still need a functioning local network to allow your POS device to communicate with the smart reader. Operating offline with smart readers is for scenarios where your POS and reader can’t communicate with Stripe, such as during an ISP outage. If you need to operate offline without a local network, consider Stripe Terminal’s mobile readers.

You can also operate offline with an Apps on Devices integration. Since your POS application runs directly on the smart reader, you don’t need a local network to collect payments. However, you still need to be on a local network when your reader first boots up, even if the network doesn’t have access to the Internet.

Common mistake

When operating offline, payment information is collected at the time of sale, and authorization is only attempted after connectivity is restored and the payment is forwarded. When operating offline with an Internet reader, the reader stores collected payment information. You, as the user, assume all decline and tamper-related risks associated with an offline transaction. If your tampered reader can’t forward payments to Stripe, or the issuer declines the transaction, there’s no way to recover the funds, and you might not receive payment from the customer for goods or services already provided.

To reduce the chances of an issuer decline, you’re encouraged to:

  • Reestablish internet connectivity as soon as possible to record the payments to Stripe.
  • Restrict transactions if they exceed a certain amount.
  • Fail all offline payments if the SDK has stored a set of transactions whose sum exceeds a certain amount.

Collect payments while offline

Offline payments follow the same steps as online payments: create, collect, process, and capture the payment. Your device can transition from online to offline at any step in the process.

  1. Enable offline mode
  2. Connect to a reader while offline
  3. Handle offline events
  4. Create a PaymentIntent while offline
  5. Collect a payment method
  6. Confirm the payment
  7. Wait for payments to forward
  8. (Optional) Capture the payment
  9. (Optional) Examine payments collected offline

Enable offline mode

Use a Configuration object or the Dashboard to enable offline mode for the supported devices at your Location.

Command Line
cURL
curl https://api.stripe.com/v1/terminal/configurations \ -u "
sk_test_BQokikJOvBiI2HlWgH4olfQ2
:"
\ -d "offline[enabled]"=true

After you enable offline mode on a Configuration object, you can assign it to a Location. You can also enable offline mode by default for all Locations by updating the default Configuration object for your account. Configuration API changes can take several minutes to propagate to your SDK and reader, and require you to disconnect from and reconnect to your reader to take effect.

Connect to a reader while offline

The reader stores necessary Location information locally after connecting online. On subsequent offline connections, it uses the stored configuration information from that Location.

To collect payments with a smart reader while offline, you must have previously connected to any mobile reader of the same type at the same Location while online within the last 30 days, on the same local network.

The reader stores the Location information locally after connecting online, and it derives configuration information from that Location while operating offline. Your reader and POS device must be on the same local network used to connect online. You can’t switch networks while offline.

If you attempt to connect to a reader while offline without meeting these requirements, the request fails with an error.

ErrorResolution
The SDK isn’t connected to the internetMake sure the Location you’re using is configured for offline mode. Otherwise, connect to any reader while online, and then connect to a reader of the same type while offline.
The selected reader requires a software update before it can be used to collect payments offline.The reader’s software hasn’t been updated in 30 days or more. Connect to the reader while online to update it.
The selected reader must be paired online at this location before it can be used to collect payments offline.You’re attempting to connect to a reader type that your POS hasn’t previously connected to while online. You must first connect to this reader or any reader of the same type while online. Or, if you want to connect while offline, you can connect to a reader type that your POS previously connected to while online.

Handle offline events
Client-side

SDK Reference

  • UserCallbacks (React Native)

To allow your application to receive updates about the SDK’s network status and the state of forwarded payments, implement the offline callbacks on the useStripeTerminal hook.

PaymentScreen.tsx
const { connectReader, disconnectReader, connectedReader } = useStripeTerminal({ onDidChangeOfflineStatus(status: OfflineStatus) { // Check the value of `offlineStatus` and update your UI accordingly. // // You can also check the SDK's current offline status calling // `getOfflineStatus`. }, onDidForwardingFailure(error) { // A non-specific error occurred while forwarding a PaymentIntent. // Check the error message and your integration implementation to // troubleshoot. }, onDidForwardPaymentIntent(paymentIntent, error) { // The PaymentIntent was successfully forwarded, or an error occurred. // Reconcile any local state using the backend-generated `paymentIntent.id` // and the metadata you supplied when creating the PaymentIntent. // // Note that the `paymentIntent.id` may still be null if creating the // PaymentIntent in the backend failed. }, });

Create a PaymentIntent while offline
Client-side

SDK Reference

  • createPaymentIntent (React Native)
  • CreatePaymentIntentParams (React Native)
  • OfflineStatus (React Native)
  • OfflineStatusDetails (React Native)

To support operating offline, use the SDK’s createPaymentIntent to create PaymentIntent objects. This allows the SDK to create PaymentIntents while offline and forward them to Stripe after you’ve re-established connectivity.

While operating offline, PaymentIntent objects have a null id. We recommend adding a custom identifier to the PaymentIntent’s metadata to help reconcile PaymentIntent objects created offline in your database.

You can set up a webhook endpoint to receive PaymentIntent events when offline payments are forwarded to Stripe, and use your identifier to associate them with a PaymentIntent ID.

PaymentScreen.tsx
const _createPaymentIntent = async (cart) => { const {error, paymentIntent} = await createPaymentIntent({ amount: cart.total, currency: cart.currency, metadata: { "unique-id": UUID().uuidString } }); }

The Terminal.createPaymentIntent accepts a CreateConfiguration parameter. By default, if you’re operating offline, the Terminal SDK stores all offline payments, then forwards them to Stripe’s backend when connectivity is restored.

To customize this behavior, you can pass in a CreateConfiguration object with an offlineBehavior attribute set to as REQUIRE_ONLINE, PREFER_ONLINE or FORCE_OFFLINE.

Managing risk

Setting offlineBehavior to REQUIRE_ONLINE fails the current transaction if you’re operating offline. For example, you might want to disallow transactions above a certain amount or disallow all offline transactions if the reader has stored a set of transactions whose sum exceeds a certain amount.

The SDK exposes two properties to help you manage risk:

  1. OfflineStatus.reader.offlinePaymentsCount
  2. OfflineStatus.reader.offlinePaymentAmountsByCurrency

Managing latency while offline

Based on your network connectivity, the Terminal SDK automatically determines whether to collect payments online or offline. However, you might want to operate offline despite having an active network connection (for example, if you need to collect transactions quickly and your network connection is slow). You can set offlineBehavior to force_offline to collect the payment offline regardless of connectivity.

Payments collected offline while the Terminal reader has an active network connection are forwarded in the background.

PaymentScreen.tsx
const _createPaymentIntent = async (cart) => { // Your app might want to prevent offline payments for too large an amount. // Here, we require a network connection if the payment if the amount is over 1000 usd. // Otherwise, we allow collecting offline if the network connection is unavailable. let offlineBehavior: if (cart.total > 1000000) { offlineBehavior = 'require_online' } else { offlineBehavior = 'prefer_online' } const {error, paymentIntent} = await createPaymentIntent({ amount: cart.total, currency: cart.currency, offlineBehavior, }); }

Collect a payment method
Client-side

SDK Reference

  • CollectPaymentMethodParams (React Native)

Note

Payment liability is your responsibility when operating your reader offline. Because magnetic stripe data is easy to spoof, Stripe disallows this option while operating offline. Tapping cards is also not supported in markets where Strong Customer Authentication is required.

Collecting payments while offline is similar to collecting payments while online. Your smart reader automatically displays the available payment options to the customer.

Note

Inspecting payment method details before authorization isn’t supported while offline. Although you can still set the updatePaymentIntent parameter in CollectConfiguration, the paymentMethod field on the PaymentIntent is absent if the SDK is operating offline.

PaymentScreen.tsx
const _collectPaymentMethod_ = async () => { const { paymentIntent, error } = await collectPaymentMethod({ paymentIntent: paymentIntent }); if (error) { // Handle errors in your application. } // ... Confirm the payment }

Confirm payment
Client-side

Confirming payments while offline is similar to confirming payments while online. The primary difference is that your integration must handle offline-specific error cases, such as when the transaction exceeds the Stripe-enforced offline maximum of 10,000 USD or equivalent in your operating currency.

In some cases, the SDK might create a PaymentIntent online, but confirm it while offline. When this happens, the PaymentIntent might have a non-null id. If it was confirmed offline, offlineDetails will be defined and populated.

PaymentScreen.tsx
const _confirmPaymentIntent = async () => { const { paymentIntent, error } = await confirmPaymentIntent({ paymentIntent: paymentIntent }); if (error) { // Handle offline-specific errors in your application (for example, // unsupported payment method). } if (paymentIntent.offlineDetails) { console.log('confirmed offline'); } else { console.log('confirmed online'); } }

Providing receipts

You might require information about the card used to complete a payment while offline. For example, you might need to generate a receipt for customers who require one at the time of purchase.

If the PaymentIntent is confirmed offline, retrieve its OfflineCardPresentDetails from the paymentIntent.offlineDetails.offlineCardPresentDetails property.

This hash contains a ReceiptDetails property you can use to generate a receipt, as well as other card details like the cardholder name and card brand.

The account_type and authorization_response_code receipt fields are unavailable on PaymentIntents processed offline. Prebuilt email receipts are only sent after connectivity is restored and the payment is successfully captured.

Wait for payments to forward
Client-side

When network connectivity is restored, the reader automatically begins forwarding the stored offline payments.

The reader attempts to forward payments even if its network status is offline. This means your connection token provider might receive a request to provide a connection token even when the device is offline.

If you disconnect or power off your smart reader too soon, your payments might not be forwarded. You can query OfflineStatus.reader.networkStatus to make sure your reader is online and can forward payments, and OfflineStatus.reader.offlinePaymentsCount to check how many payments the reader has to be forwarded.

If your smart reader becomes damaged or otherwise can’t take payments, your stored payments can often still be forwarded. Make sure to connect the smart reader to your POS and re-establish Internet access to allow it to re-connect to Stripe.

Capture payment

While offline, you can create PaymentIntents with captureMethod set to automatic.

After you confirm these PaymentIntents, they have a succeeded status instead of requiresCapture . Stripe automatically captures the payments after you forward them.

If you opt for manual capture, payments that are successfully forwarded and authorized require capture from your backend or application.

  • To capture payments from your backend, use webhooks to listen for PaymentIntents with a requires_capture status.
  • To capture payments from your application, wait for your application to receive calls to useStripeTerminal hook’s onDidForwardPaymentIntent for each PaymentIntent as the reader forwards it. A PaymentIntent is ready to capture if its status is requiresCapture and the OfflineDetails is null or has a requiresUpload value of false .
PaymentScreen.tsx
const _confirmPaymentIntent = async () => { const { paymentIntent, error } = await confirmPaymentIntent({ paymentIntent: paymentIntent }); if (error) { // Handle offline-specific errors in your application (for example, // unsupported payment method). } if (paymentIntent.status == 'requiresCapture') { const offlineDetails = paymentIntent.offlineDetails; if (offlineDetails.requiresUpload === true) { // Offline payment, wait for `onDidForwardPaymentIntent` (see snippet below) } else { // Online payment, can be captured now } } else { // handle other paymentIntent.status results here } }

Capture an offline payment after the reader forwards it in onDidForwardPaymentIntent:

PaymentScreen.tsx
const { connectReader, disconnectReader, connectedReader } = useStripeTerminal({ onDidForwardPaymentIntent(paymentIntent, error) { if (error) { // Handle the error appropriate for your application } else if (paymentIntent.status == 'requires_capture') { // The paymentIntent is ready to be captured } else { // Handle the paymentIntent.status as appropriate. } }, });

Examine payments collected offline

After authorization, you can use the PaymentIntents API to examine offline details on a payment. Access the payment method details on the latest Charge object on a PaymentIntent to determine if it was collected offline.

Was this page helpful?
YesNo
Need help? Contact Support.
Join our early access program.
Check out our changelog.
Questions? Contact Sales.
LLM? Read llms.txt.
Powered by Markdoc