From 74d04430cfa3334da5e413c8b87d7d7731d15319 Mon Sep 17 00:00:00 2001
From: hyochan
Date: Thu, 16 Apr 2026 23:01:34 +0900
Subject: [PATCH 1/6] feat: add AdvancedCommerceInfoIOS type and
getAllTransactionsIOS query
- Add AdvancedCommerceInfoIOS, AdvancedCommerceItemIOS, AdvancedCommerceItemDetailsIOS,
AdvancedCommerceRefundIOS types to GQL schema (iOS 18.4+)
- Add advancedCommerceInfoIOS field to PurchaseIOS for Advanced Commerce API metadata
- Add getAllTransactionsIOS query for consumable transaction history (iOS 18+)
- Implement Swift extraction of transaction.advancedCommerceInfo behind @available(iOS 18.4)
- Add ObjC bridge for getAllTransactionsIOS (kmp-iap interop)
- Add kmp-iap stubs (Android: emptyList, iOS: TODO pending pod publish)
- Regenerate and sync types to all platforms
- Recompile knowledge base
Co-Authored-By: Claude Opus 4.6 (1M context)
---
knowledge/_claude-context/context.md | 2 +-
libraries/expo-iap/src/types.ts | 64 +++++++
.../flutter_inapp_purchase/lib/types.dart | 156 +++++++++++++++
libraries/godot-iap/addons/godot-iap/types.gd | 179 ++++++++++++++++++
.../hyochan/kmpiap/InAppPurchaseAndroid.kt | 2 +
.../io/github/hyochan/kmpiap/openiap/Types.kt | 171 +++++++++++++++++
.../github/hyochan/kmpiap/InAppPurchaseIOS.kt | 3 +
libraries/react-native-iap/src/types.ts | 64 +++++++
.../Sources/Helpers/StoreKitTypesBridge.swift | 38 ++++
packages/apple/Sources/Models/Types.swift | 59 ++++++
.../apple/Sources/OpenIapModule+ObjC.swift | 12 ++
packages/apple/Sources/OpenIapModule.swift | 26 +++
packages/apple/Sources/OpenIapProtocol.swift | 1 +
.../OpenIapTests/VerifyPurchaseTests.swift | 1 +
.../VerifyPurchaseWithProviderTests.swift | 1 +
packages/docs/public/llms-full.txt | 2 +-
packages/docs/public/llms.txt | 2 +-
.../src/main/java/dev/hyo/openiap/Types.kt | 171 +++++++++++++++++
packages/gql/src/api-ios.graphql | 8 +
packages/gql/src/generated/Types.kt | 171 +++++++++++++++++
packages/gql/src/generated/Types.swift | 59 ++++++
packages/gql/src/generated/types.dart | 156 +++++++++++++++
packages/gql/src/generated/types.gd | 179 ++++++++++++++++++
packages/gql/src/generated/types.ts | 64 +++++++
packages/gql/src/type-ios.graphql | 92 +++++++++
25 files changed, 1680 insertions(+), 3 deletions(-)
diff --git a/knowledge/_claude-context/context.md b/knowledge/_claude-context/context.md
index 22cceeea..e90c018b 100644
--- a/knowledge/_claude-context/context.md
+++ b/knowledge/_claude-context/context.md
@@ -1,7 +1,7 @@
# OpenIAP Project Context
> **Auto-generated for Claude Code**
-> Last updated: 2026-04-16T13:24:54.898Z
+> Last updated: 2026-04-16T13:44:54.257Z
>
> Usage: `claude --context knowledge/_claude-context/context.md`
diff --git a/libraries/expo-iap/src/types.ts b/libraries/expo-iap/src/types.ts
index 9a4c0338..c533d922 100644
--- a/libraries/expo-iap/src/types.ts
+++ b/libraries/expo-iap/src/types.ts
@@ -36,6 +36,56 @@ export interface ActiveSubscription {
willExpireSoon?: (boolean | null);
}
+/**
+ * Advanced Commerce metadata from a transaction (iOS 18.4+).
+ * Contains item details, tax information, and refund data for purchases
+ * made through the Advanced Commerce API using generic SKUs.
+ * Only present for transactions that use the Advanced Commerce API.
+ */
+export interface AdvancedCommerceInfoIOS {
+ /** Optional description */
+ description?: (string | null);
+ /** Optional display name */
+ displayName?: (string | null);
+ /** Estimated tax amount (decimal string) */
+ estimatedTax?: (string | null);
+ /** The items purchased as part of this transaction */
+ items: AdvancedCommerceItemIOS[];
+ /** Request reference identifier for tracking */
+ requestReferenceId?: (string | null);
+ /** Tax code for the transaction */
+ taxCode?: (string | null);
+ /** Price excluding tax (decimal string) */
+ taxExclusivePrice?: (string | null);
+ /** Tax rate applied (decimal string) */
+ taxRate?: (string | null);
+}
+
+/** Details of an Advanced Commerce item (iOS 18.4+). */
+export interface AdvancedCommerceItemDetailsIOS {
+ /** JSON representation of the item details */
+ jsonRepresentation?: (string | null);
+}
+
+/**
+ * An item purchased through the Advanced Commerce API (iOS 18.4+).
+ * Represents a developer-defined product within a generic SKU transaction.
+ */
+export interface AdvancedCommerceItemIOS {
+ /** The item's detail information */
+ details?: (AdvancedCommerceItemDetailsIOS | null);
+ /** Refunds issued for this item, if any */
+ refunds?: (AdvancedCommerceRefundIOS[] | null);
+ /** Date access to this item was revoked (milliseconds since epoch) */
+ revocationDate?: (number | null);
+}
+
+/** Refund information for an Advanced Commerce item (iOS 18.4+). */
+export interface AdvancedCommerceRefundIOS {
+ /** JSON representation of the refund details */
+ jsonRepresentation?: (string | null);
+}
+
/**
* Alternative billing mode for Android
* Controls which billing system is used
@@ -1112,6 +1162,12 @@ export interface PurchaseError {
}
export interface PurchaseIOS extends PurchaseCommon {
+ /**
+ * Advanced Commerce API metadata (iOS 18.4+).
+ * Present only for transactions that use the Advanced Commerce API.
+ * Contains item details, tax information, and refund data for generic SKU purchases.
+ */
+ advancedCommerceInfoIOS?: (AdvancedCommerceInfoIOS | null);
appAccountToken?: (string | null);
appBundleIdIOS?: (string | null);
countryCodeIOS?: (string | null);
@@ -1188,6 +1244,13 @@ export interface Query {
fetchProducts: Promise<(ProductOrSubscription[] | Product[] | ProductSubscription[] | null)>;
/** Get active subscriptions (filters by subscriptionIds when provided) */
getActiveSubscriptions: Promise;
+ /**
+ * Get all transactions including finished consumables (iOS 18+).
+ * Requires the SK2ConsumableTransactionHistory Info.plist key in the host app.
+ * Returns all transactions from Transaction.all, including finished consumable
+ * transactions that would otherwise be excluded from getAvailablePurchases.
+ */
+ getAllTransactionsIOS: Promise;
/** Fetch the current app transaction (iOS 16+) */
getAppTransactionIOS?: Promise<(AppTransaction | null)>;
/** Get all available purchases for the current user */
@@ -1901,6 +1964,7 @@ export type QueryArgsMap = {
currentEntitlementIOS: QueryCurrentEntitlementIosArgs;
fetchProducts: QueryFetchProductsArgs;
getActiveSubscriptions: QueryGetActiveSubscriptionsArgs;
+ getAllTransactionsIOS: never;
getAppTransactionIOS: never;
getAvailablePurchases: QueryGetAvailablePurchasesArgs;
getExternalPurchaseCustomLinkTokenIOS: QueryGetExternalPurchaseCustomLinkTokenIosArgs;
diff --git a/libraries/flutter_inapp_purchase/lib/types.dart b/libraries/flutter_inapp_purchase/lib/types.dart
index 1b65274a..f6d9017f 100644
--- a/libraries/flutter_inapp_purchase/lib/types.dart
+++ b/libraries/flutter_inapp_purchase/lib/types.dart
@@ -1048,6 +1048,147 @@ class ActiveSubscription {
}
}
+/// Advanced Commerce metadata from a transaction (iOS 18.4+).
+/// Contains item details, tax information, and refund data for purchases
+/// made through the Advanced Commerce API using generic SKUs.
+/// Only present for transactions that use the Advanced Commerce API.
+class AdvancedCommerceInfoIOS {
+ const AdvancedCommerceInfoIOS({
+ this.description,
+ this.displayName,
+ this.estimatedTax,
+ required this.items,
+ this.requestReferenceId,
+ this.taxCode,
+ this.taxExclusivePrice,
+ this.taxRate,
+ });
+
+ /// Optional description
+ final String? description;
+ /// Optional display name
+ final String? displayName;
+ /// Estimated tax amount (decimal string)
+ final String? estimatedTax;
+ /// The items purchased as part of this transaction
+ final List items;
+ /// Request reference identifier for tracking
+ final String? requestReferenceId;
+ /// Tax code for the transaction
+ final String? taxCode;
+ /// Price excluding tax (decimal string)
+ final String? taxExclusivePrice;
+ /// Tax rate applied (decimal string)
+ final String? taxRate;
+
+ factory AdvancedCommerceInfoIOS.fromJson(Map json) {
+ return AdvancedCommerceInfoIOS(
+ description: json['description'] as String?,
+ displayName: json['displayName'] as String?,
+ estimatedTax: json['estimatedTax'] as String?,
+ items: (json['items'] as List).map((e) => AdvancedCommerceItemIOS.fromJson(e as Map)).toList(),
+ requestReferenceId: json['requestReferenceId'] as String?,
+ taxCode: json['taxCode'] as String?,
+ taxExclusivePrice: json['taxExclusivePrice'] as String?,
+ taxRate: json['taxRate'] as String?,
+ );
+ }
+
+ Map toJson() {
+ return {
+ '__typename': 'AdvancedCommerceInfoIOS',
+ 'description': description,
+ 'displayName': displayName,
+ 'estimatedTax': estimatedTax,
+ 'items': items.map((e) => e.toJson()).toList(),
+ 'requestReferenceId': requestReferenceId,
+ 'taxCode': taxCode,
+ 'taxExclusivePrice': taxExclusivePrice,
+ 'taxRate': taxRate,
+ };
+ }
+}
+
+/// Details of an Advanced Commerce item (iOS 18.4+).
+class AdvancedCommerceItemDetailsIOS {
+ const AdvancedCommerceItemDetailsIOS({
+ this.jsonRepresentation,
+ });
+
+ /// JSON representation of the item details
+ final String? jsonRepresentation;
+
+ factory AdvancedCommerceItemDetailsIOS.fromJson(Map json) {
+ return AdvancedCommerceItemDetailsIOS(
+ jsonRepresentation: json['jsonRepresentation'] as String?,
+ );
+ }
+
+ Map toJson() {
+ return {
+ '__typename': 'AdvancedCommerceItemDetailsIOS',
+ 'jsonRepresentation': jsonRepresentation,
+ };
+ }
+}
+
+/// An item purchased through the Advanced Commerce API (iOS 18.4+).
+/// Represents a developer-defined product within a generic SKU transaction.
+class AdvancedCommerceItemIOS {
+ const AdvancedCommerceItemIOS({
+ this.details,
+ this.refunds,
+ this.revocationDate,
+ });
+
+ /// The item's detail information
+ final AdvancedCommerceItemDetailsIOS? details;
+ /// Refunds issued for this item, if any
+ final List? refunds;
+ /// Date access to this item was revoked (milliseconds since epoch)
+ final double? revocationDate;
+
+ factory AdvancedCommerceItemIOS.fromJson(Map json) {
+ return AdvancedCommerceItemIOS(
+ details: json['details'] != null ? AdvancedCommerceItemDetailsIOS.fromJson(json['details'] as Map) : null,
+ refunds: (json['refunds'] as List?) == null ? null : (json['refunds'] as List?)!.map((e) => AdvancedCommerceRefundIOS.fromJson(e as Map)).toList(),
+ revocationDate: (json['revocationDate'] as num?)?.toDouble(),
+ );
+ }
+
+ Map toJson() {
+ return {
+ '__typename': 'AdvancedCommerceItemIOS',
+ 'details': details?.toJson(),
+ 'refunds': refunds == null ? null : refunds!.map((e) => e.toJson()).toList(),
+ 'revocationDate': revocationDate,
+ };
+ }
+}
+
+/// Refund information for an Advanced Commerce item (iOS 18.4+).
+class AdvancedCommerceRefundIOS {
+ const AdvancedCommerceRefundIOS({
+ this.jsonRepresentation,
+ });
+
+ /// JSON representation of the refund details
+ final String? jsonRepresentation;
+
+ factory AdvancedCommerceRefundIOS.fromJson(Map json) {
+ return AdvancedCommerceRefundIOS(
+ jsonRepresentation: json['jsonRepresentation'] as String?,
+ );
+ }
+
+ Map toJson() {
+ return {
+ '__typename': 'AdvancedCommerceRefundIOS',
+ 'jsonRepresentation': jsonRepresentation,
+ };
+ }
+}
+
class AppTransaction {
const AppTransaction({
required this.appId,
@@ -2612,6 +2753,7 @@ class PurchaseError {
class PurchaseIOS extends Purchase implements PurchaseCommon {
const PurchaseIOS({
+ this.advancedCommerceInfoIOS,
this.appAccountToken,
this.appBundleIdIOS,
this.countryCodeIOS,
@@ -2649,6 +2791,10 @@ class PurchaseIOS extends Purchase implements PurchaseCommon {
this.isAlternativeBilling,
});
+ /// Advanced Commerce API metadata (iOS 18.4+).
+ /// Present only for transactions that use the Advanced Commerce API.
+ /// Contains item details, tax information, and refund data for generic SKU purchases.
+ final AdvancedCommerceInfoIOS? advancedCommerceInfoIOS;
final String? appAccountToken;
final String? appBundleIdIOS;
final String? countryCodeIOS;
@@ -2688,6 +2834,7 @@ class PurchaseIOS extends Purchase implements PurchaseCommon {
factory PurchaseIOS.fromJson(Map json) {
return PurchaseIOS(
+ advancedCommerceInfoIOS: json['advancedCommerceInfoIOS'] != null ? AdvancedCommerceInfoIOS.fromJson(json['advancedCommerceInfoIOS'] as Map) : null,
appAccountToken: json['appAccountToken'] as String?,
appBundleIdIOS: json['appBundleIdIOS'] as String?,
countryCodeIOS: json['countryCodeIOS'] as String?,
@@ -2730,6 +2877,7 @@ class PurchaseIOS extends Purchase implements PurchaseCommon {
Map toJson() {
return {
'__typename': 'PurchaseIOS',
+ 'advancedCommerceInfoIOS': advancedCommerceInfoIOS?.toJson(),
'appAccountToken': appAccountToken,
'appBundleIdIOS': appBundleIdIOS,
'countryCodeIOS': countryCodeIOS,
@@ -4830,6 +4978,11 @@ abstract class QueryResolver {
});
/// Get active subscriptions (filters by subscriptionIds when provided)
Future> getActiveSubscriptions([List? subscriptionIds]);
+ /// Get all transactions including finished consumables (iOS 18+).
+ /// Requires the SK2ConsumableTransactionHistory Info.plist key in the host app.
+ /// Returns all transactions from Transaction.all, including finished consumable
+ /// transactions that would otherwise be excluded from getAvailablePurchases.
+ Future> getAllTransactionsIOS();
/// Fetch the current app transaction (iOS 16+)
Future getAppTransactionIOS();
/// Get all available purchases for the current user
@@ -5030,6 +5183,7 @@ typedef QueryFetchProductsHandler = Future Function({
ProductQueryType? type,
});
typedef QueryGetActiveSubscriptionsHandler = Future> Function([List? subscriptionIds]);
+typedef QueryGetAllTransactionsIOSHandler = Future> Function();
typedef QueryGetAppTransactionIOSHandler = Future Function();
typedef QueryGetAvailablePurchasesHandler = Future> Function({
bool? alsoPublishToEventListenerIOS,
@@ -5061,6 +5215,7 @@ class QueryHandlers {
this.currentEntitlementIOS,
this.fetchProducts,
this.getActiveSubscriptions,
+ this.getAllTransactionsIOS,
this.getAppTransactionIOS,
this.getAvailablePurchases,
this.getExternalPurchaseCustomLinkTokenIOS,
@@ -5083,6 +5238,7 @@ class QueryHandlers {
final QueryCurrentEntitlementIOSHandler? currentEntitlementIOS;
final QueryFetchProductsHandler? fetchProducts;
final QueryGetActiveSubscriptionsHandler? getActiveSubscriptions;
+ final QueryGetAllTransactionsIOSHandler? getAllTransactionsIOS;
final QueryGetAppTransactionIOSHandler? getAppTransactionIOS;
final QueryGetAvailablePurchasesHandler? getAvailablePurchases;
final QueryGetExternalPurchaseCustomLinkTokenIOSHandler? getExternalPurchaseCustomLinkTokenIOS;
diff --git a/libraries/godot-iap/addons/godot-iap/types.gd b/libraries/godot-iap/addons/godot-iap/types.gd
index 88dbdb17..e8ba7cdb 100644
--- a/libraries/godot-iap/addons/godot-iap/types.gd
+++ b/libraries/godot-iap/addons/godot-iap/types.gd
@@ -384,6 +384,161 @@ class ActiveSubscription:
dict["renewalInfoIOS"] = renewal_info_ios
return dict
+## Advanced Commerce metadata from a transaction (iOS 18.4+). Contains item details, tax information, and refund data for purchases made through the Advanced Commerce API using generic SKUs. Only present for transactions that use the Advanced Commerce API.
+class AdvancedCommerceInfoIOS:
+ ## The items purchased as part of this transaction
+ var items: Array[AdvancedCommerceItemIOS] = []
+ ## Request reference identifier for tracking
+ var request_reference_id: Variant = null
+ ## Tax code for the transaction
+ var tax_code: Variant = null
+ ## Price excluding tax (decimal string)
+ var tax_exclusive_price: Variant = null
+ ## Estimated tax amount (decimal string)
+ var estimated_tax: Variant = null
+ ## Tax rate applied (decimal string)
+ var tax_rate: Variant = null
+ ## Optional display name
+ var display_name: Variant = null
+ ## Optional description
+ var description: Variant = null
+
+ static func from_dict(data: Dictionary) -> AdvancedCommerceInfoIOS:
+ var obj = AdvancedCommerceInfoIOS.new()
+ if data.has("items") and data["items"] != null:
+ var arr = []
+ for item in data["items"]:
+ if item is Dictionary:
+ arr.append(AdvancedCommerceItemIOS.from_dict(item))
+ else:
+ arr.append(item)
+ obj.items = arr
+ if data.has("requestReferenceId") and data["requestReferenceId"] != null:
+ obj.request_reference_id = data["requestReferenceId"]
+ if data.has("taxCode") and data["taxCode"] != null:
+ obj.tax_code = data["taxCode"]
+ if data.has("taxExclusivePrice") and data["taxExclusivePrice"] != null:
+ obj.tax_exclusive_price = data["taxExclusivePrice"]
+ if data.has("estimatedTax") and data["estimatedTax"] != null:
+ obj.estimated_tax = data["estimatedTax"]
+ if data.has("taxRate") and data["taxRate"] != null:
+ obj.tax_rate = data["taxRate"]
+ if data.has("displayName") and data["displayName"] != null:
+ obj.display_name = data["displayName"]
+ if data.has("description") and data["description"] != null:
+ obj.description = data["description"]
+ return obj
+
+ func to_dict() -> Dictionary:
+ var dict = {}
+ if items != null:
+ var arr = []
+ for item in items:
+ if item != null and item.has_method("to_dict"):
+ arr.append(item.to_dict())
+ else:
+ arr.append(item)
+ dict["items"] = arr
+ else:
+ dict["items"] = null
+ if request_reference_id != null:
+ dict["requestReferenceId"] = request_reference_id
+ if tax_code != null:
+ dict["taxCode"] = tax_code
+ if tax_exclusive_price != null:
+ dict["taxExclusivePrice"] = tax_exclusive_price
+ if estimated_tax != null:
+ dict["estimatedTax"] = estimated_tax
+ if tax_rate != null:
+ dict["taxRate"] = tax_rate
+ if display_name != null:
+ dict["displayName"] = display_name
+ if description != null:
+ dict["description"] = description
+ return dict
+
+## Details of an Advanced Commerce item (iOS 18.4+).
+class AdvancedCommerceItemDetailsIOS:
+ ## JSON representation of the item details
+ var json_representation: Variant = null
+
+ static func from_dict(data: Dictionary) -> AdvancedCommerceItemDetailsIOS:
+ var obj = AdvancedCommerceItemDetailsIOS.new()
+ if data.has("jsonRepresentation") and data["jsonRepresentation"] != null:
+ obj.json_representation = data["jsonRepresentation"]
+ return obj
+
+ func to_dict() -> Dictionary:
+ var dict = {}
+ if json_representation != null:
+ dict["jsonRepresentation"] = json_representation
+ return dict
+
+## An item purchased through the Advanced Commerce API (iOS 18.4+). Represents a developer-defined product within a generic SKU transaction.
+class AdvancedCommerceItemIOS:
+ ## The item's detail information
+ var details: AdvancedCommerceItemDetailsIOS
+ ## Refunds issued for this item, if any
+ var refunds: Array[AdvancedCommerceRefundIOS] = []
+ ## Date access to this item was revoked (milliseconds since epoch)
+ var revocation_date: Variant = null
+
+ static func from_dict(data: Dictionary) -> AdvancedCommerceItemIOS:
+ var obj = AdvancedCommerceItemIOS.new()
+ if data.has("details") and data["details"] != null:
+ if data["details"] is Dictionary:
+ obj.details = AdvancedCommerceItemDetailsIOS.from_dict(data["details"])
+ else:
+ obj.details = data["details"]
+ if data.has("refunds") and data["refunds"] != null:
+ var arr = []
+ for item in data["refunds"]:
+ if item is Dictionary:
+ arr.append(AdvancedCommerceRefundIOS.from_dict(item))
+ else:
+ arr.append(item)
+ obj.refunds = arr
+ if data.has("revocationDate") and data["revocationDate"] != null:
+ obj.revocation_date = data["revocationDate"]
+ return obj
+
+ func to_dict() -> Dictionary:
+ var dict = {}
+ if details != null and details.has_method("to_dict"):
+ dict["details"] = details.to_dict()
+ else:
+ dict["details"] = details
+ if refunds != null:
+ var arr = []
+ for item in refunds:
+ if item != null and item.has_method("to_dict"):
+ arr.append(item.to_dict())
+ else:
+ arr.append(item)
+ dict["refunds"] = arr
+ else:
+ dict["refunds"] = null
+ if revocation_date != null:
+ dict["revocationDate"] = revocation_date
+ return dict
+
+## Refund information for an Advanced Commerce item (iOS 18.4+).
+class AdvancedCommerceRefundIOS:
+ ## JSON representation of the refund details
+ var json_representation: Variant = null
+
+ static func from_dict(data: Dictionary) -> AdvancedCommerceRefundIOS:
+ var obj = AdvancedCommerceRefundIOS.new()
+ if data.has("jsonRepresentation") and data["jsonRepresentation"] != null:
+ obj.json_representation = data["jsonRepresentation"]
+ return obj
+
+ func to_dict() -> Dictionary:
+ var dict = {}
+ if json_representation != null:
+ dict["jsonRepresentation"] = json_representation
+ return dict
+
class AppTransaction:
var bundle_id: String = ""
var app_version: String = ""
@@ -2130,6 +2285,8 @@ class PurchaseIOS:
var currency_symbol_ios: Variant = null
var country_code_ios: Variant = null
var renewal_info_ios: RenewalInfoIOS
+ ## Advanced Commerce API metadata (iOS 18.4+).
+ var advanced_commerce_info_ios: AdvancedCommerceInfoIOS
static func from_dict(data: Dictionary) -> PurchaseIOS:
var obj = PurchaseIOS.new()
@@ -2219,6 +2376,11 @@ class PurchaseIOS:
obj.renewal_info_ios = RenewalInfoIOS.from_dict(data["renewalInfoIOS"])
else:
obj.renewal_info_ios = data["renewalInfoIOS"]
+ if data.has("advancedCommerceInfoIOS") and data["advancedCommerceInfoIOS"] != null:
+ if data["advancedCommerceInfoIOS"] is Dictionary:
+ obj.advanced_commerce_info_ios = AdvancedCommerceInfoIOS.from_dict(data["advancedCommerceInfoIOS"])
+ else:
+ obj.advanced_commerce_info_ios = data["advancedCommerceInfoIOS"]
return obj
func to_dict() -> Dictionary:
@@ -2294,6 +2456,10 @@ class PurchaseIOS:
dict["renewalInfoIOS"] = renewal_info_ios.to_dict()
else:
dict["renewalInfoIOS"] = renewal_info_ios
+ if advanced_commerce_info_ios != null and advanced_commerce_info_ios.has_method("to_dict"):
+ dict["advancedCommerceInfoIOS"] = advanced_commerce_info_ios.to_dict()
+ else:
+ dict["advancedCommerceInfoIOS"] = advanced_commerce_info_ios
return dict
class PurchaseOfferIOS:
@@ -4934,6 +5100,15 @@ class Query:
const return_type = "AppTransaction"
const is_array = false
+ ## Get all transactions including finished consumables (iOS 18+).
+ class getAllTransactionsIOSField:
+ const name = "getAllTransactionsIOS"
+ const snake_name = "get_all_transactions_ios"
+ class Args:
+ pass
+ const return_type = "PurchaseIOS"
+ const is_array = true
+
## Validate a receipt for a specific product
class validateReceiptIOSField:
const name = "validateReceiptIOS"
@@ -5507,6 +5682,10 @@ static func get_receipt_data_ios_args() -> Dictionary:
static func get_app_transaction_ios_args() -> Dictionary:
return {}
+## Get all transactions including finished consumables (iOS 18+).
+static func get_all_transactions_ios_args() -> Dictionary:
+ return {}
+
## Validate a receipt for a specific product
static func validate_receipt_ios_args(options: VerifyPurchaseProps) -> Dictionary:
var args = {}
diff --git a/libraries/kmp-iap/library/src/androidMain/kotlin/io/github/hyochan/kmpiap/InAppPurchaseAndroid.kt b/libraries/kmp-iap/library/src/androidMain/kotlin/io/github/hyochan/kmpiap/InAppPurchaseAndroid.kt
index 224ee849..23ffe1f8 100644
--- a/libraries/kmp-iap/library/src/androidMain/kotlin/io/github/hyochan/kmpiap/InAppPurchaseAndroid.kt
+++ b/libraries/kmp-iap/library/src/androidMain/kotlin/io/github/hyochan/kmpiap/InAppPurchaseAndroid.kt
@@ -515,6 +515,8 @@ internal class InAppPurchaseAndroid : KmpInAppPurchase, Application.ActivityLife
override suspend fun getPendingTransactionsIOS(): List = emptyList()
+ override suspend fun getAllTransactionsIOS(): List = emptyList()
+
override suspend fun getReceiptDataIOS(): String? = null
override suspend fun getTransactionJwsIOS(sku: String): String? = null
diff --git a/libraries/kmp-iap/library/src/commonMain/kotlin/io/github/hyochan/kmpiap/openiap/Types.kt b/libraries/kmp-iap/library/src/commonMain/kotlin/io/github/hyochan/kmpiap/openiap/Types.kt
index 5ad6c0e7..0e2360bc 100644
--- a/libraries/kmp-iap/library/src/commonMain/kotlin/io/github/hyochan/kmpiap/openiap/Types.kt
+++ b/libraries/kmp-iap/library/src/commonMain/kotlin/io/github/hyochan/kmpiap/openiap/Types.kt
@@ -1171,6 +1171,160 @@ public data class ActiveSubscription(
)
}
+/**
+ * Advanced Commerce metadata from a transaction (iOS 18.4+).
+ * Contains item details, tax information, and refund data for purchases
+ * made through the Advanced Commerce API using generic SKUs.
+ * Only present for transactions that use the Advanced Commerce API.
+ */
+public data class AdvancedCommerceInfoIOS(
+ /**
+ * Optional description
+ */
+ val description: String? = null,
+ /**
+ * Optional display name
+ */
+ val displayName: String? = null,
+ /**
+ * Estimated tax amount (decimal string)
+ */
+ val estimatedTax: String? = null,
+ /**
+ * The items purchased as part of this transaction
+ */
+ val items: List,
+ /**
+ * Request reference identifier for tracking
+ */
+ val requestReferenceId: String? = null,
+ /**
+ * Tax code for the transaction
+ */
+ val taxCode: String? = null,
+ /**
+ * Price excluding tax (decimal string)
+ */
+ val taxExclusivePrice: String? = null,
+ /**
+ * Tax rate applied (decimal string)
+ */
+ val taxRate: String? = null
+) {
+
+ companion object {
+ fun fromJson(json: Map): AdvancedCommerceInfoIOS {
+ return AdvancedCommerceInfoIOS(
+ description = json["description"] as? String,
+ displayName = json["displayName"] as? String,
+ estimatedTax = json["estimatedTax"] as? String,
+ items = (json["items"] as? List<*>)?.mapNotNull { (it as? Map)?.let { AdvancedCommerceItemIOS.fromJson(it) } ?: throw IllegalArgumentException("Missing required object for AdvancedCommerceItemIOS") } ?: emptyList(),
+ requestReferenceId = json["requestReferenceId"] as? String,
+ taxCode = json["taxCode"] as? String,
+ taxExclusivePrice = json["taxExclusivePrice"] as? String,
+ taxRate = json["taxRate"] as? String,
+ )
+ }
+ }
+
+ fun toJson(): Map = mapOf(
+ "__typename" to "AdvancedCommerceInfoIOS",
+ "description" to description,
+ "displayName" to displayName,
+ "estimatedTax" to estimatedTax,
+ "items" to items.map { it.toJson() },
+ "requestReferenceId" to requestReferenceId,
+ "taxCode" to taxCode,
+ "taxExclusivePrice" to taxExclusivePrice,
+ "taxRate" to taxRate,
+ )
+}
+
+/**
+ * Details of an Advanced Commerce item (iOS 18.4+).
+ */
+public data class AdvancedCommerceItemDetailsIOS(
+ /**
+ * JSON representation of the item details
+ */
+ val jsonRepresentation: String? = null
+) {
+
+ companion object {
+ fun fromJson(json: Map): AdvancedCommerceItemDetailsIOS {
+ return AdvancedCommerceItemDetailsIOS(
+ jsonRepresentation = json["jsonRepresentation"] as? String,
+ )
+ }
+ }
+
+ fun toJson(): Map = mapOf(
+ "__typename" to "AdvancedCommerceItemDetailsIOS",
+ "jsonRepresentation" to jsonRepresentation,
+ )
+}
+
+/**
+ * An item purchased through the Advanced Commerce API (iOS 18.4+).
+ * Represents a developer-defined product within a generic SKU transaction.
+ */
+public data class AdvancedCommerceItemIOS(
+ /**
+ * The item's detail information
+ */
+ val details: AdvancedCommerceItemDetailsIOS? = null,
+ /**
+ * Refunds issued for this item, if any
+ */
+ val refunds: List? = null,
+ /**
+ * Date access to this item was revoked (milliseconds since epoch)
+ */
+ val revocationDate: Double? = null
+) {
+
+ companion object {
+ fun fromJson(json: Map): AdvancedCommerceItemIOS {
+ return AdvancedCommerceItemIOS(
+ details = (json["details"] as? Map)?.let { AdvancedCommerceItemDetailsIOS.fromJson(it) },
+ refunds = (json["refunds"] as? List<*>)?.mapNotNull { (it as? Map)?.let { AdvancedCommerceRefundIOS.fromJson(it) } ?: throw IllegalArgumentException("Missing required object for AdvancedCommerceRefundIOS") },
+ revocationDate = (json["revocationDate"] as? Number)?.toDouble(),
+ )
+ }
+ }
+
+ fun toJson(): Map = mapOf(
+ "__typename" to "AdvancedCommerceItemIOS",
+ "details" to details?.toJson(),
+ "refunds" to refunds?.map { it.toJson() },
+ "revocationDate" to revocationDate,
+ )
+}
+
+/**
+ * Refund information for an Advanced Commerce item (iOS 18.4+).
+ */
+public data class AdvancedCommerceRefundIOS(
+ /**
+ * JSON representation of the refund details
+ */
+ val jsonRepresentation: String? = null
+) {
+
+ companion object {
+ fun fromJson(json: Map): AdvancedCommerceRefundIOS {
+ return AdvancedCommerceRefundIOS(
+ jsonRepresentation = json["jsonRepresentation"] as? String,
+ )
+ }
+ }
+
+ fun toJson(): Map = mapOf(
+ "__typename" to "AdvancedCommerceRefundIOS",
+ "jsonRepresentation" to jsonRepresentation,
+ )
+}
+
public data class AppTransaction(
val appId: Double,
val appTransactionId: String? = null,
@@ -2656,6 +2810,12 @@ public data class PurchaseError(
}
public data class PurchaseIOS(
+ /**
+ * Advanced Commerce API metadata (iOS 18.4+).
+ * Present only for transactions that use the Advanced Commerce API.
+ * Contains item details, tax information, and refund data for generic SKU purchases.
+ */
+ val advancedCommerceInfoIOS: AdvancedCommerceInfoIOS? = null,
val appAccountToken: String? = null,
val appBundleIdIOS: String? = null,
val countryCodeIOS: String? = null,
@@ -2698,6 +2858,7 @@ public data class PurchaseIOS(
companion object {
fun fromJson(json: Map): PurchaseIOS {
return PurchaseIOS(
+ advancedCommerceInfoIOS = (json["advancedCommerceInfoIOS"] as? Map)?.let { AdvancedCommerceInfoIOS.fromJson(it) },
appAccountToken = json["appAccountToken"] as? String,
appBundleIdIOS = json["appBundleIdIOS"] as? String,
countryCodeIOS = json["countryCodeIOS"] as? String,
@@ -2738,6 +2899,7 @@ public data class PurchaseIOS(
override fun toJson(): Map = mapOf(
"__typename" to "PurchaseIOS",
+ "advancedCommerceInfoIOS" to advancedCommerceInfoIOS?.toJson(),
"appAccountToken" to appAccountToken,
"appBundleIdIOS" to appBundleIdIOS,
"countryCodeIOS" to countryCodeIOS,
@@ -4838,6 +5000,13 @@ public interface QueryResolver {
* Get active subscriptions (filters by subscriptionIds when provided)
*/
suspend fun getActiveSubscriptions(subscriptionIds: List? = null): List
+ /**
+ * Get all transactions including finished consumables (iOS 18+).
+ * Requires the SK2ConsumableTransactionHistory Info.plist key in the host app.
+ * Returns all transactions from Transaction.all, including finished consumable
+ * transactions that would otherwise be excluded from getAvailablePurchases.
+ */
+ suspend fun getAllTransactionsIOS(): List
/**
* Fetch the current app transaction (iOS 16+)
*/
@@ -5019,6 +5188,7 @@ public typealias QueryCanPresentExternalPurchaseNoticeIOSHandler = suspend () ->
public typealias QueryCurrentEntitlementIOSHandler = suspend (sku: String) -> PurchaseIOS?
public typealias QueryFetchProductsHandler = suspend (params: ProductRequest) -> FetchProductsResult
public typealias QueryGetActiveSubscriptionsHandler = suspend (subscriptionIds: List?) -> List
+public typealias QueryGetAllTransactionsIOSHandler = suspend () -> List
public typealias QueryGetAppTransactionIOSHandler = suspend () -> AppTransaction?
public typealias QueryGetAvailablePurchasesHandler = suspend (options: PurchaseOptions?) -> List
public typealias QueryGetExternalPurchaseCustomLinkTokenIOSHandler = suspend (tokenType: ExternalPurchaseCustomLinkTokenTypeIOS) -> ExternalPurchaseCustomLinkTokenResultIOS
@@ -5041,6 +5211,7 @@ public data class QueryHandlers(
val currentEntitlementIOS: QueryCurrentEntitlementIOSHandler? = null,
val fetchProducts: QueryFetchProductsHandler? = null,
val getActiveSubscriptions: QueryGetActiveSubscriptionsHandler? = null,
+ val getAllTransactionsIOS: QueryGetAllTransactionsIOSHandler? = null,
val getAppTransactionIOS: QueryGetAppTransactionIOSHandler? = null,
val getAvailablePurchases: QueryGetAvailablePurchasesHandler? = null,
val getExternalPurchaseCustomLinkTokenIOS: QueryGetExternalPurchaseCustomLinkTokenIOSHandler? = null,
diff --git a/libraries/kmp-iap/library/src/iosMain/kotlin/io/github/hyochan/kmpiap/InAppPurchaseIOS.kt b/libraries/kmp-iap/library/src/iosMain/kotlin/io/github/hyochan/kmpiap/InAppPurchaseIOS.kt
index e89d4dfa..462f5bfb 100644
--- a/libraries/kmp-iap/library/src/iosMain/kotlin/io/github/hyochan/kmpiap/InAppPurchaseIOS.kt
+++ b/libraries/kmp-iap/library/src/iosMain/kotlin/io/github/hyochan/kmpiap/InAppPurchaseIOS.kt
@@ -411,6 +411,9 @@ internal class InAppPurchaseIOS : KmpInAppPurchase {
}
}
+ // TODO: Wire to ObjC bridge after openiap-apple publishes getAllTransactionsIOSWithCompletion
+ override suspend fun getAllTransactionsIOS(): List = emptyList()
+
override suspend fun getReceiptDataIOS(): String? = suspendCoroutine { continuation ->
openIapModule.getReceiptDataIOSWithCompletion { result, error ->
if (error != null) {
diff --git a/libraries/react-native-iap/src/types.ts b/libraries/react-native-iap/src/types.ts
index 9a4c0338..c533d922 100644
--- a/libraries/react-native-iap/src/types.ts
+++ b/libraries/react-native-iap/src/types.ts
@@ -36,6 +36,56 @@ export interface ActiveSubscription {
willExpireSoon?: (boolean | null);
}
+/**
+ * Advanced Commerce metadata from a transaction (iOS 18.4+).
+ * Contains item details, tax information, and refund data for purchases
+ * made through the Advanced Commerce API using generic SKUs.
+ * Only present for transactions that use the Advanced Commerce API.
+ */
+export interface AdvancedCommerceInfoIOS {
+ /** Optional description */
+ description?: (string | null);
+ /** Optional display name */
+ displayName?: (string | null);
+ /** Estimated tax amount (decimal string) */
+ estimatedTax?: (string | null);
+ /** The items purchased as part of this transaction */
+ items: AdvancedCommerceItemIOS[];
+ /** Request reference identifier for tracking */
+ requestReferenceId?: (string | null);
+ /** Tax code for the transaction */
+ taxCode?: (string | null);
+ /** Price excluding tax (decimal string) */
+ taxExclusivePrice?: (string | null);
+ /** Tax rate applied (decimal string) */
+ taxRate?: (string | null);
+}
+
+/** Details of an Advanced Commerce item (iOS 18.4+). */
+export interface AdvancedCommerceItemDetailsIOS {
+ /** JSON representation of the item details */
+ jsonRepresentation?: (string | null);
+}
+
+/**
+ * An item purchased through the Advanced Commerce API (iOS 18.4+).
+ * Represents a developer-defined product within a generic SKU transaction.
+ */
+export interface AdvancedCommerceItemIOS {
+ /** The item's detail information */
+ details?: (AdvancedCommerceItemDetailsIOS | null);
+ /** Refunds issued for this item, if any */
+ refunds?: (AdvancedCommerceRefundIOS[] | null);
+ /** Date access to this item was revoked (milliseconds since epoch) */
+ revocationDate?: (number | null);
+}
+
+/** Refund information for an Advanced Commerce item (iOS 18.4+). */
+export interface AdvancedCommerceRefundIOS {
+ /** JSON representation of the refund details */
+ jsonRepresentation?: (string | null);
+}
+
/**
* Alternative billing mode for Android
* Controls which billing system is used
@@ -1112,6 +1162,12 @@ export interface PurchaseError {
}
export interface PurchaseIOS extends PurchaseCommon {
+ /**
+ * Advanced Commerce API metadata (iOS 18.4+).
+ * Present only for transactions that use the Advanced Commerce API.
+ * Contains item details, tax information, and refund data for generic SKU purchases.
+ */
+ advancedCommerceInfoIOS?: (AdvancedCommerceInfoIOS | null);
appAccountToken?: (string | null);
appBundleIdIOS?: (string | null);
countryCodeIOS?: (string | null);
@@ -1188,6 +1244,13 @@ export interface Query {
fetchProducts: Promise<(ProductOrSubscription[] | Product[] | ProductSubscription[] | null)>;
/** Get active subscriptions (filters by subscriptionIds when provided) */
getActiveSubscriptions: Promise;
+ /**
+ * Get all transactions including finished consumables (iOS 18+).
+ * Requires the SK2ConsumableTransactionHistory Info.plist key in the host app.
+ * Returns all transactions from Transaction.all, including finished consumable
+ * transactions that would otherwise be excluded from getAvailablePurchases.
+ */
+ getAllTransactionsIOS: Promise;
/** Fetch the current app transaction (iOS 16+) */
getAppTransactionIOS?: Promise<(AppTransaction | null)>;
/** Get all available purchases for the current user */
@@ -1901,6 +1964,7 @@ export type QueryArgsMap = {
currentEntitlementIOS: QueryCurrentEntitlementIosArgs;
fetchProducts: QueryFetchProductsArgs;
getActiveSubscriptions: QueryGetActiveSubscriptionsArgs;
+ getAllTransactionsIOS: never;
getAppTransactionIOS: never;
getAvailablePurchases: QueryGetAvailablePurchasesArgs;
getExternalPurchaseCustomLinkTokenIOS: QueryGetExternalPurchaseCustomLinkTokenIosArgs;
diff --git a/packages/apple/Sources/Helpers/StoreKitTypesBridge.swift b/packages/apple/Sources/Helpers/StoreKitTypesBridge.swift
index 85f28487..ba08e336 100644
--- a/packages/apple/Sources/Helpers/StoreKitTypesBridge.swift
+++ b/packages/apple/Sources/Helpers/StoreKitTypesBridge.swift
@@ -129,8 +129,10 @@ enum StoreKitTypesBridge {
let ownershipDescription = ownershipTypeDescription(from: transaction.ownershipType)
let reasonDetails = transactionReasonDetails(from: transaction)
+ let advancedCommerceInfo: AdvancedCommerceInfoIOS? = extractAdvancedCommerceInfo(from: transaction)
return PurchaseIOS(
+ advancedCommerceInfoIOS: advancedCommerceInfo,
appAccountToken: transaction.appAccountToken?.uuidString,
appBundleIdIOS: transaction.appBundleID,
countryCodeIOS: {
@@ -886,6 +888,42 @@ private extension StoreKitTypesBridge {
return TransactionReason(lowercased: "purchase", string: "purchase", uppercased: "PURCHASE")
}
+
+ // MARK: - Advanced Commerce Info (iOS 18.4+)
+
+ static func extractAdvancedCommerceInfo(from transaction: StoreKit.Transaction) -> AdvancedCommerceInfoIOS? {
+ #if swift(>=6.1)
+ if #available(iOS 18.4, macOS 15.4, tvOS 18.4, watchOS 11.4, visionOS 2.4, *) {
+ guard let info = transaction.advancedCommerceInfo else { return nil }
+ let items: [AdvancedCommerceItemIOS] = info.items.map { item in
+ let details = AdvancedCommerceItemDetailsIOS(
+ jsonRepresentation: String(data: item.details.jsonRepresentation, encoding: .utf8)
+ )
+ let refunds: [AdvancedCommerceRefundIOS]? = item.refunds?.map { refund in
+ AdvancedCommerceRefundIOS(
+ jsonRepresentation: String(data: refund.jsonRepresentation, encoding: .utf8)
+ )
+ }
+ return AdvancedCommerceItemIOS(
+ details: details,
+ refunds: refunds,
+ revocationDate: item.revocationDate?.milliseconds
+ )
+ }
+ return AdvancedCommerceInfoIOS(
+ description: info.description,
+ displayName: info.displayName,
+ estimatedTax: info.estimatedTax.map { "\($0)" },
+ items: items,
+ requestReferenceId: info.requestReferenceID,
+ taxCode: info.taxCode,
+ taxExclusivePrice: info.taxExclusivePrice.map { "\($0)" },
+ taxRate: info.taxRate.map { "\($0)" }
+ )
+ }
+ #endif
+ return nil
+ }
}
@available(iOS 15.0, macOS 14.0, tvOS 16.0, watchOS 8.0, *)
diff --git a/packages/apple/Sources/Models/Types.swift b/packages/apple/Sources/Models/Types.swift
index 39db135b..6a2226bb 100644
--- a/packages/apple/Sources/Models/Types.swift
+++ b/packages/apple/Sources/Models/Types.swift
@@ -488,6 +488,52 @@ public struct ActiveSubscription: Codable {
public var willExpireSoon: Bool? = nil
}
+/// Advanced Commerce metadata from a transaction (iOS 18.4+).
+/// Contains item details, tax information, and refund data for purchases
+/// made through the Advanced Commerce API using generic SKUs.
+/// Only present for transactions that use the Advanced Commerce API.
+public struct AdvancedCommerceInfoIOS: Codable {
+ /// Optional description
+ public var description: String? = nil
+ /// Optional display name
+ public var displayName: String? = nil
+ /// Estimated tax amount (decimal string)
+ public var estimatedTax: String? = nil
+ /// The items purchased as part of this transaction
+ public var items: [AdvancedCommerceItemIOS]
+ /// Request reference identifier for tracking
+ public var requestReferenceId: String? = nil
+ /// Tax code for the transaction
+ public var taxCode: String? = nil
+ /// Price excluding tax (decimal string)
+ public var taxExclusivePrice: String? = nil
+ /// Tax rate applied (decimal string)
+ public var taxRate: String? = nil
+}
+
+/// Details of an Advanced Commerce item (iOS 18.4+).
+public struct AdvancedCommerceItemDetailsIOS: Codable {
+ /// JSON representation of the item details
+ public var jsonRepresentation: String? = nil
+}
+
+/// An item purchased through the Advanced Commerce API (iOS 18.4+).
+/// Represents a developer-defined product within a generic SKU transaction.
+public struct AdvancedCommerceItemIOS: Codable {
+ /// The item's detail information
+ public var details: AdvancedCommerceItemDetailsIOS? = nil
+ /// Refunds issued for this item, if any
+ public var refunds: [AdvancedCommerceRefundIOS]? = nil
+ /// Date access to this item was revoked (milliseconds since epoch)
+ public var revocationDate: Double? = nil
+}
+
+/// Refund information for an Advanced Commerce item (iOS 18.4+).
+public struct AdvancedCommerceRefundIOS: Codable {
+ /// JSON representation of the refund details
+ public var jsonRepresentation: String? = nil
+}
+
public struct AppTransaction: Codable {
public var appId: Double
public var appTransactionId: String? = nil
@@ -995,6 +1041,10 @@ public struct PurchaseError: Codable {
}
public struct PurchaseIOS: Codable, PurchaseCommon {
+ /// Advanced Commerce API metadata (iOS 18.4+).
+ /// Present only for transactions that use the Advanced Commerce API.
+ /// Contains item details, tax information, and refund data for generic SKU purchases.
+ public var advancedCommerceInfoIOS: AdvancedCommerceInfoIOS? = nil
public var appAccountToken: String? = nil
public var appBundleIdIOS: String? = nil
public var countryCodeIOS: String? = nil
@@ -2388,6 +2438,11 @@ public protocol QueryResolver {
func fetchProducts(_ params: ProductRequest) async throws -> FetchProductsResult
/// Get active subscriptions (filters by subscriptionIds when provided)
func getActiveSubscriptions(_ subscriptionIds: [String]?) async throws -> [ActiveSubscription]
+ /// Get all transactions including finished consumables (iOS 18+).
+ /// Requires the SK2ConsumableTransactionHistory Info.plist key in the host app.
+ /// Returns all transactions from Transaction.all, including finished consumable
+ /// transactions that would otherwise be excluded from getAvailablePurchases.
+ func getAllTransactionsIOS() async throws -> [PurchaseIOS]
/// Fetch the current app transaction (iOS 16+)
func getAppTransactionIOS() async throws -> AppTransaction?
/// Get all available purchases for the current user
@@ -2579,6 +2634,7 @@ public typealias QueryCanPresentExternalPurchaseNoticeIOSHandler = () async thro
public typealias QueryCurrentEntitlementIOSHandler = (_ sku: String) async throws -> PurchaseIOS?
public typealias QueryFetchProductsHandler = (_ params: ProductRequest) async throws -> FetchProductsResult
public typealias QueryGetActiveSubscriptionsHandler = (_ subscriptionIds: [String]?) async throws -> [ActiveSubscription]
+public typealias QueryGetAllTransactionsIOSHandler = () async throws -> [PurchaseIOS]
public typealias QueryGetAppTransactionIOSHandler = () async throws -> AppTransaction?
public typealias QueryGetAvailablePurchasesHandler = (_ options: PurchaseOptions?) async throws -> [Purchase]
public typealias QueryGetExternalPurchaseCustomLinkTokenIOSHandler = (_ tokenType: ExternalPurchaseCustomLinkTokenTypeIOS) async throws -> ExternalPurchaseCustomLinkTokenResultIOS
@@ -2601,6 +2657,7 @@ public struct QueryHandlers {
public var currentEntitlementIOS: QueryCurrentEntitlementIOSHandler?
public var fetchProducts: QueryFetchProductsHandler?
public var getActiveSubscriptions: QueryGetActiveSubscriptionsHandler?
+ public var getAllTransactionsIOS: QueryGetAllTransactionsIOSHandler?
public var getAppTransactionIOS: QueryGetAppTransactionIOSHandler?
public var getAvailablePurchases: QueryGetAvailablePurchasesHandler?
public var getExternalPurchaseCustomLinkTokenIOS: QueryGetExternalPurchaseCustomLinkTokenIOSHandler?
@@ -2623,6 +2680,7 @@ public struct QueryHandlers {
currentEntitlementIOS: QueryCurrentEntitlementIOSHandler? = nil,
fetchProducts: QueryFetchProductsHandler? = nil,
getActiveSubscriptions: QueryGetActiveSubscriptionsHandler? = nil,
+ getAllTransactionsIOS: QueryGetAllTransactionsIOSHandler? = nil,
getAppTransactionIOS: QueryGetAppTransactionIOSHandler? = nil,
getAvailablePurchases: QueryGetAvailablePurchasesHandler? = nil,
getExternalPurchaseCustomLinkTokenIOS: QueryGetExternalPurchaseCustomLinkTokenIOSHandler? = nil,
@@ -2644,6 +2702,7 @@ public struct QueryHandlers {
self.currentEntitlementIOS = currentEntitlementIOS
self.fetchProducts = fetchProducts
self.getActiveSubscriptions = getActiveSubscriptions
+ self.getAllTransactionsIOS = getAllTransactionsIOS
self.getAppTransactionIOS = getAppTransactionIOS
self.getAvailablePurchases = getAvailablePurchases
self.getExternalPurchaseCustomLinkTokenIOS = getExternalPurchaseCustomLinkTokenIOS
diff --git a/packages/apple/Sources/OpenIapModule+ObjC.swift b/packages/apple/Sources/OpenIapModule+ObjC.swift
index 7d5270c1..cfa621ad 100644
--- a/packages/apple/Sources/OpenIapModule+ObjC.swift
+++ b/packages/apple/Sources/OpenIapModule+ObjC.swift
@@ -292,6 +292,18 @@ import StoreKit
}
}
+ @objc func getAllTransactionsIOSWithCompletion(_ completion: @escaping ([Any]?, Error?) -> Void) {
+ Task {
+ do {
+ let transactions = try await getAllTransactionsIOS()
+ let dictionaries = transactions.map { OpenIapSerialization.encode($0) }
+ completion(dictionaries, nil)
+ } catch {
+ completion(nil, error)
+ }
+ }
+ }
+
@objc func syncIOSWithCompletion(_ completion: @escaping (Bool, Error?) -> Void) {
Task {
do {
diff --git a/packages/apple/Sources/OpenIapModule.swift b/packages/apple/Sources/OpenIapModule.swift
index 9558a596..83fc71f0 100644
--- a/packages/apple/Sources/OpenIapModule.swift
+++ b/packages/apple/Sources/OpenIapModule.swift
@@ -503,6 +503,32 @@ public final class OpenIapModule: NSObject, OpenIapModuleProtocol {
return purchasedItems
}
+ /// Get all transactions including finished consumables (iOS 18+).
+ /// Requires the SK2ConsumableTransactionHistory Info.plist key in the host app.
+ /// Returns all transactions from Transaction.all, including finished consumable
+ /// transactions that would otherwise be excluded from getAvailablePurchases.
+ public func getAllTransactionsIOS() async throws -> [PurchaseIOS] {
+ try await ensureConnection()
+ var transactions: [PurchaseIOS] = []
+
+ for await verification in Transaction.all {
+ do {
+ let transaction = try checkVerified(verification)
+ let purchase = await StoreKitTypesBridge.purchaseIOS(
+ from: transaction,
+ jwsRepresentation: verification.jwsRepresentation
+ )
+ transactions.append(purchase)
+ } catch {
+ OpenIapLog.error("getAllTransactionsIOS: failed to verify transaction: \(error)")
+ continue
+ }
+ }
+
+ OpenIapLog.debug("🔍 getAllTransactionsIOS: \(transactions.count) transactions")
+ return transactions
+ }
+
// MARK: - Transaction Management
public func finishTransaction(purchase: PurchaseInput, isConsumable: Bool?) async throws -> Void {
diff --git a/packages/apple/Sources/OpenIapProtocol.swift b/packages/apple/Sources/OpenIapProtocol.swift
index 7540fe35..f1d7ac11 100644
--- a/packages/apple/Sources/OpenIapProtocol.swift
+++ b/packages/apple/Sources/OpenIapProtocol.swift
@@ -51,6 +51,7 @@ public protocol OpenIapModuleProtocol {
func requestPurchaseOnPromotedProductIOS() async throws -> Bool
func restorePurchases() async throws -> Void
func getAvailablePurchases(_ options: PurchaseOptions?) async throws -> [Purchase]
+ func getAllTransactionsIOS() async throws -> [PurchaseIOS]
// Transaction Management
func finishTransaction(purchase: PurchaseInput, isConsumable: Bool?) async throws -> Void
diff --git a/packages/apple/Tests/OpenIapTests/VerifyPurchaseTests.swift b/packages/apple/Tests/OpenIapTests/VerifyPurchaseTests.swift
index ad7b3f96..2018f9ef 100644
--- a/packages/apple/Tests/OpenIapTests/VerifyPurchaseTests.swift
+++ b/packages/apple/Tests/OpenIapTests/VerifyPurchaseTests.swift
@@ -87,6 +87,7 @@ private final class FakeOpenIapModule: OpenIapModuleProtocol {
func requestPurchaseOnPromotedProductIOS() async throws -> Bool { false }
func restorePurchases() async throws -> Void { () }
func getAvailablePurchases(_ options: PurchaseOptions?) async throws -> [Purchase] { [] }
+ func getAllTransactionsIOS() async throws -> [PurchaseIOS] { [] }
// MARK: - Transaction Management
func finishTransaction(purchase: PurchaseInput, isConsumable: Bool?) async throws -> Void { () }
diff --git a/packages/apple/Tests/OpenIapTests/VerifyPurchaseWithProviderTests.swift b/packages/apple/Tests/OpenIapTests/VerifyPurchaseWithProviderTests.swift
index ae247d5a..46f6d3f4 100644
--- a/packages/apple/Tests/OpenIapTests/VerifyPurchaseWithProviderTests.swift
+++ b/packages/apple/Tests/OpenIapTests/VerifyPurchaseWithProviderTests.swift
@@ -102,6 +102,7 @@ private final class FakeVerifyPurchaseModule: OpenIapModuleProtocol {
func requestPurchaseOnPromotedProductIOS() async throws -> Bool { false }
func restorePurchases() async throws -> Void { () }
func getAvailablePurchases(_ options: PurchaseOptions?) async throws -> [Purchase] { [] }
+ func getAllTransactionsIOS() async throws -> [PurchaseIOS] { [] }
// MARK: - Transaction Management
func finishTransaction(purchase: PurchaseInput, isConsumable: Bool?) async throws -> Void { () }
diff --git a/packages/docs/public/llms-full.txt b/packages/docs/public/llms-full.txt
index b3a4defa..f74aad0e 100644
--- a/packages/docs/public/llms-full.txt
+++ b/packages/docs/public/llms-full.txt
@@ -3,7 +3,7 @@
> OpenIAP: Unified in-app purchase specification for iOS & Android
> Documentation: https://openiap.dev
> Quick Reference: https://openiap.dev/llms.txt
-> Generated: 2026-04-16T13:24:54.944Z
+> Generated: 2026-04-16T13:44:54.268Z
## Table of Contents
1. Installation
diff --git a/packages/docs/public/llms.txt b/packages/docs/public/llms.txt
index c53fe836..9e68dfcc 100644
--- a/packages/docs/public/llms.txt
+++ b/packages/docs/public/llms.txt
@@ -3,7 +3,7 @@
> OpenIAP: Unified in-app purchase specification for iOS & Android
> Documentation: https://openiap.dev
> Full Reference: https://openiap.dev/llms-full.txt
-> Generated: 2026-04-16T13:24:54.944Z
+> Generated: 2026-04-16T13:44:54.268Z
## Installation
diff --git a/packages/google/openiap/src/main/java/dev/hyo/openiap/Types.kt b/packages/google/openiap/src/main/java/dev/hyo/openiap/Types.kt
index 7326529f..fb66460d 100644
--- a/packages/google/openiap/src/main/java/dev/hyo/openiap/Types.kt
+++ b/packages/google/openiap/src/main/java/dev/hyo/openiap/Types.kt
@@ -1080,6 +1080,160 @@ public data class ActiveSubscription(
)
}
+/**
+ * Advanced Commerce metadata from a transaction (iOS 18.4+).
+ * Contains item details, tax information, and refund data for purchases
+ * made through the Advanced Commerce API using generic SKUs.
+ * Only present for transactions that use the Advanced Commerce API.
+ */
+public data class AdvancedCommerceInfoIOS(
+ /**
+ * Optional description
+ */
+ val description: String? = null,
+ /**
+ * Optional display name
+ */
+ val displayName: String? = null,
+ /**
+ * Estimated tax amount (decimal string)
+ */
+ val estimatedTax: String? = null,
+ /**
+ * The items purchased as part of this transaction
+ */
+ val items: List,
+ /**
+ * Request reference identifier for tracking
+ */
+ val requestReferenceId: String? = null,
+ /**
+ * Tax code for the transaction
+ */
+ val taxCode: String? = null,
+ /**
+ * Price excluding tax (decimal string)
+ */
+ val taxExclusivePrice: String? = null,
+ /**
+ * Tax rate applied (decimal string)
+ */
+ val taxRate: String? = null
+) {
+
+ companion object {
+ fun fromJson(json: Map): AdvancedCommerceInfoIOS {
+ return AdvancedCommerceInfoIOS(
+ description = json["description"] as? String,
+ displayName = json["displayName"] as? String,
+ estimatedTax = json["estimatedTax"] as? String,
+ items = (json["items"] as? List<*>)?.mapNotNull { (it as? Map)?.let { AdvancedCommerceItemIOS.fromJson(it) } ?: throw IllegalArgumentException("Missing required object for AdvancedCommerceItemIOS") } ?: emptyList(),
+ requestReferenceId = json["requestReferenceId"] as? String,
+ taxCode = json["taxCode"] as? String,
+ taxExclusivePrice = json["taxExclusivePrice"] as? String,
+ taxRate = json["taxRate"] as? String,
+ )
+ }
+ }
+
+ fun toJson(): Map = mapOf(
+ "__typename" to "AdvancedCommerceInfoIOS",
+ "description" to description,
+ "displayName" to displayName,
+ "estimatedTax" to estimatedTax,
+ "items" to items.map { it.toJson() },
+ "requestReferenceId" to requestReferenceId,
+ "taxCode" to taxCode,
+ "taxExclusivePrice" to taxExclusivePrice,
+ "taxRate" to taxRate,
+ )
+}
+
+/**
+ * Details of an Advanced Commerce item (iOS 18.4+).
+ */
+public data class AdvancedCommerceItemDetailsIOS(
+ /**
+ * JSON representation of the item details
+ */
+ val jsonRepresentation: String? = null
+) {
+
+ companion object {
+ fun fromJson(json: Map): AdvancedCommerceItemDetailsIOS {
+ return AdvancedCommerceItemDetailsIOS(
+ jsonRepresentation = json["jsonRepresentation"] as? String,
+ )
+ }
+ }
+
+ fun toJson(): Map = mapOf(
+ "__typename" to "AdvancedCommerceItemDetailsIOS",
+ "jsonRepresentation" to jsonRepresentation,
+ )
+}
+
+/**
+ * An item purchased through the Advanced Commerce API (iOS 18.4+).
+ * Represents a developer-defined product within a generic SKU transaction.
+ */
+public data class AdvancedCommerceItemIOS(
+ /**
+ * The item's detail information
+ */
+ val details: AdvancedCommerceItemDetailsIOS? = null,
+ /**
+ * Refunds issued for this item, if any
+ */
+ val refunds: List? = null,
+ /**
+ * Date access to this item was revoked (milliseconds since epoch)
+ */
+ val revocationDate: Double? = null
+) {
+
+ companion object {
+ fun fromJson(json: Map): AdvancedCommerceItemIOS {
+ return AdvancedCommerceItemIOS(
+ details = (json["details"] as? Map)?.let { AdvancedCommerceItemDetailsIOS.fromJson(it) },
+ refunds = (json["refunds"] as? List<*>)?.mapNotNull { (it as? Map)?.let { AdvancedCommerceRefundIOS.fromJson(it) } ?: throw IllegalArgumentException("Missing required object for AdvancedCommerceRefundIOS") },
+ revocationDate = (json["revocationDate"] as? Number)?.toDouble(),
+ )
+ }
+ }
+
+ fun toJson(): Map = mapOf(
+ "__typename" to "AdvancedCommerceItemIOS",
+ "details" to details?.toJson(),
+ "refunds" to refunds?.map { it.toJson() },
+ "revocationDate" to revocationDate,
+ )
+}
+
+/**
+ * Refund information for an Advanced Commerce item (iOS 18.4+).
+ */
+public data class AdvancedCommerceRefundIOS(
+ /**
+ * JSON representation of the refund details
+ */
+ val jsonRepresentation: String? = null
+) {
+
+ companion object {
+ fun fromJson(json: Map): AdvancedCommerceRefundIOS {
+ return AdvancedCommerceRefundIOS(
+ jsonRepresentation = json["jsonRepresentation"] as? String,
+ )
+ }
+ }
+
+ fun toJson(): Map = mapOf(
+ "__typename" to "AdvancedCommerceRefundIOS",
+ "jsonRepresentation" to jsonRepresentation,
+ )
+}
+
public data class AppTransaction(
val appId: Double,
val appTransactionId: String? = null,
@@ -2565,6 +2719,12 @@ public data class PurchaseError(
}
public data class PurchaseIOS(
+ /**
+ * Advanced Commerce API metadata (iOS 18.4+).
+ * Present only for transactions that use the Advanced Commerce API.
+ * Contains item details, tax information, and refund data for generic SKU purchases.
+ */
+ val advancedCommerceInfoIOS: AdvancedCommerceInfoIOS? = null,
val appAccountToken: String? = null,
val appBundleIdIOS: String? = null,
val countryCodeIOS: String? = null,
@@ -2607,6 +2767,7 @@ public data class PurchaseIOS(
companion object {
fun fromJson(json: Map): PurchaseIOS {
return PurchaseIOS(
+ advancedCommerceInfoIOS = (json["advancedCommerceInfoIOS"] as? Map)?.let { AdvancedCommerceInfoIOS.fromJson(it) },
appAccountToken = json["appAccountToken"] as? String,
appBundleIdIOS = json["appBundleIdIOS"] as? String,
countryCodeIOS = json["countryCodeIOS"] as? String,
@@ -2647,6 +2808,7 @@ public data class PurchaseIOS(
override fun toJson(): Map = mapOf(
"__typename" to "PurchaseIOS",
+ "advancedCommerceInfoIOS" to advancedCommerceInfoIOS?.toJson(),
"appAccountToken" to appAccountToken,
"appBundleIdIOS" to appBundleIdIOS,
"countryCodeIOS" to countryCodeIOS,
@@ -4747,6 +4909,13 @@ public interface QueryResolver {
* Get active subscriptions (filters by subscriptionIds when provided)
*/
suspend fun getActiveSubscriptions(subscriptionIds: List? = null): List
+ /**
+ * Get all transactions including finished consumables (iOS 18+).
+ * Requires the SK2ConsumableTransactionHistory Info.plist key in the host app.
+ * Returns all transactions from Transaction.all, including finished consumable
+ * transactions that would otherwise be excluded from getAvailablePurchases.
+ */
+ suspend fun getAllTransactionsIOS(): List
/**
* Fetch the current app transaction (iOS 16+)
*/
@@ -4928,6 +5097,7 @@ public typealias QueryCanPresentExternalPurchaseNoticeIOSHandler = suspend () ->
public typealias QueryCurrentEntitlementIOSHandler = suspend (sku: String) -> PurchaseIOS?
public typealias QueryFetchProductsHandler = suspend (params: ProductRequest) -> FetchProductsResult
public typealias QueryGetActiveSubscriptionsHandler = suspend (subscriptionIds: List?) -> List
+public typealias QueryGetAllTransactionsIOSHandler = suspend () -> List
public typealias QueryGetAppTransactionIOSHandler = suspend () -> AppTransaction?
public typealias QueryGetAvailablePurchasesHandler = suspend (options: PurchaseOptions?) -> List
public typealias QueryGetExternalPurchaseCustomLinkTokenIOSHandler = suspend (tokenType: ExternalPurchaseCustomLinkTokenTypeIOS) -> ExternalPurchaseCustomLinkTokenResultIOS
@@ -4950,6 +5120,7 @@ public data class QueryHandlers(
val currentEntitlementIOS: QueryCurrentEntitlementIOSHandler? = null,
val fetchProducts: QueryFetchProductsHandler? = null,
val getActiveSubscriptions: QueryGetActiveSubscriptionsHandler? = null,
+ val getAllTransactionsIOS: QueryGetAllTransactionsIOSHandler? = null,
val getAppTransactionIOS: QueryGetAppTransactionIOSHandler? = null,
val getAvailablePurchases: QueryGetAvailablePurchasesHandler? = null,
val getExternalPurchaseCustomLinkTokenIOS: QueryGetExternalPurchaseCustomLinkTokenIOSHandler? = null,
diff --git a/packages/gql/src/api-ios.graphql b/packages/gql/src/api-ios.graphql
index 128959bd..59ad4ba7 100644
--- a/packages/gql/src/api-ios.graphql
+++ b/packages/gql/src/api-ios.graphql
@@ -81,6 +81,14 @@ extend type Query {
"""
# Future
getAppTransactionIOS: AppTransaction
+"""
+ Get all transactions including finished consumables (iOS 18+).
+ Requires the SK2ConsumableTransactionHistory Info.plist key in the host app.
+ Returns all transactions from Transaction.all, including finished consumable
+ transactions that would otherwise be excluded from getAvailablePurchases.
+ """
+ # Future
+ getAllTransactionsIOS: [PurchaseIOS!]!
"""
Validate a receipt for a specific product
"""
diff --git a/packages/gql/src/generated/Types.kt b/packages/gql/src/generated/Types.kt
index 856e7a9d..1a7eb3ef 100644
--- a/packages/gql/src/generated/Types.kt
+++ b/packages/gql/src/generated/Types.kt
@@ -1169,6 +1169,160 @@ public data class ActiveSubscription(
)
}
+/**
+ * Advanced Commerce metadata from a transaction (iOS 18.4+).
+ * Contains item details, tax information, and refund data for purchases
+ * made through the Advanced Commerce API using generic SKUs.
+ * Only present for transactions that use the Advanced Commerce API.
+ */
+public data class AdvancedCommerceInfoIOS(
+ /**
+ * Optional description
+ */
+ val description: String? = null,
+ /**
+ * Optional display name
+ */
+ val displayName: String? = null,
+ /**
+ * Estimated tax amount (decimal string)
+ */
+ val estimatedTax: String? = null,
+ /**
+ * The items purchased as part of this transaction
+ */
+ val items: List,
+ /**
+ * Request reference identifier for tracking
+ */
+ val requestReferenceId: String? = null,
+ /**
+ * Tax code for the transaction
+ */
+ val taxCode: String? = null,
+ /**
+ * Price excluding tax (decimal string)
+ */
+ val taxExclusivePrice: String? = null,
+ /**
+ * Tax rate applied (decimal string)
+ */
+ val taxRate: String? = null
+) {
+
+ companion object {
+ fun fromJson(json: Map): AdvancedCommerceInfoIOS {
+ return AdvancedCommerceInfoIOS(
+ description = json["description"] as? String,
+ displayName = json["displayName"] as? String,
+ estimatedTax = json["estimatedTax"] as? String,
+ items = (json["items"] as? List<*>)?.mapNotNull { (it as? Map)?.let { AdvancedCommerceItemIOS.fromJson(it) } ?: throw IllegalArgumentException("Missing required object for AdvancedCommerceItemIOS") } ?: emptyList(),
+ requestReferenceId = json["requestReferenceId"] as? String,
+ taxCode = json["taxCode"] as? String,
+ taxExclusivePrice = json["taxExclusivePrice"] as? String,
+ taxRate = json["taxRate"] as? String,
+ )
+ }
+ }
+
+ fun toJson(): Map = mapOf(
+ "__typename" to "AdvancedCommerceInfoIOS",
+ "description" to description,
+ "displayName" to displayName,
+ "estimatedTax" to estimatedTax,
+ "items" to items.map { it.toJson() },
+ "requestReferenceId" to requestReferenceId,
+ "taxCode" to taxCode,
+ "taxExclusivePrice" to taxExclusivePrice,
+ "taxRate" to taxRate,
+ )
+}
+
+/**
+ * Details of an Advanced Commerce item (iOS 18.4+).
+ */
+public data class AdvancedCommerceItemDetailsIOS(
+ /**
+ * JSON representation of the item details
+ */
+ val jsonRepresentation: String? = null
+) {
+
+ companion object {
+ fun fromJson(json: Map): AdvancedCommerceItemDetailsIOS {
+ return AdvancedCommerceItemDetailsIOS(
+ jsonRepresentation = json["jsonRepresentation"] as? String,
+ )
+ }
+ }
+
+ fun toJson(): Map = mapOf(
+ "__typename" to "AdvancedCommerceItemDetailsIOS",
+ "jsonRepresentation" to jsonRepresentation,
+ )
+}
+
+/**
+ * An item purchased through the Advanced Commerce API (iOS 18.4+).
+ * Represents a developer-defined product within a generic SKU transaction.
+ */
+public data class AdvancedCommerceItemIOS(
+ /**
+ * The item's detail information
+ */
+ val details: AdvancedCommerceItemDetailsIOS? = null,
+ /**
+ * Refunds issued for this item, if any
+ */
+ val refunds: List? = null,
+ /**
+ * Date access to this item was revoked (milliseconds since epoch)
+ */
+ val revocationDate: Double? = null
+) {
+
+ companion object {
+ fun fromJson(json: Map): AdvancedCommerceItemIOS {
+ return AdvancedCommerceItemIOS(
+ details = (json["details"] as? Map)?.let { AdvancedCommerceItemDetailsIOS.fromJson(it) },
+ refunds = (json["refunds"] as? List<*>)?.mapNotNull { (it as? Map)?.let { AdvancedCommerceRefundIOS.fromJson(it) } ?: throw IllegalArgumentException("Missing required object for AdvancedCommerceRefundIOS") },
+ revocationDate = (json["revocationDate"] as? Number)?.toDouble(),
+ )
+ }
+ }
+
+ fun toJson(): Map = mapOf(
+ "__typename" to "AdvancedCommerceItemIOS",
+ "details" to details?.toJson(),
+ "refunds" to refunds?.map { it.toJson() },
+ "revocationDate" to revocationDate,
+ )
+}
+
+/**
+ * Refund information for an Advanced Commerce item (iOS 18.4+).
+ */
+public data class AdvancedCommerceRefundIOS(
+ /**
+ * JSON representation of the refund details
+ */
+ val jsonRepresentation: String? = null
+) {
+
+ companion object {
+ fun fromJson(json: Map): AdvancedCommerceRefundIOS {
+ return AdvancedCommerceRefundIOS(
+ jsonRepresentation = json["jsonRepresentation"] as? String,
+ )
+ }
+ }
+
+ fun toJson(): Map = mapOf(
+ "__typename" to "AdvancedCommerceRefundIOS",
+ "jsonRepresentation" to jsonRepresentation,
+ )
+}
+
public data class AppTransaction(
val appId: Double,
val appTransactionId: String? = null,
@@ -2654,6 +2808,12 @@ public data class PurchaseError(
}
public data class PurchaseIOS(
+ /**
+ * Advanced Commerce API metadata (iOS 18.4+).
+ * Present only for transactions that use the Advanced Commerce API.
+ * Contains item details, tax information, and refund data for generic SKU purchases.
+ */
+ val advancedCommerceInfoIOS: AdvancedCommerceInfoIOS? = null,
val appAccountToken: String? = null,
val appBundleIdIOS: String? = null,
val countryCodeIOS: String? = null,
@@ -2696,6 +2856,7 @@ public data class PurchaseIOS(
companion object {
fun fromJson(json: Map): PurchaseIOS {
return PurchaseIOS(
+ advancedCommerceInfoIOS = (json["advancedCommerceInfoIOS"] as? Map)?.let { AdvancedCommerceInfoIOS.fromJson(it) },
appAccountToken = json["appAccountToken"] as? String,
appBundleIdIOS = json["appBundleIdIOS"] as? String,
countryCodeIOS = json["countryCodeIOS"] as? String,
@@ -2736,6 +2897,7 @@ public data class PurchaseIOS(
override fun toJson(): Map = mapOf(
"__typename" to "PurchaseIOS",
+ "advancedCommerceInfoIOS" to advancedCommerceInfoIOS?.toJson(),
"appAccountToken" to appAccountToken,
"appBundleIdIOS" to appBundleIdIOS,
"countryCodeIOS" to countryCodeIOS,
@@ -4836,6 +4998,13 @@ public interface QueryResolver {
* Get active subscriptions (filters by subscriptionIds when provided)
*/
suspend fun getActiveSubscriptions(subscriptionIds: List? = null): List
+ /**
+ * Get all transactions including finished consumables (iOS 18+).
+ * Requires the SK2ConsumableTransactionHistory Info.plist key in the host app.
+ * Returns all transactions from Transaction.all, including finished consumable
+ * transactions that would otherwise be excluded from getAvailablePurchases.
+ */
+ suspend fun getAllTransactionsIOS(): List
/**
* Fetch the current app transaction (iOS 16+)
*/
@@ -5017,6 +5186,7 @@ public typealias QueryCanPresentExternalPurchaseNoticeIOSHandler = suspend () ->
public typealias QueryCurrentEntitlementIOSHandler = suspend (sku: String) -> PurchaseIOS?
public typealias QueryFetchProductsHandler = suspend (params: ProductRequest) -> FetchProductsResult
public typealias QueryGetActiveSubscriptionsHandler = suspend (subscriptionIds: List?) -> List
+public typealias QueryGetAllTransactionsIOSHandler = suspend () -> List
public typealias QueryGetAppTransactionIOSHandler = suspend () -> AppTransaction?
public typealias QueryGetAvailablePurchasesHandler = suspend (options: PurchaseOptions?) -> List
public typealias QueryGetExternalPurchaseCustomLinkTokenIOSHandler = suspend (tokenType: ExternalPurchaseCustomLinkTokenTypeIOS) -> ExternalPurchaseCustomLinkTokenResultIOS
@@ -5039,6 +5209,7 @@ public data class QueryHandlers(
val currentEntitlementIOS: QueryCurrentEntitlementIOSHandler? = null,
val fetchProducts: QueryFetchProductsHandler? = null,
val getActiveSubscriptions: QueryGetActiveSubscriptionsHandler? = null,
+ val getAllTransactionsIOS: QueryGetAllTransactionsIOSHandler? = null,
val getAppTransactionIOS: QueryGetAppTransactionIOSHandler? = null,
val getAvailablePurchases: QueryGetAvailablePurchasesHandler? = null,
val getExternalPurchaseCustomLinkTokenIOS: QueryGetExternalPurchaseCustomLinkTokenIOSHandler? = null,
diff --git a/packages/gql/src/generated/Types.swift b/packages/gql/src/generated/Types.swift
index 39db135b..6a2226bb 100644
--- a/packages/gql/src/generated/Types.swift
+++ b/packages/gql/src/generated/Types.swift
@@ -488,6 +488,52 @@ public struct ActiveSubscription: Codable {
public var willExpireSoon: Bool? = nil
}
+/// Advanced Commerce metadata from a transaction (iOS 18.4+).
+/// Contains item details, tax information, and refund data for purchases
+/// made through the Advanced Commerce API using generic SKUs.
+/// Only present for transactions that use the Advanced Commerce API.
+public struct AdvancedCommerceInfoIOS: Codable {
+ /// Optional description
+ public var description: String? = nil
+ /// Optional display name
+ public var displayName: String? = nil
+ /// Estimated tax amount (decimal string)
+ public var estimatedTax: String? = nil
+ /// The items purchased as part of this transaction
+ public var items: [AdvancedCommerceItemIOS]
+ /// Request reference identifier for tracking
+ public var requestReferenceId: String? = nil
+ /// Tax code for the transaction
+ public var taxCode: String? = nil
+ /// Price excluding tax (decimal string)
+ public var taxExclusivePrice: String? = nil
+ /// Tax rate applied (decimal string)
+ public var taxRate: String? = nil
+}
+
+/// Details of an Advanced Commerce item (iOS 18.4+).
+public struct AdvancedCommerceItemDetailsIOS: Codable {
+ /// JSON representation of the item details
+ public var jsonRepresentation: String? = nil
+}
+
+/// An item purchased through the Advanced Commerce API (iOS 18.4+).
+/// Represents a developer-defined product within a generic SKU transaction.
+public struct AdvancedCommerceItemIOS: Codable {
+ /// The item's detail information
+ public var details: AdvancedCommerceItemDetailsIOS? = nil
+ /// Refunds issued for this item, if any
+ public var refunds: [AdvancedCommerceRefundIOS]? = nil
+ /// Date access to this item was revoked (milliseconds since epoch)
+ public var revocationDate: Double? = nil
+}
+
+/// Refund information for an Advanced Commerce item (iOS 18.4+).
+public struct AdvancedCommerceRefundIOS: Codable {
+ /// JSON representation of the refund details
+ public var jsonRepresentation: String? = nil
+}
+
public struct AppTransaction: Codable {
public var appId: Double
public var appTransactionId: String? = nil
@@ -995,6 +1041,10 @@ public struct PurchaseError: Codable {
}
public struct PurchaseIOS: Codable, PurchaseCommon {
+ /// Advanced Commerce API metadata (iOS 18.4+).
+ /// Present only for transactions that use the Advanced Commerce API.
+ /// Contains item details, tax information, and refund data for generic SKU purchases.
+ public var advancedCommerceInfoIOS: AdvancedCommerceInfoIOS? = nil
public var appAccountToken: String? = nil
public var appBundleIdIOS: String? = nil
public var countryCodeIOS: String? = nil
@@ -2388,6 +2438,11 @@ public protocol QueryResolver {
func fetchProducts(_ params: ProductRequest) async throws -> FetchProductsResult
/// Get active subscriptions (filters by subscriptionIds when provided)
func getActiveSubscriptions(_ subscriptionIds: [String]?) async throws -> [ActiveSubscription]
+ /// Get all transactions including finished consumables (iOS 18+).
+ /// Requires the SK2ConsumableTransactionHistory Info.plist key in the host app.
+ /// Returns all transactions from Transaction.all, including finished consumable
+ /// transactions that would otherwise be excluded from getAvailablePurchases.
+ func getAllTransactionsIOS() async throws -> [PurchaseIOS]
/// Fetch the current app transaction (iOS 16+)
func getAppTransactionIOS() async throws -> AppTransaction?
/// Get all available purchases for the current user
@@ -2579,6 +2634,7 @@ public typealias QueryCanPresentExternalPurchaseNoticeIOSHandler = () async thro
public typealias QueryCurrentEntitlementIOSHandler = (_ sku: String) async throws -> PurchaseIOS?
public typealias QueryFetchProductsHandler = (_ params: ProductRequest) async throws -> FetchProductsResult
public typealias QueryGetActiveSubscriptionsHandler = (_ subscriptionIds: [String]?) async throws -> [ActiveSubscription]
+public typealias QueryGetAllTransactionsIOSHandler = () async throws -> [PurchaseIOS]
public typealias QueryGetAppTransactionIOSHandler = () async throws -> AppTransaction?
public typealias QueryGetAvailablePurchasesHandler = (_ options: PurchaseOptions?) async throws -> [Purchase]
public typealias QueryGetExternalPurchaseCustomLinkTokenIOSHandler = (_ tokenType: ExternalPurchaseCustomLinkTokenTypeIOS) async throws -> ExternalPurchaseCustomLinkTokenResultIOS
@@ -2601,6 +2657,7 @@ public struct QueryHandlers {
public var currentEntitlementIOS: QueryCurrentEntitlementIOSHandler?
public var fetchProducts: QueryFetchProductsHandler?
public var getActiveSubscriptions: QueryGetActiveSubscriptionsHandler?
+ public var getAllTransactionsIOS: QueryGetAllTransactionsIOSHandler?
public var getAppTransactionIOS: QueryGetAppTransactionIOSHandler?
public var getAvailablePurchases: QueryGetAvailablePurchasesHandler?
public var getExternalPurchaseCustomLinkTokenIOS: QueryGetExternalPurchaseCustomLinkTokenIOSHandler?
@@ -2623,6 +2680,7 @@ public struct QueryHandlers {
currentEntitlementIOS: QueryCurrentEntitlementIOSHandler? = nil,
fetchProducts: QueryFetchProductsHandler? = nil,
getActiveSubscriptions: QueryGetActiveSubscriptionsHandler? = nil,
+ getAllTransactionsIOS: QueryGetAllTransactionsIOSHandler? = nil,
getAppTransactionIOS: QueryGetAppTransactionIOSHandler? = nil,
getAvailablePurchases: QueryGetAvailablePurchasesHandler? = nil,
getExternalPurchaseCustomLinkTokenIOS: QueryGetExternalPurchaseCustomLinkTokenIOSHandler? = nil,
@@ -2644,6 +2702,7 @@ public struct QueryHandlers {
self.currentEntitlementIOS = currentEntitlementIOS
self.fetchProducts = fetchProducts
self.getActiveSubscriptions = getActiveSubscriptions
+ self.getAllTransactionsIOS = getAllTransactionsIOS
self.getAppTransactionIOS = getAppTransactionIOS
self.getAvailablePurchases = getAvailablePurchases
self.getExternalPurchaseCustomLinkTokenIOS = getExternalPurchaseCustomLinkTokenIOS
diff --git a/packages/gql/src/generated/types.dart b/packages/gql/src/generated/types.dart
index 1b65274a..f6d9017f 100644
--- a/packages/gql/src/generated/types.dart
+++ b/packages/gql/src/generated/types.dart
@@ -1048,6 +1048,147 @@ class ActiveSubscription {
}
}
+/// Advanced Commerce metadata from a transaction (iOS 18.4+).
+/// Contains item details, tax information, and refund data for purchases
+/// made through the Advanced Commerce API using generic SKUs.
+/// Only present for transactions that use the Advanced Commerce API.
+class AdvancedCommerceInfoIOS {
+ const AdvancedCommerceInfoIOS({
+ this.description,
+ this.displayName,
+ this.estimatedTax,
+ required this.items,
+ this.requestReferenceId,
+ this.taxCode,
+ this.taxExclusivePrice,
+ this.taxRate,
+ });
+
+ /// Optional description
+ final String? description;
+ /// Optional display name
+ final String? displayName;
+ /// Estimated tax amount (decimal string)
+ final String? estimatedTax;
+ /// The items purchased as part of this transaction
+ final List items;
+ /// Request reference identifier for tracking
+ final String? requestReferenceId;
+ /// Tax code for the transaction
+ final String? taxCode;
+ /// Price excluding tax (decimal string)
+ final String? taxExclusivePrice;
+ /// Tax rate applied (decimal string)
+ final String? taxRate;
+
+ factory AdvancedCommerceInfoIOS.fromJson(Map json) {
+ return AdvancedCommerceInfoIOS(
+ description: json['description'] as String?,
+ displayName: json['displayName'] as String?,
+ estimatedTax: json['estimatedTax'] as String?,
+ items: (json['items'] as List).map((e) => AdvancedCommerceItemIOS.fromJson(e as Map)).toList(),
+ requestReferenceId: json['requestReferenceId'] as String?,
+ taxCode: json['taxCode'] as String?,
+ taxExclusivePrice: json['taxExclusivePrice'] as String?,
+ taxRate: json['taxRate'] as String?,
+ );
+ }
+
+ Map toJson() {
+ return {
+ '__typename': 'AdvancedCommerceInfoIOS',
+ 'description': description,
+ 'displayName': displayName,
+ 'estimatedTax': estimatedTax,
+ 'items': items.map((e) => e.toJson()).toList(),
+ 'requestReferenceId': requestReferenceId,
+ 'taxCode': taxCode,
+ 'taxExclusivePrice': taxExclusivePrice,
+ 'taxRate': taxRate,
+ };
+ }
+}
+
+/// Details of an Advanced Commerce item (iOS 18.4+).
+class AdvancedCommerceItemDetailsIOS {
+ const AdvancedCommerceItemDetailsIOS({
+ this.jsonRepresentation,
+ });
+
+ /// JSON representation of the item details
+ final String? jsonRepresentation;
+
+ factory AdvancedCommerceItemDetailsIOS.fromJson(Map json) {
+ return AdvancedCommerceItemDetailsIOS(
+ jsonRepresentation: json['jsonRepresentation'] as String?,
+ );
+ }
+
+ Map toJson() {
+ return {
+ '__typename': 'AdvancedCommerceItemDetailsIOS',
+ 'jsonRepresentation': jsonRepresentation,
+ };
+ }
+}
+
+/// An item purchased through the Advanced Commerce API (iOS 18.4+).
+/// Represents a developer-defined product within a generic SKU transaction.
+class AdvancedCommerceItemIOS {
+ const AdvancedCommerceItemIOS({
+ this.details,
+ this.refunds,
+ this.revocationDate,
+ });
+
+ /// The item's detail information
+ final AdvancedCommerceItemDetailsIOS? details;
+ /// Refunds issued for this item, if any
+ final List? refunds;
+ /// Date access to this item was revoked (milliseconds since epoch)
+ final double? revocationDate;
+
+ factory AdvancedCommerceItemIOS.fromJson(Map json) {
+ return AdvancedCommerceItemIOS(
+ details: json['details'] != null ? AdvancedCommerceItemDetailsIOS.fromJson(json['details'] as Map) : null,
+ refunds: (json['refunds'] as List?) == null ? null : (json['refunds'] as List?)!.map((e) => AdvancedCommerceRefundIOS.fromJson(e as Map)).toList(),
+ revocationDate: (json['revocationDate'] as num?)?.toDouble(),
+ );
+ }
+
+ Map toJson() {
+ return {
+ '__typename': 'AdvancedCommerceItemIOS',
+ 'details': details?.toJson(),
+ 'refunds': refunds == null ? null : refunds!.map((e) => e.toJson()).toList(),
+ 'revocationDate': revocationDate,
+ };
+ }
+}
+
+/// Refund information for an Advanced Commerce item (iOS 18.4+).
+class AdvancedCommerceRefundIOS {
+ const AdvancedCommerceRefundIOS({
+ this.jsonRepresentation,
+ });
+
+ /// JSON representation of the refund details
+ final String? jsonRepresentation;
+
+ factory AdvancedCommerceRefundIOS.fromJson(Map json) {
+ return AdvancedCommerceRefundIOS(
+ jsonRepresentation: json['jsonRepresentation'] as String?,
+ );
+ }
+
+ Map toJson() {
+ return {
+ '__typename': 'AdvancedCommerceRefundIOS',
+ 'jsonRepresentation': jsonRepresentation,
+ };
+ }
+}
+
class AppTransaction {
const AppTransaction({
required this.appId,
@@ -2612,6 +2753,7 @@ class PurchaseError {
class PurchaseIOS extends Purchase implements PurchaseCommon {
const PurchaseIOS({
+ this.advancedCommerceInfoIOS,
this.appAccountToken,
this.appBundleIdIOS,
this.countryCodeIOS,
@@ -2649,6 +2791,10 @@ class PurchaseIOS extends Purchase implements PurchaseCommon {
this.isAlternativeBilling,
});
+ /// Advanced Commerce API metadata (iOS 18.4+).
+ /// Present only for transactions that use the Advanced Commerce API.
+ /// Contains item details, tax information, and refund data for generic SKU purchases.
+ final AdvancedCommerceInfoIOS? advancedCommerceInfoIOS;
final String? appAccountToken;
final String? appBundleIdIOS;
final String? countryCodeIOS;
@@ -2688,6 +2834,7 @@ class PurchaseIOS extends Purchase implements PurchaseCommon {
factory PurchaseIOS.fromJson(Map json) {
return PurchaseIOS(
+ advancedCommerceInfoIOS: json['advancedCommerceInfoIOS'] != null ? AdvancedCommerceInfoIOS.fromJson(json['advancedCommerceInfoIOS'] as Map) : null,
appAccountToken: json['appAccountToken'] as String?,
appBundleIdIOS: json['appBundleIdIOS'] as String?,
countryCodeIOS: json['countryCodeIOS'] as String?,
@@ -2730,6 +2877,7 @@ class PurchaseIOS extends Purchase implements PurchaseCommon {
Map toJson() {
return {
'__typename': 'PurchaseIOS',
+ 'advancedCommerceInfoIOS': advancedCommerceInfoIOS?.toJson(),
'appAccountToken': appAccountToken,
'appBundleIdIOS': appBundleIdIOS,
'countryCodeIOS': countryCodeIOS,
@@ -4830,6 +4978,11 @@ abstract class QueryResolver {
});
/// Get active subscriptions (filters by subscriptionIds when provided)
Future> getActiveSubscriptions([List? subscriptionIds]);
+ /// Get all transactions including finished consumables (iOS 18+).
+ /// Requires the SK2ConsumableTransactionHistory Info.plist key in the host app.
+ /// Returns all transactions from Transaction.all, including finished consumable
+ /// transactions that would otherwise be excluded from getAvailablePurchases.
+ Future> getAllTransactionsIOS();
/// Fetch the current app transaction (iOS 16+)
Future getAppTransactionIOS();
/// Get all available purchases for the current user
@@ -5030,6 +5183,7 @@ typedef QueryFetchProductsHandler = Future Function({
ProductQueryType? type,
});
typedef QueryGetActiveSubscriptionsHandler = Future> Function([List? subscriptionIds]);
+typedef QueryGetAllTransactionsIOSHandler = Future> Function();
typedef QueryGetAppTransactionIOSHandler = Future Function();
typedef QueryGetAvailablePurchasesHandler = Future> Function({
bool? alsoPublishToEventListenerIOS,
@@ -5061,6 +5215,7 @@ class QueryHandlers {
this.currentEntitlementIOS,
this.fetchProducts,
this.getActiveSubscriptions,
+ this.getAllTransactionsIOS,
this.getAppTransactionIOS,
this.getAvailablePurchases,
this.getExternalPurchaseCustomLinkTokenIOS,
@@ -5083,6 +5238,7 @@ class QueryHandlers {
final QueryCurrentEntitlementIOSHandler? currentEntitlementIOS;
final QueryFetchProductsHandler? fetchProducts;
final QueryGetActiveSubscriptionsHandler? getActiveSubscriptions;
+ final QueryGetAllTransactionsIOSHandler? getAllTransactionsIOS;
final QueryGetAppTransactionIOSHandler? getAppTransactionIOS;
final QueryGetAvailablePurchasesHandler? getAvailablePurchases;
final QueryGetExternalPurchaseCustomLinkTokenIOSHandler? getExternalPurchaseCustomLinkTokenIOS;
diff --git a/packages/gql/src/generated/types.gd b/packages/gql/src/generated/types.gd
index 88dbdb17..e8ba7cdb 100644
--- a/packages/gql/src/generated/types.gd
+++ b/packages/gql/src/generated/types.gd
@@ -384,6 +384,161 @@ class ActiveSubscription:
dict["renewalInfoIOS"] = renewal_info_ios
return dict
+## Advanced Commerce metadata from a transaction (iOS 18.4+). Contains item details, tax information, and refund data for purchases made through the Advanced Commerce API using generic SKUs. Only present for transactions that use the Advanced Commerce API.
+class AdvancedCommerceInfoIOS:
+ ## The items purchased as part of this transaction
+ var items: Array[AdvancedCommerceItemIOS] = []
+ ## Request reference identifier for tracking
+ var request_reference_id: Variant = null
+ ## Tax code for the transaction
+ var tax_code: Variant = null
+ ## Price excluding tax (decimal string)
+ var tax_exclusive_price: Variant = null
+ ## Estimated tax amount (decimal string)
+ var estimated_tax: Variant = null
+ ## Tax rate applied (decimal string)
+ var tax_rate: Variant = null
+ ## Optional display name
+ var display_name: Variant = null
+ ## Optional description
+ var description: Variant = null
+
+ static func from_dict(data: Dictionary) -> AdvancedCommerceInfoIOS:
+ var obj = AdvancedCommerceInfoIOS.new()
+ if data.has("items") and data["items"] != null:
+ var arr = []
+ for item in data["items"]:
+ if item is Dictionary:
+ arr.append(AdvancedCommerceItemIOS.from_dict(item))
+ else:
+ arr.append(item)
+ obj.items = arr
+ if data.has("requestReferenceId") and data["requestReferenceId"] != null:
+ obj.request_reference_id = data["requestReferenceId"]
+ if data.has("taxCode") and data["taxCode"] != null:
+ obj.tax_code = data["taxCode"]
+ if data.has("taxExclusivePrice") and data["taxExclusivePrice"] != null:
+ obj.tax_exclusive_price = data["taxExclusivePrice"]
+ if data.has("estimatedTax") and data["estimatedTax"] != null:
+ obj.estimated_tax = data["estimatedTax"]
+ if data.has("taxRate") and data["taxRate"] != null:
+ obj.tax_rate = data["taxRate"]
+ if data.has("displayName") and data["displayName"] != null:
+ obj.display_name = data["displayName"]
+ if data.has("description") and data["description"] != null:
+ obj.description = data["description"]
+ return obj
+
+ func to_dict() -> Dictionary:
+ var dict = {}
+ if items != null:
+ var arr = []
+ for item in items:
+ if item != null and item.has_method("to_dict"):
+ arr.append(item.to_dict())
+ else:
+ arr.append(item)
+ dict["items"] = arr
+ else:
+ dict["items"] = null
+ if request_reference_id != null:
+ dict["requestReferenceId"] = request_reference_id
+ if tax_code != null:
+ dict["taxCode"] = tax_code
+ if tax_exclusive_price != null:
+ dict["taxExclusivePrice"] = tax_exclusive_price
+ if estimated_tax != null:
+ dict["estimatedTax"] = estimated_tax
+ if tax_rate != null:
+ dict["taxRate"] = tax_rate
+ if display_name != null:
+ dict["displayName"] = display_name
+ if description != null:
+ dict["description"] = description
+ return dict
+
+## Details of an Advanced Commerce item (iOS 18.4+).
+class AdvancedCommerceItemDetailsIOS:
+ ## JSON representation of the item details
+ var json_representation: Variant = null
+
+ static func from_dict(data: Dictionary) -> AdvancedCommerceItemDetailsIOS:
+ var obj = AdvancedCommerceItemDetailsIOS.new()
+ if data.has("jsonRepresentation") and data["jsonRepresentation"] != null:
+ obj.json_representation = data["jsonRepresentation"]
+ return obj
+
+ func to_dict() -> Dictionary:
+ var dict = {}
+ if json_representation != null:
+ dict["jsonRepresentation"] = json_representation
+ return dict
+
+## An item purchased through the Advanced Commerce API (iOS 18.4+). Represents a developer-defined product within a generic SKU transaction.
+class AdvancedCommerceItemIOS:
+ ## The item's detail information
+ var details: AdvancedCommerceItemDetailsIOS
+ ## Refunds issued for this item, if any
+ var refunds: Array[AdvancedCommerceRefundIOS] = []
+ ## Date access to this item was revoked (milliseconds since epoch)
+ var revocation_date: Variant = null
+
+ static func from_dict(data: Dictionary) -> AdvancedCommerceItemIOS:
+ var obj = AdvancedCommerceItemIOS.new()
+ if data.has("details") and data["details"] != null:
+ if data["details"] is Dictionary:
+ obj.details = AdvancedCommerceItemDetailsIOS.from_dict(data["details"])
+ else:
+ obj.details = data["details"]
+ if data.has("refunds") and data["refunds"] != null:
+ var arr = []
+ for item in data["refunds"]:
+ if item is Dictionary:
+ arr.append(AdvancedCommerceRefundIOS.from_dict(item))
+ else:
+ arr.append(item)
+ obj.refunds = arr
+ if data.has("revocationDate") and data["revocationDate"] != null:
+ obj.revocation_date = data["revocationDate"]
+ return obj
+
+ func to_dict() -> Dictionary:
+ var dict = {}
+ if details != null and details.has_method("to_dict"):
+ dict["details"] = details.to_dict()
+ else:
+ dict["details"] = details
+ if refunds != null:
+ var arr = []
+ for item in refunds:
+ if item != null and item.has_method("to_dict"):
+ arr.append(item.to_dict())
+ else:
+ arr.append(item)
+ dict["refunds"] = arr
+ else:
+ dict["refunds"] = null
+ if revocation_date != null:
+ dict["revocationDate"] = revocation_date
+ return dict
+
+## Refund information for an Advanced Commerce item (iOS 18.4+).
+class AdvancedCommerceRefundIOS:
+ ## JSON representation of the refund details
+ var json_representation: Variant = null
+
+ static func from_dict(data: Dictionary) -> AdvancedCommerceRefundIOS:
+ var obj = AdvancedCommerceRefundIOS.new()
+ if data.has("jsonRepresentation") and data["jsonRepresentation"] != null:
+ obj.json_representation = data["jsonRepresentation"]
+ return obj
+
+ func to_dict() -> Dictionary:
+ var dict = {}
+ if json_representation != null:
+ dict["jsonRepresentation"] = json_representation
+ return dict
+
class AppTransaction:
var bundle_id: String = ""
var app_version: String = ""
@@ -2130,6 +2285,8 @@ class PurchaseIOS:
var currency_symbol_ios: Variant = null
var country_code_ios: Variant = null
var renewal_info_ios: RenewalInfoIOS
+ ## Advanced Commerce API metadata (iOS 18.4+).
+ var advanced_commerce_info_ios: AdvancedCommerceInfoIOS
static func from_dict(data: Dictionary) -> PurchaseIOS:
var obj = PurchaseIOS.new()
@@ -2219,6 +2376,11 @@ class PurchaseIOS:
obj.renewal_info_ios = RenewalInfoIOS.from_dict(data["renewalInfoIOS"])
else:
obj.renewal_info_ios = data["renewalInfoIOS"]
+ if data.has("advancedCommerceInfoIOS") and data["advancedCommerceInfoIOS"] != null:
+ if data["advancedCommerceInfoIOS"] is Dictionary:
+ obj.advanced_commerce_info_ios = AdvancedCommerceInfoIOS.from_dict(data["advancedCommerceInfoIOS"])
+ else:
+ obj.advanced_commerce_info_ios = data["advancedCommerceInfoIOS"]
return obj
func to_dict() -> Dictionary:
@@ -2294,6 +2456,10 @@ class PurchaseIOS:
dict["renewalInfoIOS"] = renewal_info_ios.to_dict()
else:
dict["renewalInfoIOS"] = renewal_info_ios
+ if advanced_commerce_info_ios != null and advanced_commerce_info_ios.has_method("to_dict"):
+ dict["advancedCommerceInfoIOS"] = advanced_commerce_info_ios.to_dict()
+ else:
+ dict["advancedCommerceInfoIOS"] = advanced_commerce_info_ios
return dict
class PurchaseOfferIOS:
@@ -4934,6 +5100,15 @@ class Query:
const return_type = "AppTransaction"
const is_array = false
+ ## Get all transactions including finished consumables (iOS 18+).
+ class getAllTransactionsIOSField:
+ const name = "getAllTransactionsIOS"
+ const snake_name = "get_all_transactions_ios"
+ class Args:
+ pass
+ const return_type = "PurchaseIOS"
+ const is_array = true
+
## Validate a receipt for a specific product
class validateReceiptIOSField:
const name = "validateReceiptIOS"
@@ -5507,6 +5682,10 @@ static func get_receipt_data_ios_args() -> Dictionary:
static func get_app_transaction_ios_args() -> Dictionary:
return {}
+## Get all transactions including finished consumables (iOS 18+).
+static func get_all_transactions_ios_args() -> Dictionary:
+ return {}
+
## Validate a receipt for a specific product
static func validate_receipt_ios_args(options: VerifyPurchaseProps) -> Dictionary:
var args = {}
diff --git a/packages/gql/src/generated/types.ts b/packages/gql/src/generated/types.ts
index 9a4c0338..c533d922 100644
--- a/packages/gql/src/generated/types.ts
+++ b/packages/gql/src/generated/types.ts
@@ -36,6 +36,56 @@ export interface ActiveSubscription {
willExpireSoon?: (boolean | null);
}
+/**
+ * Advanced Commerce metadata from a transaction (iOS 18.4+).
+ * Contains item details, tax information, and refund data for purchases
+ * made through the Advanced Commerce API using generic SKUs.
+ * Only present for transactions that use the Advanced Commerce API.
+ */
+export interface AdvancedCommerceInfoIOS {
+ /** Optional description */
+ description?: (string | null);
+ /** Optional display name */
+ displayName?: (string | null);
+ /** Estimated tax amount (decimal string) */
+ estimatedTax?: (string | null);
+ /** The items purchased as part of this transaction */
+ items: AdvancedCommerceItemIOS[];
+ /** Request reference identifier for tracking */
+ requestReferenceId?: (string | null);
+ /** Tax code for the transaction */
+ taxCode?: (string | null);
+ /** Price excluding tax (decimal string) */
+ taxExclusivePrice?: (string | null);
+ /** Tax rate applied (decimal string) */
+ taxRate?: (string | null);
+}
+
+/** Details of an Advanced Commerce item (iOS 18.4+). */
+export interface AdvancedCommerceItemDetailsIOS {
+ /** JSON representation of the item details */
+ jsonRepresentation?: (string | null);
+}
+
+/**
+ * An item purchased through the Advanced Commerce API (iOS 18.4+).
+ * Represents a developer-defined product within a generic SKU transaction.
+ */
+export interface AdvancedCommerceItemIOS {
+ /** The item's detail information */
+ details?: (AdvancedCommerceItemDetailsIOS | null);
+ /** Refunds issued for this item, if any */
+ refunds?: (AdvancedCommerceRefundIOS[] | null);
+ /** Date access to this item was revoked (milliseconds since epoch) */
+ revocationDate?: (number | null);
+}
+
+/** Refund information for an Advanced Commerce item (iOS 18.4+). */
+export interface AdvancedCommerceRefundIOS {
+ /** JSON representation of the refund details */
+ jsonRepresentation?: (string | null);
+}
+
/**
* Alternative billing mode for Android
* Controls which billing system is used
@@ -1112,6 +1162,12 @@ export interface PurchaseError {
}
export interface PurchaseIOS extends PurchaseCommon {
+ /**
+ * Advanced Commerce API metadata (iOS 18.4+).
+ * Present only for transactions that use the Advanced Commerce API.
+ * Contains item details, tax information, and refund data for generic SKU purchases.
+ */
+ advancedCommerceInfoIOS?: (AdvancedCommerceInfoIOS | null);
appAccountToken?: (string | null);
appBundleIdIOS?: (string | null);
countryCodeIOS?: (string | null);
@@ -1188,6 +1244,13 @@ export interface Query {
fetchProducts: Promise<(ProductOrSubscription[] | Product[] | ProductSubscription[] | null)>;
/** Get active subscriptions (filters by subscriptionIds when provided) */
getActiveSubscriptions: Promise;
+ /**
+ * Get all transactions including finished consumables (iOS 18+).
+ * Requires the SK2ConsumableTransactionHistory Info.plist key in the host app.
+ * Returns all transactions from Transaction.all, including finished consumable
+ * transactions that would otherwise be excluded from getAvailablePurchases.
+ */
+ getAllTransactionsIOS: Promise;
/** Fetch the current app transaction (iOS 16+) */
getAppTransactionIOS?: Promise<(AppTransaction | null)>;
/** Get all available purchases for the current user */
@@ -1901,6 +1964,7 @@ export type QueryArgsMap = {
currentEntitlementIOS: QueryCurrentEntitlementIosArgs;
fetchProducts: QueryFetchProductsArgs;
getActiveSubscriptions: QueryGetActiveSubscriptionsArgs;
+ getAllTransactionsIOS: never;
getAppTransactionIOS: never;
getAvailablePurchases: QueryGetAvailablePurchasesArgs;
getExternalPurchaseCustomLinkTokenIOS: QueryGetExternalPurchaseCustomLinkTokenIosArgs;
diff --git a/packages/gql/src/type-ios.graphql b/packages/gql/src/type-ios.graphql
index 796767a2..a9dc6990 100644
--- a/packages/gql/src/type-ios.graphql
+++ b/packages/gql/src/type-ios.graphql
@@ -210,6 +210,12 @@ type PurchaseIOS implements PurchaseCommon {
currencySymbolIOS: String
countryCodeIOS: String
renewalInfoIOS: RenewalInfoIOS
+ """
+ Advanced Commerce API metadata (iOS 18.4+).
+ Present only for transactions that use the Advanced Commerce API.
+ Contains item details, tax information, and refund data for generic SKU purchases.
+ """
+ advancedCommerceInfoIOS: AdvancedCommerceInfoIOS
}
type PurchaseOfferIOS {
@@ -610,3 +616,89 @@ type ExternalPurchaseCustomLinkTokenResultIOS {
"""
error: String
}
+
+# ============================================================================
+# Advanced Commerce API Types (iOS 18.4+)
+# For apps using the Advanced Commerce API with generic SKU purchases
+# Reference: https://developer.apple.com/documentation/storekit/transaction/advancedcommerceinfo
+# ============================================================================
+
+"""
+Advanced Commerce metadata from a transaction (iOS 18.4+).
+Contains item details, tax information, and refund data for purchases
+made through the Advanced Commerce API using generic SKUs.
+Only present for transactions that use the Advanced Commerce API.
+"""
+type AdvancedCommerceInfoIOS {
+ """
+ The items purchased as part of this transaction
+ """
+ items: [AdvancedCommerceItemIOS!]!
+ """
+ Request reference identifier for tracking
+ """
+ requestReferenceId: String
+ """
+ Tax code for the transaction
+ """
+ taxCode: String
+ """
+ Price excluding tax (decimal string)
+ """
+ taxExclusivePrice: String
+ """
+ Estimated tax amount (decimal string)
+ """
+ estimatedTax: String
+ """
+ Tax rate applied (decimal string)
+ """
+ taxRate: String
+ """
+ Optional display name
+ """
+ displayName: String
+ """
+ Optional description
+ """
+ description: String
+}
+
+"""
+An item purchased through the Advanced Commerce API (iOS 18.4+).
+Represents a developer-defined product within a generic SKU transaction.
+"""
+type AdvancedCommerceItemIOS {
+ """
+ The item's detail information
+ """
+ details: AdvancedCommerceItemDetailsIOS
+ """
+ Refunds issued for this item, if any
+ """
+ refunds: [AdvancedCommerceRefundIOS!]
+ """
+ Date access to this item was revoked (milliseconds since epoch)
+ """
+ revocationDate: Float
+}
+
+"""
+Details of an Advanced Commerce item (iOS 18.4+).
+"""
+type AdvancedCommerceItemDetailsIOS {
+ """
+ JSON representation of the item details
+ """
+ jsonRepresentation: String
+}
+
+"""
+Refund information for an Advanced Commerce item (iOS 18.4+).
+"""
+type AdvancedCommerceRefundIOS {
+ """
+ JSON representation of the refund details
+ """
+ jsonRepresentation: String
+}
From b84468414c84f045e8050f92043a9fbdcb152946 Mon Sep 17 00:00:00 2001
From: hyochan
Date: Thu, 16 Apr 2026 23:04:57 +0900
Subject: [PATCH 2/6] style(docs): fix prettier formatting
Co-Authored-By: Claude Opus 4.6 (1M context)
---
.../docs/src/pages/docs/android-setup.tsx | 10 ++++----
.../docs/src/pages/docs/updates/releases.tsx | 25 +++++++++----------
2 files changed, 17 insertions(+), 18 deletions(-)
diff --git a/packages/docs/src/pages/docs/android-setup.tsx b/packages/docs/src/pages/docs/android-setup.tsx
index 6604e17c..022c2aaa 100644
--- a/packages/docs/src/pages/docs/android-setup.tsx
+++ b/packages/docs/src/pages/docs/android-setup.tsx
@@ -209,11 +209,11 @@ function AndroidSetup() {
- The OpenIAP Android core library (openiap-google) requires{' '}
- minSdk 23 (Android 6.0) with Google Play Billing 8.x.
- Each framework library may require a higher minimum — check the{' '}
- framework-specific setup page for the exact
- value.
+ The OpenIAP Android core library (openiap-google)
+ requires minSdk 23 (Android 6.0) with Google Play
+ Billing 8.x. Each framework library may require a higher minimum —
+ check the framework-specific setup page for
+ the exact value.
diff --git a/packages/docs/src/pages/docs/updates/releases.tsx b/packages/docs/src/pages/docs/updates/releases.tsx
index 7e324fa3..8722a1e8 100644
--- a/packages/docs/src/pages/docs/updates/releases.tsx
+++ b/packages/docs/src/pages/docs/updates/releases.tsx
@@ -46,14 +46,13 @@ function Releases() {
color: 'var(--text-secondary)',
}}
>
- Until now, catching a failed payment before the platform
- silently downgrades or cancels a subscription required running
- your own server and polling Apple/Google Server-to-Server
- Notifications. With the new{' '}
- subscriptionBillingIssue event, apps can detect
- billing problems purely on the client — no backend infrastructure
- needed. Listen for the event, deep-link the user to the
- platform's subscription management screen via{' '}
+ Until now, catching a failed payment before the platform silently
+ downgrades or cancels a subscription required running your own
+ server and polling Apple/Google Server-to-Server Notifications.
+ With the new subscriptionBillingIssue event, apps can
+ detect billing problems purely on the client — no backend
+ infrastructure needed. Listen for the event, deep-link the user to
+ the platform's subscription management screen via{' '}
deepLinkToSubscriptions, and turn involuntary churn
into a recoverable moment.
@@ -68,8 +67,8 @@ function Releases() {
Schema: new{' '}
IapEvent.SubscriptionBillingIssue enum value and{' '}
- subscriptionBillingIssue: Purchase! subscription
- in event.graphql. Payload is the affected{' '}
+ subscriptionBillingIssue: Purchase! subscription in{' '}
+ event.graphql. Payload is the affected{' '}
Purchase.
@@ -347,9 +346,9 @@ function Releases() {
Breaking: ErrorCode gains{' '}
.serviceTimeout
{' '}
- — the shared spec schema adds ServiceTimeout, so the
- Swift ErrorCode enum picks up a new case. Any Swift
- consumer that does an exhaustive switch on{' '}
+ — the shared spec schema adds ServiceTimeout, so
+ the Swift ErrorCode enum picks up a new case. Any
+ Swift consumer that does an exhaustive switch on{' '}
ErrorCode without a default: branch
will need to add a .serviceTimeout case (or a
fallback), hence the major bump per SemVer. The enum is not{' '}
From cb081eb2ab1c495863386398defc0a012999a839 Mon Sep 17 00:00:00 2001
From: hyochan
Date: Fri, 17 Apr 2026 00:14:57 +0900
Subject: [PATCH 3/6] fix: address PR review comments
- kmp-iap iOS: throw NotImplementedError instead of returning emptyList
- Fix getAllTransactionsIOS doc comment to clarify behavioral difference
- Fix api-ios.graphql indentation for block-string descriptions
- Add AdvancedCommerceInfoIOS docs to purchase.tsx
- Add getAllTransactionsIOS to iOS API docs
Co-Authored-By: Claude Opus 4.6 (1M context)
---
.../github/hyochan/kmpiap/InAppPurchaseIOS.kt | 8 +-
packages/apple/Sources/OpenIapModule.swift | 10 +-
packages/docs/src/pages/docs/apis/ios.tsx | 13 ++-
.../docs/src/pages/docs/types/purchase.tsx | 91 +++++++++++++++++++
packages/gql/src/api-ios.graphql | 20 ++--
5 files changed, 125 insertions(+), 17 deletions(-)
diff --git a/libraries/kmp-iap/library/src/iosMain/kotlin/io/github/hyochan/kmpiap/InAppPurchaseIOS.kt b/libraries/kmp-iap/library/src/iosMain/kotlin/io/github/hyochan/kmpiap/InAppPurchaseIOS.kt
index 462f5bfb..561d4458 100644
--- a/libraries/kmp-iap/library/src/iosMain/kotlin/io/github/hyochan/kmpiap/InAppPurchaseIOS.kt
+++ b/libraries/kmp-iap/library/src/iosMain/kotlin/io/github/hyochan/kmpiap/InAppPurchaseIOS.kt
@@ -411,8 +411,12 @@ internal class InAppPurchaseIOS : KmpInAppPurchase {
}
}
- // TODO: Wire to ObjC bridge after openiap-apple publishes getAllTransactionsIOSWithCompletion
- override suspend fun getAllTransactionsIOS(): List = emptyList()
+ // TODO: Wire to ObjC bridge once getAllTransactionsIOSWithCompletion is available in consumed CocoaPods artifacts.
+ override suspend fun getAllTransactionsIOS(): List {
+ throw NotImplementedError(
+ "getAllTransactionsIOS is not available in this kmp-iap iOS build yet"
+ )
+ }
override suspend fun getReceiptDataIOS(): String? = suspendCoroutine { continuation ->
openIapModule.getReceiptDataIOSWithCompletion { result, error ->
diff --git a/packages/apple/Sources/OpenIapModule.swift b/packages/apple/Sources/OpenIapModule.swift
index 83fc71f0..6c60a193 100644
--- a/packages/apple/Sources/OpenIapModule.swift
+++ b/packages/apple/Sources/OpenIapModule.swift
@@ -503,10 +503,12 @@ public final class OpenIapModule: NSObject, OpenIapModuleProtocol {
return purchasedItems
}
- /// Get all transactions including finished consumables (iOS 18+).
- /// Requires the SK2ConsumableTransactionHistory Info.plist key in the host app.
- /// Returns all transactions from Transaction.all, including finished consumable
- /// transactions that would otherwise be excluded from getAvailablePurchases.
+ /// Get the full StoreKit 2 transaction history as `PurchaseIOS` values.
+ /// Requires the SK2ConsumableTransactionHistory Info.plist key in the host app
+ /// for finished consumables to be included in `Transaction.all` (iOS 18+).
+ /// Unlike `getAvailablePurchases(_:)`, this method always reads from
+ /// `Transaction.all` and returns the iOS-specific `PurchaseIOS` shape rather than
+ /// the cross-platform `Purchase` type.
public func getAllTransactionsIOS() async throws -> [PurchaseIOS] {
try await ensureConnection()
var transactions: [PurchaseIOS] = []
diff --git a/packages/docs/src/pages/docs/apis/ios.tsx b/packages/docs/src/pages/docs/apis/ios.tsx
index 9eeea9cf..5e3aef23 100644
--- a/packages/docs/src/pages/docs/apis/ios.tsx
+++ b/packages/docs/src/pages/docs/apis/ios.tsx
@@ -28,7 +28,8 @@ function IOSAPIs() {
Transaction Management
- : clearTransactionIOS, getPendingTransactionsIOS
+ : clearTransactionIOS, getPendingTransactionsIOS,
+ getAllTransactionsIOS
@@ -68,6 +69,16 @@ function IOSAPIs() {
Retrieve all pending transactions in the StoreKit queue.
{`func getPendingTransactionsIOS() async throws -> [Purchase]`}
+
+ getAllTransactionsIOS
+
+
+ Get the full StoreKit 2 transaction history as PurchaseIOS values.
+ Requires the SK2ConsumableTransactionHistory Info.plist key for
+ finished consumables to be included (iOS 18+).
+
+ {`func getAllTransactionsIOS() async throws -> [PurchaseIOS]`}
+
syncIOS
diff --git a/packages/docs/src/pages/docs/types/purchase.tsx b/packages/docs/src/pages/docs/types/purchase.tsx
index b3aa69dd..dec5960f 100644
--- a/packages/docs/src/pages/docs/types/purchase.tsx
+++ b/packages/docs/src/pages/docs/types/purchase.tsx
@@ -377,6 +377,18 @@ function TypesPurchase() {
below)
+
+
+ advancedCommerceInfoIOS
+ |
+
+ Advanced Commerce API metadata (iOS 18.4+, see{' '}
+
+ AdvancedCommerceInfoIOS
+ {' '}
+ below)
+ |
+
@@ -478,6 +490,85 @@ function TypesPurchase() {
+
+
+
+ AdvancedCommerceInfoIOS{' '}
+
+ (iOS 18.4+, from{' '}
+
+ Transaction.AdvancedCommerceInfo
+
+ )
+
+
+
+ Present only for transactions using the Advanced Commerce
+ API with generic SKU purchases.
+
+
+
+
+ | Name |
+ Summary |
+
+
+
+
+
+ items
+ |
+ Items purchased in this transaction |
+
+
+
+ requestReferenceId
+ |
+ Request reference identifier for tracking |
+
+
+
+ taxCode
+ |
+ Tax code for the transaction |
+
+
+
+ taxExclusivePrice
+ |
+ Price excluding tax (decimal string) |
+
+
+
+ estimatedTax
+ |
+ Estimated tax amount (decimal string) |
+
+
+
+ taxRate
+ |
+ Tax rate applied (decimal string) |
+
+
+
+ displayName
+ |
+ Optional display name |
+
+
+
+ description
+ |
+ Optional description |
+
+
+
+
>
),
android: (
diff --git a/packages/gql/src/api-ios.graphql b/packages/gql/src/api-ios.graphql
index 59ad4ba7..ba7802c0 100644
--- a/packages/gql/src/api-ios.graphql
+++ b/packages/gql/src/api-ios.graphql
@@ -81,19 +81,19 @@ extend type Query {
"""
# Future
getAppTransactionIOS: AppTransaction
-"""
- Get all transactions including finished consumables (iOS 18+).
- Requires the SK2ConsumableTransactionHistory Info.plist key in the host app.
- Returns all transactions from Transaction.all, including finished consumable
- transactions that would otherwise be excluded from getAvailablePurchases.
+ """
+ Get the full StoreKit 2 transaction history as PurchaseIOS values.
+ Requires the SK2ConsumableTransactionHistory Info.plist key in the host app
+ for finished consumables to be included (iOS 18+).
+ Unlike getAvailablePurchases, always returns the iOS-specific PurchaseIOS shape.
"""
# Future
getAllTransactionsIOS: [PurchaseIOS!]!
-"""
-Validate a receipt for a specific product
-"""
-# Future
-validateReceiptIOS(options: VerifyPurchaseProps!): VerifyPurchaseResultIOS! @deprecated(reason: "Use verifyPurchase")
+ """
+ Validate a receipt for a specific product
+ """
+ # Future
+ validateReceiptIOS(options: VerifyPurchaseProps!): VerifyPurchaseResultIOS! @deprecated(reason: "Use verifyPurchase")
}
extend type Mutation {
From 60e85030bdc398de3e31def6a5fdbbee26f6d2e4 Mon Sep 17 00:00:00 2001
From: hyochan
Date: Fri, 17 Apr 2026 00:34:43 +0900
Subject: [PATCH 4/6] fix: use UnsupportedOperationException and mark optional
fields in docs
- kmp-iap iOS: use UnsupportedOperationException instead of NotImplementedError
so callers catching Exception can handle it
- Mark optional AdvancedCommerceInfoIOS fields explicitly in purchase.tsx docs
Co-Authored-By: Claude Opus 4.6 (1M context)
---
.../io/github/hyochan/kmpiap/InAppPurchaseIOS.kt | 2 +-
packages/docs/src/pages/docs/types/purchase.tsx | 12 +++++++-----
2 files changed, 8 insertions(+), 6 deletions(-)
diff --git a/libraries/kmp-iap/library/src/iosMain/kotlin/io/github/hyochan/kmpiap/InAppPurchaseIOS.kt b/libraries/kmp-iap/library/src/iosMain/kotlin/io/github/hyochan/kmpiap/InAppPurchaseIOS.kt
index 561d4458..9131ce60 100644
--- a/libraries/kmp-iap/library/src/iosMain/kotlin/io/github/hyochan/kmpiap/InAppPurchaseIOS.kt
+++ b/libraries/kmp-iap/library/src/iosMain/kotlin/io/github/hyochan/kmpiap/InAppPurchaseIOS.kt
@@ -413,7 +413,7 @@ internal class InAppPurchaseIOS : KmpInAppPurchase {
// TODO: Wire to ObjC bridge once getAllTransactionsIOSWithCompletion is available in consumed CocoaPods artifacts.
override suspend fun getAllTransactionsIOS(): List {
- throw NotImplementedError(
+ throw UnsupportedOperationException(
"getAllTransactionsIOS is not available in this kmp-iap iOS build yet"
)
}
diff --git a/packages/docs/src/pages/docs/types/purchase.tsx b/packages/docs/src/pages/docs/types/purchase.tsx
index dec5960f..17074155 100644
--- a/packages/docs/src/pages/docs/types/purchase.tsx
+++ b/packages/docs/src/pages/docs/types/purchase.tsx
@@ -528,31 +528,33 @@ function TypesPurchase() {
requestReferenceId
|
- Request reference identifier for tracking |
+
+ Request reference identifier for tracking (optional)
+ |
taxCode
|
- Tax code for the transaction |
+ Tax code for the transaction (optional) |
taxExclusivePrice
|
- Price excluding tax (decimal string) |
+ Price excluding tax, decimal string (optional) |
estimatedTax
|
- Estimated tax amount (decimal string) |
+ Estimated tax amount, decimal string (optional) |
taxRate
|
- Tax rate applied (decimal string) |
+ Tax rate applied, decimal string (optional) |
From 1fbb68694939d33761639b3398c06d963dfe3ecc Mon Sep 17 00:00:00 2001
From: hyochan
Date: Fri, 17 Apr 2026 00:47:42 +0900
Subject: [PATCH 5/6] chore: regenerate types after api-ios.graphql doc update
Co-Authored-By: Claude Opus 4.6 (1M context)
---
libraries/expo-iap/src/types.ts | 8 ++++----
libraries/flutter_inapp_purchase/lib/types.dart | 8 ++++----
libraries/godot-iap/addons/godot-iap/types.gd | 4 ++--
.../kotlin/io/github/hyochan/kmpiap/openiap/Types.kt | 8 ++++----
libraries/react-native-iap/src/types.ts | 8 ++++----
packages/apple/Sources/Models/Types.swift | 8 ++++----
.../google/openiap/src/main/java/dev/hyo/openiap/Types.kt | 8 ++++----
packages/gql/src/generated/Types.kt | 8 ++++----
packages/gql/src/generated/Types.swift | 8 ++++----
packages/gql/src/generated/types.dart | 8 ++++----
packages/gql/src/generated/types.gd | 4 ++--
packages/gql/src/generated/types.ts | 8 ++++----
12 files changed, 44 insertions(+), 44 deletions(-)
diff --git a/libraries/expo-iap/src/types.ts b/libraries/expo-iap/src/types.ts
index c533d922..4afb30b7 100644
--- a/libraries/expo-iap/src/types.ts
+++ b/libraries/expo-iap/src/types.ts
@@ -1245,10 +1245,10 @@ export interface Query {
/** Get active subscriptions (filters by subscriptionIds when provided) */
getActiveSubscriptions: Promise;
/**
- * Get all transactions including finished consumables (iOS 18+).
- * Requires the SK2ConsumableTransactionHistory Info.plist key in the host app.
- * Returns all transactions from Transaction.all, including finished consumable
- * transactions that would otherwise be excluded from getAvailablePurchases.
+ * Get the full StoreKit 2 transaction history as PurchaseIOS values.
+ * Requires the SK2ConsumableTransactionHistory Info.plist key in the host app
+ * for finished consumables to be included (iOS 18+).
+ * Unlike getAvailablePurchases, always returns the iOS-specific PurchaseIOS shape.
*/
getAllTransactionsIOS: Promise;
/** Fetch the current app transaction (iOS 16+) */
diff --git a/libraries/flutter_inapp_purchase/lib/types.dart b/libraries/flutter_inapp_purchase/lib/types.dart
index f6d9017f..ea75b5b3 100644
--- a/libraries/flutter_inapp_purchase/lib/types.dart
+++ b/libraries/flutter_inapp_purchase/lib/types.dart
@@ -4978,10 +4978,10 @@ abstract class QueryResolver {
});
/// Get active subscriptions (filters by subscriptionIds when provided)
Future> getActiveSubscriptions([List? subscriptionIds]);
- /// Get all transactions including finished consumables (iOS 18+).
- /// Requires the SK2ConsumableTransactionHistory Info.plist key in the host app.
- /// Returns all transactions from Transaction.all, including finished consumable
- /// transactions that would otherwise be excluded from getAvailablePurchases.
+ /// Get the full StoreKit 2 transaction history as PurchaseIOS values.
+ /// Requires the SK2ConsumableTransactionHistory Info.plist key in the host app
+ /// for finished consumables to be included (iOS 18+).
+ /// Unlike getAvailablePurchases, always returns the iOS-specific PurchaseIOS shape.
Future> getAllTransactionsIOS();
/// Fetch the current app transaction (iOS 16+)
Future getAppTransactionIOS();
diff --git a/libraries/godot-iap/addons/godot-iap/types.gd b/libraries/godot-iap/addons/godot-iap/types.gd
index e8ba7cdb..f1b51f5a 100644
--- a/libraries/godot-iap/addons/godot-iap/types.gd
+++ b/libraries/godot-iap/addons/godot-iap/types.gd
@@ -5100,7 +5100,7 @@ class Query:
const return_type = "AppTransaction"
const is_array = false
- ## Get all transactions including finished consumables (iOS 18+).
+ ## Get the full StoreKit 2 transaction history as PurchaseIOS values.
class getAllTransactionsIOSField:
const name = "getAllTransactionsIOS"
const snake_name = "get_all_transactions_ios"
@@ -5682,7 +5682,7 @@ static func get_receipt_data_ios_args() -> Dictionary:
static func get_app_transaction_ios_args() -> Dictionary:
return {}
-## Get all transactions including finished consumables (iOS 18+).
+## Get the full StoreKit 2 transaction history as PurchaseIOS values.
static func get_all_transactions_ios_args() -> Dictionary:
return {}
diff --git a/libraries/kmp-iap/library/src/commonMain/kotlin/io/github/hyochan/kmpiap/openiap/Types.kt b/libraries/kmp-iap/library/src/commonMain/kotlin/io/github/hyochan/kmpiap/openiap/Types.kt
index 0e2360bc..becd8523 100644
--- a/libraries/kmp-iap/library/src/commonMain/kotlin/io/github/hyochan/kmpiap/openiap/Types.kt
+++ b/libraries/kmp-iap/library/src/commonMain/kotlin/io/github/hyochan/kmpiap/openiap/Types.kt
@@ -5001,10 +5001,10 @@ public interface QueryResolver {
*/
suspend fun getActiveSubscriptions(subscriptionIds: List? = null): List
/**
- * Get all transactions including finished consumables (iOS 18+).
- * Requires the SK2ConsumableTransactionHistory Info.plist key in the host app.
- * Returns all transactions from Transaction.all, including finished consumable
- * transactions that would otherwise be excluded from getAvailablePurchases.
+ * Get the full StoreKit 2 transaction history as PurchaseIOS values.
+ * Requires the SK2ConsumableTransactionHistory Info.plist key in the host app
+ * for finished consumables to be included (iOS 18+).
+ * Unlike getAvailablePurchases, always returns the iOS-specific PurchaseIOS shape.
*/
suspend fun getAllTransactionsIOS(): List
/**
diff --git a/libraries/react-native-iap/src/types.ts b/libraries/react-native-iap/src/types.ts
index c533d922..4afb30b7 100644
--- a/libraries/react-native-iap/src/types.ts
+++ b/libraries/react-native-iap/src/types.ts
@@ -1245,10 +1245,10 @@ export interface Query {
/** Get active subscriptions (filters by subscriptionIds when provided) */
getActiveSubscriptions: Promise;
/**
- * Get all transactions including finished consumables (iOS 18+).
- * Requires the SK2ConsumableTransactionHistory Info.plist key in the host app.
- * Returns all transactions from Transaction.all, including finished consumable
- * transactions that would otherwise be excluded from getAvailablePurchases.
+ * Get the full StoreKit 2 transaction history as PurchaseIOS values.
+ * Requires the SK2ConsumableTransactionHistory Info.plist key in the host app
+ * for finished consumables to be included (iOS 18+).
+ * Unlike getAvailablePurchases, always returns the iOS-specific PurchaseIOS shape.
*/
getAllTransactionsIOS: Promise;
/** Fetch the current app transaction (iOS 16+) */
diff --git a/packages/apple/Sources/Models/Types.swift b/packages/apple/Sources/Models/Types.swift
index 6a2226bb..a3547e12 100644
--- a/packages/apple/Sources/Models/Types.swift
+++ b/packages/apple/Sources/Models/Types.swift
@@ -2438,10 +2438,10 @@ public protocol QueryResolver {
func fetchProducts(_ params: ProductRequest) async throws -> FetchProductsResult
/// Get active subscriptions (filters by subscriptionIds when provided)
func getActiveSubscriptions(_ subscriptionIds: [String]?) async throws -> [ActiveSubscription]
- /// Get all transactions including finished consumables (iOS 18+).
- /// Requires the SK2ConsumableTransactionHistory Info.plist key in the host app.
- /// Returns all transactions from Transaction.all, including finished consumable
- /// transactions that would otherwise be excluded from getAvailablePurchases.
+ /// Get the full StoreKit 2 transaction history as PurchaseIOS values.
+ /// Requires the SK2ConsumableTransactionHistory Info.plist key in the host app
+ /// for finished consumables to be included (iOS 18+).
+ /// Unlike getAvailablePurchases, always returns the iOS-specific PurchaseIOS shape.
func getAllTransactionsIOS() async throws -> [PurchaseIOS]
/// Fetch the current app transaction (iOS 16+)
func getAppTransactionIOS() async throws -> AppTransaction?
diff --git a/packages/google/openiap/src/main/java/dev/hyo/openiap/Types.kt b/packages/google/openiap/src/main/java/dev/hyo/openiap/Types.kt
index fb66460d..bc6306db 100644
--- a/packages/google/openiap/src/main/java/dev/hyo/openiap/Types.kt
+++ b/packages/google/openiap/src/main/java/dev/hyo/openiap/Types.kt
@@ -4910,10 +4910,10 @@ public interface QueryResolver {
*/
suspend fun getActiveSubscriptions(subscriptionIds: List? = null): List
/**
- * Get all transactions including finished consumables (iOS 18+).
- * Requires the SK2ConsumableTransactionHistory Info.plist key in the host app.
- * Returns all transactions from Transaction.all, including finished consumable
- * transactions that would otherwise be excluded from getAvailablePurchases.
+ * Get the full StoreKit 2 transaction history as PurchaseIOS values.
+ * Requires the SK2ConsumableTransactionHistory Info.plist key in the host app
+ * for finished consumables to be included (iOS 18+).
+ * Unlike getAvailablePurchases, always returns the iOS-specific PurchaseIOS shape.
*/
suspend fun getAllTransactionsIOS(): List
/**
diff --git a/packages/gql/src/generated/Types.kt b/packages/gql/src/generated/Types.kt
index 1a7eb3ef..d5151235 100644
--- a/packages/gql/src/generated/Types.kt
+++ b/packages/gql/src/generated/Types.kt
@@ -4999,10 +4999,10 @@ public interface QueryResolver {
*/
suspend fun getActiveSubscriptions(subscriptionIds: List? = null): List
/**
- * Get all transactions including finished consumables (iOS 18+).
- * Requires the SK2ConsumableTransactionHistory Info.plist key in the host app.
- * Returns all transactions from Transaction.all, including finished consumable
- * transactions that would otherwise be excluded from getAvailablePurchases.
+ * Get the full StoreKit 2 transaction history as PurchaseIOS values.
+ * Requires the SK2ConsumableTransactionHistory Info.plist key in the host app
+ * for finished consumables to be included (iOS 18+).
+ * Unlike getAvailablePurchases, always returns the iOS-specific PurchaseIOS shape.
*/
suspend fun getAllTransactionsIOS(): List
/**
diff --git a/packages/gql/src/generated/Types.swift b/packages/gql/src/generated/Types.swift
index 6a2226bb..a3547e12 100644
--- a/packages/gql/src/generated/Types.swift
+++ b/packages/gql/src/generated/Types.swift
@@ -2438,10 +2438,10 @@ public protocol QueryResolver {
func fetchProducts(_ params: ProductRequest) async throws -> FetchProductsResult
/// Get active subscriptions (filters by subscriptionIds when provided)
func getActiveSubscriptions(_ subscriptionIds: [String]?) async throws -> [ActiveSubscription]
- /// Get all transactions including finished consumables (iOS 18+).
- /// Requires the SK2ConsumableTransactionHistory Info.plist key in the host app.
- /// Returns all transactions from Transaction.all, including finished consumable
- /// transactions that would otherwise be excluded from getAvailablePurchases.
+ /// Get the full StoreKit 2 transaction history as PurchaseIOS values.
+ /// Requires the SK2ConsumableTransactionHistory Info.plist key in the host app
+ /// for finished consumables to be included (iOS 18+).
+ /// Unlike getAvailablePurchases, always returns the iOS-specific PurchaseIOS shape.
func getAllTransactionsIOS() async throws -> [PurchaseIOS]
/// Fetch the current app transaction (iOS 16+)
func getAppTransactionIOS() async throws -> AppTransaction?
diff --git a/packages/gql/src/generated/types.dart b/packages/gql/src/generated/types.dart
index f6d9017f..ea75b5b3 100644
--- a/packages/gql/src/generated/types.dart
+++ b/packages/gql/src/generated/types.dart
@@ -4978,10 +4978,10 @@ abstract class QueryResolver {
});
/// Get active subscriptions (filters by subscriptionIds when provided)
Future> getActiveSubscriptions([List? subscriptionIds]);
- /// Get all transactions including finished consumables (iOS 18+).
- /// Requires the SK2ConsumableTransactionHistory Info.plist key in the host app.
- /// Returns all transactions from Transaction.all, including finished consumable
- /// transactions that would otherwise be excluded from getAvailablePurchases.
+ /// Get the full StoreKit 2 transaction history as PurchaseIOS values.
+ /// Requires the SK2ConsumableTransactionHistory Info.plist key in the host app
+ /// for finished consumables to be included (iOS 18+).
+ /// Unlike getAvailablePurchases, always returns the iOS-specific PurchaseIOS shape.
Future> getAllTransactionsIOS();
/// Fetch the current app transaction (iOS 16+)
Future getAppTransactionIOS();
diff --git a/packages/gql/src/generated/types.gd b/packages/gql/src/generated/types.gd
index e8ba7cdb..f1b51f5a 100644
--- a/packages/gql/src/generated/types.gd
+++ b/packages/gql/src/generated/types.gd
@@ -5100,7 +5100,7 @@ class Query:
const return_type = "AppTransaction"
const is_array = false
- ## Get all transactions including finished consumables (iOS 18+).
+ ## Get the full StoreKit 2 transaction history as PurchaseIOS values.
class getAllTransactionsIOSField:
const name = "getAllTransactionsIOS"
const snake_name = "get_all_transactions_ios"
@@ -5682,7 +5682,7 @@ static func get_receipt_data_ios_args() -> Dictionary:
static func get_app_transaction_ios_args() -> Dictionary:
return {}
-## Get all transactions including finished consumables (iOS 18+).
+## Get the full StoreKit 2 transaction history as PurchaseIOS values.
static func get_all_transactions_ios_args() -> Dictionary:
return {}
diff --git a/packages/gql/src/generated/types.ts b/packages/gql/src/generated/types.ts
index c533d922..4afb30b7 100644
--- a/packages/gql/src/generated/types.ts
+++ b/packages/gql/src/generated/types.ts
@@ -1245,10 +1245,10 @@ export interface Query {
/** Get active subscriptions (filters by subscriptionIds when provided) */
getActiveSubscriptions: Promise;
/**
- * Get all transactions including finished consumables (iOS 18+).
- * Requires the SK2ConsumableTransactionHistory Info.plist key in the host app.
- * Returns all transactions from Transaction.all, including finished consumable
- * transactions that would otherwise be excluded from getAvailablePurchases.
+ * Get the full StoreKit 2 transaction history as PurchaseIOS values.
+ * Requires the SK2ConsumableTransactionHistory Info.plist key in the host app
+ * for finished consumables to be included (iOS 18+).
+ * Unlike getAvailablePurchases, always returns the iOS-specific PurchaseIOS shape.
*/
getAllTransactionsIOS: Promise;
/** Fetch the current app transaction (iOS 16+) */
From a60aae67e98bbd97d687ff751859f218b0e88b08 Mon Sep 17 00:00:00 2001
From: hyochan
Date: Fri, 17 Apr 2026 00:50:48 +0900
Subject: [PATCH 6/6] fix(readme): CI badge should only track main branch
Co-Authored-By: Claude Opus 4.6 (1M context)
---
README.md | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/README.md b/README.md
index 3c1e723d..7d4aa519 100644
--- a/README.md
+++ b/README.md
@@ -22,8 +22,8 @@ This monorepo contains all OpenIAP packages:
- **[docs](packages/docs)** - Documentation site at [openiap.dev](https://openiap.dev)
- **[spec](packages/gql)** - OpenIAP specification and type generation [](https://github.com/hyodotdev/openiap/releases?q=gql&expanded=true)
-- **[google](packages/google)** - Android library [](https://central.sonatype.com/artifact/io.github.hyochan.openiap/openiap-google) [](https://central.sonatype.com/artifact/io.github.hyochan.openiap/openiap-google-horizon) [](https://github.com/hyodotdev/openiap/actions/workflows/ci.yml)
-- **[apple](packages/apple)** - iOS/macOS library [](https://github.com/hyodotdev/openiap/releases?q=Apple&expanded=true) [](https://cocoapods.org/pods/openiap) [](https://github.com/hyodotdev/openiap/actions/workflows/ci.yml)
+- **[google](packages/google)** - Android library [](https://central.sonatype.com/artifact/io.github.hyochan.openiap/openiap-google) [](https://central.sonatype.com/artifact/io.github.hyochan.openiap/openiap-google-horizon) [](https://github.com/hyodotdev/openiap/actions/workflows/ci.yml?query=branch%3Amain)
+- **[apple](packages/apple)** - iOS/macOS library [](https://github.com/hyodotdev/openiap/releases?q=Apple&expanded=true) [](https://cocoapods.org/pods/openiap) [](https://github.com/hyodotdev/openiap/actions/workflows/ci.yml?query=branch%3Amain)
## Libraries
|