android上的Unity IAP错误,找不到您尝试购买的商品

时间:2019-12-05 10:48:01

标签: c# unity3d in-app-purchase

我正在我的统一游戏中实现IAP,并且当我在PC PC Screenshot上测试IAP时,如您在屏幕截图中所见,IAP正常运行,但是当我在具有测试产品的真实Android设备上对其进行测试来自Google public string NO_ADS = "android.test.purchased";的ID名称,它在真正的android设备上给我这个错误enter image description here,但在PC上运行正常,所以为什么这是我丢失的东西呢?这是我的代码 IAPManager

    public class IAPManager : Singleton<IAPManager> , IStoreListener
{
    private static IStoreController m_StoreController;          
    private static IExtensionProvider m_StoreExtensionProvider; 


    //public static string kProductIDConsumable = "consumable";
    public string NO_ADS = "android.test.purchased"; // Non consumable
    //public static string kProductIDSubscription = "subscription";

    //// Apple App Store-specific product identifier for the subscription product.
    //private static string kProductNameAppleSubscription = "com.unity3d.subscription.new";

    //// Google Play Store-specific product identifier subscription product.
    //private static string kProductNameGooglePlaySubscription = 
"com.unity3d.subscription.original";

    void Start()
    {
        // If we haven't set up the Unity Purchasing reference
        if (m_StoreController == null)
        {
            // Begin to configure our connection to Purchasing
            InitializePurchasing();
        }
    }

public void InitializePurchasing()
{
    // If we have already connected to Purchasing ...
    if (IsInitialized())
    {
        // ... we are done here.
        return;
    }

    // Create a builder, first passing in a suite of Unity provided stores.
    var builder = ConfigurationBuilder.Instance(StandardPurchasingModule.Instance());

    // Add a product to sell / restore by way of its identifier, associating the general identifier
    // with its store-specific identifiers.
    //builder.AddProduct(kProductIDConsumable, ProductType.Consumable);
    // Continue adding the non-consumable product.
    builder.AddProduct(NO_ADS, ProductType.NonConsumable);
    // And finish adding the subscription product. Notice this uses store-specific IDs, illustrating
    // if the Product ID was configured differently between Apple and Google stores. Also note that
    // one uses the general kProductIDSubscription handle inside the game - the store-specific IDs 
    // must only be referenced here. 
    //builder.AddProduct(kProductIDSubscription, ProductType.Subscription, new IDs(){
    //        { kProductNameAppleSubscription, AppleAppStore.Name },
    //        { kProductNameGooglePlaySubscription, GooglePlay.Name },
    //    });

    // Kick off the remainder of the set-up with an asynchrounous call, passing the configuration 
    // and this class' instance. Expect a response either in OnInitialized or OnInitializeFailed.
    UnityPurchasing.Initialize(this, builder);
}


public bool IsInitialized()
{
    // Only say we are initialized if both the Purchasing references are set.
    return m_StoreController != null && m_StoreExtensionProvider != null;
}


//public void BuyConsumable()
//{
//    Buy the consumable product using its general identifier.Expect a response either
//     through ProcessPurchase or OnPurchaseFailed asynchronously.
//    BuyProductID(kProductIDConsumable);
//}


public void BuyNoAds()
{
    // Buy the non-consumable product using its general identifier. Expect a response either 
    // through ProcessPurchase or OnPurchaseFailed asynchronously.
    BuyProductID(NO_ADS);
}

public string GetProductPriceFromStore(string id)
{
    if(m_StoreController!=null && m_StoreController.products != null)
    {
        return m_StoreController.products.WithID(id).metadata.localizedPriceString;
    }
    else
    {
        return "";
    }
}


//public void BuySubscription()
//{
//    // Buy the subscription product using its the general identifier. Expect a response either 
//    // through ProcessPurchase or OnPurchaseFailed asynchronously.
//    // Notice how we use the general product identifier in spite of this ID being mapped to
//    // custom store-specific identifiers above.
//    BuyProductID(kProductIDSubscription);
//}


void BuyProductID(string productId)
{
    // If Purchasing has been initialized ...
    if (IsInitialized())
    {
        // ... look up the Product reference with the general product identifier and the Purchasing 
        // system's products collection.
        Product product = m_StoreController.products.WithID(productId);

        // If the look up found a product for this device's store and that product is ready to be sold ... 
        if (product != null && product.availableToPurchase)
        {
            Debug.Log(string.Format("Purchasing product asychronously: '{0}'", product.definition.id));
            // ... buy the product. Expect a response either through ProcessPurchase or OnPurchaseFailed 
            // asynchronously.
            m_StoreController.InitiatePurchase(product);
        }
        // Otherwise ...
        else
        {
            // ... report the product look-up failure situation  
            Debug.Log("BuyProductID: FAIL. Not purchasing product, either is not found or is not available for purchase");
        }
    }
    // Otherwise ...
    else
    {
        // ... report the fact Purchasing has not succeeded initializing yet. Consider waiting longer or 
        // retrying initiailization.
        Debug.Log("BuyProductID FAIL. Not initialized.");
    }
}


// Restore purchases previously made by this customer. Some platforms automatically restore purchases, like Google. 
// Apple currently requires explicit purchase restoration for IAP, conditionally displaying a password prompt.
public void RestorePurchases()
{
    // If Purchasing has not yet been set up ...
    if (!IsInitialized())
    {
        // ... report the situation and stop restoring. Consider either waiting longer, or retrying initialization.
        Debug.Log("RestorePurchases FAIL. Not initialized.");
        return;
    }

    // If we are running on an Apple device ... 
    if (Application.platform == RuntimePlatform.IPhonePlayer ||
        Application.platform == RuntimePlatform.OSXPlayer)
    {
        // ... begin restoring purchases
        Debug.Log("RestorePurchases started ...");

        // Fetch the Apple store-specific subsystem.
        var apple = m_StoreExtensionProvider.GetExtension<IAppleExtensions>();
        // Begin the asynchronous process of restoring purchases. Expect a confirmation response in 
        // the Action<bool> below, and ProcessPurchase if there are previously purchased products to 
restore.
        apple.RestoreTransactions((result) => {
            // The first phase of restoration. If no more responses are received on ProcessPurchase 
then 
            // no purchases are available to be restored.
            Debug.Log("RestorePurchases continuing: " + result + ". If no further messages, no 
purchases available to restore.");
        });
    }
    // Otherwise ...
    else
    {
        // We are not running on an Apple device. No work is necessary to restore purchases.
        Debug.Log("RestorePurchases FAIL. Not supported on this platform. Current = " + 
Application.platform);
    }
}


//  
// --- IStoreListener
//

public void OnInitialized(IStoreController controller, IExtensionProvider extensions)
{
    // Purchasing has succeeded initializing. Collect our Purchasing references.
    Debug.Log("OnInitialized: PASS");

    // Overall Purchasing system, configured with products for this application.
    m_StoreController = controller;
    // Store specific subsystem, for accessing device-specific store features.
    m_StoreExtensionProvider = extensions;
}


public void OnInitializeFailed(InitializationFailureReason error)
{
    // Purchasing set-up has not succeeded. Check error for reason. Consider sharing this reason 
with the user.
    Debug.Log("OnInitializeFailed InitializationFailureReason:" + error);
}


public PurchaseProcessingResult ProcessPurchase(PurchaseEventArgs args)
{
    // A consumable product has been purchased by this user.
    //if (String.Equals(args.purchasedProduct.definition.id, kProductIDConsumable, 
StringComparison.Ordinal))
    //{
    //    Debug.Log(string.Format("ProcessPurchase: PASS. Product: '{0}'", 
args.purchasedProduct.definition.id));
    //    // The consumable item has been successfully purchased, add 100 coins to the player's in- 
  game score.

    //}
    // Or ... a non-consumable product has been purchased by this user.
    if (String.Equals(args.purchasedProduct.definition.id, NO_ADS, StringComparison.Ordinal))
    {
        Debug.Log(string.Format("ProcessPurchase: PASS. Product: '{0}'", 
args.purchasedProduct.definition.id));
        // TODO: The non-consumable item has been successfully purchased, grant this item to the 
player.
        DataManager.instance.RemoveAds();
    }
    // Or ... a subscription product has been purchased by this user.
    //else if (String.Equals(args.purchasedProduct.definition.id, kProductIDSubscription, 
