Share via

I love UWP Platform

Gianfranco Percopo 16 Reputation points
2019-11-30T10:57:35.243+00:00

Hi, this is original message from App Certification Kit

  • Name: …….
  • App ID: 9N43VPZH82F7
  • Publisher name: ……
  • Test ID: fa473b92-6984-4e38-b8bf-ab3671f5804e
  • Review completed: 11/29/2019 01:48PM

Hello,

Thank you for contacting us. The app offers the ability to purchase digital goods or services in-app and must use the Microsoft Store in-app purchase API. Apps may enable users to consume previously purchased digital content or services (subscriptions) but must not direct users to a purchase mechanism other than the Microsoft Store in-app purchase API.

For more information on the Microsoft Store in-app purchase API, please see:
Enable in-app purchases of apps and add-ons: https://learn.microsoft.com/en-us/windows/uwp/monetize/enable-in-app-purchases-of-apps-and-add-ons
Enable subscription add-ons for your app: https://learn.microsoft.com/en-us/windows/uwp/monetize/enable-subscription-add-ons-for-your-app

If you need assistance implementing this feature, please contact Developer Support via your Partner Dashboard or at this link: http://aka.ms/storesupport.

Please let us know if you need any additional assistance.

Thank you,
Alice
Microsoft Store Team


This is my page.

namespace MyApp  
{  
    ///   
    /// Pagina vuota che può essere usata autonomamente oppure per l'esplorazione all'interno di un frame.  
    ///   
    public sealed partial class MainPage : Page  
    {  
        private StoreContext context = null;  
        private StoreProduct subscriptionStoreProduct;  
  
        // Assign this variable to the Store ID of your subscription add-on.  
        private string subscriptionStoreId = "hide for security reason";  
  
        public MainPage()  
        {  
            this.InitializeComponent();  
        }  
  
        private async void Page_Loaded(object sender, RoutedEventArgs e)  
        {  
            await GetSubscriptionsInfo();  
        }  
  
        // This is the entry point method for the example.  
        public async Task SetupSubscriptionInfoAsync()  
        {  
           if (context == null)  
            {  
                context = StoreContext.GetDefault();  
                // If your app is a desktop app that uses the Desktop Bridge, you  
                // may need additional code to configure the StoreContext object.  
                // For more info, see https://aka.ms/storecontext-for-desktop.  
            }  
  
            bool userOwnsSubscription = await CheckIfUserHasSubscriptionAsync();  
            if (userOwnsSubscription)  
            {  
                // Unlock all the subscription add-on features here.  
                Frame.Navigate(typeof(Accedi));  
                return;  
            }  
  
            // Get the StoreProduct that represents the subscription add-on.  
            subscriptionStoreProduct = await GetSubscriptionProductAsync();  
            if (subscriptionStoreProduct == null)  
            {  
                return;  
            }  
  
            // Check if the first SKU is a trial and notify the customer that a trial is available.  
            // If a trial is available, the Skus array will always have 2 purchasable SKUs and the  
            // first one is the trial. Otherwise, this array will only have one SKU.  
            StoreSku sku = subscriptionStoreProduct.Skus[0];  
            if (sku.SubscriptionInfo.HasTrialPeriod)  
            {  
                // You can display the subscription trial info to the customer here. You can use  
                // sku.SubscriptionInfo.TrialPeriod and sku.SubscriptionInfo.TrialPeriodUnit  
                // to get the trial details.  
            }  
            else  
            {  
                // You can display the subscription purchase info to the customer here. You can use  
                // sku.SubscriptionInfo.BillingPeriod and sku.SubscriptionInfo.BillingPeriodUnit  
                // to provide the renewal details.  
            }  
  
            // Prompt the customer to purchase the subscription.  
            await PromptUserToPurchaseAsync();  
        }  
  
        private async Task CheckIfUserHasSubscriptionAsync()  
        {  
            StoreAppLicense appLicense = await context.GetAppLicenseAsync();  
  
            // Check if the customer has the rights to the subscription.  
            foreach (var addOnLicense in appLicense.AddOnLicenses)  
            {  
                StoreLicense license = addOnLicense.Value;  
                if (license.SkuStoreId.StartsWith(subscriptionStoreId))  
                {  
                    if (license.IsActive)  
                    {  
                        // The expiration date is available in the license.ExpirationDate property.  
                        return true;  
                    }  
                }  
            }  
  
            // The customer does not have a license to the subscription.  
            return false;  
        }  
  
        private async Task GetSubscriptionProductAsync()  
        {  
            // Load the sellable add-ons for this app and check if the trial is still  
            // available for this customer. If they previously acquired a trial they won't  
            // be able to get a trial again, and the StoreProduct.Skus property will  
            // only contain one SKU.  
            StoreProductQueryResult result =  
                await context.GetAssociatedStoreProductsAsync(new string[] { "Durable" });  
  
            if (result.ExtendedError != null)  
            {  
                //System.Diagnostics.Debug.WriteLine("Something went wrong while getting the add-ons. " +  
                //"ExtendedError:" + result.ExtendedError);  
  
                var messageDialog = new MessageDialog("Qualcosa è andato storto durante il recupero dei componenti aggiuntivi. Errore: " + result.ExtendedError, "Avviso");  
                await messageDialog.ShowAsync();  
  
                return null;  
            }  
  
            // Look for the product that represents the subscription.  
            foreach (var item in result.Products)  
            {  
                StoreProduct product = item.Value;  
                if (product.StoreId == subscriptionStoreId)  
                {  
                    return product;  
                }  
            }  
  
            //System.Diagnostics.Debug.WriteLine("The subscription was not found.");  
            var messageDialogNull = new MessageDialog("L'abbonamento non è stato trovato.", "Avviso");  
            await messageDialogNull.ShowAsync();  
            return null;  
        }  
  
