Skip to main content
You are viewing early implementations that may change before release. Use them to prepare and provide feedback to our team. Check out Swan's public roadmap to see what else is in the works.

Initialize the device for payments

Connect your device to the Stripe Terminal reader before accepting payments. This involves setting up a connection token provider and running the reader discovery flow.

Prerequisites

Step 1: Implement a connection token provider

The Stripe Terminal SDK requires a connection token to connect to the reader. You obtain this token from Swan's API using the requestTerminalConnectionToken mutation. The SDK handles token refresh automatically. Do not cache the token yourself.

Get a connection token from Swan

Call requestTerminalConnectionToken from your server and pass the returned connectionToken to your provider.

mutation GetConnectionToken {
requestTerminalConnectionToken(
input: {
merchantProfileId: "$YOUR_MERCHANT_PROFILE_ID"
}
) {
... on RequestTerminalConnectionTokenSuccessPayload {
connectionToken
}
... on ForbiddenRejection {
__typename
message
}
... on InternalErrorRejection {
__typename
message
}
... on NotFoundRejection {
__typename
message
}
}
}
Early access only

If you receive a ForbiddenRejection with the message Coming Soon, your project doesn't have the required feature flag. Contact your Product Integration Manager or the Swan team to request access.

Wire up the provider

Pass a tokenProvider function as a prop to StripeTerminalProvider. The function must return a connection token fetched from Swan's API.

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

const fetchTokenProvider = async () => {
const connectionToken = "$YOUR_CONNECTION_TOKEN"; // fetch from Swan's API
return connectionToken;
};

function Root() {
return (
<StripeTerminalProvider
logLevel="verbose"
tokenProvider={fetchTokenProvider}
>
<App />
</StripeTerminalProvider>
);
}

Then call initialize from a component nested inside StripeTerminalProvider:

function App() {
const { initialize } = useStripeTerminal();

useEffect(() => {
initialize();
}, [initialize]);

return <View />;
}
note

Call initialize from a component nested inside StripeTerminalProvider, not from the component that contains the provider itself.

Step 2: Discover and connect to the reader

With the token provider configured, discover the device's reader and connect to it.

Debug mode

The Stripe Terminal SDK blocks reader connections in debug builds as a security measure. Use a simulated reader for development (see code examples below).

iOS Terms and Conditions

On iOS, the first time a user connects to a reader, Apple's Terms and Conditions screen appears automatically. This is handled by the SDK.

Use discoverReaders to find available readers, then connectReader to connect. Set simulated: true during development.

export default function MainScreen() {
const [status, setStatus] = useState<Reader.ConnectionStatus>("notConnected");
const { discoverReaders, connectReader, connectedReader, cancelDiscovering } =
useStripeTerminal({
onDidChangeConnectionStatus: setStatus,
onUpdateDiscoveredReaders: async (readers: Reader.Type[]) => {
const tapToPayReader = readers.find(
(reader) => reader.deviceType === "tapToPay"
);
if (tapToPayReader != null) {
const { error } = await connectReader(
{
reader: tapToPayReader,
locationId: "$LOCATION_ID",
},
"tapToPay"
);
if (error != null) {
Alert.alert(error.code, error.message);
}
}
},
});

const hasConnectedReader = connectedReader != null;

useEffect(() => {
if (!hasConnectedReader) {
discoverReaders({
discoveryMethod: "tapToPay",
simulated: true, // set to false for production
}).then(({ error }) => {
if (error != null) {
Alert.alert(error.code, error.message);
}
});
return () => {
cancelDiscovering();
};
}
}, [hasConnectedReader, discoverReaders, cancelDiscovering]);

return <Text>{status}</Text>;
}
Location ID: temporary during early access

The $LOCATION_ID in the code above is provided manually by Swan during the early access phase. After you create a merchant profile and request Tap to Pay setup, your Product Integration Manager will share your location ID. In a future release, it will be available as mainLocationId on the InPersonCardMerchantPaymentMethod object directly from the API.

Troubleshooting

Firewall or restricted network

If your app runs behind a firewall, configure it to allow access to the hosts required by Tap to Pay on iPhone. Refer to the Tap to Pay section of Apple's network configuration guide.

Reset Apple Terms and Conditions acceptance

The first time a user connects to a reader on iOS, Apple's Terms and Conditions screen appears automatically. Once accepted, it won't appear again for that user.

To reset acceptance for testing:

  1. Go to Apple Business Register for Tap to Pay on iPhone.
  2. Sign in with the Apple ID used to accept the Terms and Conditions.
  3. From the list of Merchant IDs, select Remove and confirm to unlink the Apple ID.
  4. The Terms and Conditions screen appears again on the next connection attempt.

If the user closes the Terms and Conditions screen without accepting, the connection fails with tapToPayReaderTOSAcceptanceFailed. Prompt the user to accept and retry.

InternalErrorRejection when requesting a connection token

Merchant profile configuration is done manually during early access. If requestTerminalConnectionToken is called before a profile is fully configured, the mutation returns an InternalErrorRejection. Contact your Product Integration Manager with your merchant profile ID so they can complete the configuration.

Next steps

Create in-person card payments