Reader Lifecycle
Keep reader software updates, status, and display messaging under control so Terminal operations do not interrupt checkout.
Listen for software updates
The reader may start updating itself when needed. Listen for available updates, install or cancel them, and surface progress while an install is running.
Constraints:
- Call
setSimulatorConfigurationbeforediscoverReaderswhen you need a simulated update (SimulateReaderUpdate.UpdateAvailableorRequired). WebsetSimulatorConfigurationis a no-op. StartInstallingUpdate,ReaderSoftwareUpdateProgress, andFinishInstallingUpdateapply to Bluetooth and USB readers. A mandatory update on first connect installs automatically, beforeConnectedReaderand beforeconnectReader()resolves. Sequence:StartInstallingUpdate→ReaderSoftwareUpdateProgress(repeated) →FinishInstallingUpdate→ConnectedReader→connectReader()resolves. Show UI so a long connect is not mistaken for a hang.ReportAvailableUpdatemeans an optional update is ready; callinstallAvailableUpdatewhen the merchant can wait. Do not start an optional install during checkout.progressis a float between0and1.cancelInstallUpdatecancels an in-flight install when the SDK allows it. Web install/cancel methods are no-ops.- iOS Tap to Pay also reports install start/progress/finish through the Tap to Pay reader delegate. Android Tap to Pay UX is separate; see Tap to Pay.
method installAvailableUpdate()
installAvailableUpdate() => Promise<void>
method cancelInstallUpdate()
cancelInstallUpdate() => Promise<void>
method setSimulatorConfiguration(...)
Stripe docs reference
setSimulatorConfiguration(options: { update?: SimulateReaderUpdate; simulatedCard?: SimulatedCardType; simulatedTipAmount?: number; }) => Promise<void>
Listen for status and input
For readers without a leader screen, retrieve battery level, reader events, display messages, and input prompts with listeners and show them on the mobile device.
BatteryLevel, ReaderEvent, RequestDisplayMessage, and RequestReaderInput apply to Bluetooth and USB readers. Battery updates are emitted on connection and about every 10 minutes.
Set reader display
On devices with a leader screen, show cart contents before collectPaymentMethod. Clear the display when you are done. Internet readers on web support these calls.
method setReaderDisplay(...)
setReaderDisplay(options: Cart) => Promise<void>
method clearReaderDisplay()
clearReaderDisplay() => Promise<void>
type alias Cart
{ currency: string; tax: number; total: number; lineItems: CartLineItem[]; }
type alias CartLineItem
{ displayName: string; quantity: number; amount: number; }
Cancel discovery
Call cancelDiscoverReaders when the user leaves the scan screen or after a timeout. On success, native platforms emit CancelDiscoveredReaders. If nothing is in progress, the promise still resolves.
iOS Bluetooth discovery can run for a long time and will keep emitting DiscoveredReaders. Pair cancel with bluetoothScanWaitTime or your own timeout. Web cancelDiscoverReaders is a no-op.
method cancelDiscoverReaders()
cancelDiscoverReaders() => Promise<void>
Disconnect and reconnection
disconnectReader disconnects the current reader. If none is connected, the promise resolves.
DisconnectedReader behavior:
- Every reader type emits it in response to
disconnectReader()without areason. - Bluetooth and USB also emit it with a
reasonwhen the reader finishes disconnecting. A user-initiated disconnect therefore yields two events: acknowledgement, then the reasoned disconnect.
Do not treat ConnectionStatusChange as an unexpected disconnect. Use UnexpectedReaderDisconnect to notify the user. You may call discoverReaders again to reconnect; always provide a timeout or cancelDiscoverReaders.
Set autoReconnectOnUnexpectedDisconnect: true on connectReader for Tap to Pay and Bluetooth when you want the SDK to retry. Then listen for:
ReaderReconnectStarted— includesreaderandreasonReaderReconnectSucceededReaderReconnectFailed
cancelReaderReconnection cancels an in-flight reconnect. Web rebootReader and cancelReaderReconnection are no-ops.
method getConnectedReader()
getConnectedReader() => Promise<{ reader: ReaderInterface | null; }>
method rebootReader()
rebootReader() => Promise<void>
method cancelReaderReconnection()
cancelReaderReconnection() => Promise<void>
Error handling
Failed fires when collect or confirm fails; the corresponding promise rejects with the same message / code / declineCode when the native SDK provides them.
UnexpectedReaderDisconnect means the Terminal dropped the reader outside of disconnectReader(). For Bluetooth and USB, inspect DisconnectedReader for DisconnectReason (POWERED_OFF, BLUETOOTH_DISABLED, CRITICALLY_LOW_BATTERY, and others).
import { StripeTerminal, TerminalEventsEnum } from '@capacitor-community/stripe-terminal';
await StripeTerminal.addListener(
TerminalEventsEnum.ReportAvailableUpdate,
async ({ update }) => {
if (window.confirm('Will you update the device?')) {
await StripeTerminal.installAvailableUpdate();
}
},
);
await StripeTerminal.addListener(
TerminalEventsEnum.StartInstallingUpdate,
async ({ update }) => {
console.log(update);
if (window.confirm('Will you interrupt the update?')) {
await StripeTerminal.cancelInstallUpdate();
}
},
);
await StripeTerminal.addListener(
TerminalEventsEnum.ReaderSoftwareUpdateProgress,
async ({ progress }) => {
console.log(progress);
},
);
await StripeTerminal.addListener(
TerminalEventsEnum.FinishInstallingUpdate,
async (args) => {
console.log(args);
},
);
await StripeTerminal.addListener(
TerminalEventsEnum.BatteryLevel,
async ({ level, charging, status }) => {
console.log(level, charging, status);
},
);
await StripeTerminal.addListener(
TerminalEventsEnum.ReaderEvent,
async ({ event }) => {
console.log(event);
},
);
await StripeTerminal.addListener(
TerminalEventsEnum.RequestDisplayMessage,
async ({ messageType, message }) => {
console.log(messageType, message);
},
);
await StripeTerminal.addListener(
TerminalEventsEnum.RequestReaderInput,
async ({ options, message }) => {
console.log(options, message);
},
);
await StripeTerminal.setReaderDisplay({
currency: 'usd',
tax: 0,
total: 1000,
lineItems: [
{
displayName: 'winecode',
quantity: 2,
amount: 500,
},
],
});
await StripeTerminal.clearReaderDisplay();
await StripeTerminal.cancelDiscoverReaders();
await StripeTerminal.addListener(
TerminalEventsEnum.UnexpectedReaderDisconnect,
async ({ reader }) => {
console.log(reader);
},
);
await StripeTerminal.addListener(
TerminalEventsEnum.ReaderReconnectStarted,
async ({ reader, reason }) => {
console.log(reader, reason);
},
);
await StripeTerminal.addListener(
TerminalEventsEnum.ReaderReconnectSucceeded,
async ({ reader }) => {
console.log(reader);
},
);
await StripeTerminal.addListener(
TerminalEventsEnum.ReaderReconnectFailed,
async ({ reader }) => {
console.log(reader);
},
);
await StripeTerminal.cancelReaderReconnection();
await StripeTerminal.rebootReader();
await StripeTerminal.addListener(
TerminalEventsEnum.Failed,
(info) => {
console.log(info.message, info.code, info.declineCode);
},
);