Lesson 9: In-App Purchases & Monetization

Welcome back! Now that your mobile puzzle game has polished gameplay and engaging mechanics, it's time to implement monetization systems that generate revenue while maintaining a positive player experience. In this lesson, you'll learn how to integrate in-app purchases, design ethical monetization strategies, and create pricing models that work for both players and your business.

What You'll Learn

  • Design ethical monetization strategies for puzzle games
  • Implement Unity IAP (In-App Purchases) system
  • Create consumable and non-consumable purchase items
  • Set up store product catalogs for iOS and Android
  • Implement purchase validation and receipt verification
  • Design player-friendly monetization flows
  • Test purchases in sandbox environments

Prerequisites

  • Unity 2022.3 LTS or newer
  • Completed Lesson 8: Performance & Battery Optimization
  • Basic understanding of mobile app stores
  • Unity IAP package (we'll install it in this lesson)
  • Developer accounts for App Store and Google Play (for testing)

Why Monetization Matters

Monetization is essential for sustaining your game development business, but it must be done thoughtfully. The best mobile games balance revenue generation with player satisfaction:

  • Ethical monetization builds trust and long-term player relationships
  • Player-friendly pricing increases conversion rates and retention
  • Multiple revenue streams provide stability and growth opportunities
  • Transparent systems reduce player frustration and support requests

Step 1: Install Unity IAP Package

Let's start by installing the Unity In-App Purchases package:

  1. Open Package Manager: Window → Package Manager
  2. Switch to Unity Registry: Click the dropdown and select "Unity Registry"
  3. Search for IAP: Type "In App Purchasing" in the search bar
  4. Install Package: Click "Install" on the "In App Purchasing" package
  5. Wait for Installation: Unity will download and install the package

Pro Tip: The Unity IAP package supports both iOS App Store and Google Play Store purchases, making it perfect for cross-platform monetization.

Step 2: Design Your Monetization Strategy

Before implementing purchases, design your monetization model:

Common Monetization Models for Puzzle Games

1. Freemium Model

  • Free to download and play
  • Optional in-app purchases for power-ups, extra lives, or cosmetic items
  • Best for: Casual puzzle games with broad appeal

2. Premium Model

  • One-time purchase to unlock full game
  • No additional purchases required
  • Best for: High-quality puzzle games with strong gameplay

3. Hybrid Model

  • Free base game with optional purchases
  • Premium currency for convenience items
  • Best for: Games with multiple content types

Recommended Purchase Items for Puzzle Games

Consumable Items (can be purchased multiple times):

  • Extra lives or moves
  • Hint coins or power-ups
  • Energy refills
  • Temporary boosters

Non-Consumable Items (purchased once, owned forever):

  • Remove ads permanently
  • Unlock premium levels
  • Character skins or themes
  • Premium features

Subscription Items (recurring purchases):

  • Monthly premium pass
  • Ad-free subscription
  • Exclusive content access

Step 3: Create Purchase Manager Script

Create a purchase manager to handle all IAP functionality:

  1. Create Script: Create new C# script called PurchaseManager.cs
  2. Add IAP Namespace: Import Unity IAP libraries
using UnityEngine;
using UnityEngine.Purchasing;
using System;

public class PurchaseManager : MonoBehaviour, IStoreListener
{
    private static IStoreController m_StoreController;
    private static IExtensionProvider m_StoreExtensionProvider;

    // Product IDs - must match store product IDs exactly
    public const string PRODUCT_REMOVE_ADS = "remove_ads";
    public const string PRODUCT_EXTRA_LIVES = "extra_lives";
    public const string PRODUCT_HINT_PACK = "hint_pack_10";
    public const string PRODUCT_PREMIUM_PASS = "premium_pass";

    void Start()
    {
        if (m_StoreController == null)
        {
            InitializePurchasing();
        }
    }

    public void InitializePurchasing()
    {
        if (IsInitialized())
        {
            return;
        }

        var builder = ConfigurationBuilder.Instance(StandardPurchasingModule.Instance());

        // Add products
        builder.AddProduct(PRODUCT_REMOVE_ADS, ProductType.NonConsumable);
        builder.AddProduct(PRODUCT_EXTRA_LIVES, ProductType.Consumable);
        builder.AddProduct(PRODUCT_HINT_PACK, ProductType.Consumable);
        builder.AddProduct(PRODUCT_PREMIUM_PASS, ProductType.Subscription);

        UnityPurchasing.Initialize(this, builder);
    }

    private bool IsInitialized()
    {
        return m_StoreController != null && m_StoreExtensionProvider != null;
    }

    public void BuyProductID(string productId)
    {
        if (IsInitialized())
        {
            Product product = m_StoreController.products.WithID(productId);

            if (product != null && product.availableToPurchase)
            {
                Debug.Log($"Purchasing product: {product.definition.id}");
                m_StoreController.InitiatePurchase(product);
            }
            else
            {
                Debug.LogError("Product not available for purchase");
            }
        }
        else
        {
            Debug.LogError("Store not initialized");
        }
    }

    public void OnInitialized(IStoreController controller, IExtensionProvider extensions)
    {
        Debug.Log("IAP initialized successfully");
        m_StoreController = controller;
        m_StoreExtensionProvider = extensions;
    }

    public void OnInitializeFailed(InitializationFailureReason error)
    {
        Debug.LogError($"IAP initialization failed: {error}");
    }

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

        Debug.Log($"Purchase successful: {productId}");

        // Handle purchase based on product ID
        switch (productId)
        {
            case PRODUCT_REMOVE_ADS:
                HandleRemoveAds();
                break;
            case PRODUCT_EXTRA_LIVES:
                HandleExtraLives();
                break;
            case PRODUCT_HINT_PACK:
                HandleHintPack();
                break;
            case PRODUCT_PREMIUM_PASS:
                HandlePremiumPass();
                break;
        }

        return PurchaseProcessingResult.Complete;
    }

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

    // Purchase handlers
    private void HandleRemoveAds()
    {
        PlayerPrefs.SetInt("AdsRemoved", 1);
        Debug.Log("Ads removed permanently");
    }

    private void HandleExtraLives()
    {
        int currentLives = PlayerPrefs.GetInt("Lives", 5);
        PlayerPrefs.SetInt("Lives", currentLives + 5);
        Debug.Log("Extra lives added");
    }

    private void HandleHintPack()
    {
        int currentHints = PlayerPrefs.GetInt("Hints", 0);
        PlayerPrefs.SetInt("Hints", currentHints + 10);
        Debug.Log("Hint pack added");
    }

    private void HandlePremiumPass()
    {
        PlayerPrefs.SetInt("PremiumPass", 1);
        Debug.Log("Premium pass activated");
    }
}

