Use this page with AI Copy this into your coding assistant and add your request.
Read https://openiap.dev/docs/types/ios/app-transaction-ios and https://openiap.dev/llms.txt. Follow the reading instructions, detailed reference, and linked guides relevant to my task before making changes.
Inspect my existing project and reuse its framework and conventions. Ask me for missing product decisions. Implement the requested behavior and run the applicable checks.
Show the working result, the commands and actual test results, and any remaining limitations. Keep your explanation brief.
My request: [describe what customers should be able to do]See an example request → AppTransaction AppTransaction# Represents the app transaction information returned by getAppTransactionIOS() . Contains metadata about the app's purchase and installation.
iOS only. Mirrors AppTransaction (iOS 16+) — the JWS-verified record of how the app was acquired (Apple docs ).
Native reference: Apple · StoreKit AppTransaction
Fields# Name Summary bundleIdApp bundle identifier appVersionCurrent app version originalAppVersionVersion when user originally purchased/downloaded originalPurchaseDateOriginal purchase timestamp deviceVerificationDevice verification data deviceVerificationNonceNonce for device verification environmentEnvironment: "Sandbox" or "Production" signedDateDate when the transaction was signed appIdApp ID number appVersionIdApp version ID number preorderDatePreorder date (optional) appTransactionIdStable app transaction ID. Introduced on iOS 18.4, macOS 15.4, tvOS 18.4, watchOS 11.4, and visionOS 2.4; StoreKit back-deploys it across the supported AppTransaction runtime range when built with Xcode 16.4+. originalPlatformOriginal platform. OpenIAP uses StoreKit's compatibility string on the AppTransaction baseline and the typed value on iOS 18.4, macOS 15.4, tvOS 18.4, watchOS 11.4, and visionOS 2.4 or later. Xcode 16.4+ provides the compatibility path; the Xcode 27 SDK also adds the back-deployed managed value. revocationDateApp-acquisition revocation timestamp. The Xcode 27 SDK exposes this back-deployed property on Apple 16+. storeTypeStore channel of the original app acquisition, such as consumer, education, or enterprise (Xcode 27 / Apple 27).
Xcode 27 boundary
StoreKit also exposes AppTransaction.all, an async sequence of app-acquisition records. OpenIAP 3 does not export that sequence. getAppTransactionIOS returns the current verified app transaction, while getAllTransactionsIOS remains in-app purchase history; the two histories are not interchangeable.
Type Definition# struct AppTransaction {
let bundleId: String
let appVersion: String
let originalAppVersion: String
let originalPurchaseDate: Double // epoch ms
let deviceVerification: String
let deviceVerificationNonce: String
let environment: String // "Sandbox" | "Production"
let signedDate: Double // epoch ms
let appId: Double
let appVersionId: Double
let preorderDate: Double? // epoch ms
// iOS 18.4+ properties
let appTransactionId: String?
let originalPlatform: String?
// Published by the Xcode 27 SDK; availability follows each StoreKit property
let revocationDate: Double? // epoch ms
let storeType: String?
}Kotlin example data class AppTransaction(
val bundleId: String,
val appVersion: String,
val originalAppVersion: String,
val originalPurchaseDate: Double, // epoch ms
val deviceVerification: String,
val deviceVerificationNonce: String,
val environment: String, // "Sandbox" | "Production"
val signedDate: Double, // epoch ms
val appId: Double,
val appVersionId: Double,
val preorderDate: Double? = null,
// iOS 18.4+ properties
val appTransactionId: String? = null,
val originalPlatform: String? = null,
// Published by the Xcode 27 SDK; availability follows each StoreKit property
val revocationDate: Double? = null,
val storeType: String? = null
)TypeScript example interface AppTransaction {
bundleId: string;
appVersion: string;
originalAppVersion: string;
originalPurchaseDate: number; // epoch ms
deviceVerification: string;
deviceVerificationNonce: string;
environment: string;
signedDate: number; // epoch ms
appId: number;
appVersionId: number;
preorderDate?: number | null; // epoch ms
// iOS 18.4+ properties
appTransactionId?: string | null;
originalPlatform?: string | null;
// Published by the Xcode 27 SDK; availability follows each StoreKit property
revocationDate?: number | null; // epoch ms
storeType?: string | null;
}Dart example class AppTransaction {
final String bundleId;
final String appVersion;
final String originalAppVersion;
final double originalPurchaseDate; // epoch ms
final String deviceVerification;
final String deviceVerificationNonce;
final String environment; // "Sandbox" | "Production"
final double signedDate; // epoch ms
final double appId;
final double appVersionId;
final double? preorderDate;
// iOS 18.4+ properties
final String? appTransactionId;
final String? originalPlatform;
// Published by the Xcode 27 SDK; availability follows each StoreKit property
final double? revocationDate;
final String? storeType;
AppTransaction({
required this.bundleId,
required this.appVersion,
required this.originalAppVersion,
required this.originalPurchaseDate,
required this.deviceVerification,
required this.deviceVerificationNonce,
required this.environment,
required this.signedDate,
required this.appId,
required this.appVersionId,
this.preorderDate,
this.appTransactionId,
this.originalPlatform,
this.revocationDate,
this.storeType,
});
}C# (MAUI) example using OpenIap;
public sealed record AppTransaction
{
public required string BundleId { get; init; }
public required string AppVersion { get; init; }
public required string OriginalAppVersion { get; init; }
public required double OriginalPurchaseDate { get; init; } // epoch ms
public required string DeviceVerification { get; init; }
public required string DeviceVerificationNonce { get; init; }
public required string Environment { get; init; } // "Sandbox" | "Production"
public required double SignedDate { get; init; } // epoch ms
public required double AppId { get; init; }
public required double AppVersionId { get; init; }
public double? PreorderDate { get; init; }
// iOS 18.4+ properties
public string? AppTransactionId { get; init; }
public string? OriginalPlatform { get; init; }
// Published by the Xcode 27 SDK; availability follows each StoreKit property
public double? RevocationDate { get; init; }
public string? StoreType { get; init; }
}GDScript example class AppTransaction:
var bundle_id: String
var app_version: String
var original_app_version: String
var original_purchase_date: float # epoch ms
var device_verification: String
var device_verification_nonce: String
var environment: String
var signed_date: float # epoch ms
var app_id: float
var app_version_id: float
var preorder_date: Variant # optional, epoch ms
# iOS 18.4+ properties
var app_transaction_id: Variant
var original_platform: Variant
# Published by the Xcode 27 SDK; availability follows each StoreKit property
var revocation_date: Variant
var store_type: VariantUsage Example# import OpenIap
// Get app transaction (iOS only)
let appTransaction = try await OpenIapModule.shared.getAppTransactionIOS()
if let transaction = appTransaction {
print("Bundle ID: \(transaction.bundleId)")
print("Original version: \(transaction.originalAppVersion)")
print("Environment: \(transaction.environment)")
// Check if user originally purchased on a different platform (iOS 18.4+)
if let platform = transaction.originalPlatform {
print("Originally purchased on: \(platform)")
}
}Kotlin example import io.github.hyochan.kmpiap.kmpIapInstance
// Get app transaction (iOS only via KMP)
val appTransaction = kmpIapInstance.getAppTransactionIOS()
appTransaction?.let { transaction ->
println("Bundle ID: ${transaction.bundleId}")
println("Original version: ${transaction.originalAppVersion}")
println("Environment: ${transaction.environment}")
// Check if user originally purchased on a different platform (iOS 18.4+)
transaction.originalPlatform?.let { platform ->
println("Originally purchased on: $platform")
}
}TypeScript example import { getAppTransactionIOS } from 'expo-iap';
// Get app transaction (iOS only)
const appTransaction = await getAppTransactionIOS();
if (appTransaction) {
console.log('Bundle ID:', appTransaction.bundleId);
console.log('Original version:', appTransaction.originalAppVersion);
console.log('Environment:', appTransaction.environment);
// Check if user originally purchased on a different platform (iOS 18.4+)
if (appTransaction.originalPlatform) {
console.log('Originally purchased on:', appTransaction.originalPlatform);
}
}Dart example import 'package:flutter_inapp_purchase/flutter_inapp_purchase.dart';
// Get app transaction (iOS only)
final appTransaction = await FlutterInappPurchase.instance.getAppTransactionIOS();
if (appTransaction != null) {
print('Bundle ID: ${appTransaction.bundleId}');
print('Original version: ${appTransaction.originalAppVersion}');
print('Environment: ${appTransaction.environment}');
// Check if user originally purchased on a different platform (iOS 18.4+)
if (appTransaction.originalPlatform != null) {
print('Originally purchased on: ${appTransaction.originalPlatform}');
}
}C# (MAUI) example using OpenIap;
using OpenIap.Maui;
var appTransaction =
await ((QueryResolver)OpenIapClient.Instance).GetAppTransactionIOSAsync();
if (appTransaction is not null)
{
Console.WriteLine(
quot;Bundle ID: {appTransaction.BundleId}");
Console.WriteLine(
quot;Original version: {appTransaction.OriginalAppVersion}");
Console.WriteLine(
quot;Environment: {appTransaction.Environment}");
if (appTransaction.OriginalPlatform is string platform)
{
Console.WriteLine(
quot;Originally purchased on: {platform}");
}
}GDScript example # Get app transaction (iOS only)
var app_transaction = await iap.get_app_transaction_ios()
if app_transaction != null:
print("Bundle ID: %s" % app_transaction.bundle_id)
print("Original version: %s" % app_transaction.original_app_version)
print("Environment: %s" % app_transaction.environment)
# Check if user originally purchased on a different platform (iOS 18.4+)
if app_transaction.original_platform != "":
print("Originally purchased on: %s" % app_transaction.original_platform)