Поделиться через


Включение покупок дополнений с возможностью повторной покупки

В этой статье показано, как использовать методы класса StoreContext в пространстве имен Windows.Services.Store для управления использованием потребляемых дополнений пользователя в приложениях UWP. Используйте потребляемые дополнения для предметов, которые можно приобрести, использовать и приобрести снова. Это особенно полезно для таких вещей, как валюта в игре (золото, монеты и т. д.), которые можно приобрести, а затем использовать для приобретения конкретных power ups.

Заметка

Пространство имен Windows.Services.Store было представлено в Windows 10 версии 1607, и его можно использовать только в проектах, предназначенных для Windows 10 Anniversary Edition (10.0; Сборка 14393) или более поздней версии в Visual Studio. Если приложение предназначено для более ранней версии Windows 10, необходимо использовать пространство имен Windows.ApplicationModel.Store вместо пространства имен Windows.Services.Store. Дополнительные сведения см. в этой статье.

Обзор расширений, которые могут расходоваться

Приложения могут предлагать два типа потребляемых дополнений, которые различаются по способу управления их выполнением.

  • управляемые разработчиком расходные материалы. Для этого типа потребляемых компонентов вы отвечаете за отслеживание баланса предметов, которые представляет надстройка, и за сообщение в Магазин о выполнении покупки надстройки после того, как пользователь потребил все предметы. Пользователь не может снова приобрести надстройку, пока ваше приложение не сообщит о выполненной предыдущей покупке надстройки.

    Например, если дополнение представляет 100 монет в игре, а пользователь потребляет 10 монет, ваше приложение или служба должны поддерживать новый остаток в 90 монет для пользователя. После того как пользователь использовал все 100 монет, ваше приложение должно сообщить о выполнении дополнения, а затем пользователь может приобрести дополнение на 100 монет еще раз.

  • управляемый магазином расходный материал. Для этого типа потребляемых продуктов Магазин отслеживает остаток предметов, представленных дополнением. Когда пользователь потребляет любые предметы, вы несете ответственность за то, чтобы отчитаться о выполнении этих действий в магазине, и магазин обновляет баланс пользователя. Пользователь может приобрести дополнение столько раз, сколько захочет (при этом не обязательно сначала использовать элементы). Ваше приложение может запрашивать информацию у Магазина о текущем балансе пользователя в любое время.

    Например, если ваша надстройка представляет начальное количество 100 монет в игре, а пользователь потребляет 50 монет, ваше приложение сообщает Магазину, что 50 единиц надстройки были выполнены, и Магазин обновляет оставшийся баланс. Если пользователь затем снова покупает ваше дополнение, чтобы получить еще 100 монет, у них теперь будет 150 монет в общей сложности.

    Заметка

    В Windows 10 версии 1607 появились управляемые магазином расходные материалы.

Чтобы предложить пользователю расходуемое дополнение, выполните следующую последовательность действий:

  1. Позвольте пользователям приобретать дополнение в приложении.
  2. Когда пользователь использует надстройку (например, тратит монеты в игре), отметьте надстройку как выполненную.

В любое время вы также можете получить остаток баланса для управляемого Магазином расходуемого товара.

Необходимые условия

В этих примерах имеются следующие предварительные требования:

  • Проект Visual Studio для приложения универсальной платформы Windows (UWP), совместимого с Windows 10 Anniversary Edition (10.0; Сборка 14393) или более поздней версии.
  • Вы создали отправки приложений в Центре партнеров, и это приложение опубликовано в Магазине. При необходимости можно настроить приложение, чтобы оно не было обнаружено в Магазине во время его тестирования. Дополнительные сведения см. в руководстве по тестированию .
  • Вы создали надстройку для приложения в Центре Партнеров.

Код в этих примерах предполагает:

  • Код выполняется в контексте страницы , которая содержит ProgressRing по имени workingProgressRing и TextBlock с именем textBlock. Эти объекты используются для указания, что выполняется асинхронная операция и для отображения выходных сообщений соответственно.
  • Файл кода содержит с помощью инструкции для пространства имен Windows.Services.Store.
  • Приложение — это однопользовательское приложение, которое запускается только в контексте пользователя, запускающего приложение. Дополнительные сведения см. в разделе покупки и пробные версии в приложении.

Полный пример приложения см. в примере магазина.

Заметка

Если у вас есть настольное приложение, использующее Desktop Bridge, может потребоваться добавить дополнительный код, не показанный в этих примерах, чтобы настроить объект StoreContext. Дополнительные сведения см. в статье Использование класса StoreContext в классическом приложении, использующемнастольный мост.

Сообщите о используемой надстройке по мере выполнения

После того как пользователь приобретает надстройку из вашего приложения и потребляет ее, ваше приложение должно сообщить о ней как об исполненной, вызвав метод ReportConsumableFulfillmentAsync из класса StoreContext. Для этого метода необходимо передать следующие сведения:

  • Идентификатор магазина надстройки, которую вы хотите пометить как выполненную.
  • Единицы надстройки, о которых вы хотите сообщить как о выполненных.
    • Для управлямого разработчиком расходуемого материала укажите 1 в качестве параметра количества . Это сообщает Магазину, что потребляемый товар был использован, и клиент может снова приобрести его. Пользователь не может снова приобрести расходуемый товар, пока ваше приложение не уведомило Магазин о выполнении заказа.
    • Для управляемого Магазином расходного материала укажите фактическое количество единиц, которые были израсходованы. Магазин обновит остаток по расходуемому.
  • Идентификатор отслеживания для исполнения. Это идентификатор GUID, предоставленный разработчиком, который определяет конкретную транзакцию, связанную с операцией исполнения для отслеживания. Дополнительные сведения можно найти в примечаниях к ReportConsumableFulfillmentAsync.

В этом примере показано, как сообщить об управляемом магазином потребительском товаре как завершенном.

private StoreContext context = null;

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

Получите остаток баланса для расходуемого товара, управляемого магазином.

В этом примере показано, как использовать метод GetConsumableBalanceRemainingAsync класса StoreContext, чтобы получить оставшийся баланс для управляемой магазином расходуемой надстройки.

private StoreContext context = null;

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

    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;
    }
}