[Solved] IAP Works fine in Editor but no pop-ups on Android Device

Hello, I’m encountering a problem with the Unity IAP for Android.

I had managed IAPs working fine but I’ve added subscriptions since and now no in-app purchases work. I tried commenting all out the subscription code I’d done and they still didn’t work. It seems I did something that stopped them from working.

They work fine in the editor but when testing on my phone, there are no Google Play pop-ups or anything to indicate that anything is trying to do something.

Here is the code for the purchasing manager:

using System;
using UnityEngine;
using System.Collections.Generic;
using UnityEngine.Purchasing;

public class purchaseManager : MonoBehaviour, IStoreListener {

    private static IStoreController m_StoreController;        
    private static IExtensionProvider m_StoreExtensionProvider;
     
    public static string ProductID_100coins = "100coins";
    public static string ProductID_200coins = "200coins";

    public static string ProductID_SUB_MONTH_TRIAL = "free_trial_monthly_subscription";
    public static string ProductID_SUB_MONTH = "monthly_subscription";
    public static string ProductID_SUB_6MONTHS = "subscription_6_months";
    public static string ProductID_SUB_YEAR = "subscription_1_year";
   
    private static string kProductNameGooglePlaySubscription =  "com.unity3d.subscription.original";
    private static string kProductNameAppleSubscription =  "com.unity3d.subscription.new";

    void Start()
    {
        DontDestroyOnLoad (this.gameObject);
        if (m_StoreController == null)
        {
            InitializePurchasing();
        }
    }

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

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

        builder.AddProduct(ProductID_100coins, ProductType.Consumable);
        builder.AddProduct(ProductID_200coins, ProductType.Consumable);

        builder.AddProduct(ProductID_SUB_MONTH_TRIAL, ProductType.Subscription, new IDs(){
            {kProductNameGooglePlaySubscription,GooglePlay.Name},
            {kProductNameAppleSubscription,AppleAppStore.Name}
        });

        builder.AddProduct (ProductID_SUB_MONTH, ProductType.Subscription, new IDs () {
            {kProductNameGooglePlaySubscription,GooglePlay.Name},
            {kProductNameAppleSubscription,AppleAppStore.Name}
        });

        builder.AddProduct (ProductID_SUB_6MONTHS, ProductType.Subscription, new IDs(){
            {kProductNameGooglePlaySubscription,GooglePlay.Name},
            {kProductNameAppleSubscription,AppleAppStore.Name}
        });

        builder.AddProduct (ProductID_SUB_YEAR, ProductType.Subscription, new IDs () {
            { kProductNameGooglePlaySubscription,GooglePlay.Name },
            { kProductNameAppleSubscription,AppleAppStore.Name }
        });