        private async Task PromptUserToPurchaseAsync()  
        {  
            // Request a purchase of the subscription product. If a trial is available it will be offered  
            // to the customer. Otherwise, the non-trial SKU will be offered.  
            StorePurchaseResult result = await subscriptionStoreProduct.RequestPurchaseAsync();  
  
            // Capture the error message for the operation, if any.  
            string extendedError = string.Empty;  
            if (result.ExtendedError != null)  
            {  
                extendedError = result.ExtendedError.Message;  
            }  
  
            switch (result.Status)  
            {  
                case StorePurchaseStatus.Succeeded:  
                    // Show a UI to acknowledge that the customer has purchased your subscription  
                    // and unlock the features of the subscription.  
                    Frame.Navigate(typeof(Accedi));  
                    break;  
  
                case StorePurchaseStatus.NotPurchased:  
                    //System.Diagnostics.Debug.WriteLine("The purchase did not complete. " +  
                    //"The customer may have cancelled the purchase. ExtendedError: " + extendedError);  
                    var messageDialog = new MessageDialog("L'acquisto non è stato completato o è stato annullato. Errore: " + result.ExtendedError, "Avviso");  
                    await messageDialog.ShowAsync();  
                    break;  
  
                case StorePurchaseStatus.ServerError:  
                case StorePurchaseStatus.NetworkError:  
                    //System.Diagnostics.Debug.WriteLine("The purchase was unsuccessful due to a server or network error. " +  
                    //"ExtendedError: " + extendedError);  
  
                    var messageDialogServerNetworkError = new MessageDialog("L'acquisto non è andato a buon fine a causa di un errore del server o della rete. Errore: " + result.ExtendedError, "Avviso");  
                    await messageDialogServerNetworkError.ShowAsync();  
                    break;  
  
                case StorePurchaseStatus.AlreadyPurchased:  
                    //System.Diagnostics.Debug.WriteLine("The customer already owns this subscription." +  
                    //"ExtendedError: " + extendedError);  
  
                    var messageDialogAlreadyPurchased = new MessageDialog("Il cliente possiede già questo abbonamento. Errore: " + result.ExtendedError, "Avviso");  
                    await messageDialogAlreadyPurchased.ShowAsync();  
                    break;  
            }  
        }  
  
        public async Task GetSubscriptionsInfo()  
        {  
            if (context == null)  
            {  
                context = StoreContext.GetDefault();  
                // If your app is a desktop app that uses the Desktop Bridge, you  
                // may need additional code to configure the StoreContext object.  
                // For more info, see https://aka.ms/storecontext-for-desktop.  
            }  
  
            // Subscription add-ons are Durable products.  
            string[] productKinds = { "Durable" };  
            List filterList = new List(productKinds);  
  
            StoreProductQueryResult queryResult =  
                await context.GetAssociatedStoreProductsAsync(productKinds);  
  
            if (queryResult.ExtendedError != null)  
            {  
                // The user may be offline or there might be some other server failure.  
                System.Diagnostics.Debug.WriteLine($"ExtendedError: {queryResult.ExtendedError.Message}");  
                return;  
            }  
  
            foreach (KeyValuePair item in queryResult.Products)  
            {  
                // Access the Store product info for the add-on.  
                StoreProduct product = item.Value;  
  
                // For each add-on, the subscription info is available in the SKU objects in the add-on.  
                foreach (StoreSku sku in product.Skus)  
                {  
                    if (sku.IsSubscription)  
                    {  
                        // Use the sku.SubscriptionInfo property to get info about the subscription.  
                        // For example, the following code gets the units and duration of the  
                        // subscription billing period.  
                        StoreDurationUnit billingPeriodUnit = sku.SubscriptionInfo.BillingPeriodUnit;  
                        uint billingPeriod = sku.SubscriptionInfo.BillingPeriod;  
  
                        tb_info.Text = "Tipologia: " + sku.Title.ToString() + Environment.NewLine;  
                        tb_info.Text += "Descrizione: " + sku.Description.ToString() + Environment.NewLine;  
                        tb_info.Text += "Periodo di fatturazione: " + sku.SubscriptionInfo.BillingPeriodUnit.ToString() + Environment.NewLine;  
                    }  
                }  
            }  
        }  
  
        private async void btn_prosegui_Click(object sender, RoutedEventArgs e)  
        {  
            //CONTROLLO L'ABBONAMENTO  
            await SetupSubscriptionInfoAsync();  
        }  
    }  
}  

Nevertheless my app is not valid. In my opinion the Microosft certifiers drink during the certification process :))))

I'm really frustrated :(((((((((((((((((((((((((((((((

Developer technologies | Universal Windows Platform (UWP)

2 answers

Sort by: Most helpful
  1. Gianfranco Percopo 16 Reputation points
    2019-12-02T13:49:42.747+00:00

    Finally passed certification. I love uwp platform :) Finally.... I'm happy

    Was this answer helpful?


  2. Alberto T. Gomez 1 Reputation point
    2019-12-01T16:05:40.187+00:00

    Internet connection

    Was this answer helpful?


Your answer

Answers can be marked as 'Accepted' by the question author and 'Recommended' by moderators, which helps users know the answer solved the author's problem.