KPayment
0.3.1indexedUnified type-safe API integrating Google Pay and Apple Pay, with reactive capability detection, Compose UI payment components, serializable tokens, robust error handling and thread-safe, production-ready state management.
Unified type-safe API integrating Google Pay and Apple Pay, with reactive capability detection, Compose UI payment components, serializable tokens, robust error handling and thread-safe, production-ready state management.
Quickstart • Installation • Samples • Documentation •
A Kotlin Multiplatform payment library with Compose Multiplatform UI components for Google Pay and Apple Pay across Android, iOS, and Web. One API, shared types, reactive availability detection, and platform-native payment buttons.
Apple Pay on Web works natively in Safari. On other browsers (Chrome, Firefox, Edge), the Apple Pay JS SDK enables a QR code flow where users scan with their iPhone to pay (iOS 18+).
// Mobile (Android / iOS)
val manager = rememberMobilePaymentManager(config)
val launcher = rememberNativePaymentLauncher { result ->
when (result) {
is PaymentResult.Success -> handleSuccess(result.token)
is PaymentResult.Error -> handleError(result)
PaymentResult.Cancelled -> { }
}
}
PaymentButton(enabled = isReady, onClick = { launcher.launch() })
manager = rememberWebPaymentManager(config)
applePay = rememberApplePayWebLauncher { result -> }
googlePay = rememberGooglePayWebLauncher { result -> }
Button(onClick = { applePay.launch() }) { Text() }
Ensure Maven Central is in your repositories, then add dependencies:
# libs.versions.toml
[versions]
kpayment = "0.1.0"
[libraries]
kpayment-core = { module = "com.kttipay:kpayment-core", version.ref = "kpayment" }
kpayment-mobile = { module = "com.kttipay:kpayment-mobile", version.ref = "kpayment" }
kpayment-web = { module = "com.kttipay:kpayment-web", version.ref = "kpayment" }
kotlin {
sourceSets {
commonMain.dependencies { implementation(libs.kpayment.core) }
androidMain.dependencies { implementation(libs.kpayment.mobile) }
iosMain.dependencies { implementation(libs.kpayment.mobile) }
jsMain.dependencies { implementation(libs.kpayment.web) }
wasmJsMain.dependencies { implementation(libs.kpayment.web) }
}
}
Android: No additional setup. Google Play Services Wallet is included.
iOS: Add "Apple Pay" capability in Xcode and configure your merchant ID.
Web: For cross-browser Apple Pay, add the JS SDK to your HTML <head>:
<script src="https://applepay.cdn-apple.com/jsapi/1.latest/apple-pay-sdk.js"
crossorigin="anonymous"></script>
// Google Pay
val googlePay = GooglePayConfig(
merchantId = "YOUR_MERCHANT_ID",
merchantName = "Your Store",
gateway = GatewayConfig.Stripe(publishableKey = "pk_live_...")
)
See Google Pay gateway configuration for FatZebra, Braintree, Adyen, and other gateways.
// Apple Pay (Mobile)
val applePayMobile = ApplePayMobileConfig(
merchantId = "merchant.com.yourcompany.app",
base = ApplePayBaseConfig(merchantName = "Your Store")
)
// Apple Pay (Web)
val applePayWeb = ApplePayWebConfig(
base = ApplePayBaseConfig(merchantName = "Your Store"),
merchantValidationEndpoint = "https://example.com/apple-pay/validate",
baseUrl = "https://example.com",
domain = "example.com",
enableJsSdk = true // cross-browser QR code flow (default)
)
// Reactive (recommended)
val isReady by manager.observeAvailability(PaymentProvider.GooglePay)
.collectAsState(initial = false)
Button(enabled = isReady, onClick = { launcher.launch("10.00") }) { Text("Pay") }
// Explicit check
val capabilities = manager.checkCapabilities()
when (capabilities.googlePay) {
CapabilityStatus.Ready -> { /* show button */ }
CapabilityStatus.Checking -> { /* loading */ }
CapabilityStatus.Error -> { }
-> { }
}
when (result) {
is PaymentResult.Success -> sendTokenToBackend(result.token)
is PaymentResult.Error -> {
when (result.reason) {
PaymentErrorReason.NetworkError -> showNetworkError()
PaymentErrorReason.NotAvailable -> showAlternativePayment()
PaymentErrorReason.AlreadyInProgress -> { /* disable button via launcher.isProcessing */ }
else -> showGenericError(result.message)
}
}
is PaymentResult.Cancelled -> { /* no action needed */ }
}
KPayment/
├── payment-core/ Shared interfaces, models, config, result types
├── payment-mobile/ Android (Google Pay) + iOS (Apple Pay) implementations
└── payment-web/ Web JS/WASM (Google Pay + Apple Pay) implementations
Each module has its own README with platform-specific details:
payment-core/README.mdpayment-mobile/README.mdpayment-web/README.md — includes Apple Pay JS SDK button options and cross-browser QR flowKPaymentLogger.enabled = true
KPaymentLogger.callback = object : KPaymentLogCallback {
override fun onLog(event: LogEvent) { println("[${event.tag}] ${event.message}") }
}
./gradlew sampleMobile:installDebug # Android
cd iosApp && pod install && open iosApp.xcworkspace # iOS
./gradlew sampleWeb:wasmJsBrowserDevelopmentRun # Web
./gradlew check)Report a bug | Development setup
Apache 2.0. See LICENSE.
Built with ❤️ using Kotlin Multiplatform
| Platform | Google Pay | Apple Pay | Compose UI |
|---|
| Android | ✅ | ❌ | ✅ |
| iOS | ❌ | ✅ | ✅ |
| Web (JS) | ✅ | ✅ | ✅ |
| WASM | ✅ | ✅ | ✅ |
| Reason | Suggested Action |
|---|
NetworkError | Check network, retry |
NotAvailable | Show alternative payment |
AlreadyInProgress | Disable button via launcher.isProcessing |
DeveloperError | Fix configuration |
Timeout | Retry after delay |
SignInRequired | Prompt sign-in |
Surfaced from shared tags and platforms — no rankings paid for.