Step 4: Set Up Store Product Catalogs

Configure products in both App Store Connect and Google Play Console:

iOS App Store Setup

  1. Log into App Store Connect: https://appstoreconnect.apple.com
  2. Navigate to Your App: Select your app or create a new one
  3. Go to In-App Purchases: Features → In-App Purchases
  4. Create Products: Add each product with:
    • Product ID: Must match your script (e.g., "remove_ads")
    • Type: Consumable, Non-Consumable, or Auto-Renewable Subscription
    • Price: Set pricing tier
    • Localization: Add descriptions and names

Google Play Console Setup

  1. Log into Google Play Console: https://play.google.com/console
  2. Navigate to Your App: Select your app
  3. Go to Monetize: Monetize → Products → In-app products
  4. Create Products: Add each product with:
    • Product ID: Must match your script
    • Name: Display name for players
    • Description: What the product does
    • Price: Set price in your currency

Pro Tip: Use consistent product IDs across both platforms to simplify your code. The Unity IAP package handles platform differences automatically.

Step 5: Create Purchase UI

Design user-friendly purchase interfaces:

Purchase Button Script

using UnityEngine;
using UnityEngine.UI;

public class PurchaseButton : MonoBehaviour
{
    [Header("Purchase Settings")]
    public string productId;
    public string displayName;
    public string displayPrice;

    [Header("UI References")]
    public Button purchaseButton;
    public Text nameText;
    public Text priceText;

    private PurchaseManager purchaseManager;

    void Start()
    {
        purchaseManager = FindObjectOfType<PurchaseManager>();

        if (nameText != null)
            nameText.text = displayName;

        if (priceText != null)
            priceText.text = displayPrice;

        if (purchaseButton != null)
            purchaseButton.onClick.AddListener(OnPurchaseClicked);
    }

    public void OnPurchaseClicked()
    {
        if (purchaseManager != null)
        {
            purchaseManager.BuyProductID(productId);
        }
    }
}

Best Practices for Purchase UI

  • Clear Value Proposition: Show what players get
  • Transparent Pricing: Display prices clearly
  • Non-Intrusive: Don't force purchases on players
  • Easy to Dismiss: Always provide a close button
  • Visual Feedback: Show purchase progress and confirmation

Step 6: Implement Purchase Validation

Add server-side validation for security (recommended for production):

using UnityEngine;
using System.Collections;

public class PurchaseValidator : MonoBehaviour
{
    private const string VALIDATION_URL = "https://your-server.com/validate-purchase";

