Terminal

The Terminal API allows you to accept in-person payments using Stripe Terminal. This includes "Tap to Pay on iPhone" for contactless card payments and physical Terminal readers for point-of-sale systems.

Overview

Terminal payments enable:

  • Tap to Pay on iPhone: Accept contactless payments directly on iPhone devices
  • Physical readers: Support for Stripe Terminal readers (BBPOS WisePOS E, Stripe Reader M2, etc.)
  • Secure processing: PCI-compliant payment processing through Stripe Terminal SDK
  • Location management: Manage Terminal locations programmatically

Prerequisites

Before using Terminal, you must:

  1. Set up a Terminal location (required for all Terminal operations)
  2. Install Stripe Terminal SDK in your mobile app
  3. Get a connection token from our API to initialize Stripe Terminal

Setting up a Terminal location

You can create a location using our API or through the Stripe Dashboard.


Terminal location management

Create location

Create a new Terminal location. Locations are required for all Terminal operations.

Required Parameters

  • Name
    display_name
    Type
    string
    Description

    Display name for the location

  • Name
    address
    Type
    object
    Description

    Address object with location details

    • Name
      line1
      Type
      string
      Description

      Address line 1

    • Name
      city
      Type
      string
      Description

      City

    • Name
      state
      Type
      string
      Description

      State or province

    • Name
      postal_code
      Type
      string
      Description

      Postal code

    • Name
      country
      Type
      string
      Description

      Two-letter country code (e.g., "US")

Optional Parameters

  • Name
    line2
    Type
    string
    Description

    Address line 2 (suite, unit, etc.)

  • Name
    metadata
    Type
    object
    Description

    Custom key-value pairs

Request

POST
/terminal/locations
curl -X POST https://api.cari.finance/terminal/locations \
  -H "Authorization: Bearer pk_test_27436257e3fe4b0fa266f4a6f59047a3" \
  -H "Content-Type: application/json" \
  -d '{
    "display_name": "Main Store",
    "address": {
      "line1": "123 Main St",
      "line2": "Suite 100",
      "city": "New York",
      "state": "NY",
      "postal_code": "10001",
      "country": "US"
    },
    "metadata": {
      "store_id": "store_123"
    }
  }'

Response

{
  "id": "tmloc_abc123...",
  "object": "terminal.location",
  "display_name": "Main Store",
  "address": {
    "line1": "123 Main St",
    "line2": "Suite 100",
    "city": "New York",
    "state": "NY",
    "postal_code": "10001",
    "country": "US"
  },
  "metadata": {
    "store_id": "store_123"
  }
}

List locations

Retrieve all Terminal locations for your account.

Request

GET
/terminal/locations
curl https://api.cari.finance/terminal/locations \
  -H "Authorization: Bearer pk_test_27436257e3fe4b0fa266f4a6f59047a3"

Response

{
  "object": "list",
  "data": [
    {
      "id": "tmloc_abc123...",
      "display_name": "Main Store",
      "address": { ... }
    }
  ],
  "has_more": false
}

Get location

Retrieve a specific Terminal location by ID.

Request

GET
/terminal/locations/{id}
curl https://api.cari.finance/terminal/locations/tmloc_abc123 \
  -H "Authorization: Bearer pk_test_27436257e3fe4b0fa266f4a6f59047a3"

Update location

Update an existing Terminal location.

Request

PUT
/terminal/locations/{id}
curl -X PUT https://api.cari.finance/terminal/locations/tmloc_abc123 \
  -H "Authorization: Bearer pk_test_27436257e3fe4b0fa266f4a6f59047a3" \
  -H "Content-Type: application/json" \
  -d '{
    "display_name": "Updated Store Name",
    "address": {
      "line1": "456 New St",
      "city": "Boston",
      "postal_code": "02101",
      "country": "US"
    }
  }'

Delete location

Delete a Terminal location.

Request

DELETE
/terminal/locations/{id}
curl -X DELETE https://api.cari.finance/terminal/locations/tmloc_abc123 \
  -H "Authorization: Bearer pk_test_27436257e3fe4b0fa266f4a6f59047a3"

Terminal reader management

Register reader

Register a new Terminal reader to a location. You'll need the registration code from your physical reader device.

Required Parameters

  • Name
    registration_code
    Type
    string
    Description

    Registration code from the reader (starts with "pst_reg_")

  • Name
    location
    Type
    string
    Description

    Terminal location ID

Optional Parameters

  • Name
    label
    Type
    string
    Description

    Custom label for the reader

  • Name
    metadata
    Type
    object
    Description

    Custom metadata

