[WP8] IAP - Unable to initialize purchases & connect to store?

Greetings,

I'm trying to get IAP working in the WP8 port of our game. I followed this guide but it didn't seem to cover WP8. One of the gotchas was that you should check "InternetClientServer" in your build settings otherwise you'd get errors screaming that it should be enabled.

The issue I'm having right now is that the game seems to connect properly to a mockup ad server or something where it shows fake prices etc. But the point is that the initialization code for purchasing etc seems to be working fine. Not the case when building and running in the phone though, the purchase initialization doesn't seem to be working.

This is the code I'm using:

using System;
using UnityEngine;
using UnityEngine.Assertions;
using UnityEngine.Purchasing;

public class WindowsIAP : IStoreListener
{
    public static WindowsIAP Instance;

    static WindowsIAP()
    {
        Instance = new WindowsIAP();
    }

    public Action<Product> OnPurchaseSuccessCallback;
    public Action<Product> OnPurchaseFailedCallback;
    public ProductInfo[] Products;

    IStoreController _StoreController;
    IExtensionProvider _StoreExtensionProvider;

    const string kWinStorePostfix = "ws";

    public struct ProductInfo
    {
        public string Name;
        public ProductType Type;
    }

    public void Initialize(Action<Product> onPurchaseSuccess, Action<Product> onPurchaseFailed, ProductInfo[] products)
    {
        Assert.IsTrue(!IsInitialized());

        this.Products = products;
        this.OnPurchaseSuccessCallback = onPurchaseSuccess;
        this.OnPurchaseFailedCallback = onPurchaseFailed;

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

        // NOTE (Ali): mockup billing
        //builder.Configure<IMicrosoftConfiguration>().useMockBillingSystem = true;

        Assert.IsNotNull(Products);

        foreach (var p in Products)
            builder.AddProduct(p.Name, p.Type, new IDs() { { p.Name + kWinStorePostfix, WinRT.Name } });

        UnityPurchasing.Initialize(this, builder);
    }

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

    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.
        _StoreController = controller;

        // Store specific subsystem, for accessing device-specific store features.
        _StoreExtensionProvider = extensions;

        Debug.Log("Available items:");
        foreach (var item in _StoreController.products.all)
        {
            if (item.availableToPurchase)
            {
                Debug.Log(string.Join(" - ",
                    new[]
                    {
                        item.metadata.localizedTitle,
                        item.metadata.localizedDescription,
                        item.metadata.isoCurrencyCode,
                        item.metadata.localizedPrice.ToString(),
                        item.metadata.localizedPriceString
                    }));
            }
        }
    }

    public void OnInitializeFailed(InitializationFailureReason error)
    {
        Debug.Log("Billing failed to initialize!");
        switch (error)
        {
            case InitializationFailureReason.AppNotKnown:
            Debug.LogError("Is your App correctly uploaded on the relevant publisher console?");
            break;
            case InitializationFailureReason.PurchasingUnavailable:
            // Ask the user if billing is disabled in device settings.
            Debug.Log("Billing disabled!");
            break;
            case InitializationFailureReason.NoProductsAvailable:
            // Developer configuration error; check product metadata.
            Debug.Log("No products available for purchase!");
            break;
        }
    }

    public void OnPurchaseFailed(Product product, PurchaseFailureReason error)
    {
        OnPurchaseFailedCallback(product);

        // A product purchase attempt did not succeed. Check failureReason for more detail. Consider sharing this reason with the user.
        Debug.Log(string.Format("OnPurchaseFailed: FAIL. Product: '{0}', PurchaseFailureReason: {1}", product.definition.storeSpecificId, error));
    }

    public PurchaseProcessingResult ProcessPurchase(PurchaseEventArgs args)
    {
        OnPurchaseSuccessCallback(args.purchasedProduct);

        // A consumable product has been purchased by this user.
        if (string.Equals(args.purchasedProduct.definition.id, NativeStoreProducts.DQ_GOLD0, StringComparison.Ordinal))
        {
            Debug.Log(string.Format("ProcessPurchase: PASS. Product: '{0}'", args.purchasedProduct.definition.id));
        }

        return PurchaseProcessingResult.Complete;
    }

    public Product GetProduct(string productId)
    {
        Product result = _StoreController.products.WithID(productId);
        return result;
    }

    public string BuyProduct(string productId)
    {
        string error;

        // If the stores throw an unexpected exception, use try..catch to protect my logic here.
        try
        {
            // 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 = GetProduct(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.
                    _StoreController.InitiatePurchase(product);
                    error = "";
                }
                // Otherwise ...
                else
                {
                    // ... report the product look-up failure situation
                    error = "BuyProductID: FAIL. Not purchasing product, either is not found or is not available for purchase";
                    Debug.Log(error);
                }
            }
            // Otherwise ...
            else
            {
                // ... report the fact Purchasing has not succeeded initializing yet. Consider waiting longer or retrying initiailization.
                error = "BuyProductID FAIL. Not initialized.";
                Debug.Log(error);
            }
        }
        // Complete the unexpected exception handling ...
        catch (Exception e)
        {
            // ... by reporting any unexpected exception for later diagnosis.
            error = "BuyProductID: FAIL. Exception during purchase: " + e;
            Debug.Log(error);
        }

        return error;
    }
}

I tried WindowsPhone8.Name instead of WinRT.Name but it didn't make a difference. (What's the difference between them anyway?)

In my game code I have something like:

if (WindowsIAP.Instance.IsInitialized())
    DoIAPStuff();
else
    WhoopsCantConnectMessage();

And I always get the can't connect message...

Any help or advice is appreciated.
Thanks[/Code]

So I was able to get debug logs to show and break at breakpoints and it seems that I'm never getting the OnInitialized callback to initialize the controller etc. Which leads me to think there's either a problem wit the way I setup the 'builder' or something int the build settings.

Note: the way I'm building is: Windows Store | Phone 8.1

I was just curious if after enabling client/server in Unity, if you double checked the manifest in visual studio to see if it had been updated (or just started a new build directory for the project)? Once the manifest has been built from Unity to a new build folder, the exporter from Unity will not change any VS related project files afterwards for the build target.

I built many times, and even deleted the build folder and started from scratch. Still the same...

I have the exact same problem :(. Can you try to use

builder.AddProduct (p.Name, p.Type)

instead

builder.AddProduct (p.Name, p.Type, new IDs () {{p.Name + kWinStorePostfix, WinRT.Name}});

I'm also having trouble with this, mockup purchase is working but when trying to test without it I get:
UnibillWin8:Exception loading listing information:Exception from HRESULT: 0x805A0194
App is published and hidden from public like tutorial suggested

I am having the exact same issue, any solution?