# Use Terminal with Connect

Integrate Stripe Terminal with your Connect platform.

Stripe Terminal is compatible with *Connect* (Connect is Stripe's solution for multi-party businesses, such as marketplace or software platforms, to route payments between sellers, customers, and other recipients), allowing your platform and connected accounts to accept in-person payments.

Integrate Terminal with Connect according to how your platform processes payments for your connected accounts.

- If you use [direct charges](https://docs.stripe.com/connect/direct-charges.md), you submit Terminal API requests to configure readers and accept payments using your platform’s API key and the `Stripe-Account` header to identify the connected account.
- If you use [destination charges](https://docs.stripe.com/connect/destination-charges.md), you submit Terminal API requests to configure readers and accept payments using your platform API key and identify the connected account using metadata.
- If you use [separate charges and transfers](https://docs.stripe.com/connect/separate-charges-and-transfers.md), you submit Terminal API requests using your platform API key to create charges on your platform account, then create separate transfers to move funds to your connected accounts.

In all cases, use [locations](https://docs.stripe.com/api/terminal/locations.md) to group readers applicably.

> Terminal connected accounts must have the `card_payments` capability to perform transactions.

# Destination charges


When using [destination charges](https://docs.stripe.com/connect/destination-charges.md), your platform owns API resources like [PaymentIntents](https://docs.stripe.com/api/payment_intents.md) and [Locations](https://docs.stripe.com/api/terminal/locations.md). Each payment creates a transfer to a connected account automatically.

In the Dashboard, you can view your Terminal data directly when logged into your platform account.

## Create locations and readers (Server-side) 

Group Reader objects by connected account by assigning them to `Locations`. On your platform account, [create a Location](https://docs.stripe.com/terminal/fleet/locations-and-zones.md?dashboard-or-api=dashboard#create-locations-and-zones) for a connected account using a display name that identifies the account.

```curl
curl https://api.stripe.com/v1/terminal/locations \
  -u "<<YOUR_SECRET_KEY>>:" \
  -d display_name=HQ \
  -d "address[line1]=1272 Valencia Street" \
  -d "address[city]=San Francisco" \
  -d "address[state]=CA" \
  -d "address[country]=US" \
  -d "address[postal_code]=94110"
```

Before you can connect your application to a [smart reader](https://docs.stripe.com/terminal/payments/connect-reader.md?reader-type=internet), you must register the reader to your platform account.

```curl
curl https://api.stripe.com/v1/terminal/readers \
  -u "<<YOUR_SECRET_KEY>>:" \
  -d registration_code={{READER_REGISTRATION_CODE}} \
  --data-urlencode "label=Alice's reader" \
  -d "location={{TERMINALLOCATION_ID}}"
```

## Create connection tokens (Server-side) 

When creating a `ConnectionToken` for the Terminal SDK, use your platform account’s secret key. Don’t set the `Stripe-Account` header. Provide a `location` parameter to control access to readers. If you provide a location, the `ConnectionToken` is only usable with readers assigned to that location. If you don’t provide a location, the `ConnectionToken` is usable with all readers.

```curl
curl https://api.stripe.com/v1/terminal/connection_tokens \
  -u "<<YOUR_SECRET_KEY>>:" \
  -d "location={{TERMINALLOCATION_ID}}"
```

If you’re using a server-driven integration, you don’t need to create a connection token.

## Create PaymentIntents (Client-side) (Server-side) 

When creating a `PaymentIntent` using destination charges, provide the [on_behalf_of](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-on_behalf_of) and [transfer_data[destination]](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-transfer_data-destination), and [application_fee_amount](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-application_fee_amount) parameters.

The `on_behalf_of` parameter is the ID of the connected account that becomes the settlement merchant for the payment. For Terminal transactions, you must set this parameter if the platform country isn’t the same as the connected account country. When you set `on_behalf_of`, Stripe automatically:

- Settles charges in the country of the specified account, minimizing declines and avoiding currency conversions.
- Uses the fee structure for the connected account’s country.
- Lists the connected account’s address and phone number instead of your platform’s address and phone number on the customer’s credit card statement. (Only if the account and platform are in different countries.)

For `transfer_data[destination]`, set the ID of the connected account that receives the transfer.

Finally, you can withhold an application fee for your platform by providing the [application_fee_amount](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-application_fee_amount) parameter.

### Client-side 

With the iOS, Android, and React Native SDKs, you can create a `PaymentIntent` client-side and provide the `onBehalfOf`, `transferDataDestination`, and `applicationFeeAmount` parameters.

#### JavaScript

> Client-side `PaymentIntent` creation is possible with the other SDKs. If you’re using the JavaScript SDK for Stripe Terminal, create a `PaymentIntent` server-side.

#### iOS

- [PaymentIntentParameters (iOS)](https://stripe.dev/stripe-terminal-ios/docs/Classes/SCPPaymentIntentParameters.html)

#### Swift

```swift
import UIKit
import StripeTerminal

class PaymentViewController: UIViewController {

    // ...

    // Action for a "Checkout" button
    func checkoutAction() throws {
        let params = try PaymentIntentParametersBuilder(amount: 1000, currency: "usd")
            .setOnBehalfOf(""{{CONNECTED_ACCOUNT_ID}}"")
            .setTransferDataDestination(""{{CONNECTED_ACCOUNT_ID}}"")
            .setApplicationFeeAmount(200)
            .build()
        Terminal.shared.createPaymentIntent(params) { createResult, createError in
            if let error = createError {
                print("createPaymentIntent failed: \(error)")
            }
            else if let paymentIntent = createResult {
                print("createPaymentIntent succeeded")
                // ...
            }

        }
    }

    // ...
}
```

#### Android

- [PaymentIntentParameters (Android)](https://stripe.dev/stripe-terminal-android/external/com.stripe.stripeterminal.external.models/-payment-intent-parameters/index.html)

#### Kotlin

```kotlin
    val params = PaymentIntentParameters.Builder()
        .setAmount(1000)
        .setCurrency("usd")
        .setOnBehalfOf(""{{CONNECTED_ACCOUNT_ID}}"")
        .setTransferDataDestination(""{{CONNECTED_ACCOUNT_ID}}"")
        .setApplicationFeeAmount(200)
        .build()
    Terminal.getInstance().createPaymentIntent(
        params,
        object : PaymentIntentCallback {
            override fun onSuccess(paymentIntent: PaymentIntent) {
                // Placeholder for handling successful operation
            }

            override fun onFailure(e: TerminalException) {
                // Placeholder for handling exception
            }
        }
    )
```

#### React Native

- [CreatePaymentIntentParams (React Native)](https://stripe.dev/stripe-terminal-react-native/api-reference/index.html#CreatePaymentIntentParams)

```js
const {paymentIntent, error} = await createPaymentIntent({
  amount: 1000,
  currency: "usd",
  onBehalfOf: "{{CONNECTED_ACCOUNT_ID}}" ,
  transferDataDestination: "{{CONNECTED_ACCOUNT_ID}}",
  applicationFeeAmount: 200,
});

if (error) {
  // Placeholder for handling exception
  return;
}

// Placeholder for collecting a payment method with PaymentIntent
```

### Server-side 

The JavaScript SDK requires you to create the `PaymentIntent` on your server. For the other client SDKs, you want to create the `PaymentIntent` on your server if the information required to start a payment isn’t readily available in your app. For more information, see [Create PaymentIntents Server-side](https://docs.stripe.com/terminal/payments/collect-card-payment.md?terminal-sdk-platform=js#create-payment).

```curl
curl https://api.stripe.com/v1/payment_intents \
  -u "<<YOUR_SECRET_KEY>>:" \
  -d amount=1000 \
  -d currency=usd \
  -d "payment_method_types[]=card_present" \
  -d capture_method=manual \
  -d application_fee_amount=200 \
  -d "on_behalf_of={{CONNECTEDACCOUNT_ID}}" \
  -d "transfer_data[destination]={{CONNECTEDACCOUNT_ID}}"
```

Then follow the steps to [collect a payment](https://docs.stripe.com/terminal/payments/collect-card-payment.md) to process the PaymentIntent.


## See also

- [Cart display](https://docs.stripe.com/terminal/features/display.md)
- [Receipts](https://docs.stripe.com/terminal/features/receipts.md)
