支持购买可消耗加载项Enable consumable add-on purchases

本文介绍了如何使用 Windows.Services.Store 命名空间中 StoreContext 类的方法,管理 UWP 应用中可消耗加载项的实施情况。This article demonstrates how to use methods of the StoreContext class in the Windows.Services.Store namespace to manage the user's fulfillment of consumable add-ons in your UWP apps. 对可以购买、使用并再次购买的商品使用可消耗加载项。Use consumable add-ons for items that can be purchased, used, and purchased again. 这对游戏内货币(金子、硬币等)等来说尤为有用,可以购买此类货币,然后将其用于购买特定道具。This is especially useful for things like in-game currency (gold, coins, etc.) that can be purchased and then used to purchase specific power-ups.

备注

Windows.Services.Store 命名空间在 Windows 10 版本 1607 中引入,它仅可用于面向 Windows 10 周年纪念版(10.0;版本 14393)或 Visual Studio 更高版本的项目中。The Windows.Services.Store namespace was introduced in Windows 10, version 1607, and it can only be used in projects that target Windows 10 Anniversary Edition (10.0; Build 14393) or a later release in Visual Studio. 如果你的应用面向 Windows 10 的较早版本,则必须使用 Windows.ApplicationModel.Store 命名空间来替代 Windows.Services.Store 命名空间。If your app targets an earlier version of Windows 10, you must use the Windows.ApplicationModel.Store namespace instead of the Windows.Services.Store namespace. 有关详细信息,请参阅此文章For more information, see this article.

可消耗加载项概述Overview of consumable add-ons

应用可以提供在实施情况管理方式上大不相同的两种类型的可消耗加载项:Apps can offer two types of consumable add-ons that differ in the way that fulfillments are managed:

  • 开发人员管理的消耗品Developer-managed consumable. 对于此类型的消耗品,你负责跟踪加载项所表示的商品的用户余量,并在用户消耗完所有商品后向应用商店将加载项购买报告为已完成。For this type of consumable, you are responsible for keeping track of the user's balance of items that the add-on represents, and for reporting the purchase of the add-on as fulfilled to the Store after the user has consumed all of the items. 在你的应用将之前的加载项购买报告为已完成前,用户无法再次购买该加载项。The user cannot purchase the add-on again until your app has reported the previous add-on purchase as fulfilled.

    例如,如果你的加载项表示游戏中的 100 个硬币,并且用户消耗了 10 个硬币,则你的用户或服务必须为该用户保留 90 个硬币的新剩余余额。For example, if your add-on represents 100 coins in a game and the user consumes 10 coins, your app or service must maintain the new remaining balance of 90 coins for the user. 在用户消耗完全部 100 个硬币后,你的应用必须将加载项报告为已完成,然后用户才可以再次购买 100 个硬币的加载项。After the user has consumed all 100 coins, your app must report the add-on as fulfilled, and then the user can purchase the 100 coin add-on again.

  • 应用商店管理的消耗品Store-managed consumable. 对于此类型的消耗品,应用商店会跟踪用户拥有的加载项所表示商品的余量。For this type of consumable, the Store keeps track of the user's balance of items that the add-on represents. 当用户消耗任何商品时,你负责向应用商店报告这些商品已完成,然后应用商店会更新用户的余量。When the user consumes any items, you are responsible for reporting those items as fulfilled to the Store, and the Store updates the user's balance. 用户可以根据需要多次购买加载项(他们不需要首先使用这些项目)。The user can purchase the add-on as many times as they want (they do not need to consume the items first). 你的应用可以随时向 Microsoft Store 查询用户的当前余量。Your app can query the Store for the current balance for the user at any time.

    例如,如果加载项在游戏中表示 100 个硬币的初始数量,并且用户消耗了 50 个硬币,则应用将向 Microsoft Store 报告 50 个单位的加载项已完成,然后 Microsoft Store 会更新剩余余额。For example, if your add-on represents an initial quantity of 100 coins in a game and the user consumes 50 coins, your app reports to the Store that 50 units of the add-on were fulfilled, and the Store updates the remaining balance. 如果用户再次购买你的加载项(增加 100 个硬币),他们现在总共有 150 个硬币。If the user then repurchases your add-on to acquire 100 more coins, they will now have 150 coins total.

    备注

    Microsoft Store 管理的易耗品是在 Windows 10 版本 1607 引入。Store-managed consumables were introduced in Windows 10, version 1607.

