Compartilhar via


Habilitar compras de complementos consumíveis

Este artigo demonstra como usar métodos da classe StoreContext no namespace Windows.Services.Store para gerenciar o cumprimento de complementos consumíveis do usuário em seus aplicativos UWP. Use complementos consumíveis para itens que podem ser comprados, usados e comprados novamente. Isso é especialmente útil para coisas como moeda do jogo (ouro, moedas, etc.) que podem ser compradas e usadas para comprar power-ups específicos.

Observação

O namespace Windows.Services.Store foi introduzido no Windows 10, versão 1607 e só pode ser usado em projetos direcionados ao Windows 10 Anniversary Edition (10.0; Build 14393) ou uma versão posterior no Visual Studio. Se o aplicativo for direcionado a uma versão anterior do Windows 10, você deverá usar o namespace Windows.ApplicationModel.Store em vez do namespace Windows.Services.Store. Para obter mais informações, consulte este artigo.

Visão geral dos complementos consumíveis

Os aplicativos podem oferecer dois tipos de complementos consumíveis que diferem na maneira como os processamentos são gerenciados:

  • Consumível gerenciado pelo desenvolvedor. Para esse tipo de consumível, você é responsável por acompanhar o saldo de itens do usuário que o complemento representa e por relatar a compra do complemento como atendida para a Loja depois que o usuário tiver consumido todos os itens. O usuário só poderá comprar o complemento novamente quando o aplicativo relatar a compra anterior do complemento como atendida.

    Por exemplo, se o complemento representa 100 moedas em um jogo e o usuário consome 10 moedas, o aplicativo ou o serviço precisa manter o novo saldo restante de 90 moedas referente ao usuário. Depois que o usuário consumir todas as 100 moedas, o aplicativo precisará relatar o complemento como atendido e, em seguida, o usuário poderá comprar o complemento de 100 moedas novamente.

  • Consumível gerenciado pela loja. Para esse tipo de consumível, a Loja controla o saldo de itens do usuário que o complemento representa. Quando o usuário consome itens, você é responsável por relatar esses itens como processados para a Loja, e a Loja atualiza o saldo do usuário. O usuário poderá comprar o complemento quantas vezes quiser (ele não precisa consumir os itens primeiro). Seu aplicativo pode consultar a Loja para obter o saldo atual do usuário a qualquer momento.

    Por exemplo, se o complemento representar uma quantidade inicial de 100 moedas em um jogo e o usuário consumir 50 moedas, o aplicativo informará à Microsoft Store que 50 unidades do complemento foram atendidas e a Microsoft Store atualizará o saldo restante. Se, em seguida, o usuário comprar o complemento de novo para adquirir mais 100 moedas, ele passará a ter 150 moedas no total.

    Observação

    Os consumíveis gerenciados pela loja foram introduzidos no Windows 10, versão 1607.

Para oferecer um complemento consumível a um usuário, siga este processo geral:

  1. Permita que os usuários comprem o complemento do seu aplicativo.
  2. Quando o usuário consumir o complemento (por exemplo, ele gasta moedas em um jogo), informe o complemento como cumprido.

A qualquer momento, você também pode obter o saldo restante de um consumível gerenciado pela Loja.

Pré-requisitos

Esses exemplos têm os seguintes pré-requisitos:

  • Um projeto do Visual Studio para um aplicativo da Plataforma Universal do Windows (UWP) direcionado ao Windows 10 Anniversary Edition (10.0; Build 14393) ou uma versão posterior.
  • Você criou um envio de aplicativo no Partner Center e este aplicativo é publicado na Loja. Opcionalmente, você pode configurar o aplicativo para que ele não seja detectável na Store enquanto você o testa. Para obter mais informações, confira nossas diretrizes de teste.
  • Você criou um complemento consumível para o aplicativo no Partner Center.

O código nesses exemplos pressupõe:

  • O código é executado no contexto de uma Página que contém um ProgressRing denominado workingProgressRing e um TextBlock denominado textBlock. Esses objetos são usados para indicar que uma operação assíncrona está ocorrendo e exibir mensagens de saída, respectivamente.
  • O arquivo de código tem uma instrução using para o namespace Windows.Services.Store.
  • O app seja um app de usuário único executado somente no contexto do usuário que o iniciou. Para obter mais informações, confira Compras e avaliações no aplicativo.

Para obter um aplicativo de exemplo completo, confira o Exemplo da Store.

Observação

Se você tiver um aplicativo da área de trabalho que usa a Ponte de Desktop, talvez seja necessário adicionar código adicional não mostrado nesses exemplos para configurar o objeto StoreContext . Para obter mais informações, confira Como usar a classe StoreContext em um aplicativo da área de trabalho que usa a Ponte de Desktop.

Relatar um complemento consumível como atendido

Depois que o usuário comprar o complemento do seu aplicativo e consumir seu complemento, seu aplicativo deverá relatar o complemento como atendido chamando o método ReportConsumableFulfillmentAsync da classe StoreContext . Você deve passar as seguintes informações para este método:

  • A ID da Loja do complemento que você deseja relatar como atendido.
  • As unidades do complemento que você deseja relatar como atendidas.
    • Para um consumível gerenciado pelo desenvolvedor, especifique 1 para o parâmetro de quantidade . Isso alerta a Loja de que o consumível foi atendido e o cliente pode comprá-lo novamente. O usuário não pode comprar o consumível novamente até que seu aplicativo tenha notificado a Loja de que ele foi atendido.
    • Para um consumível gerenciado pela Store, especifique o número real de unidades que foram consumidas. A Loja atualizará o saldo restante do consumível.
  • O ID de rastreamento do processamento. Esse é um GUID fornecido pelo desenvolvedor que identifica a transação específica à qual a operação de atendimento está associada para fins de rastreamento. Para obter mais informações, consulte os comentários em ReportConsumableFulfillmentAsync.

Este exemplo demonstra como relatar um consumível gerenciado pela Loja como atendido.

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

Obter o saldo restante de um consumível gerenciado pela Loja

Este exemplo demonstra como usar o método GetConsumableBalanceRemainingAsync da classe StoreContext para obter o saldo restante de um complemento consumível gerenciado pela Store.

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