This release syncs with OpenIAP gql v1.3.15 / google v1.3.26 / apple v1.3.13.
New Features
One-Time Purchase Discounts (Android 7.0+)
Apply discount offers to one-time (non-subscription) purchases using the new offerToken field:
// Fetch products and get available discount offers
val products = kmpIapInstance.fetchProducts {
skus = listOf("premium_unlock")
type = ProductQueryType.InApp
}
val product = products.firstOrNull { it.id == "premium_unlock" }
// Check for available discount offers on one-time purchases
(product as? ProductAndroid)?.let { androidProduct ->
val discountOffer = androidProduct.oneTimePurchaseOfferDetailsAndroid
?.discountOffers
?.firstOrNull()
if (discountOffer != null) {
// Purchase with discount applied
kmpIapInstance.requestPurchase {
type = ProductType.InApp
android {
skus = listOf("premium_unlock")
offerToken = discountOffer.offerToken // Apply discount
}
}
}
}
Simplified Input Field Names
Input field names for Android-specific request props have been simplified by removing redundant Android suffixes. This follows the OpenIAP naming convention where input types inside platform-specific props don't need platform suffixes (they're already scoped to Android).
Migration Guide
RequestPurchaseAndroidProps:
| Old Name | New Name |
|---|---|
obfuscatedAccountIdAndroid | obfuscatedAccountId |
obfuscatedProfileIdAndroid | obfuscatedProfileId |
| - | offerToken (NEW) |
RequestSubscriptionAndroidProps:
| Old Name | New Name |
|---|---|
obfuscatedAccountIdAndroid | obfuscatedAccountId |
obfuscatedProfileIdAndroid | obfuscatedProfileId |
purchaseTokenAndroid | purchaseToken |
replacementModeAndroid | replacementMode |
Code Migration
If you're using the raw props directly:
// Before (1.3.2 and earlier)
RequestPurchaseAndroidProps(
skus = listOf("sku"),
obfuscatedAccountIdAndroid = "account-123",
obfuscatedProfileIdAndroid = "profile-456"
)
RequestSubscriptionAndroidProps(
skus = listOf("sub"),
purchaseTokenAndroid = "token",
replacementModeAndroid = 1,
obfuscatedAccountIdAndroid = "account-123",
obfuscatedProfileIdAndroid = "profile-456"
)
// After (1.3.4+)
RequestPurchaseAndroidProps(
skus = listOf("sku"),
obfuscatedAccountId = "account-123",
obfuscatedProfileId = "profile-456",
offerToken = "discount-token" // NEW: for one-time purchase discounts
)
RequestSubscriptionAndroidProps(
skus = listOf("sub"),
purchaseToken = "token",
replacementMode = 1,
obfuscatedAccountId = "account-123",
obfuscatedProfileId = "profile-456"
)
DSL Updates
The DSL builders have been updated with the new field names:
// Before (1.3.2 and earlier)
kmpIapInstance.requestPurchase {
android {
skus = listOf("sku")
obfuscatedAccountIdAndroid = "account-123"
obfuscatedProfileIdAndroid = "profile-456"
}
}
// After (1.3.4+)
kmpIapInstance.requestPurchase {
android {
skus = listOf("sku")
obfuscatedAccountId = "account-123"
obfuscatedProfileId = "profile-456"
offerToken = "discount-token"
}
}
OpenIAP Versions
| Package | Version |
|---|---|
| openiap-gql | 1.3.15 |
| openiap-google | 1.3.26 |
| openiap-apple | 1.3.13 |
Installation
implementation("io.github.hyochan:kmp-iap:1.3.4")
