Documentation

​
​

Development

User Acquisition

Monetization

Industry

In-App Purchasing

IAP Client API

IAP SDK API

Webshop Admin API

Webshop Client API

In-App Purchasing

LiveOps
​
​
Get started
  • Overview
  • Introduction to IAP
  • What's new in IAP v5.4
  • Upgrade from IAP v4 to v5
  • AI skill for In-App Purchasing
Direct to Consumer (D2C) payments
  • Direct to Consumer (D2C) payment providers
Webshop
  • Overview
  • Get started with webshops
  • Webshop setup
  • Catalog and payments
  • Game integration for webshops
  • Troubleshooting webshops
Platform-native stores
  • Set up IAP for platform-native stores
  • Codeless IAP
Catalogs and store management
  • Create product catalogs
    • Catalogs and catalog listings
    • Catalog schema
    • Create a catalog in the Editor
    • IAP Catalog window reference
    • Create your catalog programmatically
    • Create Remote Catalog
    • Set up store credentials for catalog import
    • Troubleshooting catalog import
    • Manage catalogs in the Dashboard
    • Codeless IAP
    • Stores
    • Purchases
    • Receipt validation
    • Restore purchases
  • Supported stores
Purchases
  • Purchase management and fulfillment
    • Purchases
    • Receipt validation
    • Restore purchases
    • SubscriptionInfo class reference
Monitor IAP performance
  • Overview
  • IAP revenue performance
  • D2C performance
Privacy
  • Privacy and consent
  1. Unity In-App Purchasing

Purchases

Retrieve purchase information and determine purchase status for products bought by players.
Read time 1 minute
Last updated 7 months ago

Unity IAP fetches purchase information from the store so your application can recognize and fulfill what players have bought. This ensures that your game can deliver content or entitlements to users based on their purchase history, even if they bought items outside your app or on another device.
A purchase is represented as an
Order
object. The
Order
contains all relevant details about the purchase and provides information needed to track and manage it with the store.

Retrieve purchases

Purchases made by the user can be retrieved from the store. However, consumable products must be tracked by your application after they are consumed, because stores don't return consumables that have already been fulfilled. For non-consumable products and subscriptions, the store accurately returns these purchases when you call
FetchPurchases
or
CheckEntitlement
.

Determine purchase status

You can determine the status of a purchase in two ways:
  • Use
    Order
    to determine if the
    Order
    is a
    PendingOrder
    ,
    ConfirmedOrder
    ,
    DeferredOrder
    or
    FailedOrder
    .
  • Use
    CheckEntitlement
    to receive
    EntitlementStatus
    , which returns
    EntitledButNotFinished
    ,
    EntitledUntilConsumed
    ,
    FullyEntitled
    ,
    NotEntitled
    or
    Unknown
    .

Purchase attributes

Attribute

Description

transactionId
A unique identifier for the purchase.
product
The purchased product.
quantity
The quantity of the product purchased.
receipt
Receipt data for validating the purchase with the store.

Purchase states

State

Description

Pending
The purchase has been paid but not yet fulfilled.
Confirmed
The purchase has been fulfilled and acknowledged.
Failed
The purchase failed due to an error.
Deferred
The purchase is waiting for payment.

Process purchases

The
OnPurchasePending
callback is invoked when a purchase is made and is awaiting fulfillment. Your application should fulfill the purchase at this point, for example by unlocking local content or sending the purchase receipt to a server to update a server-side game model.
Note that
OnPurchasePending
may be called at any point following a successful initialization. If your application crashes during execution of the
OnPurchasePending
handler, then it is invoked again the next time Unity IAP initializes. Consider implementing your own de-duplication logic.
Note
If you don't confirm purchases, the store sends back the purchases, and some stores may even refund it automatically to protect the users.
// Handle restore on initializationprivate async void Start(){ // Setup, e.g. add listeners to your StoreController... m_StoreController.OnPurchasePending += OnPurchasePending; m_StoreController.OnPurchasesFetched += OnPurchasesFetched; await m_StoreController.Connect(); // Fetch previous purchases (includes confirmed orders) m_StoreController.FetchPurchases();}// Handle new purchases and pending transactionsprivate void OnPurchasePending(PendingOrder order){ ProcessPurchase(order);}// Handle fetched purchases (includes previously confirmed orders)private void OnPurchasesFetched(Orders orders){ foreach (var confirmedOrder in orders.ConfirmedOrders) { if (confirmedOrder.CartOrdered.Items().FirstOrDefault()?.Product.definition.type != ProductType.Consumable) { // Mark non-consumable and subscription products as entitled on fetch, as they only need to be granted once MarkAsEntitled(confirmedOrder.CartOrdered.Items().FirstOrDefault().Product); } }}// Your ProcessPurchase logicprivate void ProcessPurchase(PendingOrder order){ foreach (var product in order.CartOrdered.Items()) { // Grant product GrantProduct(product); } // Confirm the order to finalize the transaction m_StoreController.ConfirmPurchase(order);}

Reflect purchase state in your UI

Keep your buy buttons in sync with the purchase and entitlement state that Unity IAP reports, rather than treating them as always available. Syncing button states prevents duplicate purchase attempts, avoids offering a product the player already owns, and gives clear feedback while a purchase is processing. The correct mapping depends on the product type.

Non-consumables and subscriptions