        UnityPurchasing.Initialize(this, builder);
    }

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

    public void Buy100Coins()
    {
        BuyProductID(ProductID_100coins);
    }
    public void Buy200Coins()
    {
        BuyProductID(ProductID_200coins);
    }
       
    public void Subscribe_Month_TRIAL(){
        BuyProductID (ProductID_SUB_MONTH_TRIAL);
    }

    public void Subscribe_Month(){
        BuyProductID (ProductID_SUB_MONTH);
    }

    public void Subscribe_Year(){
        BuyProductID (ProductID_SUB_YEAR);
    }

    public void Subscribe_6Month(){
        BuyProductID (ProductID_SUB_6MONTHS);
    }

    void BuyProductID(string productId)
    {

        if (IsInitialized())
        {
            Product product = m_StoreController.products.WithID(productId);

            if (product != null && product.availableToPurchase)
            {
                Debug.Log(string.Format("Purchasing product asychronously: '{0}'", product.definition.id));
                m_StoreController.InitiatePurchase(product);
            }
            else
            {
                Debug.Log("BuyProductID: FAIL. Not purchasing product, either is not found or is not available for purchase");
            }
        }
        else
        {
            Debug.Log("BuyProductID FAIL. Not initialized.");
        }

    }
       
    public void RestorePurchases()
    {
        if (!IsInitialized())
        {
            Debug.Log("RestorePurchases FAIL. Not initialized.");
            return;
        }
    }

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


    public void OnInitializeFailed(InitializationFailureReason error)
    {
        Debug.Log("OnInitializeFailed InitializationFailureReason:" + error);
    }


    public PurchaseProcessingResult ProcessPurchase(PurchaseEventArgs args)
    {
        if (String.Equals (args.purchasedProduct.definition.id, ProductID_100coins, StringComparison.Ordinal)) {
           
            Debug.Log (string.Format ("ProcessPurchase: PASS. Product: '{0}'", args.purchasedProduct.definition.id));
            FindObjectOfType<inventoryManager> ().ChangeCoins (100);

        } else if (String.Equals (args.purchasedProduct.definition.id, ProductID_200coins, StringComparison.Ordinal)) {
           
            Debug.Log (string.Format ("ProcessPurchase: PASS. Product: '{0}'", args.purchasedProduct.definition.id));
            FindObjectOfType<inventoryManager> ().ChangeCoins (200);

        } else if (String.Equals (args.purchasedProduct.definition.id, ProductID_SUB_MONTH_TRIAL, StringComparison.Ordinal)) {
            FindObjectOfType<subscriptionManager> ().Subscribe ();
        } else if (String.Equals (args.purchasedProduct.definition.id, ProductID_SUB_MONTH, StringComparison.Ordinal)) {
            FindObjectOfType<subscriptionManager> ().Subscribe ();
        } else if (String.Equals (args.purchasedProduct.definition.id, ProductID_SUB_6MONTHS, StringComparison.Ordinal)) {
            FindObjectOfType<subscriptionManager> ().Subscribe ();   
        }else if (String.Equals (args.purchasedProduct.definition.id, ProductID_SUB_YEAR, StringComparison.Ordinal)){
            FindObjectOfType<subscriptionManager> ().Subscribe ();
        }else
        {
            Debug.Log(string.Format("ProcessPurchase: FAIL. Unrecognized product: '{0}'", args.purchasedProduct.definition.id));
        }
        return PurchaseProcessingResult.Complete;
    }

    public void OnPurchaseFailed(Product product, PurchaseFailureReason failureReason)
    {
        Debug.Log(string.Format("OnPurchaseFailed: FAIL. Product: '{0}', PurchaseFailureReason: {1}", product.definition.storeSpecificId, failureReason));
    }

    public bool isSubscribed(){

        bool s = false;

        if (m_StoreController.products.WithID ("free_trial_monthly_subscription").hasReceipt){
            s = true;
        }else if (m_StoreController.products.WithID ("monthly_subscription").hasReceipt){
            s = true;
        }else if (m_StoreController.products.WithID ("subscription_6_months").hasReceipt){
            s = true;
        }else if (m_StoreController.products.WithID ("subscription_1_year").hasReceipt){
            s = true;
        }

        s = false;

        return s;

    }
}

Some functions are called externally from buttons on the UI.

Thank you in advance for any assistance.

Are you doing this
builder.Configure().SetPublicKey(“your public key here”);
?

That didn’t work. I’ve also found that the issue is something on line 63

UnityPurchasing.Initialize(this, builder);

I’ve now got a text element on the UI that reads out error messages so I can debug on the device. The debugs tracking the progress stop before coming up to this line and purchase attempts come up with an error saying the purchasing has not been initialized.

@wireheadking

It looks like you are giving all of your products the same product ids. You are using kProductNameGooglePlaySubscription and kProductNameAppleSubscription for every product. These are store-specific ids and they should match the product id you set up in the Google Play and Apple App Store, respectively.

You can learn more about store-specific ids on the Manual:

If you have the same product id in both stores, then you don’t need to set them. You can simplify your product definitions:

builder.AddProduct(ProductID_Example, ProductType.Subscription);