问题
I want to integrate in-app purchasing in my windows universal app. I do the following thing before coding.
Make App on Windows Dev Center
Add products with details in IAPs section and submit to Store as you can see in Image
- After that I use the following code in my app to get list of products of In-App purchasing and button to purchase product. I also used
CurrentAppinstead ofCurrentAppSimulatorin my code but it goes in exception.
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();
}
}
I also Associate my app with Store and my app package is same as in MS Dev Center App as you can see in Image
When I run my app and click on Buy button, I got this dialogue box as you can see in Image after that I did not get receipt data from Store.
If I'm doing wrong then Please give me proper guide to implement the In-app purchase and test that In-app purchase in my laptop device.
回答1:
I also had this issue and the problem was in the WindowsStoreProxy.xml file.
Solution in short
By default in the WindowsStoreProxy.xml the IsTrial is set to true and in that mode in-app purchases do not seem to work. When I changed it to false it started to work for me.
Solution a little bit longer
So first of all here we are talking about the simulation of an In-App Purchase in development time (by using the
CurrentAppSimulatorclass). In that case you need aWindowsStoreProxy.xmlfile. It’s described hereNow the window you showed is opened by the
CurrentAppSimulator.RequestProductPurchaseAsyncline. It basically controls the return value of a Windows Runtime native method (which is very strange for me… I think it’s not intentional by Microsoft… something else should be done there), but if you let it returnS_OKthat basically is the case when the user paid for the in-App Purchase.When it returns nothing then with very high probability something in the
WindowsStoreProxy.xmlis wrong. I suggest you to create your ownWindowsStoreProxy.xmland read it with theCurrentAppSimulator.ReloadSimulatorAsyncmethod like this:var file = await Windows.ApplicationModel.Package.Current.InstalledLocation.GetFileAsync(@"Testing\WindowsStoreProxy.xml"); await CurrentAppSimulator.ReloadSimulatorAsync(file);For me using the default one from
C:\Users\<username>\AppData\Local\Packages\<app package folder>\LocalState\Microsoft\Windows Store\ApiData\WindowsStoreProxy.xmldid not work, but a single change already solved the problem: I changed this part<LicenseInformation> <App> <IsActive>true</IsActive> <IsTrial>true</IsTrial> </App> </LicenseInformation>To this:
<LicenseInformation> <App> <IsActive>true</IsActive> <IsTrial>false</IsTrial> </App> </LicenseInformation>(So
IsTrialwas set to false...)Now at this point I also would like to mention that this was a little bit strange, since in in the default
WindowsStoreProxy.xmlthere was no Product defined for my In-App Purchase. So for my “RemoveAds” a properWindowsStoreProxy.xmlwould be something like this:<?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>Another thing I would like to point out is that the
CurrentAppSimulator.RequestProductPurchaseAsyncwith two parameter is obsolete. Leave the true parameter out and you getPurchaseResultsinstance as the result, which contains the receipt in theReceiptXMLproperty.
回答2:
WindowsStoreProxy.xml to c# code and serialize to xml file
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;
}
Base xml model
[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; }
}
Get 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;
}
来源:https://stackoverflow.com/questions/32308032/how-to-implement-in-app-purchases-in-windows-10-apps