Demo
Setup
To run the demo app, you need to get the project and configure your API credentials:
Get the Demo Project
- Clone the Git repository:
https://github.com/koardlabs/koard-android.git - Or download the ZIP file
Open the Project in Android Studio
- Open Android Studio
- Select File > Open
- Navigate to the
koard-androidfolder and open it - Wait for Gradle sync to complete
The koard-android repository is fully standalone—no parent project or linked modules required. The demo app is the root Gradle module, and the SDK itself resolves from Maven Central as com.koard.
Configure Your Credentials
Open build.gradle.kts and set your API key for each build flavor via the API_KEY buildConfigField. The flavor's ENVIRONMENT field selects the matching KoardEnvironment at startup:
android {
flavorDimensions += "environment"
productFlavors {
create("uat") {
dimension = "environment"
isDefault = true
buildConfigField("String", "ENVIRONMENT", "\"UAT\"")
buildConfigField("String", "API_KEY", "\"YOUR_API_KEY\"")
applicationIdSuffix = ".uat"
}
create("prod") {
dimension = "environment"
buildConfigField("String", "ENVIRONMENT", "\"PROD\"")
buildConfigField("String", "API_KEY", "\"YOUR_API_KEY\"")
}
}
}
Replace YOUR_API_KEY with your Koard API key.
The merchant code and PIN are not build config values — you enter them on the demo's login screen at runtime, where they are passed to sdk.login(merchantCode, merchantPin). The active location is selected in-app after login.
Important: For production use, externalize these credentials using secure storage or environment variables. Never commit actual credentials to version control.
Select Build Flavor
The demo app has two build flavors:
| Flavor | API Environment | Application ID Suffix |
|---|---|---|
| uat | UAT/Testing (default) | .uat |
| prod | Production | (none) |
In Android Studio:
- Go to Build > Select Build Variant
- Choose your desired flavor (e.g.,
uatDebugfor testing)
There is no dev flavor. To point the demo at a development backend, switch the SDK to KoardEnvironment.Custom(...) in DemoApplication.
Build the Project
Build the project using one of these methods:
Via Android Studio:
- Click Build > Make Project (⌘+F9 / Ctrl+F9)
Via Command Line:
# Build UAT flavor
./gradlew assembleUatDebug
# Build production flavor
./gradlew assembleProdRelease
Install on Physical Device
Physical Device Required: Tap to Pay on Android requires a physical device with NFC hardware. The emulator does not support NFC payments.
Prerequisites:
- Physical Android device with NFC support (Android 12+)
- Tap-to-pay kernel app installed on the device (see the Running Payments guide)
- USB debugging enabled on the device
Install the app:
Via Android Studio:
- Connect your device via USB
- Click Run > Run 'app' (Shift+F10)
Via Command Line:
# Install UAT build
./gradlew installUatDebug
# Install production build
./gradlew installProdRelease
Running the Demo
Launch the App
Open the Koard Demo app on your device. You should see the main screen.
Authenticate Merchant
Enter your merchant code and PIN on the login screen — these are entered at runtime, not baked into the build — and submit. The demo calls sdk.login(merchantCode, merchantPin).
You will know authentication was successful if you see:
- The app navigates past the login screen
- The location selector and enrollment panel become available
Select Location
Tap the location selector in the top bar and choose your active location. The demo calls sdk.setActiveLocation(location.id) with your choice.
The selected location is used for all transactions, and enrollment cannot proceed without it.
Enroll the Device
Enrollment is not automatic. Nothing enrolls as a side effect of logging in or picking a location — you must press the button. Until enrollment completes, the demo's home screen shows the enrollment panel instead of the transaction form, and any tap API would throw KoardErrorType.NotReady.NotEnrolled.
While readinessState.enrollmentState is anything other than Enrolled, the demo's home screen renders an enrollment panel in place of the transaction form. Press Enroll Device to run sdk.enrollDevice().
Under the hood the demo:
- Checks the tap-to-pay kernel app is installed via
sdk.isKernelAppInstalled(), and surfaces "Visa Kernel app is not installed." if it isn't - Calls
sdk.enrollDevice(), which generates device certificates and enrolls the device with Koard's payment services - Treats the returned
Stringas an error message if it contains "failed" or "error", and catchesKoardExceptionfor typed failures
You will know enrollment was successful if you see:
- The enrollment panel is replaced by the transaction form
readinessState.enrollmentStatebecomesEnrolledand the reader status banner clears- NFC transactions can be initiated
Enrollment is rejected outright if developer mode is on, if no active location is set, or if the device is already enrolled. To re-enroll, use Unenroll Device on the Settings screen (which calls sdk.unenrollDevice()) first.
Disable Developer Mode
IMPORTANT: Turn Off Developer Mode
Before processing any tap to pay transactions, you MUST disable developer mode on your Android device:
- Go to Settings > System > Developer Options
- Toggle Developer Mode to OFF
- Restart your device (recommended)
Tap to Pay transactions will fail if developer mode is enabled. This is a security requirement from the payment processor.
Developer Workflow:
- Enable Developer Mode → Install/update app → Disable Developer Mode → Run transactions
Process Sample Transaction
Test a contactless payment:
- Tap Process Transaction or New Payment
- Enter a sample dollar amount (e.g., $10.00)
- Select transaction type (Sale or Preauth)
- Tap Start or Continue
Complete Tap to Pay Transaction
Complete the payment flow:
- Prompt the customer to tap their card or phone
- Hold the card/phone against the device's NFC reader
- Wait for the transaction to process
- View the transaction result (approved/declined)
Transaction details will include:
- Transaction ID
- Authorization code
- Card type and last 4 digits
- Amount charged
- Transaction status
View Transaction History
Navigate to Transaction History to:
- View all completed transactions
- Filter by date or status
- View detailed transaction information
- Send receipts via email or SMS
Demo App Features
The demo app showcases the following SDK capabilities:
Merchant Authentication
- Login with merchant code and PIN
- Session management
- Automatic token refresh
Device Enrollment
- NFC configuration with Koard's tap-to-pay services
- Certificate management
- Device provisioning status
Location Management
- Retrieve all merchant locations
- Select active location
- Location-based transaction processing
Transaction Processing
- Sale transactions (immediate capture)
- Preauthorization (auth hold)
- Capture (settle preauth)
- Refund processing
- Transaction reversal
- Tip adjustment
Transaction History
- List all transactions
- View transaction details
- Filter and search
- Transaction status tracking
Digital Receipts
- Send receipts via email
- Send receipts via SMS
- Receipt customization
Project Structure
The demo app structure:
koard-android/
├── src/
│ └── main/
│ ├── java/com/koard/android/
│ │ ├── DemoApplication.kt # SDK initialization
│ │ ├── MainActivity.kt # NFC register/unregister in onResume/onPause
│ │ ├── navigation/ # Tab navigation (History, Home, Settings)
│ │ └── ui/
│ │ ├── LoginScreen.kt / LoginViewModel.kt
│ │ ├── MainScreen.kt / MainScreenViewModel.kt
│ │ ├── SettingsScreen.kt
│ │ ├── TransactionDetailsScreen.kt
│ │ └── TransactionHistoryScreen.kt
│ ├── res/
│ │ └── xml/nfc_tech_filter.xml # IsoDep tech filter for TECH_DISCOVERED
│ └── AndroidManifest.xml
├── build.gradle.kts # Build configuration + SDK coordinate
├── settings.gradle.kts # google() + mavenCentral() only
└── README.md
SDK Integration
The demo resolves the SDK straight from Maven Central — there is no bundled AAR and no local repository to configure:
// build.gradle.kts
implementation("com.koard:koard-android-sdk:1.0.6")
The published artifact is a shaded fat AAR: it bundles the tap-to-pay engine (KiC) and relocates OkHttp, Okio, Retrofit, kotlinx.serialization, and Ktor under com.koardlabs.*, so those never clash with your app's own versions. It also means they are not transitive dependencies — see Installing the SDK for what you must declare yourself.
The environment (UAT vs. PROD) is chosen at runtime from the flavor's ENVIRONMENT buildConfigField, not by swapping artifacts:
- UAT builds →
KoardEnvironment.UAT - Prod builds →
KoardEnvironment.PROD
How the Demo Initializes the SDK
DemoApplication.onCreate() maps BuildConfig.ENVIRONMENT to a KoardEnvironment and initializes the SDK on a worker thread, passing the API key from BuildConfig:
val environment = when (BuildConfig.ENVIRONMENT) {
"PROD" -> KoardEnvironment.PROD
"UAT" -> KoardEnvironment.UAT
else -> KoardEnvironment.UAT
}
KoardMerchantSdk.initialize(
application = this@DemoApplication,
apiKey = BuildConfig.API_KEY,
environment = environment,
timeoutSeconds = 30L
)
Merchant credentials are supplied later, on the login screen, via sdk.login(merchantCode, merchantPin).
To shave first-tap latency, you can warm the reader up after init by collecting sdk.prepare() in the background and keying off the KoardPrepareStatus.Done emission. See Running Payments for details.
Build Commands Reference
# Clean build
./gradlew clean
# Build all flavors
./gradlew build
# Build specific flavor
./gradlew assembleUatDebug
./gradlew assembleProdRelease
# Install on device
./gradlew installUatDebug
./gradlew installProdRelease
# Uninstall from device
./gradlew uninstallUatDebug
./gradlew uninstallProd
# Run tests
./gradlew test
# Generate APK
./gradlew assembleDebug
./gradlew assembleRelease
Troubleshooting
Common Issues
App crashes on startup
Solution:
- Verify credentials are configured correctly in
build.gradle.kts - Check that you're not using placeholder values (YOUR_API_KEY_HERE)
- Review Logcat for specific error messages
"Device not provisioned" error
Solution:
- Ensure the tap-to-pay kernel app is installed (see the Running Payments guide for setup steps)
- Confirm you selected a location and then pressed Enroll Device — enrollment never runs on its own
- Check NFC hardware is functioning
- Verify the kernel app is up to date
NFC not working
Solution:
- Confirm device has NFC hardware
- Enable NFC in device settings
- Verify device enrollment was successful
- Test with a physical payment card
- IMPORTANT: Ensure developer mode is DISABLED on the device
"Transaction failed" or "NFC error" during tap to pay
Solution:
- Disable developer mode - This is the most common cause of transaction failures
- Go to Settings > System > Developer Options and toggle OFF
- Restart your device after disabling developer mode
- Ensure the tap-to-pay kernel app is running and up to date
- Check that NFC is enabled in device settings
Build errors
Solution:
- Verify JDK 21 is configured
- Check minimum SDK is set to 31
- Clean and rebuild:
./gradlew clean build - Invalidate caches: File > Invalidate Caches / Restart
Network errors
Solution:
- Check device has internet connection
- Verify API key and credentials are correct
- Ensure you're using the correct build flavor for your environment (uat/prod)
Debugging Tips
Enable verbose logging:
SDK log verbosity is set once, at initialization — there is no runtime setter. Pass a KoardLogLevel in DemoApplication.onCreate():
import com.koardlabs.merchant.sdk.domain.KoardLogLevel
KoardMerchantSdk.initialize(
application = this@DemoApplication,
apiKey = BuildConfig.API_KEY,
environment = environment,
timeoutSeconds = 30L,
logLevel = KoardLogLevel.VERBOSE
)
Levels are VERBOSE, DEBUG, INFO, WARN, ERROR, and NONE. The default is DEBUG in debug builds and NONE in release, and the level applies in release builds too if you opt in. Secrets — API key and token headers, device certificates, and enrollment key material — are never logged at any level.
Check Logcat:
The SDK logs under the fixed tag KoardSDK:
adb logcat -s KoardSDK
Verify SDK version:
Check which SDK version the demo is using:
./gradlew dependencies | grep koard
Security Notes
- Never commit actual credentials to version control
- Use environment variables or secure credential management for production
- The
build.gradle.ktscredentials are for demo purposes only - Consider using Android Keystore for sensitive data in production apps
- Keep the demo app on devices used exclusively for testing
Updating the SDK
Updating the SDK is a one-line change — bump the Maven coordinate in build.gradle.kts and rebuild:
implementation("com.koard:koard-android-sdk:<version>")
There is no AAR to download or copy: the artifact resolves from mavenCentral(), which settings.gradle.kts already declares.
1.0.6 changed bytecode signatures (initialize, getTransactions, and sale gained defaulted parameters) and replaced the leaked Visa ButtonProperties type with KoardButtonProperties. Always do a clean rebuild after bumping the version rather than dropping a new artifact onto pre-compiled call sites.
Next Steps
After running the demo app successfully:
- Install SDK in Your App - Integrate SDK into your own application, including login, location selection, and enrollment
- Running Payments - Drive tap-to-pay sessions and post-reader operations
- SDK Response Codes - Understand transaction outcomes, error codes, and error handling
- Payment Lifecycle - Understand payment flows
- Supported Devices & NFC Tap Location - Device compatibility and where to tap
- Troubleshooting - Fix enrollment failures and taps that cancel instantly
Support
For technical support or questions:
- Email: support@koard.com
- Documentation: https://docs.koard.com
- GitHub Issues: https://github.com/koardlabs/koard-android/issues

