Habilitar compras de complementos consumíveis

Este artigo demonstra como usar métodos da classe StoreContext no namespace Windows.Services.Store para gerenciar o atendimento 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 itens como moedas em jogos (ouro, moedas etc.) que podem ser comprados e então usados para comprar power-ups específicos.

Observação

O namespace Windows.Services.Store foi introduzido no Windows 10, versão 1607 e pode ser usada somente em projetos para Windows 10 Anniversary Edition (10.0; Compilação 14393) ou uma versão posterior no Visual Studio. Se seu aplicativo for direcionado para uma versão anterior do Windows 10, use o namespace ApplicationModel em vez do 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 variam dependendo da maneira como o atendimento é gerenciado:

  • Consumível gerenciado pelo desenvolvedor. Para esse tipo de produto consumível, você é responsável por controlar o saldo do usuário de itens do usuário que o complemento representa e por relatar a compra do complemento como providenciada para a Store depois que o usuário consome todos os itens. O usuário não pode comprar o complemento novamente até que seu aplicativo tenha informado a compra anterior do complemento como providenciada.

    Por exemplo, se o seu complemento representar 100 moedas em um jogo e o usuário consumir 10 moedas, seu aplicativo ou o serviço deverá manter o novo saldo restante de 90 moedas para o usuário. Depois que o usuário tiver consumido todas as 100 moedas, seu aplicativo deverá declarar o complemento como providenciado e, em seguida, o usuário poderá comprar o complemento de 100 moedas novamente.

  • Consumível gerenciado pela loja. Para esse tipo de produto consumível, a Store mantém o controle do saldo de itens do usuário que o complemento representa. Quando o usuário consome todos os itens, você é responsável por relatar esses itens como providenciados para a Store, e a Store atualiza o saldo do usuário. O usuário pode adquirir o complemento quantas vezes desejar (não é necessário consumir os itens primeiro). Seu aplicativo pode consultar o saldo atual na Store para o 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 relatará para a Store que 50 unidades do complemento foram providenciadas, e a Store atualizará o saldo restante. Se o usuário comprar o complemento novamente para adquirir mais 100 moedas, ele agora terá 150 moedas no total.

    Observação

    Os consumíveis gerenciados pela Microsoft Store 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, gastar moedas em um jogo), declare o complemento como providenciado.

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

Pré-requisitos

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

  • Um projeto do Visual Studio para um aplicativo da Plataforma Universal do Windows (UWP) destinado ao Windows 10 Anniversary Edition (10.0; Build 14393) ou uma versão posterior.
  • Você criou um envio de aplicativo no Partner Center e esse aplicativo é publicado na Loja. Opcionalmente, é possível configurar o app para que ele não possa ser descoberto na Store enquanto você o testa. Para obter mais informações, consulte as diretrizes para teste.
  • Você criou um complemento consumível para o aplicativo no Partner Center.

O código nestes exemplos pressupõe que:

  • O código seja executado no contexto de uma Página que contenha um ProgressRing denominado workingProgressRing e um TextBlock denominado textBlock. Esses objetos sejam usados para indicar que uma operação assíncrona está ocorrendo e exibir mensagens de saída, respectivamente.
  • O arquivo de código tenha 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, consulte Compras no aplicativo e avaliações.

Para obter um app de exemplo completo, consulte o exemplo da Store.

Observação

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

Declarar um complemento consumível como providenciado

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

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

Este exemplo demonstra como relatar um consumível gerenciado pela Store como providenciado.

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 Store

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