Complete Implementation
tip
The complete working example can be found at example/composeApp.
Flow Overview
Connect → Fetch Products → Request Purchase → Validate → Finish Transaction
Example Screens
| Screen | Description | Source |
|---|---|---|
| Purchase Flow | One-time purchases | PurchaseFlowScreen.kt |
| Subscription Flow | Recurring purchases | SubscriptionFlowScreen.kt |
Key Patterns
ViewModel with StateFlow
class StoreViewModel : ViewModel() {
private val _state = MutableStateFlow(StoreState())
val state: StateFlow<StoreState> = _state.asStateFlow()
init {
viewModelScope.launch {
kmpIapInstance.initConnection()
kmpIapInstance.purchaseUpdatedListener.collect { purchase ->
handlePurchase(purchase)
}
}
}
}
Product Configuration
object ProductConfig {
private val products = mapOf(
"coins_100" to ProductType.CONSUMABLE,
"remove_ads" to ProductType.NON_CONSUMABLE,
"premium_monthly" to ProductType.SUBSCRIPTION
)
fun isConsumable(productId: String) =
products[productId] == ProductType.CONSUMABLE
}
Error Recovery
when (error.code) {
ErrorCode.NetworkError -> retry(delay = 2000)
ErrorCode.AlreadyOwned -> restorePurchases()
else -> showError(error.message)
}
Security Best Practices
- Server-side validation - Always validate receipts on your backend
- Secure storage - Use platform-specific secure storage for sensitive data
- HTTPS only - All network requests must use TLS
- Code obfuscation - Enable R8/ProGuard for release builds
Resources
- Example App Source
- Purchase Flow - One-time purchases
- Subscription Flow - Recurring payments