若要向用户提供可使用加载项,请按照此一般过程执行:To offer a consumable add-on to a user, follow this general process:

  1. 让用户可以从你的应用中购买加载项Enable users to purchase the add-on from your app.
  2. 用户消耗掉该加载项后(例如,他们在游戏中将硬币花掉),请将该加载项报告为已完成When the user consumes the add-on (for example, they spend coins in a game), report the add-on as fulfilled.

你还可以随时获取应用商店管理的易耗品的剩余余额At any time, you can also get the remaining balance for a Store-managed consumable.

先决条件Prerequisites

这些示例有以下先决条件:These examples have the following prerequisites:

  • 适用于面向 Windows 10 周年纪念版(10.0;版本 14393)或更高版本的通用 Windows 平台 (UWP) 应用的 Visual Studio 项目。A Visual Studio project for a Universal Windows Platform (UWP) app that targets Windows 10 Anniversary Edition (10.0; Build 14393) or a later release.
  • 你已在 Windows 开发人员中心仪表板中创建了一个应用提交,并且该应用已发布到 Microsoft Store 中。You have created an app submission in the Windows Dev Center dashboard and this app is published in the Store. 在测试应用期间,你可以选择将应用配置为在 Microsoft Store 中隐藏。You can optionally configure the app so it is not discoverable in the Store while you test it. 有关详细信息,请参阅我们的测试指南For more information, see our testing guidance.
  • 你已经在开发人员中心仪表板中为该应用创建了一个可使用加载项You have created a consumable add-on for the app in the Dev Center dashboard.

这些示例中的代码假设:The code in these examples assume:

  • 代码在含有 ProgressRing(名为 workingProgressRing)和 TextBlock(名为 textBlock)的 Page 上下文中运行。The code runs in the context of a Page that contains a ProgressRing named workingProgressRing and a TextBlock named textBlock. 这些对象分别用于指示是否正在进行异步操作和显示输出消息。These objects are used to indicate that an asynchronous operation is occurring and to display output messages, respectively.
  • 代码文件有一个适用于 Windows.Services.Store 命名空间的 using 语句。The code file has a using statement for the Windows.Services.Store namespace.
  • 该应用是单用户应用,仅在启动该应用的用户上下文中运行。The app is a single-user app that runs only in the context of the user that launched the app. 有关详细信息,请参阅应用内购买和试用For more information, see In-app purchases and trials.

有关完整的示例应用程序,请参阅应用商店示例For a complete sample application, see the Store sample.

备注

如果你有使用桌面桥的桌面应用程序,可能需要添加未在这些示例中显示的额外代码来配置 StoreContext 对象。If you have a desktop application that uses the Desktop Bridge, you may need to add additional code not shown in these examples to configure the StoreContext object. 有关详细信息,请参阅在使用桌面桥的桌面应用程序中使用 StoreContext 类For more information, see Using the StoreContext class in a desktop application that uses the Desktop Bridge.

将可消耗加载项报告为已完成Report a consumable add-on as fulfilled

