Purchase

Purchase#

Represents a completed or pending purchase transaction. The type is a union of PurchaseIOS and PurchaseAndroid, discriminated by the platform field.

Normalized purchase / transaction record. iOS: derived from Transaction (Apple docs). Android: derived from Purchase (Google docs).

PurchaseState#

Enum representing the current state of a purchase:

NameSummaryPlatform
PendingPurchase initiated, awaiting completionAndroid
PurchasedPayment successful, needs validationiOS, Android
UnknownState could not be determinedAndroid

Note: iOS StoreKit 2 only returns Transaction objects on successful purchases, so iOS purchases always have Purchased state. See release notes for details.

Common Fields#

These fields are available on both iOS and Android:

NameSummary
idPurchase identifier (primary key). Maps to orderId on Android, transactionId on iOS
productIdProduct identifier that was purchased
idsArray of SKUs for bundled purchases (optional)
transactionDateTransaction timestamp (epoch ms)
purchaseTokenJWS token (iOS) or Play purchase token (Android) for server validation
storeStore discriminator: "apple", "google", or "horizon"
quantityNumber of items purchased
purchaseStateCurrent purchase state (see PurchaseState above)
isAutoRenewingWhether subscription will auto-renew
currentPlanIdUnified plan identifier. On Android: basePlanId (e.g., "premium"). On iOS: productId (e.g., "com.example.premium_monthly"). ⚠️ Android: May be inaccurate for multi-plan subscriptions. See limitation.

The shared id field maps to Google Play's orderId. When Play omits it—common for consumables—the SDK falls back to the long purchaseToken so you retain a stable primary key.

Platform-Specific Fields#

PurchaseIOS#

Additional fields available on iOS:

NameSummary
quantityIOSPurchase quantity (iOS-specific)
originalTransactionDateIOSOriginal purchase timestamp (for renewals/restores)
originalTransactionIdentifierIOSOriginal transaction ID (links renewal chain)
appAccountTokenYour server's user identifier (UUID you provided at purchase). Only returned if a valid UUID format was provided during purchase—non-UUID values result in null.
expirationDateIOSSubscription expiration timestamp
webOrderLineItemIdIOSWeb order line item ID
environmentIOSEnvironment: "Sandbox" or "Production"
storefrontCountryCodeIOSStorefront country code
appBundleIdIOSApp bundle identifier
subscriptionGroupIdIOSSubscription group identifier
isUpgradedIOSTrue if this transaction was upgraded
ownershipTypeIOSOwnership type: purchased, familyShared, or the Xcode 27 SDK's back-deployed assigned value
reasonIOSStoreKit 2 transaction reason (StoreKit raw value)
reasonStringRepresentationIOSString representation of the reason value
transactionReasonIOSReason: "PURCHASE" or "RENEWAL"
revocationDateIOSRevocation timestamp (if refunded)
revocationReasonIOSRevocation reason, including upgraded_to_bundle for a subscription moved into an Apple Subscription Bundle
revocationTypeIOSStoreKit revocation type raw value, such as full refund, prorated refund, Family Sharing revocation, or assignment revocation (Apple 26.4+ with the Xcode 27 SDK)
offerIOSApplied offer details. Contains: id, type, paymentMode
billingPlanTypeIOSStoreKit 26.4 billing plan selected for a subscription transaction: monthly, up-front, or unknown.
commitmentInfoIOSCommitment state for the transaction, including current billing period, total periods, expiration, and price. See TransactionCommitmentInfoIOS.
bundleOriginalTransactionIdIOSOriginal transaction ID of the Subscription Bundle or Suite associated with this component transaction (Xcode 27 SDK).
bundleProductIdIOSProduct ID of the associated bundle or suite.
bundleSubscriptionGroupIdIOSSubscription-group ID of the associated bundle or suite.
bundleTransactionIdIOSBundle transaction ID linked to this component transaction.
previousOriginalTransactionIdIOSOriginal transaction replaced when moving between a standalone subscription and a bundle.
currencyCodeIOSISO 4217 currency code
currencySymbolIOSCurrency symbol
countryCodeIOSCountry code
renewalInfoIOSSubscription renewal information — see RenewalInfoIOS.
advancedCommerceInfoIOSAdvanced Commerce API metadata (iOS 18.4+, see AdvancedCommerceInfoIOS below)

renewalInfoIOS resolves to RenewalInfoIOS — see that page for the full field reference.

AdvancedCommerceInfoIOS (iOS 18.4+, from Transaction.AdvancedCommerceInfo)#

Present only for transactions using the Advanced Commerce API with generic SKU purchases. On Apple 27, each item's details.jsonRepresentation also contains a partners array with partner id and name values.

NameSummary
itemsItems purchased in this transaction
periodSubscription period unit and value (optional)
requestReferenceIdRequest reference identifier for tracking (optional)
taxCodeTax code for the transaction (optional)
taxExclusivePricePrice excluding tax, decimal string (optional)
estimatedTaxEstimated tax amount, decimal string (optional)
taxRateTax rate applied, decimal string (optional)
displayNameOptional display name
descriptionOptional description

PurchaseOptions#

Optional input to getAvailablePurchases. PurchaseOptions does not have its own dedicated page — it lives here next to Purchase because every field is platform- specific and changes which subset of purchases the query returns.

All fields are optional; pass null / omit the argument entirely to use defaults. iOS-only fields are ignored on Android (and vice-versa).

NamePlatformDefaultSummary
alsoPublishToEventListenerIOSiOSfalseWhen true, every purchase returned by the query is also re-emitted on purchaseUpdatedListener so existing listeners can process them with the same code path used for live purchases.
onlyIncludeActiveItemsIOSiOSfalseSwitches the query from Transaction.all (full StoreKit 2 history, including refunded / revoked entries) to Transaction.currentEntitlements, which narrows the result to active non-consumables and live subscriptions.
includeSuspendedAndroidAndroidfalseWhen true, includes subscriptions in a paused or grace-period state in the returned list. Suspended subscriptions should not grant entitlements — see isSuspendedAndroid on the Purchase fields above.