簡體   English   中英

如何在Windows 10應用中實施應用內購買?

[英]How to Implement In-App Purchases in Windows 10 Apps?

我想將應用內購買集成到我的Windows通用應用中。 在編碼之前,我要做以下事情。

  • Windows Dev Center上制作應用

  • 在IAP部分中添加具有詳細信息的產品,然后提交到商店,如您在Image中所見

  • 之后,我在我的應用程序中使用以下代碼來獲取應用內購買產品的列表以及購買產品的按鈕。 我在代碼中也使用了CurrentApp而不是CurrentAppSimulator ,但是它例外。
private async void RenderStoreItems()
    {
        picItems.Clear();

        try
        {
            //StoreManager mySM = new StoreManager();
            ListingInformation li = await CurrentAppSimulator.LoadListingInformationAsync();

            System.Diagnostics.Debug.WriteLine(li);

            foreach (string key in li.ProductListings.Keys)
            {
                ProductListing pListing = li.ProductListings[key];
                System.Diagnostics.Debug.WriteLine(key);

                string status = CurrentAppSimulator.LicenseInformation.ProductLicenses[key].IsActive ? "Purchased" : pListing.FormattedPrice;

                string imageLink = string.Empty;

                picItems.Add(
                    new ProductItem
                    {
                        imgLink = key.Equals("BaazarMagzine101") ? "block-ads.png" : "block-ads.png",
                        Name = pListing.Name,
                        Status = status,
                        key = key,
                        BuyNowButtonVisible = CurrentAppSimulator.LicenseInformation.ProductLicenses[key].IsActive ? false : true
                    }
                );
            }

            pics.ItemsSource = picItems;
        }
        catch (Exception e)
        {
            System.Diagnostics.Debug.WriteLine(e.ToString());
        }
    }

    private async void ButtonBuyNow_Clicked(object sender, RoutedEventArgs e)
    {
        Button btn = sender as Button;

        string key = btn.Tag.ToString();

        if (!CurrentAppSimulator.LicenseInformation.ProductLicenses[key].IsActive)
        {
            ListingInformation li = await CurrentAppSimulator.LoadListingInformationAsync();
            string pID = li.ProductListings[key].ProductId;

            string receipt = await CurrentAppSimulator.RequestProductPurchaseAsync(pID, true);

            System.Diagnostics.Debug.WriteLine(receipt);

            // RenderStoreItems();
        }
    }

我還將我的應用程序與Store關聯,並且我的應用程序包與MS Dev Center App中的相同,如您在Image中看到的

當我運行我的應用程序並單擊“購買”按鈕時,我得到了這個對話框,正如您在圖像中看到的那樣,因為我沒有從商店獲得收據數據。

如果我做錯了,請給我適當的指導,以實施應用內購買並在我的筆記本電腦設備中測試該應用內購買。

我也遇到了這個問題,問題出在WindowsStoreProxy.xml文件中。

簡而言之

默認情況下, WindowsStoreProxy.xmlIsTrial設置為true,在這種模式下,應用內購買似乎無效。 當我將其更改為false時,它開始為我工作。

解決方案更長一點

  • 因此,首先我們要在開發過程中(通過使用CurrentAppSimulator類)討論對應用內購買的模擬。 在這種情況下,您需要一個WindowsStoreProxy.xml文件。 在這里描述

  • 現在,您顯示的窗口由CurrentAppSimulator.RequestProductPurchaseAsync行打開。 它基本上控制着Windows Runtime本機方法的返回值(這對我來說很奇怪……我認為這不是Microsoft故意的……應該在此做其他事情),但是如果讓它返回S_OK ,基本上就是這種情況。用戶為應用內購買付費。

    購買模擬窗口的屏幕截圖

  • 當它什么也不返回時,則很有可能WindowsStoreProxy.xml某些內容是錯誤的。 我建議您創建自己的WindowsStoreProxy.xml並使用CurrentAppSimulator.ReloadSimulatorAsync方法讀取它,如下所示:

     var file = await Windows.ApplicationModel.Package.Current.InstalledLocation.GetFileAsync(@"Testing\\WindowsStoreProxy.xml"); await CurrentAppSimulator.ReloadSimulatorAsync(file); 
  • 對我來說,使用C:\\Users\\<username>\\AppData\\Local\\Packages\\<app package folder>\\LocalState\\Microsoft\\Windows Store\\ApiData\\WindowsStoreProxy.xml不起作用,但是單個更改已解決問題:我更改了這部分

     <LicenseInformation> <App> <IsActive>true</IsActive> <IsTrial>true</IsTrial> </App> </LicenseInformation> 

    對此:

     <LicenseInformation> <App> <IsActive>true</IsActive> <IsTrial>false</IsTrial> </App> </LicenseInformation> 

    (因此IsTrial設置為false ...)

  • 現在,在這一點上,我還想提一下,這有點奇怪,因為在默認的WindowsStoreProxy.xml中,沒有為我的應用內購買定義任何產品。 因此,對於我的“ RemoveAds”,正確的WindowsStoreProxy.xml如下所示:

     <?xml version="1.0" encoding="utf-16" ?> <CurrentApp> <ListingInformation> <App> <AppId>00000000-0000-0000-0000-000000000000</AppId> <LinkUri>http://apps.microsoft.com/webpdp/app/00000000-0000-0000-0000-000000000000</LinkUri> <CurrentMarket>en-US</CurrentMarket> <AgeRating>3</AgeRating> <MarketData xml:lang="en-US"> <Name>AppName</Name> <Description>AppDescription</Description> <Price>1.00</Price> <CurrencySymbol>$</CurrencySymbol> <CurrencyCode>USD</CurrencyCode> </MarketData> </App> <Product ProductId="RemoveAds" LicenseDuration="1" ProductType="Durable"> <MarketData xml:lang="en-US"> <Name>RemoveAds</Name> <Price>1.00</Price> <CurrencySymbol>$</CurrencySymbol> <CurrencyCode>USD</CurrencyCode> </MarketData> </Product> </ListingInformation> <LicenseInformation> <App> <IsActive>true</IsActive> <IsTrial>false</IsTrial> </App> <Product ProductId="1"> <IsActive>true</IsActive> </Product> </LicenseInformation> <ConsumableInformation> <Product ProductId="RemoveAds" TransactionId="10000000-0000-0000-0000-000000000000" Status="Active" /> </ConsumableInformation> </CurrentApp> 
  • 我想指出的另一件事是,帶有兩個參數的CurrentAppSimulator.RequestProductPurchaseAsync已過時。 省略true參數,您將獲得PurchaseResults實例作為結果,該實例包含ReceiptXML屬性中的收據。

