我想在我的Windows通用应用中集成应用内购买。我在编码之前做了以下事情。
在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();
}
}
我还将我的应用与商店关联,我的应用包与MS开发中心应用相同,您可以在Image
中看到当我运行我的应用程序并单击“购买”按钮时,我在Image中看到了这个对话框,之后我没有从商店获得收据数据。
如果我做错了,请给我一个正确的指南,以实现应用内购买并测试我的笔记本电脑设备中的应用内购买。
答案 0 :(得分:3)
我也有这个问题,问题出现在WindowsStoreProxy.xml
文件中。
默认情况下,WindowsStoreProxy.xml
IsTrial
设置为true,在该模式下,应用内购买似乎无效。当我把它改成假时,它开始为我工作。
首先,我们在讨论在开发时间内模拟应用程序内购买(使用CurrentAppSimulator
类)。在这种情况下,您需要一个WindowsStoreProxy.xml
文件。它描述了here
现在您显示的窗口由CurrentAppSimulator.RequestProductPurchaseAsync
行打开。它基本上控制了Windows运行时本机方法的返回值(这对我来说非常奇怪......我认为这不是微软的故意......应该在那里做其他事情),但是如果你让它返回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
属性中的收据。
答案 1 :(得分:0)
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;
}