Back to Blog
Mobile Game Development
2026-07-25
8 min read

Unity In-App Purchases: Implementation Basics & Best Practices

Learn the basics of Unity In-App Purchases, including product types, initialization, purchase handling, restoration, validation, and common mistakes.

IAPMonetizationUnityC#Google Play
RR
Rohit Rewani — Unity Developer
Unity • C# • Mobile Games • Multiplayer • AR
Unity In-App Purchases: Implementation Basics & Best Practices cover visual

The Problem: Storefront Fragmentation

Implementing Google Play Billing and Apple's StoreKit natively requires maintaining two complex, asynchronous Java/Kotlin and Swift/Objective-C codebases. Handling receipts, restoring purchases, and managing network failures natively is highly error-prone.

Why It Happens

Each ecosystem has strict requirements for how purchases are acknowledged. If a purchase is not securely acknowledged within a specific timeframe (e.g., 3 days on Google Play), the store automatically refunds the user.

The Solution: Unity IAP

Unity In-App Purchasing provides a unified API. You initialize a `ConfigurationBuilder` mapping your internal string IDs to specific store IDs, and implement the `IStoreListener` interface to handle asynchronous callbacks.

infoUnderstand the three product types: Consumable (bought repeatedly, e.g., Coins), Non-Consumable (bought once permanently, e.g., Remove Ads), and Subscriptions.

Code Example: Secure Purchase Processing

When a transaction completes, your `ProcessPurchase` callback is triggered. You must return `PurchaseProcessingResult.Complete` ONLY after you have securely granted the digital item.

csharp
using UnityEngine.Purchasing;
using UnityEngine;

public class StoreManager : MonoBehaviour, IStoreListener {
    // Initialization omitted for brevity

    public PurchaseProcessingResult ProcessPurchase(PurchaseEventArgs args) {
        string productId = args.purchasedProduct.definition.id;

        if (productId == "com.mygame.remove_ads") {
            // Grant non-consumable
            PlayerPrefs.SetInt("AdsRemoved", 1);
            Debug.Log("Ads removed successfully!");
        }
        else if (productId == "com.mygame.100_coins") {
            // Grant consumable
            int coins = PlayerPrefs.GetInt("Coins", 0) + 100;
            PlayerPrefs.SetInt("Coins", coins);
            Debug.Log("100 Coins added!");
        }

        // Inform the store the transaction is fully complete and acknowledged
        return PurchaseProcessingResult.Complete;
    }

    public void OnPurchaseFailed(Product product, PurchaseFailureReason failureReason) {
        Debug.LogError($"Purchase of {product.definition.id} failed due to {failureReason}");
    }
}

Common Mistakes

  • Granting the item *before* the `ProcessPurchase` callback, or granting it in a UI script instead of the central IAP manager.
  • Forgetting to implement a 'Restore Purchases' button on iOS. Apple will reject your app if non-consumables cannot be restored.
  • Trusting local receipts blindly without utilizing Unity's `CrossPlatformValidator` to prevent piracy (e.g., LuckyPatcher).

Best Practices

Always use Unity's `CrossPlatformValidator` to verify the cryptographic signature of the receipt before granting high-value items. For server-authoritative games (e.g., using Unity Netcode), send the receipt token to your backend to validate it directly with Google/Apple servers.

Related Articles

If you are monetizing your game, you should track purchase events deeply. Learn how to log revenue data with our Firebase Analytics Integration Guide. Alternatively, explore AdMob Integration for ad-based revenue.

Conclusion

Unity IAP abstracts the nightmare of cross-platform billing. By understanding product types, properly acknowledging purchases with `PurchaseProcessingResult.Complete`, and enforcing receipt validation, you can secure your game's revenue streams confidently.