Purchase not working for XBox and Microsoft Store

Vasya Goblin 21 Reputation points
2020-10-15T19:07:11.987+00:00

Unity3D. Xbox.
Implemented the purchase of a license for the game. In the Microsoft Store for desctop Windows it works fine (and when installed from the store and from under Visual Studio, including in the debug assembly), it does NOT work on XBox in dev and retail modes. The license (purchase) has been in the store for a week. For the experiment, I posted the assembly in open access (the day has not yet passed). I repeat: the purchase works without problems on the desktop, it does not work on the XBox. This code does not work (the check works, in both cases):

// Get product information from the app store
StoreProductResult productResult = await context.GetStoreProductForCurrentAppAsync();
if (productResult == null || productResult.Product == null)
//if (productResult.ExtendedError != null)
{
    // User may be disconnected or there may be some other server failure
    purchaseCallback?.Invoke(XBoxIAPStatus.NotGetStoreProduct, productResult.ExtendedError);

    return;
}

Весь код:

    public static async void PurchaseFullLicense(Action<XBoxIAPStatus, Exception> purchaseCallback, Action<XBoxIAPStatus> licChanged)
    {
#if ENABLE_IL2CPP && UNITY_WSA_10_0
        licenseChanged = licChanged;

        if (context == null)
        {
            context = StoreContext.GetDefault();

            // Подписываемся на событие изменения лицензии
            context.OfflineLicensesChanged += context_OfflineLicensesChanged;
        }

        if (context == null)
        {
            purchaseCallback?.Invoke(XBoxIAPStatus.NoInitContext, null);

            return;
        }

        // Получить информацию о продукте в магазине приложений
        StoreProductResult productResult = await context.GetStoreProductForCurrentAppAsync();
        if (productResult == null || productResult.Product == null)
        //if (productResult.ExtendedError != null)
        {
            // Пользователь может быть отключен или может быть какой-то другой сбой сервера
            purchaseCallback?.Invoke(XBoxIAPStatus.NotGetStoreProduct, productResult.ExtendedError);

            return;
        }

        // Покупка полной лицензии ...
        StoreAppLicense license = await context.GetAppLicenseAsync();
        if (license != null && appLicense.IsActive && license.IsTrial)
        {
            // Пока демо версия
            StorePurchaseResult result = await productResult.Product.RequestPurchaseAsync();
            if (result.ExtendedError != null)
            {
                // Ошибка: print result.ExtendedError.Message
                purchaseCallback?.Invoke(XBoxIAPStatus.NotRequestPurchase, null);

                return;
            }

            // Покупка прошла. Результат:
            switch (result.Status)
            {
                case StorePurchaseStatus.AlreadyPurchased:
                    // Вы уже купили это приложение и имеете полностью лицензированную версию
                    purchaseCallback?.Invoke(XBoxIAPStatus.AlreadyPurchased, null);
                    return;

                case StorePurchaseStatus.Succeeded:
                    // Лицензия будет обновлена автоматически с помощью события StoreContext.OfflineLicensesChanged
                    purchaseCallback?.Invoke(XBoxIAPStatus.Succeeded, null);
                    return;

                case StorePurchaseStatus.NotPurchased:
                    // Товар не был куплен, возможно, он был отменен
                    purchaseCallback?.Invoke(XBoxIAPStatus.NotPurchased, null);
                    return;

                case StorePurchaseStatus.NetworkError:
                    // Сетевая ошибка
                    purchaseCallback?.Invoke(XBoxIAPStatus.NetworkError, null);
                    return;

                case StorePurchaseStatus.ServerError:
                    // Ошибка сервера
                    purchaseCallback?.Invoke(XBoxIAPStatus.ServerError, null);
                    return;

                default:
                    // Не определённая ошибка
                    purchaseCallback?.Invoke(XBoxIAPStatus.UnDefined, null);
                    return;
            }
        }
        else
            // Вы уже купили это приложение и имеете полностью лицензированную версию
            purchaseCallback?.Invoke(XBoxIAPStatus.LicenseFull, null);
#else
        purchaseCallback?.Invoke(XBoxIAPStatus.NotXBoxPlatform, null);
#endif
#pragma warning restore 1998
    }
Microsoft Partner Center
Microsoft Partner Center
A Microsoft website for partners that provides access to product support, a partner community, and other partner services.
870 questions
{count} votes

2 additional answers

Sort by: Most helpful
  1. Vasya Goblin 21 Reputation points
    2020-10-16T04:10:24.947+00:00

    Hi!

    I am making additional explanations.
    The code is identical for purchasing the full license for the desktop and Xbox application. But for a desktop computer, it works (both when loading an application from the store and when debugging in Visual Studio) and on Xbox the system window is not displayed in both dev and pro console modes.
    The task of the code is to display a system window for purchasing a full license.

    In the xbox mode, I can see the returned exception when GetStoreProductForCurrentAppAsync is called, but it is extremely uninformative (the description boils down to the fact that this is a system exception). Of course, something similar to displaying in the prod console mode can also be organized, but for this you need to put the application in the store and ..., in general, this is an extreme way of debugging. Later I will post a screenshot of the returned exception (Exception.ToString ()), now there is no console nearby.
    The application was in private access (only for testers). I got the assumption that Xbox does not see the product in the store, because the application was released to the public only yesterday and it has not yet passed 24 hours to set up the product in the store. in the hope that this is the only reason why the purchase does not work.
    Another suggested reason is to initialize StoreContext.GetDefault () with parameters, and named with the current user.

    The code that receives the result of an attempt to purchase a license:

        private void Purchase()
        {
            Loger(">>>>>>>>>> #0 InAppPurchaseManagerXBox.Purchases()");
    
            CPurchaseXBox.PurchaseFullLicense((CPurchaseXBox.XBoxIAPStatus result, Exception e) =>
            {
                if (e != null)
                {
                    Loger($">>>>>>>>>> #1 InAppPurchaseManagerXBox.Purchases() Exception message: \"{e.ToString()}\"");
    
                    return;
                }
    
                Loger($">>>>>>>>>> #2 InAppPurchaseManagerXBox.Purchases() result = {result}");
    
                if (result == CPurchaseXBox.XBoxIAPStatus.AlreadyPurchased || result == CPurchaseXBox.XBoxIAPStatus.LicenseFull)
                {
                    TryUnlockGame(true, "1");
    
                    OnPurchaseHandler?.Invoke(this, new PurchaseEventArgs(true, "Is Product Purchased"));
                }
    
            }, LicensesChanged);          
        }
    

    Also, later I will attach a more detailed output of the exception.


  2. Vasya Goblin 21 Reputation points
    2020-10-20T06:30:59.723+00:00

    Hi.
    Thanks for your attention to my problem.

    The code is written in Unity3d, after which it is assembled into the Visual Studio project. Therefore, unfortunately, there is no way to set a breakpoint. I use logging.
    The GetStoreProductForCurrentAppAsync () function returns a StoreProductResult, which contains an exception that has already been handled by the system and I don't need to catch it. You just need to check its presence and if it is, then process the fact of its presence. Standard schema according to documentation and numerous examples.
    As a result, if I install an application from a store on a stationary computer, then everything works, and if I also install an application on an XBox, it does not work because GetStoreProductForCurrentAppAsync cannot get products in the XBox environment and the PurchaseFullLicense function is terminated for verification:

    StoreProductResult productResult = await context.GetStoreProductForCurrentAppAsync();
             if (productResult == null || productResult.Product == null)
             //if (productResult.ExtendedError != null) //  is equivalent to interrupting the check