Windows 10 UWP上的应用内购买问题

我正在尝试在我的应用上启用应用内购买项目(已在Windows 10商店中),但在尝试购买此商品时,我始终收到相同的错误消息:

MyAppName中不再提供此应用内购买项目

MyAppName中不再提供此应用内购买项目

代码非常简单,只是文档推荐的内容:

var itemName = "app.advanced_items.full"; if (CurrentApp.LicenseInformation.ProductLicenses[itemName].IsActive) { return true; } var results = await CurrentApp.RequestProductPurchaseAsync(itemName); if (results.Status == ProductPurchaseStatus.Succeeded || results.Status == ProductPurchaseStatus.AlreadyPurchased) { return true; } else { return false; } 

更多信息:

  • 在文档告诉我之前,我在构建包之前创建并将应用内项目提交到商店
  • 商店和应用程序上的项目名称相同(代码上的itemName
  • 我在提交到商店之前尝试了这个
  • 我提交到商店后尝试了这个(我的应用程序目前在那里破了! – 无法购买该商品)

我怀疑问题可能与以下内容有关:

  • 应用程序显示名称(在Package.appxmanifest )与商店中的应用程序名称不同(我想要的名称不可用,因此我将其设置得更长,但安装后的应用程序将显示原始名称)。 这个较短的名称是错误消息中的名称…

我将“显示名称”更改为应用程序的全名,但错误是相同的。 我不知道是否将它发送到商店可能会改变这一点(我并不想为了测试这个理论而部署另一个错误的版本)

额外:我在网上找到的关于这个问题的唯一资源是无用的,与Windows 8相关: 链接

建议?

在与微软支持人员交谈2个月后,他们终于修复了一些问题,我的IAP开始工作了。

我相信修复程序是全局的,但是如果您的IAP仍然不起作用,请与他们联系以重新发布它。

以下是他们发给我的电子邮件的摘录:

我们已在此应用中为您的IAP发布了重新发布。 这应该在过程完成后立即纠正这种情况。 您可能需要在接下来的几个小时内定期检查,看看您是否能够确认修复程序适合您。 让我知道你看到了什么。

请查看IAP的productId。 我想你在代码中提到的那个与商店中的不同。

如果它相同,我建议使用LoadListingInformationAsync方法返回IAP列表,然后从该列表中选择所需的IAP。 如果名称不匹配,那么您将无法检索该IAP。 因此,我们能够找到它,因为命名问题。 我还为此添加了一个示例代码。 试一下。

  try { var listing = await CurrentApp.LoadListingInformationAsync(); var iap = listing.ProductListings.FirstOrDefault(p => p.Value.ProductId == "removeads"); receipt = await CurrentApp.RequestProductPurchaseAsync(iap.Value.ProductId, true); if (CurrentApp.LicenseInformation.ProductLicenses[iap.Value.ProductId].IsActive) { CurrentApp.ReportProductFulfillment(iap.Value.ProductId); //your code after purchase is successful } } catch (Exception ex) { //exception } 

我认为这里的问题是你需要区分测试和生产。 除非您在商店中发布,否则无法使用生产模式。 请参见CurrentApp和CurrentAppSimulator 。

CurrentAppSimiulator页面:

备注

在应用程序已在Windowsapp store中列出之前,CurrentApp对象将无法在应用程序中运行。 在开发应用程序时,使用CurrentAppSimulator测试应用程序的许可和应用程序内产品。 在测试应用程序之后,在将其提交到Windowsapp store之前,必须使用CurrentApp替换CurrentAppSimulator的实例。 如果使用CurrentAppSimulator,您的应用将无法通过认证。

以下是我在我的应用程序中使用#define解决此问题的方法,我为测试/生产更改了#define,以及在CurrentApp和CurrentAppSimulator之间切换的代理类,使我的其他代码更加容易。

App.xaml.cs,App()

  // // configure in-app purchasing // #if false #warning WARNING: You are using CurrentAppProxy in TEST MODE! CurrentAppProxy.SetTestMode(true); // true for test, false for production #else CurrentAppProxy.SetTestMode(false); // true for test, false for production 

CurrentAppProxy.cs

 public static class CurrentAppProxy { static bool? testmode = null; public static async void SetTestMode(bool mode) { testmode = mode; if (mode) { var file = await Package.Current.InstalledLocation.GetFileAsync("WindowsStoreProxy.xml"); if (file != null) { await CurrentAppSimulator.ReloadSimulatorAsync(file); } } } public static LicenseInformation LicenseInformation { get { if (testmode == null) throw new NotSupportedException(); else if (testmode.Value) return CurrentAppSimulator.LicenseInformation; else return CurrentApp.LicenseInformation; } } public static IAsyncOperation> GetUnfulfilledConsumablesAsync() { if (testmode == null) throw new NotSupportedException(); else if (testmode.Value) return CurrentAppSimulator.GetUnfulfilledConsumablesAsync(); else return CurrentApp.GetUnfulfilledConsumablesAsync(); } public static IAsyncOperation LoadListingInformationAsync() { if (testmode == null) throw new NotSupportedException(); else if (testmode.Value) return CurrentAppSimulator.LoadListingInformationAsync(); else return CurrentApp.LoadListingInformationAsync(); } public static IAsyncOperation ReportConsumableFulfillmentAsync(string productId, Guid transactionId) { if (testmode == null) throw new NotSupportedException(); else if (testmode.Value) return CurrentAppSimulator.ReportConsumableFulfillmentAsync(productId, transactionId); else return CurrentApp.ReportConsumableFulfillmentAsync(productId, transactionId); } public static IAsyncOperation RequestProductPurchaseAsync(string productId) { if (testmode == null) throw new NotSupportedException(); else if (testmode.Value) return CurrentAppSimulator.RequestProductPurchaseAsync(productId); else return CurrentApp.RequestProductPurchaseAsync(productId); } } 

在我的应用中使用…

  private async Task RefreshInAppOffers() { // in-app offers List> products = null; UnfulfilledConsumable unfulfilledConsumable = null; InAppOffers.Children.Clear(); try { var listinginfo = await CurrentAppProxy.LoadListingInformationAsync(); products = listinginfo.ProductListings.ToList(); products.Sort((p1, p2) => p1.Value.FormattedPrice.CompareTo(p2.Value.FormattedPrice)); 

CurrentAppProxy是关键所在。 如果它适用于模拟器,它应该适用于您的生产项目。 您只需要为所有各种条件准备好所有其他部件。 在调试器中最容易进行一些测试。

我尝试联系Microsoft了解这个问题,他们让我让IAP不可用,然后再次使用。 我必须说它没有解决我的问题 ,但如果你想尝试一下,请按照以下步骤操作:

  1. 为IAP创建更新
  2. 在分配和可见性下,将IAP设置为不可购买
  3. 提交更新
  4. 等待更新发布
  5. 为IAP创建新的更新
  6. 将分配和可见性设置回可供购买
  7. 提交更新
  8. 此更新发布后,重新测试IAP

在那之后,他们告诉我尝试让所有国家都无法使用整个应用程序并发布它。 然后做相反的事情。 没有成功……

我有同样的问题。 在我的情况下,解决方案是在IAP中添加所有语言描述,然后它工作正常

我的新UWP应用程序“Midi Player”也有类似的问题。 在认证和发布后,可以在WP 8.1上购买IAP,但在W10M(Windows 10移动)平台上显示相同的错误(我相信,所有Windows 10 UWP应用程序都有相同的商店)。 我已经向微软提出了问题,但他们无法帮助我。 幸运的是,问题现在已经消失了:)我做了什么:

  • 发布初始应用修订版
  • 创建了IAP
  • 测试IAP(适用于WP8.1,不适用于W10M)
  • 我发现我的Package.appxmanifest文件稍有改动(字符串mp:PhoneIdentity PhoneProductId =“7f32ab79-xxx-xxx-aff3-ce228745b36f”PhonePublisherId =“00000000-0000-0000-0000-000000000000”
  • 我更改了版本(次要编号)并提交了更新的Package.appxmanifest的新版本
  • 今天,我检查了W10M Lumia 950上的IAP,它确实有效。

所以,我的结论是:

  • 您需要创建IAP 重新发布应用程序
  • 你应该等一下