Zeal ECR SDK Guide
Trigger transactions on Zeal-integrated terminals from your Android ECR. Real-time Pusher events, dialogs included.
The Zeal ECR SDK provides a direct interface for integrating your Android application with the Zeal e-POS ecosystem. It handles device initialization, terminal management, and transaction processing using a structured and asynchronous API design.
What this is for. Any ECR (electronic cash register) integrated with Zeal can use the ECR SDK to trigger transactions on payment terminals that have Zeal integrated — and listen for real-time transaction state via Pusher.
Installation
Step 1 · Create a GitHub Personal Access Token
You need a PAT with the read:packages permission. Generate a token (classic) from
GitHub Developer settings.
Step 2 · Add the Maven repository
Add the GitHub Packages Maven repository to your project-level settings.gradle.kts:
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
google()
mavenCentral()
// Add GitHub Packages repository
maven {
name = "GitHubPackages"
url = uri("https://maven.pkg.github.com/zeal-io/epos-sdk")
credentials {
username = "your-github-username"
password = "your-github-pat-token"
}
}
}
}Step 3 · Add the dependency
In your module-level app/build.gradle.kts:
dependencies {
implementation("com.zeal:epos_sdk:1.0.4")
// Required for EPOS SDK
implementation("io.insert-koin:koin-core:4.1.1")
}Step 4 · Permissions
The SDK needs internet access. Add the following to your AndroidManifest.xml:
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
Initialize the SDK
suspend fun initialize(zealSdkConfig: SdkConfig): Boolean Sets up internal dependencies (Koin), stores essential configuration, and performs asynchronous setup tasks such as API calls. Must be called once before using other SDK functions.
Parameters
zealSdkConfig SdkConfig Returns
BooleanThrows
Exceptionval config = SdkConfig( context = applicationContext, ecrId = "ECR12345", terminalsTokensList = listOf("token1", "token2"), appId = "app-id-example" ) // must be called from a coroutine or another suspend function val initialized = ZealSDK.initialize(config)
List terminals
suspend fun listTerminals(): List<TerminalData> Retrieves the list of configured terminals associated with the initialized SDK configuration.
Returns
List<TerminalData>Throws
Exception// must be called from a coroutine or another suspend function val terminals = ZealSDK.listTerminals() terminals.forEach { println("Terminal ID: ${it.terminalId}") }
Sync catalog
suspend fun syncCatalog(syncData: SyncData): Boolean Synchronizes catalog items with Zeal.
Parameters
syncData SyncData Returns
BooleanThrows
Exception// must be called from a coroutine or another suspend function val syncData = SyncData(tid = "2223223", items = listOf(CatalogItem())) val success = ZealSDK.syncCatalog(syncData)
Start a transaction
suspend fun startTrx(amount: Double, terminalId: String, items: List<OrderItems>): TrxResponse Starts a transaction on a specific terminal. The SDK listens for real-time Pusher events representing the transaction's progress and completion.
Parameters
amount Double terminalId String items List<OrderItems> Returns
TrxResponseThrows
TimeoutExceptionExceptionval orderItems = listOf( OrderItems("Coffee", 2, 25.0), OrderItems("Cake", 1, 40.0) ) // see Show Transaction Dialogs below ZealSDK.showDialogs(context as ComponentActivity) try { val trxResponse = ZealSDK.startTrx( amount = 20.0, terminalId = "T12345", items = orderItems ) println("Transaction completed: ${trxResponse.state}") } catch (e: TimeoutException) { println("Transaction timed out.") } catch (e: Exception) { println("Transaction failed: ${e.message}") }
60-second hard timeout. If the terminal does not return a final state within
60 seconds, startTrx() throws TimeoutException. Always wrap the call in
try/catch and present a recoverable state to the cashier.
Show transaction dialogs
fun showDialogs(activity: Activity) Displays visual dialogs for transaction states such as processing, success, and decline. Enhances UX by providing transaction feedback through the UI. Call once per Activity, before the first transaction.
Parameters
activity Activity ZealSDK.showDialogs(this)
Internal components
KoinApplicationKtorModulePusherDialogsHelperOrderListenerTrxDataError handling
The SDK uses a structured Result wrapper to handle success and error states in all
use cases. Common error causes include:
- Invalid or expired terminal tokens.
- Network communication failures.
- Unresponsive terminals.
- Timeouts or missing transaction responses.
Always wrap SDK calls in try/catch blocks for reliable error handling.
try { val success = ZealSDK.initialize(config) } catch (e: Exception) { Log.e("ZealSDK", "Initialization failed: ${e.message}") }
Lifecycle recommendations
- Initialize once — at the start of your application or main activity.
- Call
showDialogs()before starting any transaction to enable UI dialogs. - Use coroutines for all suspend functions (
initialize,listTerminals,startTrx). - Handle exceptions properly with try/catch.
- Be timeout-aware — transactions automatically fail after 60 seconds with a
TimeoutException.
Full example
End-to-end transaction flow inside an Activity:
lifecycleScope.launch {
try {
// Step 1: Initialize SDK
val initialized = ZealSDK.initialize(config)
// Step 2: Enable dialogs
ZealSDK.showDialogs(this@MainActivity)
// Step 3: Get terminals
val terminals = ZealSDK.listTerminals()
val terminal = terminals.first()
// Step 4: Start transaction
val trxResponse = ZealSDK.startTrx(
amount = 5000L,
terminalId = terminal.id,
items = listOf(OrderItems("Latte", 1, 50.0))
)
Log.d("ZealSDK", "Transaction success: ${trxResponse.state}")
} catch (e: TimeoutException) {
Log.e("ZealSDK", "Transaction timed out.")
} catch (e: Exception) {
Log.e("ZealSDK", "Error: ${e.message}")
}
}