Skip to content

Commit 5f8cf95

Browse files
hyochanclaude
andcommitted
feat: sync with openiap v1.3.17
- Update openiap-versions.json (gql: 1.3.17, apple: 1.3.14, google: 1.3.28) - Add InstallmentPlanDetailsAndroid class (Billing Library 7.0+) - Add PendingPurchaseUpdateAndroid class (Billing Library 5.0+) - Add purchaseOptionIdAndroid field to DiscountOffer (Billing Library 7.0+) - Update llms.txt with new type documentation - Add release blog post Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent c0aa063 commit 5f8cf95

File tree

4 files changed

+193
-2
lines changed

4 files changed

+193
-2
lines changed
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
---
2+
slug: 8.2.6
3+
title: 8.2.6 - OpenIAP 1.3.17 Sync
4+
authors: [hyochan]
5+
tags: [release, openiap, android, billing-library]
6+
date: 2026-02-11
7+
---
8+
9+
# 8.2.6 Release Notes
10+
11+
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.
12+
13+
<!-- truncate -->
14+
15+
## New Types
16+
17+
### InstallmentPlanDetailsAndroid (Billing Library 7.0+)
18+
19+
Subscription installment plan details for plans that allow users to pay in installments.
20+
21+
```dart
22+
class InstallmentPlanDetailsAndroid {
23+
/// Committed payments count after signup (e.g., 12 monthly payments)
24+
final int commitmentPaymentsCount;
25+
/// Subsequent commitment payments when plan renews (0 if reverts to normal)
26+
final int subsequentCommitmentPaymentsCount;
27+
}
28+
```
29+
30+
This is available on `ProductSubscriptionAndroidOfferDetails.installmentPlanDetails`.
31+
32+
### PendingPurchaseUpdateAndroid (Billing Library 5.0+)
33+
34+
Details about pending subscription upgrades/downgrades.
35+
36+
```dart
37+
class PendingPurchaseUpdateAndroid {
38+
/// Product IDs for the pending purchase update
39+
final List<String> products;
40+
/// Purchase token for the pending transaction
41+
final String purchaseToken;
42+
}
43+
```
44+
45+
This is available on `PurchaseAndroid.pendingPurchaseUpdateAndroid`.
46+
47+
### purchaseOptionIdAndroid (Billing Library 7.0+)
48+
49+
New field on `DiscountOffer` and `ProductAndroidOneTimePurchaseOfferDetail` to identify which purchase option the user selected.
50+
51+
```dart
52+
// Available on DiscountOffer
53+
discountOffer.purchaseOptionIdAndroid // String?
54+
```
55+
56+
## OpenIAP Versions
57+
58+
| Package | Version |
59+
|---------|---------|
60+
| openiap-gql | 1.3.17 |
61+
| openiap-google | 1.3.28 |
62+
| openiap-apple | 1.3.14 |
63+
64+
## Installation
65+
66+
```yaml
67+
dependencies:
68+
flutter_inapp_purchase: ^8.2.6
69+
```
70+
71+
## Related
72+
73+
- [OpenIAP Release Notes](https://www.openiap.dev/docs/updates/notes#gql-1317)

docs/static/llms.txt

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,19 @@ class DiscountOffer {
250250
String? offerTokenAndroid;
251251
int? percentageDiscountAndroid;
252252
String? discountAmountMicrosAndroid;
253+
String? purchaseOptionIdAndroid; // v8.2.6+, Billing Library 7.0+
254+
}
255+
256+
// Installment plan details (v8.2.6+, Billing Library 7.0+)
257+
class InstallmentPlanDetailsAndroid {
258+
int commitmentPaymentsCount; // Initial commitment (e.g., 12 months)
259+
int subsequentCommitmentPaymentsCount; // Renewal commitment
260+
}
261+
262+
// Pending subscription update (v8.2.6+, Billing Library 5.0+)
263+
class PendingPurchaseUpdateAndroid {
264+
List<String> products; // New products being switched to
265+
String purchaseToken; // Pending transaction token
253266
}
254267

255268
enum DiscountOfferType {

lib/types.dart

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1362,6 +1362,7 @@ class DiscountOffer {
13621362
this.percentageDiscountAndroid,
13631363
this.preorderDetailsAndroid,
13641364
required this.price,
1365+
this.purchaseOptionIdAndroid,
13651366
this.rentalDetailsAndroid,
13661367
required this.type,
13671368
this.validTimeWindowAndroid,
@@ -1400,6 +1401,10 @@ class DiscountOffer {
14001401
final PreorderDetailsAndroid? preorderDetailsAndroid;
14011402
/// Numeric price value
14021403
final double price;
1404+
/// [Android] Purchase option ID for this offer.
1405+
/// Used to identify which purchase option the user selected.
1406+
/// Available in Google Play Billing Library 7.0+
1407+
final String? purchaseOptionIdAndroid;
14031408
/// [Android] Rental details if this is a rental offer.
14041409
final RentalDetailsAndroid? rentalDetailsAndroid;
14051410
/// Type of discount offer
@@ -1422,6 +1427,7 @@ class DiscountOffer {
14221427
percentageDiscountAndroid: json['percentageDiscountAndroid'] as int?,
14231428
preorderDetailsAndroid: json['preorderDetailsAndroid'] != null ? PreorderDetailsAndroid.fromJson(json['preorderDetailsAndroid'] as Map<String, dynamic>) : null,
14241429
price: (json['price'] as num).toDouble(),
1430+
purchaseOptionIdAndroid: json['purchaseOptionIdAndroid'] as String?,
14251431
rentalDetailsAndroid: json['rentalDetailsAndroid'] != null ? RentalDetailsAndroid.fromJson(json['rentalDetailsAndroid'] as Map<String, dynamic>) : null,
14261432
type: DiscountOfferType.fromJson(json['type'] as String),
14271433
validTimeWindowAndroid: json['validTimeWindowAndroid'] != null ? ValidTimeWindowAndroid.fromJson(json['validTimeWindowAndroid'] as Map<String, dynamic>) : null,
@@ -1443,6 +1449,7 @@ class DiscountOffer {
14431449
'percentageDiscountAndroid': percentageDiscountAndroid,
14441450
'preorderDetailsAndroid': preorderDetailsAndroid?.toJson(),
14451451
'price': price,
1452+
'purchaseOptionIdAndroid': purchaseOptionIdAndroid,
14461453
'rentalDetailsAndroid': rentalDetailsAndroid?.toJson(),
14471454
'type': type.toJson(),
14481455
'validTimeWindowAndroid': validTimeWindowAndroid?.toJson(),
@@ -1714,6 +1721,41 @@ class FetchProductsResultSubscriptions extends FetchProductsResult {
17141721
final List<ProductSubscription>? value;
17151722
}
17161723

1724+
/// Installment plan details for subscription offers (Android)
1725+
/// Contains information about the installment plan commitment.
1726+
/// Available in Google Play Billing Library 7.0+
1727+
class InstallmentPlanDetailsAndroid {
1728+
const InstallmentPlanDetailsAndroid({
1729+
required this.commitmentPaymentsCount,
1730+
required this.subsequentCommitmentPaymentsCount,
1731+
});
1732+
1733+
/// Committed payments count after a user signs up for this subscription plan.
1734+
/// For example, for a monthly subscription with commitmentPaymentsCount of 12,
1735+
/// users will be charged monthly for 12 months after signup.
1736+
final int commitmentPaymentsCount;
1737+
/// Subsequent committed payments count after the subscription plan renews.
1738+
/// For example, for a monthly subscription with subsequentCommitmentPaymentsCount of 12,
1739+
/// users will be committed to another 12 monthly payments when the plan renews.
1740+
/// Returns 0 if the installment plan has no subsequent commitment (reverts to normal plan).
1741+
final int subsequentCommitmentPaymentsCount;
1742+
1743+
factory InstallmentPlanDetailsAndroid.fromJson(Map<String, dynamic> json) {
1744+
return InstallmentPlanDetailsAndroid(
1745+
commitmentPaymentsCount: json['commitmentPaymentsCount'] as int,
1746+
subsequentCommitmentPaymentsCount: json['subsequentCommitmentPaymentsCount'] as int,
1747+
);
1748+
}
1749+
1750+
Map<String, dynamic> toJson() {
1751+
return {
1752+
'__typename': 'InstallmentPlanDetailsAndroid',
1753+
'commitmentPaymentsCount': commitmentPaymentsCount,
1754+
'subsequentCommitmentPaymentsCount': subsequentCommitmentPaymentsCount,
1755+
};
1756+
}
1757+
}
1758+
17171759
/// Limited quantity information for one-time purchase offers (Android)
17181760
/// Available in Google Play Billing Library 7.0+
17191761
class LimitedQuantityInfoAndroid {
@@ -1743,6 +1785,40 @@ class LimitedQuantityInfoAndroid {
17431785
}
17441786
}
17451787

1788+
/// Pending purchase update for subscription upgrades/downgrades (Android)
1789+
/// When a user initiates a subscription change (upgrade/downgrade), the new purchase
1790+
/// may be pending until the current billing period ends. This type contains the
1791+
/// details of the pending change.
1792+
/// Available in Google Play Billing Library 5.0+
1793+
class PendingPurchaseUpdateAndroid {
1794+
const PendingPurchaseUpdateAndroid({
1795+
required this.products,
1796+
required this.purchaseToken,
1797+
});
1798+
1799+
/// Product IDs for the pending purchase update.
1800+
/// These are the new products the user is switching to.
1801+
final List<String> products;
1802+
/// Purchase token for the pending transaction.
1803+
/// Use this token to track or manage the pending purchase update.
1804+
final String purchaseToken;
1805+
1806+
factory PendingPurchaseUpdateAndroid.fromJson(Map<String, dynamic> json) {
1807+
return PendingPurchaseUpdateAndroid(
1808+
products: (json['products'] as List<dynamic>).map((e) => e as String).toList(),
1809+
purchaseToken: json['purchaseToken'] as String,
1810+
);
1811+
}
1812+
1813+
Map<String, dynamic> toJson() {
1814+
return {
1815+
'__typename': 'PendingPurchaseUpdateAndroid',
1816+
'products': products,
1817+
'purchaseToken': purchaseToken,
1818+
};
1819+
}
1820+
}
1821+
17461822
/// Pre-order details for one-time purchase products (Android)
17471823
/// Available in Google Play Billing Library 8.1.0+
17481824
class PreorderDetailsAndroid {
@@ -1949,6 +2025,7 @@ class ProductAndroidOneTimePurchaseOfferDetail {
19492025
this.preorderDetailsAndroid,
19502026
required this.priceAmountMicros,
19512027
required this.priceCurrencyCode,
2028+
this.purchaseOptionId,
19522029
this.rentalDetailsAndroid,
19532030
this.validTimeWindow,
19542031
});
@@ -1973,6 +2050,10 @@ class ProductAndroidOneTimePurchaseOfferDetail {
19732050
final PreorderDetailsAndroid? preorderDetailsAndroid;
19742051
final String priceAmountMicros;
19752052
final String priceCurrencyCode;
2053+
/// Purchase option ID for this offer (Android)
2054+
/// Used to identify which purchase option the user selected.
2055+
/// Available in Google Play Billing Library 7.0+
2056+
final String? purchaseOptionId;
19762057
/// Rental details for rental offers
19772058
final RentalDetailsAndroid? rentalDetailsAndroid;
19782059
/// Valid time window for the offer
@@ -1990,6 +2071,7 @@ class ProductAndroidOneTimePurchaseOfferDetail {
19902071
preorderDetailsAndroid: json['preorderDetailsAndroid'] != null ? PreorderDetailsAndroid.fromJson(json['preorderDetailsAndroid'] as Map<String, dynamic>) : null,
19912072
priceAmountMicros: json['priceAmountMicros'] as String,
19922073
priceCurrencyCode: json['priceCurrencyCode'] as String,
2074+
purchaseOptionId: json['purchaseOptionId'] as String?,
19932075
rentalDetailsAndroid: json['rentalDetailsAndroid'] != null ? RentalDetailsAndroid.fromJson(json['rentalDetailsAndroid'] as Map<String, dynamic>) : null,
19942076
validTimeWindow: json['validTimeWindow'] != null ? ValidTimeWindowAndroid.fromJson(json['validTimeWindow'] as Map<String, dynamic>) : null,
19952077
);
@@ -2008,6 +2090,7 @@ class ProductAndroidOneTimePurchaseOfferDetail {
20082090
'preorderDetailsAndroid': preorderDetailsAndroid?.toJson(),
20092091
'priceAmountMicros': priceAmountMicros,
20102092
'priceCurrencyCode': priceCurrencyCode,
2093+
'purchaseOptionId': purchaseOptionId,
20112094
'rentalDetailsAndroid': rentalDetailsAndroid?.toJson(),
20122095
'validTimeWindow': validTimeWindow?.toJson(),
20132096
};
@@ -2204,13 +2287,18 @@ class ProductSubscriptionAndroid extends ProductSubscription implements ProductC
22042287
class ProductSubscriptionAndroidOfferDetails {
22052288
const ProductSubscriptionAndroidOfferDetails({
22062289
required this.basePlanId,
2290+
this.installmentPlanDetails,
22072291
this.offerId,
22082292
required this.offerTags,
22092293
required this.offerToken,
22102294
required this.pricingPhases,
22112295
});
22122296

22132297
final String basePlanId;
2298+
/// Installment plan details for this subscription offer.
2299+
/// Only set for installment subscription plans; null for non-installment plans.
2300+
/// Available in Google Play Billing Library 7.0+
2301+
final InstallmentPlanDetailsAndroid? installmentPlanDetails;
22142302
final String? offerId;
22152303
final List<String> offerTags;
22162304
final String offerToken;
@@ -2219,6 +2307,7 @@ class ProductSubscriptionAndroidOfferDetails {
22192307
factory ProductSubscriptionAndroidOfferDetails.fromJson(Map<String, dynamic> json) {
22202308
return ProductSubscriptionAndroidOfferDetails(
22212309
basePlanId: json['basePlanId'] as String,
2310+
installmentPlanDetails: json['installmentPlanDetails'] != null ? InstallmentPlanDetailsAndroid.fromJson(json['installmentPlanDetails'] as Map<String, dynamic>) : null,
22222311
offerId: json['offerId'] as String?,
22232312
offerTags: (json['offerTags'] as List<dynamic>).map((e) => e as String).toList(),
22242313
offerToken: json['offerToken'] as String,
@@ -2230,6 +2319,7 @@ class ProductSubscriptionAndroidOfferDetails {
22302319
return {
22312320
'__typename': 'ProductSubscriptionAndroidOfferDetails',
22322321
'basePlanId': basePlanId,
2322+
'installmentPlanDetails': installmentPlanDetails?.toJson(),
22332323
'offerId': offerId,
22342324
'offerTags': offerTags,
22352325
'offerToken': offerToken,
@@ -2371,6 +2461,7 @@ class PurchaseAndroid extends Purchase implements PurchaseCommon {
23712461
this.obfuscatedAccountIdAndroid,
23722462
this.obfuscatedProfileIdAndroid,
23732463
this.packageNameAndroid,
2464+
this.pendingPurchaseUpdateAndroid,
23742465
required this.platform,
23752466
required this.productId,
23762467
required this.purchaseState,
@@ -2400,6 +2491,11 @@ class PurchaseAndroid extends Purchase implements PurchaseCommon {
24002491
final String? obfuscatedAccountIdAndroid;
24012492
final String? obfuscatedProfileIdAndroid;
24022493
final String? packageNameAndroid;
2494+
/// Pending purchase update for uncommitted subscription upgrade/downgrade (Android)
2495+
/// Contains the new products and purchase token for the pending transaction.
2496+
/// Returns null if no pending update exists.
2497+
/// Available in Google Play Billing Library 5.0+
2498+
final PendingPurchaseUpdateAndroid? pendingPurchaseUpdateAndroid;
24032499
final IapPlatform platform;
24042500
final String productId;
24052501
final PurchaseState purchaseState;
@@ -2426,6 +2522,7 @@ class PurchaseAndroid extends Purchase implements PurchaseCommon {
24262522
obfuscatedAccountIdAndroid: json['obfuscatedAccountIdAndroid'] as String?,
24272523
obfuscatedProfileIdAndroid: json['obfuscatedProfileIdAndroid'] as String?,
24282524
packageNameAndroid: json['packageNameAndroid'] as String?,
2525+
pendingPurchaseUpdateAndroid: json['pendingPurchaseUpdateAndroid'] != null ? PendingPurchaseUpdateAndroid.fromJson(json['pendingPurchaseUpdateAndroid'] as Map<String, dynamic>) : null,
24292526
platform: IapPlatform.fromJson(json['platform'] as String),
24302527
productId: json['productId'] as String,
24312528
purchaseState: PurchaseState.fromJson(json['purchaseState'] as String),
@@ -2455,6 +2552,7 @@ class PurchaseAndroid extends Purchase implements PurchaseCommon {
24552552
'obfuscatedAccountIdAndroid': obfuscatedAccountIdAndroid,
24562553
'obfuscatedProfileIdAndroid': obfuscatedProfileIdAndroid,
24572554
'packageNameAndroid': packageNameAndroid,
2555+
'pendingPurchaseUpdateAndroid': pendingPurchaseUpdateAndroid?.toJson(),
24582556
'platform': platform.toJson(),
24592557
'productId': productId,
24602558
'purchaseState': purchaseState.toJson(),
@@ -2912,6 +3010,7 @@ class SubscriptionOffer {
29123010
this.currency,
29133011
required this.displayPrice,
29143012
required this.id,
3013+
this.installmentPlanDetailsAndroid,
29153014
this.keyIdentifierIOS,
29163015
this.localizedPriceIOS,
29173016
this.nonceIOS,
@@ -2939,6 +3038,10 @@ class SubscriptionOffer {
29393038
/// - iOS: Discount identifier from App Store Connect
29403039
/// - Android: offerId from ProductSubscriptionAndroidOfferDetails
29413040
final String id;
3041+
/// [Android] Installment plan details for this subscription offer.
3042+
/// Only set for installment subscription plans; null for non-installment plans.
3043+
/// Available in Google Play Billing Library 7.0+
3044+
final InstallmentPlanDetailsAndroid? installmentPlanDetailsAndroid;
29423045
/// [iOS] Key identifier for signature validation.
29433046
/// Used with server-side signature generation for promotional offers.
29443047
final String? keyIdentifierIOS;
@@ -2980,6 +3083,7 @@ class SubscriptionOffer {
29803083
currency: json['currency'] as String?,
29813084
displayPrice: json['displayPrice'] as String,
29823085
id: json['id'] as String,
3086+
installmentPlanDetailsAndroid: json['installmentPlanDetailsAndroid'] != null ? InstallmentPlanDetailsAndroid.fromJson(json['installmentPlanDetailsAndroid'] as Map<String, dynamic>) : null,
29833087
keyIdentifierIOS: json['keyIdentifierIOS'] as String?,
29843088
localizedPriceIOS: json['localizedPriceIOS'] as String?,
29853089
nonceIOS: json['nonceIOS'] as String?,
@@ -3004,6 +3108,7 @@ class SubscriptionOffer {
30043108
'currency': currency,
30053109
'displayPrice': displayPrice,
30063110
'id': id,
3111+
'installmentPlanDetailsAndroid': installmentPlanDetailsAndroid?.toJson(),
30073112
'keyIdentifierIOS': keyIdentifierIOS,
30083113
'localizedPriceIOS': localizedPriceIOS,
30093114
'nonceIOS': nonceIOS,

openiap-versions.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
22
"apple": "1.3.14",
3-
"google": "1.3.27",
4-
"gql": "1.3.16"
3+
"google": "1.3.28",
4+
"gql": "1.3.17"
55
}

0 commit comments

Comments
 (0)