ZealDeveloper Hub Beta
EN ES
ECR SDK · v1.0.4 · Android

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
Configuration object containing applicationContext, ecrId, terminalsTokensList, and appId.

Returns

Boolean
Returns true if initialization succeeds; otherwise throws.

Throws

Exception
Thrown if initialization fails.
val 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>
Each item contains terminalId, currencyCode, currencySymbol, and tag.

Throws

Exception
Thrown if data fetching fails.
// 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
Data to be synced; includes tid and items to be synced.

Returns

Boolean
Returns true if sync succeeds; otherwise throws.

Throws

Exception
Thrown if sync fails.
// 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
Transaction amount in cents (smallest currency unit).
terminalId String
The ID of the terminal where the transaction will be processed.
items List<OrderItems>
List of order items included in the transaction.

Returns

TrxResponse
Contains transaction state, total amount, and timestamps.

Throws

TimeoutException
Thrown if the transaction does not complete within 60 seconds.
Exception
Thrown for network or Pusher errors.
val 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
The activity reference used to show dialogs.
ZealSDK.showDialogs(this)

Internal components

KoinApplication
Manages SDK dependencies and modules.
KtorModule
Provides networking, storage, repository, and use case modules.
Pusher
Handles real-time communication and event listening for transaction updates.
DialogsHelper
Manages all user-facing dialogs for transaction progress.
OrderListener
Listens for transaction-related Pusher events.
TrxData
Represents internal transaction request data.

Error 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

  1. Initialize once — at the start of your application or main activity.
  2. Call showDialogs() before starting any transaction to enable UI dialogs.
  3. Use coroutines for all suspend functions (initialize, listTerminals, startTrx).
  4. Handle exceptions properly with try/catch.
  5. 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}")
  }
}