在用户从你的应用中购买加载项并消耗完后,你的应用必须通过调用 StoreContext 类的 ReportConsumableFulfillmentAsync 方法,将该加载项报告为已完成。After the user purchases the add-on from your app and they consume your add-on, your app must report the add-on as fulfilled by calling the ReportConsumableFulfillmentAsync method of the StoreContext class. 必须将以下信息传递给此方法:You must pass the following information to this method:

  • 你想要将其报告为已完成的加载项的应用商店 IDThe Store ID of the add-on that you want to report as fulfilled.
  • 你想要将其报告为已完成的加载项的单位。The units of the add-on you want to report as fulfilled.
    • 对于开发人员管理的消耗品,将 quantity 参数指定为 1。For a developer-managed consumable, specify 1 for the quantity parameter. 这将通知应用商店该消耗品已完成,然后客户可以再次购买该消耗品。This alerts the Store that the consumable has been fulfilled, and the customer can then purchase the consumable again. 只有在你的应用通知应用商店消耗品已完成后,用户才能再次购买该消耗品。The user cannot purchase the consumable again until your app has notified the Store that it was fulfilled.
    • 对于应用商店管理的消耗品,请指定已消耗的实际数量。For a Store-managed consumable, specify the actual number of units that have been consumed. 应用商店将更新该消耗品的剩余余额。The Store will update the remaining balance for the consumable.
  • 完成情况的追踪 ID。The tracking ID for the fulfillment. 这是开发人员提供的 GUID,可标识实施情况与之相关联的具体交易记录以用于跟踪。This is a developer-supplied GUID that identifies the specific transaction that the fulfillment operation is associated with for tracking purposes. 有关详细信息,请参阅 ReportConsumableFulfillmentAsync 中的备注。For more information, see the remarks in ReportConsumableFulfillmentAsync.

此示例演示如何将 Microsoft Store 管理的易耗品报告为已完成。This example demonstrates how to report a Store-managed consumable as fulfilled.

private StoreContext context = null;

public async void ConsumeAddOn(string storeId)
{
    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.
    }

    // This is an example for a Store-managed consumable, where you specify the actual number
    // of units that you want to report as consumed so the Store can update the remaining
    // balance. For a developer-managed consumable where you maintain the balance, specify 1
    // to just report the add-on as fulfilled to the Store.
    uint quantity = 10;
    string addOnStoreId = "9NBLGGH4TNNR";
    Guid trackingId = Guid.NewGuid();

    workingProgressRing.IsActive = true;
    StoreConsumableResult result = await context.ReportConsumableFulfillmentAsync(
        addOnStoreId, quantity, trackingId);
    workingProgressRing.IsActive = false;

    // 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 StoreConsumableStatus.Succeeded:
            textBlock.Text = "The fulfillment was successful. " + 
                $"Remaining balance: {result.BalanceRemaining}";
            break;

        case StoreConsumableStatus.InsufficentQuantity:
            textBlock.Text = "The fulfillment was unsuccessful because the remaining " +
                $"balance is insufficient. Remaining balance: {result.BalanceRemaining}";
            break;

        case StoreConsumableStatus.NetworkError:
            textBlock.Text = "The fulfillment was unsuccessful due to a network error. " +
                "ExtendedError: " + extendedError;
            break;

        case StoreConsumableStatus.ServerError:
            textBlock.Text = "The fulfillment was unsuccessful due to a server error. " +
                "ExtendedError: " + extendedError;
            break;

        default:
            textBlock.Text = "The fulfillment was unsuccessful due to an unknown error. " +
                "ExtendedError: " + extendedError;
            break;
    }
}

获取应用商店管理的易耗品的剩余余额Get the remaining balance for a Store-managed consumable

此示例演示如何使用 StoreContext 类的 GetConsumableBalanceRemainingAsync 方法获取应用商店管理的易耗型加载项的剩余余额。This example demonstrates how to use the GetConsumableBalanceRemainingAsync method of the StoreContext class to get the remaining balance for a Store-managed consumable add-on.

private StoreContext context = null;

public async void GetRemainingBalance(string storeId)
{
    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.
    }

    string addOnStoreId = "9NBLGGH4TNNR";

    workingProgressRing.IsActive = true;
    StoreConsumableResult result = await context.GetConsumableBalanceRemainingAsync(addOnStoreId);
    workingProgressRing.IsActive = false;

    // 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 StoreConsumableStatus.Succeeded:
            textBlock.Text = "Remaining balance: " + result.BalanceRemaining;
            break;

        case StoreConsumableStatus.NetworkError:
            textBlock.Text = "Could not retrieve balance due to a network error. " +
                "ExtendedError: " + extendedError;
            break;

        case StoreConsumableStatus.ServerError:
            textBlock.Text = "Could not retrieve balance due to a server error. " +
                "ExtendedError: " + extendedError;
            break;

        default:
            textBlock.Text = "Could not retrieve balance due to an unknown error. " +
                "ExtendedError: " + extendedError;
            break;
    }
}