Non-consumable and subscription products are entitled once and shouldn't be offered for purchase while the user owns them.
After
FetchPurchases
succeeds, or when
CheckEntitlement
returns
FullyEntitled
, reflect that entitlement state in your UI instead of a purchase action:
  • Non-consumables: Show an Owned state. Non-consumables are purchased once and owned forever, so no further action is needed unless the purchase is later refunded.
  • Subscriptions: Show a Manage or Renew action. Unlike non-consumables, subscriptions can expire or be canceled, so provide a mechanism for the player to manage, renew, or cancel them.
Because subscriptions can expire, reevaluate subscription state on each app launch. Don't permanently cache subscriptions as owned.

Consumables

Consumables are normally available for purchase. Don't deactivate the buy button based on entitlement.
NotEntitled
is expected for a consumable that the player can buy again.
Only deactivate the buy button when there's an unfinished order. If a consumable has an associated
PendingOrder
, either reported through
OnPurchasePending
or returned as
EntitledUntilConsumed
by
CheckEntitlement
, complete the order before reenabling the button:
  1. Grant the reward.
  2. Call
    ConfirmPurchase
    .
  3. Re-enable the buy button.
Don't permanently deactivate the buy button of a consumable after purchase.

Update the button state during purchase flow

Deactivate the buy button when the purchase starts, whether you call
PurchaseProduct
or the Direct-to-Consumer (D2C)
ShowPurchaseOption
.
Because the button is deactivated when the purchase starts, update its state in every callback that can resolve the purchase attempt. Otherwise, the button can remain deactivated.
Update the button state in the following callbacks when the purchase attempt resolves:

Callback

Description

OnPurchasePending
The purchase is paid and awaiting fulfillment. This order can be a new purchase or an unconfirmed order redelivered at launch. After you fulfill and confirm the order, set the resolved state: owned for a non-consumable product or subscription, or buyable for a consumable product. For more information, refer to Process purchases.
OnPurchaseConfirmed
The order has been fulfilled and acknowledged. Use this callback to set the final owned state for non-consumable products and subscriptions if you don't do so in
OnPurchasePending
.
OnPurchaseFailed
The purchase failed or the player canceled it. Return the button to its buyable state.
OnPurchaseDeferred
The purchase is deferred and waiting to complete, such as for Ask to Buy approval. Show a waiting state instead of re-enabling the button.
OnPurchasesFetched
Purchases retrieved on launch or restore. Set the owned state for any non-consumable products and subscriptions the player already owns.
OnPurchasesFetchFailed
The fetch couldn't complete, including when the device is offline and the status is
Unknown
. Leave the button in its buyable state so the player isn't locked out of a purchase they're entitled to make.
Register these callbacks on your
StoreController
during setup, as shown in the example in Process purchases.
Note
You don't need to call
CheckEntitlement
to keep the UI in sync. The purchase and entitlement state is available from the
Order
objects that
FetchPurchases
returns and from pending orders delivered through
OnPurchasePending
.
CheckEntitlement
is an optional convenience method that returns the status of a single product, so you don't have to inspect fetched orders yourself.

Purchase acknowledgement and reliability

Unity IAP requires you to explicitly acknowledge purchases to ensure that purchases are reliably fulfilled, even during network outages or application crashes. If a purchase is paid for but not fulfilled, Unity IAP delivers the purchase to your application the next time it initializes. This process prevents purchases from being lost when the purchase flow is interrupted or when purchases are completed while the application is offline.
After successfully fulfilling a purchase, call
ConfirmPurchase
with the relevant
PendingOrder
to acknowledge the purchase to the store.
Warning
Always acknowledge purchases. If you don't, the following can happen:
  • Unity IAP re-invokes
    OnPurchasePending
    for the order on every subsequent
    FetchPurchases
    call or session start until you acknowledge it. Without your own de-duplication logic, this can grant the same item more than once.
  • Some stores reverse the purchase automatically. For example, Google Play refunds an unacknowledged purchase after three days, and the Apple App Store applies similar protective logic on a less strict timeline.
  • To the player, the purchase appears to succeed and then disappear, which looks like a broken purchase.
Note
For consumables, once you acknowledge the purchase, the store does not return it again. Always persist consumable rewards remotely. If you store consumable rewards locally, you risk losing data with no way to restore it.

Acknowledge purchases persisted to the cloud

If you are saving consumable purchases to the cloud, you must call
ConfirmPurchase
when you have successfully persisted the purchase.
When returning
Pending
, Unity IAP keeps transactions open on the underlying store until confirmed as processed. This ensures consumable purchases are not lost even if a user reinstalls your application while a consumable is pending.

Copyright © 2026 Unity Technologies
LegalPrivacy PolicyCookiesDocumentation Terms of UseDo Not Sell or Share My Personal InformationYour Privacy Choices (Cookie Settings)

"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S and elsewhere (more info here). Other names or brands are trademarks of their respective owners.

Some pages are machine-translated for convenience, and may contain inaccuracies. In the event of conflicting information, the English version is authoritative.

  • On this page
    • Retrieve purchases

    • Determine purchase status

      • Purchase attributes

      • Purchase states

    • Process purchases

    • Reflect purchase state in your UI

      • Non-consumables and subscriptions

      • Consumables

      • Update the button state during purchase flow

    • Purchase acknowledgement and reliability

    • Acknowledge purchases persisted to the cloud


Report a problem with this page