Connect SDK
The Rootline Connect SDK lets the app you run on the payment device integrate with the Rootline Connect app. Use the SDK to start the Connect app, observe connection state and payment results, and print receipts.
How a payment flows through the SDK
Your app starts the Connect app using the SDK. When a payment request is initiated on the payment device, the Connect SDK opens the Connect app to let the customer complete the payment. Once the payment is completed, your app returns to the foreground.
Step by step
- On startup, your app creates the
RootlineConnectclient, registers the handlers and finally callsconnect.start(). - Your app starts a payment. Your backend sends a
POST /paymentsrequest to Rootline with thepayment_rails.payment_device_id. - Rootline initiates the payment on the device, the device acknowledges, and Rootline responds with
checkout_status=open. - The Connect SDK automatically foregrounds the Rootline Connect app, displaying the payment screen to the customer.
- The customer presents their card, the payment finalizes and the result is displayed.
- The Connect app sends the result to Rootline's servers and to your app. The
onPaymentStatehandler delivers the result init.outcome. - Rootline additionally sends the result asynchronously via webhooks. Optionally, you can retrieve the status with
GET /payments/{payment_id}.
SDK integration
Before you begin, contact your Rootline point of contact to add your app to the integrator list of the Connect app.
Add the SDK to your project
Add the Connect SDK dependency to your Gradle build.
Starting the SDK
Create the RootlineConnect client, register the event handlers and start the Connect app.
The start() function is asynchronous. The onRuntimeStarted handler fires when the runtime is fully up or once it has failed to boot. We recommend waiting for the handler rather than assuming readiness when start() returns.
If the Connect app is already running when you call start(), you still get a RuntimeStarted(success = true) event. The handler works regardless of ordering. A failed boot is not cached: the next start() attempts to start the Connect app again.
The event handlers
The event handlers are split into two channels: status and outcomes.
The onRuntimeStarted and onConnectionState handlers report the current status. The onConnectionState handler also fires once right after registration so that you know the current state without waiting for a change.
Outcomes are handled by onPaymentState and onPrintResult. Outcomes are delivered durably: an outcome that occurs while your app is backgrounded, killed, or offline is replayed when your app comes back. Delivery is at-least-once. Deduplicate payment outcomes by PaymentState.id and print outcomes by PrintResult.requestId (the id printReceipt returned).
| Handler — event | Fields | Meaning |
|---|---|---|
onRuntimeStarted — RuntimeStarted | success, reason | The runtime finished booting or failed, with a coarse reason. |
onConnectionState — ConnectionState | connected, reason | The terminal's connection to Rootline became reachable/unreachable. |
onPaymentState — PaymentState | id, outcome, amountMinor, currency, clientId | A payment reached a terminal outcome. |
onPrintResult — PrintResult | paymentId, recipient, outcome, requestId | The result of a receipt print you requested. |
PaymentState fields
| Field | Description |
|---|---|
id | The payment's payment_id. |
outcome | The result of the payment: succeeded, failed or cancelled. |
amountMinor | The payment amount in minor units. |
currency | The currency of the payment, e.g. EUR. |
clientId | This field is currently null |
PrintResult fields
| Field | Description |
|---|---|
paymentId | The id of the payment the receipt belongs to. |
recipient | CUSTOMER or MERCHANT. |
outcome | The result of the print operation: Ok, OutOfPaper, etc. See printing receipts for the full list. |
requestId | The id of the print operation, as returned by printReceipt. |
On-device outcomes are authenticated by the SDK, making them safe to act on in the UI. For business operations, we strongly recommend verifying the payment's final status against the Rootline API from your backend.
Initiating a payment from your app
To initiate a payment from your app you need to call the Rootline Payments API as explained in the accept in-person payments guide.
On the payment device the Connect SDK automatically brings the Connect app to the foreground to complete the payment, and returns your app to the foreground afterwards.
The payment status is communicated directly to your app through the onPaymentState handler. Additionally, Rootline sends payment.* webhooks to your configured webhook endpoint and you can use the GET /payments/{payment_id} API to retrieve the status.
Make sure you do not include your Rootline API key in your app, and follow the security best practices.
Printing receipts
A PaymentState carries the payment's id, so when a payment succeeds you can ask Connect to print its receipt. It's fire-and-forget; the outcome arrives durably on onPrintResult.
PrintResult.outcome is a sealed PrintOutcome with these cases (an unrecognized wire value maps to Unknown(raw)):
| Outcome | Meaning |
|---|---|
Ok | The receipt printed successfully. |
OutOfPaper | The printer is out of paper. |
Overheated | The print head is too hot to print right now. |
LowVoltage | Not enough power to drive the printer. |
NoPrinter | The device has no printer (e.g. an A77/A35 without the printer module). |
NotFound | No payment with that id is known to Connect, so there was nothing to print. |
Error | The request was invalid (e.g. an unknown recipient) or the printer reported a malfunction / unknown failure. |
The result is correlated back to your request by requestId — the id printReceipt returned, echoed on PrintResult.requestId. Unlike paymentId + recipient, it stays unique across reprints of the same receipt, so it is also the key that tells a redelivered outcome apart from a genuine reprint's.
App design considerations
When building your own app to run on the payment device, keep the following device constraints in mind:
Build for kiosk mode
Your app runs in kiosk mode. The Android navigation bar is not available. You should provide in-app navigation for every screen the user needs to reach.
Device management via Android system settings
The payment device user does not have access to the Android system settings. You must build in explicit ways for your users to manage the device. You can do this by launching the relevant Android system settings screens directly from your app:
- Wi-Fi: launch
ACTION_WIFI_SETTINGSso the user can join a wireless network. - LAN / Ethernet: launch
ACTION_WIRELESS_SETTINGSso the user can configure a wired connection. - Bluetooth: launch
ACTION_BLUETOOTH_SETTINGSso the user can pair Bluetooth devices.
Use your own logging service
Your app should ship its logs to your own remote logging / observability service.