-
Notifications
You must be signed in to change notification settings - Fork 2
feat: sync with openiap v1.3.17 #33
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,72 @@ | ||
| --- | ||
| slug: 1.3.7 | ||
| title: 1.3.7 - OpenIAP 1.3.17 Sync | ||
| authors: [hyochan] | ||
| tags: [release, openiap, android, billing-library] | ||
| date: 2026-02-11 | ||
| --- | ||
|
|
||
| # 1.3.7 Release Notes | ||
|
|
||
| This release syncs with [OpenIAP v1.3.17](https://www.openiap.dev/docs/updates/notes#gql-1317), adding new types for Google Play Billing Library 5.0+ and 7.0+ features. | ||
|
|
||
| <!-- truncate --> | ||
|
|
||
| ## New Types | ||
|
|
||
| ### InstallmentPlanDetailsAndroid (Billing Library 7.0+) | ||
|
|
||
| Subscription installment plan details for plans that allow users to pay in installments. | ||
|
|
||
| ```kotlin | ||
| data class InstallmentPlanDetailsAndroid( | ||
| /** Committed payments count after signup (e.g., 12 monthly payments) */ | ||
| val commitmentPaymentsCount: Int, | ||
| /** Subsequent commitment payments when plan renews (0 if reverts to normal) */ | ||
| val subsequentCommitmentPaymentsCount: Int | ||
| ) | ||
| ``` | ||
|
|
||
| This is available on `ProductSubscriptionAndroidOfferDetails.installmentPlanDetails`. | ||
|
|
||
| ### PendingPurchaseUpdateAndroid (Billing Library 5.0+) | ||
|
|
||
| Details about pending subscription upgrades/downgrades. | ||
|
|
||
| ```kotlin | ||
| data class PendingPurchaseUpdateAndroid( | ||
| /** Product IDs for the pending purchase update */ | ||
| val products: List<String>, | ||
| /** Purchase token for the pending transaction */ | ||
| val purchaseToken: String | ||
| ) | ||
| ``` | ||
|
|
||
| This is available on `PurchaseAndroid.pendingPurchaseUpdateAndroid`. | ||
|
|
||
| ### purchaseOptionIdAndroid (Billing Library 7.0+) | ||
|
|
||
| New field on `DiscountOffer` and `ProductAndroidOneTimePurchaseOfferDetail` to identify which purchase option the user selected. | ||
|
|
||
| ```kotlin | ||
| // Available on DiscountOffer | ||
| discountOffer.purchaseOptionIdAndroid // String? | ||
| ``` | ||
|
|
||
| ## OpenIAP Versions | ||
|
|
||
| | Package | Version | | ||
| |---------|---------| | ||
| | openiap-gql | 1.3.17 | | ||
| | openiap-google | 1.3.28 | | ||
| | openiap-apple | 1.3.14 | | ||
|
|
||
| ## Installation | ||
|
|
||
| ```kotlin | ||
| implementation("io.github.hyochan:kmp-iap:1.3.7") | ||
| ``` | ||
|
|
||
| ## Related | ||
|
|
||
| - [OpenIAP Release Notes](https://www.openiap.dev/docs/updates/notes#gql-1317) | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -1486,6 +1486,12 @@ public data class DiscountOffer( | |
| * Numeric price value | ||
| */ | ||
| val price: Double, | ||
| /** | ||
| * [Android] Purchase option ID for this offer. | ||
| * Used to identify which purchase option the user selected. | ||
| * Available in Google Play Billing Library 7.0+ | ||
| */ | ||
| val purchaseOptionIdAndroid: String? = null, | ||
| /** | ||
| * [Android] Rental details if this is a rental offer. | ||
| */ | ||
|
|
@@ -1516,6 +1522,7 @@ public data class DiscountOffer( | |
| percentageDiscountAndroid = (json["percentageDiscountAndroid"] as? Number)?.toInt(), | ||
| preorderDetailsAndroid = (json["preorderDetailsAndroid"] as? Map<String, Any?>)?.let { PreorderDetailsAndroid.fromJson(it) }, | ||
| price = (json["price"] as? Number)?.toDouble() ?: 0.0, | ||
| purchaseOptionIdAndroid = json["purchaseOptionIdAndroid"] as? String, | ||
| rentalDetailsAndroid = (json["rentalDetailsAndroid"] as? Map<String, Any?>)?.let { RentalDetailsAndroid.fromJson(it) }, | ||
| type = (json["type"] as? String)?.let { DiscountOfferType.fromJson(it) } ?: DiscountOfferType.Introductory, | ||
| validTimeWindowAndroid = (json["validTimeWindowAndroid"] as? Map<String, Any?>)?.let { ValidTimeWindowAndroid.fromJson(it) }, | ||
|
|
@@ -1537,6 +1544,7 @@ public data class DiscountOffer( | |
| "percentageDiscountAndroid" to percentageDiscountAndroid, | ||
| "preorderDetailsAndroid" to preorderDetailsAndroid?.toJson(), | ||
| "price" to price, | ||
| "purchaseOptionIdAndroid" to purchaseOptionIdAndroid, | ||
| "rentalDetailsAndroid" to rentalDetailsAndroid?.toJson(), | ||
| "type" to type.toJson(), | ||
| "validTimeWindowAndroid" to validTimeWindowAndroid?.toJson(), | ||
|
|
@@ -1731,7 +1739,7 @@ public data class ExternalPurchaseCustomLinkTokenResultIOS( | |
| } | ||
|
|
||
| /** | ||
| * Result of presenting an external purchase link (iOS 17.4+) | ||
| * Result of presenting an external purchase link | ||
| */ | ||
| public data class ExternalPurchaseLinkResultIOS( | ||
| /** | ||
|
|
@@ -1807,6 +1815,43 @@ public data class FetchProductsResultProducts(val value: List<Product>?) : Fetch | |
|
|
||
| public data class FetchProductsResultSubscriptions(val value: List<ProductSubscription>?) : FetchProductsResult | ||
|
|
||
| /** | ||
| * Installment plan details for subscription offers (Android) | ||
| * Contains information about the installment plan commitment. | ||
| * Available in Google Play Billing Library 7.0+ | ||
| */ | ||
| public data class InstallmentPlanDetailsAndroid( | ||
| /** | ||
| * Committed payments count after a user signs up for this subscription plan. | ||
| * For example, for a monthly subscription with commitmentPaymentsCount of 12, | ||
| * users will be charged monthly for 12 months after signup. | ||
| */ | ||
| val commitmentPaymentsCount: Int, | ||
| /** | ||
| * Subsequent committed payments count after the subscription plan renews. | ||
| * For example, for a monthly subscription with subsequentCommitmentPaymentsCount of 12, | ||
| * users will be committed to another 12 monthly payments when the plan renews. | ||
| * Returns 0 if the installment plan has no subsequent commitment (reverts to normal plan). | ||
| */ | ||
| val subsequentCommitmentPaymentsCount: Int | ||
| ) { | ||
|
|
||
| companion object { | ||
| fun fromJson(json: Map<String, Any?>): InstallmentPlanDetailsAndroid { | ||
| return InstallmentPlanDetailsAndroid( | ||
| commitmentPaymentsCount = (json["commitmentPaymentsCount"] as? Number)?.toInt() ?: 0, | ||
| subsequentCommitmentPaymentsCount = (json["subsequentCommitmentPaymentsCount"] as? Number)?.toInt() ?: 0, | ||
| ) | ||
| } | ||
| } | ||
|
|
||
| fun toJson(): Map<String, Any?> = mapOf( | ||
| "__typename" to "InstallmentPlanDetailsAndroid", | ||
| "commitmentPaymentsCount" to commitmentPaymentsCount, | ||
| "subsequentCommitmentPaymentsCount" to subsequentCommitmentPaymentsCount, | ||
| ) | ||
| } | ||
|
|
||
| /** | ||
| * Limited quantity information for one-time purchase offers (Android) | ||
| * Available in Google Play Billing Library 7.0+ | ||
|
|
@@ -1838,6 +1883,42 @@ public data class LimitedQuantityInfoAndroid( | |
| ) | ||
| } | ||
|
|
||
| /** | ||
| * Pending purchase update for subscription upgrades/downgrades (Android) | ||
| * When a user initiates a subscription change (upgrade/downgrade), the new purchase | ||
| * may be pending until the current billing period ends. This type contains the | ||
| * details of the pending change. | ||
| * Available in Google Play Billing Library 5.0+ | ||
| */ | ||
| public data class PendingPurchaseUpdateAndroid( | ||
| /** | ||
| * Product IDs for the pending purchase update. | ||
| * These are the new products the user is switching to. | ||
| */ | ||
| val products: List<String>, | ||
| /** | ||
| * Purchase token for the pending transaction. | ||
| * Use this token to track or manage the pending purchase update. | ||
| */ | ||
| val purchaseToken: String | ||
| ) { | ||
|
|
||
| companion object { | ||
| fun fromJson(json: Map<String, Any?>): PendingPurchaseUpdateAndroid { | ||
| return PendingPurchaseUpdateAndroid( | ||
| products = (json["products"] as? List<*>)?.mapNotNull { it as? String } ?: emptyList(), | ||
| purchaseToken = json["purchaseToken"] as? String ?: "", | ||
| ) | ||
| } | ||
| } | ||
|
|
||
| fun toJson(): Map<String, Any?> = mapOf( | ||
| "__typename" to "PendingPurchaseUpdateAndroid", | ||
| "products" to products, | ||
| "purchaseToken" to purchaseToken, | ||
| ) | ||
| } | ||
|
Comment on lines
+1893
to
+1920
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The public data class PendingPurchaseUpdateAndroid(
/**
* Product IDs for the pending purchase update.
* These are the new products the user is switching to.
*/
val products: List<String>,
/**
* Purchase token for the pending transaction.
* Use this token to track or manage the pending purchase update.
*/
val purchaseToken: String?
) {
companion object {
fun fromJson(json: Map<String, Any?>): PendingPurchaseUpdateAndroid {
return PendingPurchaseUpdateAndroid(
products = (json["products"] as? List<*>)?.mapNotNull { it as? String } ?: emptyList(),
purchaseToken = json["purchaseToken"] as? String,
)
}
}
fun toJson(): Map<String, Any?> = mapOf(
"__typename" to "PendingPurchaseUpdateAndroid",
"products" to products,
"purchaseToken" to purchaseToken,
)
}
Owner
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This type is auto-generated from the OpenIAP GraphQL specification, where The OpenIAP spec follows Google Play Billing Library's contract where Changes to this type should be proposed upstream at the OpenIAP specification: https://github.com/hyodotdev/openiap.dev/discussions |
||
|
|
||
| /** | ||
| * Pre-order details for one-time purchase products (Android) | ||
| * Available in Google Play Billing Library 8.1.0+ | ||
|
|
@@ -2051,6 +2132,12 @@ public data class ProductAndroidOneTimePurchaseOfferDetail( | |
| val preorderDetailsAndroid: PreorderDetailsAndroid? = null, | ||
| val priceAmountMicros: String, | ||
| val priceCurrencyCode: String, | ||
| /** | ||
| * Purchase option ID for this offer (Android) | ||
| * Used to identify which purchase option the user selected. | ||
| * Available in Google Play Billing Library 7.0+ | ||
| */ | ||
| val purchaseOptionId: String? = null, | ||
| /** | ||
| * Rental details for rental offers | ||
| */ | ||
|
|
@@ -2074,6 +2161,7 @@ public data class ProductAndroidOneTimePurchaseOfferDetail( | |
| preorderDetailsAndroid = (json["preorderDetailsAndroid"] as? Map<String, Any?>)?.let { PreorderDetailsAndroid.fromJson(it) }, | ||
| priceAmountMicros = json["priceAmountMicros"] as? String ?: "", | ||
| priceCurrencyCode = json["priceCurrencyCode"] as? String ?: "", | ||
| purchaseOptionId = json["purchaseOptionId"] as? String, | ||
| rentalDetailsAndroid = (json["rentalDetailsAndroid"] as? Map<String, Any?>)?.let { RentalDetailsAndroid.fromJson(it) }, | ||
| validTimeWindow = (json["validTimeWindow"] as? Map<String, Any?>)?.let { ValidTimeWindowAndroid.fromJson(it) }, | ||
| ) | ||
|
|
@@ -2092,6 +2180,7 @@ public data class ProductAndroidOneTimePurchaseOfferDetail( | |
| "preorderDetailsAndroid" to preorderDetailsAndroid?.toJson(), | ||
| "priceAmountMicros" to priceAmountMicros, | ||
| "priceCurrencyCode" to priceCurrencyCode, | ||
| "purchaseOptionId" to purchaseOptionId, | ||
| "rentalDetailsAndroid" to rentalDetailsAndroid?.toJson(), | ||
| "validTimeWindow" to validTimeWindow?.toJson(), | ||
| ) | ||
|
|
@@ -2264,6 +2353,12 @@ public data class ProductSubscriptionAndroid( | |
| */ | ||
| public data class ProductSubscriptionAndroidOfferDetails( | ||
| val basePlanId: String, | ||
| /** | ||
| * Installment plan details for this subscription offer. | ||
| * Only set for installment subscription plans; null for non-installment plans. | ||
| * Available in Google Play Billing Library 7.0+ | ||
| */ | ||
| val installmentPlanDetails: InstallmentPlanDetailsAndroid? = null, | ||
| val offerId: String? = null, | ||
| val offerTags: List<String>, | ||
| val offerToken: String, | ||
|
|
@@ -2274,6 +2369,7 @@ public data class ProductSubscriptionAndroidOfferDetails( | |
| fun fromJson(json: Map<String, Any?>): ProductSubscriptionAndroidOfferDetails { | ||
| return ProductSubscriptionAndroidOfferDetails( | ||
| basePlanId = json["basePlanId"] as? String ?: "", | ||
| installmentPlanDetails = (json["installmentPlanDetails"] as? Map<String, Any?>)?.let { InstallmentPlanDetailsAndroid.fromJson(it) }, | ||
| offerId = json["offerId"] as? String, | ||
| offerTags = (json["offerTags"] as? List<*>)?.mapNotNull { it as? String } ?: emptyList(), | ||
| offerToken = json["offerToken"] as? String ?: "", | ||
|
|
@@ -2285,6 +2381,7 @@ public data class ProductSubscriptionAndroidOfferDetails( | |
| fun toJson(): Map<String, Any?> = mapOf( | ||
| "__typename" to "ProductSubscriptionAndroidOfferDetails", | ||
| "basePlanId" to basePlanId, | ||
| "installmentPlanDetails" to installmentPlanDetails?.toJson(), | ||
| "offerId" to offerId, | ||
| "offerTags" to offerTags, | ||
| "offerToken" to offerToken, | ||
|
|
@@ -2410,6 +2507,13 @@ public data class PurchaseAndroid( | |
| val obfuscatedAccountIdAndroid: String? = null, | ||
| val obfuscatedProfileIdAndroid: String? = null, | ||
| val packageNameAndroid: String? = null, | ||
| /** | ||
| * Pending purchase update for uncommitted subscription upgrade/downgrade (Android) | ||
| * Contains the new products and purchase token for the pending transaction. | ||
| * Returns null if no pending update exists. | ||
| * Available in Google Play Billing Library 5.0+ | ||
| */ | ||
| val pendingPurchaseUpdateAndroid: PendingPurchaseUpdateAndroid? = null, | ||
| override val platform: IapPlatform, | ||
| override val productId: String, | ||
| override val purchaseState: PurchaseState, | ||
|
|
@@ -2439,6 +2543,7 @@ public data class PurchaseAndroid( | |
| obfuscatedAccountIdAndroid = json["obfuscatedAccountIdAndroid"] as? String, | ||
| obfuscatedProfileIdAndroid = json["obfuscatedProfileIdAndroid"] as? String, | ||
| packageNameAndroid = json["packageNameAndroid"] as? String, | ||
| pendingPurchaseUpdateAndroid = (json["pendingPurchaseUpdateAndroid"] as? Map<String, Any?>)?.let { PendingPurchaseUpdateAndroid.fromJson(it) }, | ||
| platform = (json["platform"] as? String)?.let { IapPlatform.fromJson(it) } ?: IapPlatform.Ios, | ||
| productId = json["productId"] as? String ?: "", | ||
| purchaseState = (json["purchaseState"] as? String)?.let { PurchaseState.fromJson(it) } ?: PurchaseState.Pending, | ||
|
|
@@ -2466,6 +2571,7 @@ public data class PurchaseAndroid( | |
| "obfuscatedAccountIdAndroid" to obfuscatedAccountIdAndroid, | ||
| "obfuscatedProfileIdAndroid" to obfuscatedProfileIdAndroid, | ||
| "packageNameAndroid" to packageNameAndroid, | ||
| "pendingPurchaseUpdateAndroid" to pendingPurchaseUpdateAndroid?.toJson(), | ||
| "platform" to platform.toJson(), | ||
| "productId" to productId, | ||
| "purchaseState" to purchaseState.toJson(), | ||
|
|
@@ -2876,6 +2982,12 @@ public data class SubscriptionOffer( | |
| * - Android: offerId from ProductSubscriptionAndroidOfferDetails | ||
| */ | ||
| val id: String, | ||
| /** | ||
| * [Android] Installment plan details for this subscription offer. | ||
| * Only set for installment subscription plans; null for non-installment plans. | ||
| * Available in Google Play Billing Library 7.0+ | ||
| */ | ||
| val installmentPlanDetailsAndroid: InstallmentPlanDetailsAndroid? = null, | ||
| /** | ||
| * [iOS] Key identifier for signature validation. | ||
| * Used with server-side signature generation for promotional offers. | ||
|
|
@@ -2947,6 +3059,7 @@ public data class SubscriptionOffer( | |
| currency = json["currency"] as? String, | ||
| displayPrice = json["displayPrice"] as? String ?: "", | ||
| id = json["id"] as? String ?: "", | ||
| installmentPlanDetailsAndroid = (json["installmentPlanDetailsAndroid"] as? Map<String, Any?>)?.let { InstallmentPlanDetailsAndroid.fromJson(it) }, | ||
| keyIdentifierIOS = json["keyIdentifierIOS"] as? String, | ||
| localizedPriceIOS = json["localizedPriceIOS"] as? String, | ||
| nonceIOS = json["nonceIOS"] as? String, | ||
|
|
@@ -2971,6 +3084,7 @@ public data class SubscriptionOffer( | |
| "currency" to currency, | ||
| "displayPrice" to displayPrice, | ||
| "id" to id, | ||
| "installmentPlanDetailsAndroid" to installmentPlanDetailsAndroid?.toJson(), | ||
| "keyIdentifierIOS" to keyIdentifierIOS, | ||
| "localizedPriceIOS" to localizedPriceIOS, | ||
| "nonceIOS" to nonceIOS, | ||
|
|
@@ -4593,7 +4707,7 @@ public interface MutationResolver { | |
| */ | ||
| suspend fun presentCodeRedemptionSheetIOS(): Boolean | ||
| /** | ||
| * Present external purchase custom link with StoreKit UI (iOS 17.4+) | ||
| * Present external purchase custom link with StoreKit UI | ||
| */ | ||
| suspend fun presentExternalPurchaseLinkIOS(url: String): ExternalPurchaseLinkResultIOS | ||
| /** | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,6 +1,6 @@ | ||
| { | ||
| "apple": "1.3.14", | ||
| "google": "1.3.27", | ||
| "gql": "1.3.16", | ||
| "google": "1.3.28", | ||
| "gql": "1.3.17", | ||
| "kmp-iap": "1.3.6" | ||
| } |
Uh oh!
There was an error while loading. Please reload this page.