Installing the SDK
Install the Koard Merchant SDK to enable tap-to-pay functionality in your Android application.
If you're ready to start developing, see our Android SDK implementation guide.
What you learn
In this guide, you'll learn:
- How to add the Koard Merchant SDK to your Android project
- How to configure Gradle dependencies
- How to initialize the SDK in your application
- How to verify your installation is working correctly
Prerequisites
Before you begin, ensure you have:
- Android Studio Hedgehog or newer (required for modern Gradle support)
- JDK 21 (required for compilation)
- Android SDK 36 (minimum SDK 31 - Android 12)
- Physical Android device with NFC support (Android 12+)
- Valid Koard merchant account (configured in Koard MMS)
- Install the Visa Kernel app on every NFC-enabled test device before running tap-to-pay flows (download from the Google Play Store)
Physical Device Required: Tap to Pay on Android requires a physical device with NFC hardware. The Android emulator does not support NFC contactless payments.
Developer Mode Workflow:
When working with Tap to Pay on Android, follow this important workflow:
- Enable Developer Mode - Turn on developer mode to install and test app revisions
- Install/Update Your App - Deploy your application updates
- Disable Developer Mode - You MUST turn off developer mode before running tap to pay transactions
- Run Transactions - Process payments with developer mode disabled
Tap to Pay transactions will NOT work if developer mode is enabled. This is a security requirement from the payment processor.
Step 1: Add the SDK Dependency
Option A: Manual AAR Installation
If you have the SDK as AAR files:
- Create a
libsdirectory in your app module if it doesn't exist - Copy the AAR file (e.g.,
koard-android-release.aar) to thelibs/directory - Add the dependency in your
build.gradle.kts:
dependencies {
implementation(files("libs/koard-android-release.aar"))
// Required dependencies
implementation("androidx.core:core-ktx:1.12.0")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3")
implementation("com.squareup.retrofit2:retrofit:2.9.0")
implementation("com.squareup.retrofit2:converter-kotlinx-serialization:2.9.0")
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.0")
}
Option B: Gradle (Coming Soon)
Add the Koard SDK to your app's build.gradle.kts:
dependencies {
implementation("com.github.koardlabs:merchant-sdk:0.0.1")
}
Step 2: Configure Build Settings
Set Minimum SDK Version
Ensure your app's minimum SDK is set to Android 12 (API level 31):
android {
defaultConfig {
minSdk = 31
targetSdk = 36
compileSdk = 36
}
}
Configure Java Compatibility
Set Java version to 21:
android {
compileOptions {
sourceCompatibility = JavaVersion.VERSION_21
targetCompatibility = JavaVersion.VERSION_21
}
kotlinOptions {
jvmTarget = "21"
}
}
Add Build Flavors (Optional)
For multi-environment support (dev, uat, prod):
android {
flavorDimensions += "environment"
productFlavors {
create("prod") {
dimension = "environment"
// Production: https://api.koard.com
}
create("uat") {
dimension = "environment"
// UAT: https://api.uat.koard.com
}
create("dev") {
dimension = "environment"
// Development: https://api.dev.koard.com
}
}
}
Step 3: Initialize the SDK
Create Application Class
Initialize the SDK in your Application.onCreate() method on a worker thread:
import android.app.Application
import com.koardlabs.merchant.sdk.KoardMerchantSdk
import com.koardlabs.merchant.sdk.domain.KoardEnvironment
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.withContext
class MyApplication : Application() {
override fun onCreate() {
super.onCreate()
// Initialize SDK synchronously during app startup
runBlocking {
withContext(Dispatchers.IO) {
try {
val environment = KoardEnvironment.PROD // or .UAT, .DEV
KoardMerchantSdk.initialize(
application = this@MyApplication,
apiKey = "your-api-key",
environment = environment
)
println("Koard SDK initialized successfully")
} catch (e: Exception) {
// Handle initialization error
println("Failed to initialize SDK: ${e.message}")
}
}
}
}
}
Important:
- SDK initialization must be performed on a worker thread (not the main UI thread). Always use
Dispatchers.IOwith coroutines. - The
initialize()method takesapplication,apiKey, andenvironment- NOT merchantCode/merchantPin. - Merchant authentication is done separately using
login(merchantCode, merchantPin)after initialization.
Register Application in Manifest
Add your custom Application class to AndroidManifest.xml:
<application
android:name=".MyApplication"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:theme="@style/Theme.MyApp">
<!-- Your activities here -->
</application>
Step 4: Authenticate Merchant
After SDK initialization, authenticate the merchant using their credentials:
import androidx.lifecycle.lifecycleScope
import com.koardlabs.merchant.sdk.KoardMerchantSdk
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
lifecycleScope.launch(Dispatchers.IO) {
try {
val sdk = KoardMerchantSdk.getInstance()
// Login with merchant credentials
val success = sdk.login(
merchantCode = "your-merchant-code",
merchantPin = "your-merchant-pin"
)
if (success) {
println("Merchant authenticated successfully")
} else {
println("Authentication failed")
}
} catch (e: Exception) {
println("Error: ${e.message}")
}
}
}
}
The login() method authenticates the merchant and retrieves an access token. This must be done before processing transactions.
Test Basic Import
Add this import statement to verify the SDK is accessible:
import com.koardlabs.merchant.sdk.KoardMerchantSdk
import com.koardlabs.merchant.sdk.domain.KoardEnvironment
import com.koardlabs.merchant.sdk.domain.KoardLocation
import com.koardlabs.merchant.sdk.domain.exception.KoardException
If the imports succeed without errors, your installation is working correctly.
Step 5: Add Required Permissions
Add NFC permissions to your AndroidManifest.xml:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.NFC" />
<uses-feature
android:name="android.hardware.nfc"
android:required="true" />
Step 6: Transaction Processing
With installation complete you can now run Tap to Pay sessions. Keep these guardrails in mind:
sdk.sale(...)andsdk.preauth(...)are the only APIs that talk to the tap-to-pay thin client, so they return a coldFlow<KoardTransactionResponse>stream that drives the reader UI.- Every other payment action (capture, refund, reverse, incremental auth, receipts, tip adjustment, cancel) is a suspend function that returns a
Result<T>and never emits reader events. - The SDK enforces readiness (
sdk.readinessState.value.isReadyForTransactions) and blocks taps if the required tap-to-pay dependency is missing, developer mode is on, or no active location is set.
Rather than duplicating code here, the dedicated Running Payments guide shows:
- How the demo’s
TransactionFlowViewModelbuildsPaymentBreakdown, collects the Flow, and updates UI state - Mapping
KoardReaderStatus+ reader status codes to your own UX - Handling surcharge confirmation, canceling the reader, and orchestrating post-reader calls (capture/refund/reverse/incremental/tip adjust/receipt)
Use that guide as the canonical reference when wiring payments into your application.
Troubleshooting
Common Installation Issues
SDK Not Initialized Error
IllegalStateException: Instance is null. Did you forget to call initialize?
Solution: Ensure KoardMerchantSdk.initialize() is called in Application.onCreate() on a worker thread before accessing getInstance().
Thread Enforcement Error
Solution: All SDK operations must be called from a worker thread. Use Dispatchers.IO:
lifecycleScope.launch(Dispatchers.IO) {
// SDK operations here
}
Dependency Conflicts
Solution: Ensure you're using compatible versions of AndroidX and Kotlin libraries. Check for dependency conflicts with:
./gradlew app:dependencies
Build Errors
Solution:
- Verify you're using JDK 21
- Ensure minimum SDK is set to 31 (Android 12)
- Clean and rebuild:
./gradlew clean build
NFC Transactions Failing
Solution:
- Disable developer mode before running transactions - This is required for security
- Developer mode blocks tap to pay functionality
- Workflow: Enable dev mode → Install app → Disable dev mode → Run transactions
- Go to Settings > System > Developer Options and toggle OFF
- Restart device after disabling developer mode
Verification Checklist
- Android Studio Hedgehog or newer installed
- JDK 21 configured
- Minimum SDK set to 31 (Android 12)
- SDK dependency added to build.gradle.kts
- Application class created and registered
- SDK.initialize() called on worker thread
- NFC permissions added to manifest
- Project builds without errors
- Import statements work correctly
- Tap-to-pay kernel dependency installed on test device
- Physical device with NFC available for testing
- Aware of developer mode workflow (enable → install → disable → run transactions)
Next Steps
Once the SDK is installed and configured:
- Run the Demo App - Test SDK functionality with the demo application
- Authenticate Merchant - Set up merchant login
- Enable NFC Payments - Configure Tap to Pay on Android
- Running Payments - Implement tap-to-pay flows, surcharging, and post-reader actions
- Understand Payment Lifecycle - Learn about the complete payment flow
See also
This wraps up the SDK installation. See the links below for next steps in your integration:
- Demo App Setup - Run the demo application
- Merchant Authentication - Implement login
- Payment Lifecycle - Complete payment flow guide
- Android Best Practices - Android development guidelines
Best Practices
- Idempotency: Generate a unique
eventId(UUID) for every transaction mutation (sale, refund, adjust) and persist it with your POS records. - Threading: Always hop to
Dispatchers.IObefore calling any SDK method; return results to the main thread only after the call completes. - Environment Flavors: Mirror the demo’s
prod/uat/devflavors so each build points at the correct Koard environment and credential set. - Logging: Plant a
Timber.DebugTreein development builds. The SDK logs enrollment/transaction events viaKoardTimeEventLogger, which is invaluable when debugging device provisioning. - Device Re-provisioning: When wiping devices or reinstalling the tap-to-pay kernel app, call
refreshDeviceCertificates()to regenerate keys and rerun enrollment.