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


Включение покупок потребляемых надстроек

В этой статье показано, как использовать методы класса 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 Эти объекты используются для указания, что выполняется асинхронная операция и для отображения выходных сообщений соответственно.
  • Файл кода содержит инструкцию using для пространства имен Windows.Services.Store .
  • Приложение — это однопользовательское приложение, которое запускается только в контексте пользователя, запускающего приложение. Дополнительные сведения см. в разделе "Покупки в приложении" и пробные версии.

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

Примечание.

Если у вас есть классическое приложение, использующее мост для классических приложений, может потребоваться добавить дополнительный код, не показанный в этих примерах, чтобы настроить объект 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;
    }
}