Use this page with AI
Copy this into your coding assistant and add your request.
Read https://openiap.dev/docs/types/purchase 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]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).
Native references: Apple · StoreKit Transaction · Google · Purchase
PurchaseState#
Enum representing the current state of a purchase:
| Name | Summary | Platform |
|---|---|---|
Pending | Purchase initiated, awaiting completion | Android |
Purchased | Payment successful, needs validation | iOS, Android |
Unknown | State could not be determined | Android |
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:
| Name | Summary |
|---|---|
id | Purchase identifier (primary key). Maps to orderId on Android, transactionId on iOS |
productId | Product identifier that was purchased |
ids | Array of SKUs for bundled purchases (optional) |
transactionDate | Transaction timestamp (epoch ms) |
purchaseToken | JWS token (iOS) or Play purchase token (Android) for server validation |
store | Fixed store discriminator: "apple", "google", "horizon", "amazon", or "unknown" |
storeId | Required stable store id: apple, play, horizon, amazon, or the community provider id. Store identity · upgrade notes |
quantity | Number of items purchased |
purchaseState | Current purchase state (see PurchaseState above) |
isAutoRenewing | Legacy renewal hint that cannot represent unknown. Use nullable platform renewal metadata or backend status for renewal decisions. |
currentPlanId | Unified 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:
| Name | Summary |
|---|---|
quantityIOS | Purchase quantity (iOS-specific) |
originalTransactionDateIOS | Original purchase timestamp (for renewals/restores) |
originalTransactionIdentifierIOS | Original transaction ID (links renewal chain) |
appAccountToken | Your 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. |
expirationDateIOS | Subscription expiration timestamp |
webOrderLineItemIdIOS | Web order line item ID |
environmentIOS | Environment: "Sandbox" or "Production" |
storefrontCountryCodeIOS | Storefront country code |
appBundleIdIOS | App bundle identifier |
subscriptionGroupIdIOS | Subscription group identifier |
isUpgradedIOS | True if this transaction was upgraded |
ownershipTypeIOS | Ownership type: purchased, familyShared, or the Xcode 27 SDK's back-deployed assigned value |
reasonIOS | StoreKit 2 transaction reason (StoreKit raw value) |
reasonStringRepresentationIOS | String representation of the reason value |
transactionReasonIOS | Reason: "PURCHASE" or "RENEWAL" |
revocationDateIOS | Revocation timestamp (if refunded) |
revocationReasonIOS | Revocation reason, including upgraded_to_bundle for a subscription moved into an Apple Subscription Bundle |
revocationTypeIOS | StoreKit revocation type raw value, such as full refund, prorated refund, Family Sharing revocation, or assignment revocation (Apple 26.4+ with the Xcode 27 SDK) |
offerIOS | Applied offer details. Contains: id, type, paymentMode |
billingPlanTypeIOS | StoreKit 26.4 billing plan selected for a subscription transaction: monthly, up-front, or unknown. |
commitmentInfoIOS | Commitment state for the transaction, including current billing period, total periods, expiration, and price. See TransactionCommitmentInfoIOS. |
bundleOriginalTransactionIdIOS | Original transaction ID of the Subscription Bundle or Suite associated with this component transaction (Xcode 27 SDK). |
bundleProductIdIOS | Product ID of the associated bundle or suite. |
bundleSubscriptionGroupIdIOS | Subscription-group ID of the associated bundle or suite. |
bundleTransactionIdIOS | Bundle transaction ID linked to this component transaction. |
previousOriginalTransactionIdIOS | Original transaction replaced when moving between a standalone subscription and a bundle. |
currencyCodeIOS | ISO 4217 currency code |
currencySymbolIOS | Currency symbol |
countryCodeIOS | Country code |
renewalInfoIOS | Subscription renewal information — see RenewalInfoIOS. |
advancedCommerceInfoIOS | Advanced 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.
| Name | Summary |
|---|---|
items | Items purchased in this transaction |
period | Subscription period unit and value (optional) |
requestReferenceId | Request reference identifier for tracking (optional) |
taxCode | Tax code for the transaction (optional) |
taxExclusivePrice | Price excluding tax, decimal string (optional) |
estimatedTax | Estimated tax amount, decimal string (optional) |
taxRate | Tax rate applied, decimal string (optional) |
displayName | Optional display name |
description | Optional 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).
| Name | Platform | Default | Summary |
|---|---|---|---|
alsoPublishToEventListenerIOS | iOS | false | When 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. |
onlyIncludeActiveItemsIOS | iOS | false | Switches 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. |
includeSuspendedAndroid | Android | false | When 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. |