KTQRam is a Kotlin Multiplatform (KMP) library designed for generating and managing EMV-compliant QR code payloads for merchant payment systems Currently, it supports Singapore's SGQR standard and PayNow extension.
- Kotlin Multiplatform: Supports JVM and Android (can be extended to iOS and other KMP targets).
- EMV Compliant: Generates QR payloads following the EMV specification for merchant-presented QR codes.
- Type-Safe Models: Robust data classes for Merchant Account Information, Transaction Details, and SGQR-specific identifiers.
- Validation: Ensures mandatory fields are present and data lengths comply with the specification.
- CRC Calculation: Automatic calculation of the 16-bit Cyclic Redundancy Check (CRC) required for valid QR payloads.
- Country Specific Extensions
- Specialized support for SGQR (Singapore Quick Response Code) and PayNow.
libs.version.toml
slightred-ktqram = { group = "sg.slightred", name = "ktqram-android", version = "1.0.0" }build.gradle.kts
dependencies {
implementation(libs.slightred.ktqram)
}or in build.gradle.kts
dependencies {
implementation("sg.slightred:ktqram:1.0.0")
}import sg.slightred.ktqram.domain.merchant.models.sgp.PayNow
import sg.slightred.ktqram.domain.merchant.enum.PointOfInit
import sg.slightred.ktqram.domain.merchant.enum.sgqr.PayNowProxyType
import sg.slightred.ktqram.domain.merchant.enum.sgqr.TxnAmountMutability
import kotlinx.datetime.LocalDateTime
// Create a PayNow object
val payNow = PayNow(
id = "1",
pointOfInit = PointOfInit.STATIC,
transactionAmount = "12.00",
proxyType = PayNowProxyType.UEN,
proxyValue = "202300000A",
txnAmountMutability = TxnAmountMutability.IMMUTABLE,
reference = "ORDER789"
)
val payNowWithExpiry = PayNow(
id = "2",
pointOfInit = PointOfInit.STATIC,
transactionAmount = "12.00",
proxyType = PayNowProxyType.UEN,
proxyValue = "202300000A",
txnAmountMutability = TxnAmountMutability.IMMUTABLE,
reference = "ORDER789",
expiryDateTime = "20250812"
)
// Generate the final QR payload string with CRC
val qrPayload = payNow.getQrPayloadWithCrc()
println(qrPayload)- SGQR: Support for SGQR ID info (Tag 51) including postal code, level, and unit numbers.
- PayNow: Support for PayNow specific data (Tag 36) including Proxy Type (Mobile/UEN), Proxy Value, Amount Mutability, and Expiry.
commonMain: Core logic, EMV base classes, and SGQR/PayNow implementations.androidMain/jvmMain: Platform-specific targets.
- Kotlin 2.4+
- Java 21+ (for JVM/Android targets)