    public void ValidatePurchase(string receipt, string productId)
    {
        StartCoroutine(SendValidationRequest(receipt, productId));
    }

    private IEnumerator SendValidationRequest(string receipt, string productId)
    {
        // Create validation request
        WWWForm form = new WWWForm();
        form.AddField("receipt", receipt);
        form.AddField("product_id", productId);
        form.AddField("platform", Application.platform.ToString());

        using (UnityEngine.Networking.UnityWebRequest www = 
            UnityEngine.Networking.UnityWebRequest.Post(VALIDATION_URL, form))
        {
            yield return www.SendWebRequest();

            if (www.result == UnityEngine.Networking.UnityWebRequest.Result.Success)
            {
                Debug.Log("Purchase validated successfully");
                // Grant product to player
            }
            else
            {
                Debug.LogError($"Validation failed: {www.error}");
            }
        }
    }
}

Pro Tip: For indie developers, Unity IAP's built-in validation is sufficient for most games. Server-side validation is recommended for high-revenue games or when security is critical.

Step 7: Test Purchases in Sandbox

Test your purchase system before release:

iOS Sandbox Testing

  1. Create Sandbox Tester: App Store Connect → Users and Access → Sandbox Testers
  2. Sign Out of App Store: On your test device
  3. Test Purchase: Attempt purchase in your app
  4. Sign In: Use sandbox tester credentials when prompted
  5. Verify Purchase: Check that purchase is processed correctly

Android Testing

  1. Upload APK: Upload to Google Play Console (internal testing track)
  2. Add Testers: Add test accounts to internal testing
  3. Test Purchase: Use test card numbers provided by Google
  4. Verify Purchase: Check purchase processing

Step 8: Implement Ethical Monetization Practices

Design monetization that players appreciate:

Do's

  • Offer Value: Ensure purchases provide real value
  • Be Transparent: Clearly explain what players get
  • Respect Player Choice: Never force purchases
  • Fair Pricing: Price items reasonably
  • Provide Free Content: Always offer free gameplay

Don'ts

  • Don't Be Aggressive: Avoid constant purchase prompts
  • Don't Hide Costs: Always show prices clearly
  • Don't Create Paywalls: Don't block essential gameplay
  • Don't Mislead: Be honest about what purchases do
  • Don't Ignore Feedback: Listen to player concerns

Mini Challenge: Implement Three Purchase Items

Create three different purchase items for your puzzle game:

  1. Consumable Item: Extra lives or moves (can buy multiple times)
  2. Non-Consumable Item: Remove ads permanently (buy once)
  3. Subscription Item: Premium pass with monthly benefits

Test each purchase type in sandbox and verify they work correctly.

Troubleshooting Common Issues

Issue: Purchases Not Working

Symptoms: Purchase button does nothing or shows error Solutions:

  • Verify product IDs match store catalogs exactly
  • Check that IAP is initialized before purchase attempts
  • Ensure test accounts are set up correctly
  • Check device internet connection

Issue: Products Not Available

Symptoms: Products show as unavailable Solutions:

  • Verify products are approved in store consoles
  • Check product IDs match exactly (case-sensitive)
  • Ensure app is properly configured in store consoles
  • Wait for store propagation (can take hours)

Issue: Receipt Validation Fails

Symptoms: Purchases complete but validation fails Solutions:

  • Check receipt format for your platform
  • Verify server validation endpoint is working
  • Check network connectivity
  • Review receipt data structure

Pro Tips

  • A/B Test Pricing: Test different price points to find optimal pricing
  • Bundle Products: Offer product bundles for better value
  • Seasonal Sales: Run limited-time promotions to boost sales
  • Analytics Integration: Track purchase conversion rates
  • Player Feedback: Monitor reviews for monetization concerns

What's Next?

Congratulations! You've implemented a complete in-app purchase system. In the next lesson, you'll learn how to integrate analytics to track player behavior, measure monetization effectiveness, and make data-driven decisions to optimize your game's revenue.

Next Lesson: Lesson 10: Analytics & User Tracking - Integrate analytics for user behavior tracking and implement A/B testing for game features.

Key Takeaways

  • Unity IAP package simplifies cross-platform purchase implementation
  • Design ethical monetization that provides value to players
  • Test all purchases thoroughly in sandbox environments
  • Multiple revenue streams provide stability and growth
  • Transparent pricing and clear value propositions increase conversions

Related Resources


Ready to track your game's performance? Bookmark this lesson and move on to analytics integration to understand how players interact with your monetization systems and optimize your revenue strategy.