StringComparison.Ordinal))
    //{
    //    Debug.Log(string.Format("ProcessPurchase: PASS. Product: '{0}'", 
args.purchasedProduct.definition.id));
    //    // TODO: The subscription item has been successfully purchased, grant this to the player.
    //}
    // Or ... an unknown product has been purchased by this user. Fill in additional products 
here....
    else
    {
        Debug.Log(string.Format("ProcessPurchase: FAIL. Unrecognized product: '{0}'", 
args.purchasedProduct.definition.id));
    }

    // Return a flag indicating whether this product has completely been received, or if the 
application needs 
    // to be reminded of this purchase at next app launch. Use PurchaseProcessingResult.Pending when 
still 
    // saving purchased products to the cloud, and when that save is delayed. 
    return PurchaseProcessingResult.Complete;
}



}

单班

public class Singleton<T> : MonoBehaviour where T: MonoBehaviour
{
    public bool dontDestroy = false;
    static T m_instance;

    public static T instance
{
    get
    {
        if(m_instance == null)
        {
            m_instance = GameObject.FindObjectOfType<T>();
            if(m_instance == null)
            {
                GameObject singleton = new GameObject(typeof(T).Name);
                m_instance = singleton.AddComponent<T>();
            }
        }

        return m_instance;
    }
}

public virtual void Awake()
{
    if(m_instance == null)
    {
        m_instance = this as T;
        if (dontDestroy)
        {
            transform.parent = null;
            DontDestroyOnLoad(this.gameObject);
        }
    }
    else
    {
        Destroy(gameObject);
    }
}
}

DataManager

public GameObject noAdsButton;
//public GameObject AdsManager;
bool noAds = false;

public void RemoveAds()
{
    noAds = true;
    noAdsButton.SetActive(false);
    //AdsManager.GetComponent<AdsManager>().enabled = false;
    //AdsManager.SetActive(false);

}

被调用进行购买的功能

public void ClickBuy()
{
    switch (itemType)
    {
        case ItemType.noAds:
            IAPManager.instance.BuyNoAds();
            break;
    }
}

0 个答案:

没有答案