Request

POST
/terminal/readers
curl -X POST https://api.cari.finance/terminal/readers \
  -H "Authorization: Bearer pk_test_27436257e3fe4b0fa266f4a6f59047a3" \
  -H "Content-Type: application/json" \
  -d '{
    "registration_code": "pst_reg_abc123...",
    "location": "tmloc_abc123...",
    "label": "Front Counter Reader",
    "metadata": {
      "store_section": "checkout_1"
    }
  }'

Response

{
  "id": "tmr_abc123...",
  "object": "terminal.reader",
  "device_type": "bbpos_wisepos_e",
  "label": "Front Counter Reader",
  "location": "tmloc_abc123...",
  "serial_number": "...",
  "status": "online",
  "metadata": {
    "store_section": "checkout_1"
  }
}

List readers

Retrieve all Terminal readers for your account.

Request

GET
/terminal/readers
curl https://api.cari.finance/terminal/readers \
  -H "Authorization: Bearer pk_test_27436257e3fe4b0fa266f4a6f59047a3"

POST/terminal/connection_token

Connection token

Generate a connection token to initialize Stripe Terminal SDK in your mobile app. This token is required to connect to Terminal readers.

Request

POST
/terminal/connection_token
curl -X POST https://api.cari.finance/terminal/connection_token \
  -H "Authorization: Bearer pk_test_27436257e3fe4b0fa266f4a6f59047a3" \
  -H "Content-Type: application/json"

Response

{
  "secret": "pst_test_abc123..."
}

Mobile integration

React Native example

import { StripeTerminalProvider } from "@stripe/stripe-terminal-react-native";

function App() {
   const fetchConnectionToken = async () => {
      const response = await fetch("https://api.cari.finance/terminal/connection_token", {
         method: "POST",
         headers: {
            Authorization: `Bearer ${YOUR_API_KEY}`,
            "Content-Type": "application/json",
         },
      });
      const { secret } = await response.json();
      return secret;
   };

   return (
      <StripeTerminalProvider
         logLevel="verbose"
         tokenProvider={fetchConnectionToken}>
         <YourApp />
      </StripeTerminalProvider>
   );
}

Processing a payment

import {
   useStripeTerminal,
   useStripeTerminalDiscovery,
} from "@stripe/stripe-terminal-react-native";

function PaymentScreen() {
   const { discoverReaders, connectReader, collectPaymentMethod, processPayment } =
      useStripeTerminal();

   const processTapToPay = async (amount: number) => {
      // 1. Create payment intent
      const paymentResponse = await fetch(
         "https://api.cari.finance/payments/create-intent",
         {
            method: "POST",
            headers: {
               Authorization: `Bearer ${YOUR_API_KEY}`,
               "Content-Type": "application/json",
            },
            body: JSON.stringify({
               amount: amount,
               currency: "usd",
            }),
         }
      );
      const payment = await paymentResponse.json();

      // 2. Discover and connect to reader (for Tap to Pay on iPhone, use "localMobile")
      const { discoveredReaders } = await discoverReaders({
         discoveryMethod: "localMobile",
         simulated: false,
      });

      await connectReader(discoveredReaders[0]);

      // 3. Collect payment method
      const { paymentIntent } = await collectPaymentMethod(
         payment.client_secret
      );

      // 4. Process payment
      await processPayment(paymentIntent);

      // 5. Complete payment on backend
      await fetch(`https://api.cari.finance/payments/${payment.payment_id}/complete`, {
         method: "POST",
         headers: {
            Authorization: `Bearer ${YOUR_API_KEY}`,
         },
      });
   };
}

Error handling

Common errors:

  • Name
    Location setup required
    Type
    string
    Description

    No Terminal location has been created. Create a location first.

  • Name
    Invalid registration code
    Type
    string
    Description

    The reader registration code is invalid or expired.

  • Name
    Reader not found
    Type
    string
    Description

    The specified reader doesn't exist or isn't registered.

  • Name
    Connection failed
    Type
    string
    Description

    Failed to connect to the Terminal reader. Check device connectivity.


Best practices

  1. Create locations first: Always create a Terminal location before attempting to process payments
  2. Handle errors gracefully: Implement proper error handling for connection and payment failures
  3. Test in test mode: Use test mode and simulated readers during development
  4. Store location IDs: Save location IDs for reuse in your application
  5. Monitor reader status: Check reader status before processing payments

Additional resources

Was this page helpful?