WindowsStoreProxy.xml轉換為C#代碼並序列化為xml文件

public static CurrentApp LoadCurrentApp(string productKey = "Premium", bool isActive = false, bool isTrial = false)
    {
        CurrentApp currentApp = new CurrentApp();
        currentApp.ListingInformation = new ListingInformation()
        {
            App = new App()
            {
                AgeRating = "3",
                AppId = BasicAppInfo.AppId,
                CurrentMarket = "en-us",
                LinkUri = "",
                MarketData = new MarketData()
                {
                    Name = "In-app purchases",
                    Description = "AppDescription",
                    Price = "5.99",
                    CurrencySymbol = "$",
                    CurrencyCode = "USD",
                }
            },
            Product = new Product()
            {
                ProductId = productKey,
                MarketData = new MarketData()
                {
                    Lang = "en-us",
                    Name = productKey,
                    Description = "AppDescription",
                    Price = "5.99",
                    CurrencySymbol = "$",
                    CurrencyCode = "USD",
                }
            }
        };
        currentApp.LicenseInformation = new LicenseInformation()
        {
            App = new App()
            {
                IsActive = isActive.ToString(),
                IsTrial = isTrial.ToString(),
            },
            Product = new Product()
            {
                ProductId = productKey,
                IsActive = isActive.ToString(),
            }
        };
        return currentApp;
    }

基本xml模型

[XmlRoot(ElementName = "MarketData")]
public class MarketData
{
    [XmlElement(ElementName = "Name")]
    public string Name { get; set; }
    [XmlElement(ElementName = "Description")]
    public string Description { get; set; }
    [XmlElement(ElementName = "Price")]
    public string Price { get; set; }
    [XmlElement(ElementName = "CurrencySymbol")]
    public string CurrencySymbol { get; set; }
    [XmlElement(ElementName = "CurrencyCode")]
    public string CurrencyCode { get; set; }
    [XmlAttribute(AttributeName = "lang", Namespace = "http://www.w3.org/XML/1998/namespace")]
    public string Lang { get; set; }
}

[XmlRoot(ElementName = "App")]
public class App
{
    [XmlElement(ElementName = "AppId")]
    public string AppId { get; set; }
    [XmlElement(ElementName = "LinkUri")]
    public string LinkUri { get; set; }
    [XmlElement(ElementName = "CurrentMarket")]
    public string CurrentMarket { get; set; }
    [XmlElement(ElementName = "AgeRating")]
    public string AgeRating { get; set; }
    [XmlElement(ElementName = "MarketData")]
    public MarketData MarketData { get; set; }
    [XmlElement(ElementName = "IsActive")]
    public string IsActive { get; set; }
    [XmlElement(ElementName = "IsTrial")]
    public string IsTrial { get; set; }
}

[XmlRoot(ElementName = "Product")]
public class Product
{
    [XmlElement(ElementName = "MarketData")]
    public MarketData MarketData { get; set; }
    [XmlAttribute(AttributeName = "ProductId")]
    public string ProductId { get; set; }
    [XmlElement(ElementName = "IsActive")]
    public string IsActive { get; set; }
}

[XmlRoot(ElementName = "ListingInformation")]
public class ListingInformation
{
    [XmlElement(ElementName = "App")]
    public App App { get; set; }
    [XmlElement(ElementName = "Product")]
    public Product Product { get; set; }
}

[XmlRoot(ElementName = "LicenseInformation")]
public class LicenseInformation
{
    [XmlElement(ElementName = "App")]
    public App App { get; set; }
    [XmlElement(ElementName = "Product")]
    public Product Product { get; set; }
}

[XmlRoot(ElementName = "CurrentApp")]
public class CurrentApp
{
    [XmlElement(ElementName = "ListingInformation")]
    public ListingInformation ListingInformation { get; set; }
    [XmlElement(ElementName = "LicenseInformation")]
    public LicenseInformation LicenseInformation { get; set; }
}

獲取XmlFile

public async static Task<StorageFile> GetWindowsStoreProxyXmlAsync(string productKey, bool isActive = false, bool isTrial = false)
    {
        StorageFile xmlFile = null;
        var currentApp = LoadCurrentApp(productKey, isActive, isTrial);
        var xml = StorageHelper.SerializeToXML<CurrentApp>(currentApp);
        if (!string.IsNullOrEmpty(xml))
        {
            xmlFile = await StorageHelper.LocalFolder.CreateFileAsync("MarketData.xml", CreationCollisionOption.ReplaceExisting);
            await FileIO.WriteTextAsync(xmlFile, xml);
        }
        return xmlFile;
    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM