Gerencie ofertas direcionadas usando os serviços da loja

Se você criar uma oferta direcionada na página Envolver > ofertas direcionadas para seu aplicativo no Partner Center, use a API de ofertas direcionadas da Microsoft Store no código do aplicativo para recuperar informações que ajudam você a implementar a experiência no aplicativo para a oferta de destino. Para obter mais informações sobre ofertas direcionadas e como criá-las no painel, consulte Use ofertas direcionadas para maximizar o engajamento e as conversões.

A API de ofertas direcionadas é uma API REST simples que você pode usar para obter as ofertas segmentadas disponíveis para o usuário atual, com base no fato de o usuário fazer parte do segmento de clientes ou não para a oferta segmentada. Para usar esta API no código do seu aplicativo, siga estas etapas:

  1. Obtenha um token da conta da Microsoft para o usuário atual conectado do seu aplicativo.
  2. Obtenha as ofertas direcionadas para o usuário atual.
  3. Implemente a experiência de compra realizada em aplicativo para o complemento associado a uma das ofertas direcionadas. Para obter mais informações sobre como implementar compras realizadas em aplicativo, consulte este artigo.

Para obter um exemplo de código completo que demonstre todas estas etapas, consulte o exemplo de código no final deste artigo. As seções a seguir fornecem mais detalhes sobre cada etapa.

Obtenha uma conta da Microsoft para o usuário atual

No código do seu aplicativo, obtenha um token da Conta da Microsoft (MSA) para o usuário conectado no momento. Você deve passar esse token no cabeçalho de solicitação Authorization para a API de ofertas direcionadas da Microsoft Store. Este token é usado pela Store para recuperar as ofertas direcionadas disponíveis para o usuário atual.

Para obter o token MSA, use a classe WebAuthenticationCoreManager para solicitar um token usando o escopo devcenter_implicit.basic,wl.basic. O exemplo a seguir demonstra como fazer isso. Este exemplo é um trecho do exemplo completo e requer as instruções using fornecidas no exemplo completo.

private async Task<string> GetMicrosoftAccountTokenAsync()
{
    var msaProvider = await WebAuthenticationCoreManager.FindAccountProviderAsync(
        "https://login.microsoft.com", "consumers");

    WebTokenRequest request = new WebTokenRequest(msaProvider, "devcenter_implicit.basic,wl.basic");
    WebTokenRequestResult result = await WebAuthenticationCoreManager.RequestTokenAsync(request);

    if (result.ResponseStatus == WebTokenRequestStatus.Success)
    {
        return result.ResponseData[0].Token;
    }
    else
    {
        return string.Empty;
    }
}

Para obter mais informações sobre como obter os tokens MSA, consulte Gerenciador de contas da Web .

Obtenha as ofertas direcionadas para o usuário atual

Depois de ter um token MSA para o usuário atual, chame o método GET do URI https://manage.devcenter.microsoft.com/v2.0/my/storeoffers/user para obter as ofertas direcionadas disponíveis para o usuário atual. Para obter mais informações sobre esse método REST, consulte Obter ofertas direcionadas.

Esse método retorna as IDs do produto dos complementos que estão associados às ofertas direcionadas disponíveis para o usuário atual. Com esta informação, você pode oferecer uma ou mais ofertas direcionadas como uma compra no aplicativo ao usuário.

O exemplo a seguir demonstra como obter as ofertas direcionadas para o usuário atual. Este exemplo é um trecho do exemplo completo. Isso requer a biblioteca Json.NET da Newtonsoft e as classes adicionais, e as instruções using fornecidas no exemplo completo.

private async Task<List<TargetedOfferData>> GetTargetedOffersForUserAsync(string msaToken)
{
    if (string.IsNullOrEmpty(msaToken))
    {
        System.Diagnostics.Debug.WriteLine("Microsoft Account token is null or empty.");
        return null;
    }

    HttpClient httpClientGetOffers = new HttpClient();
    httpClientGetOffers.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", msaToken);
    List<TargetedOfferData> availableOfferData = null;

    try
    {
        string getOffersResponse = await httpClientGetOffers.GetStringAsync(new Uri(storeOffersUri));
        availableOfferData = 
            Newtonsoft.Json.JsonConvert.DeserializeObject<List<TargetedOfferData>>(getOffersResponse);
    }
    catch (Exception ex)
    {
        System.Diagnostics.Debug.WriteLine(ex.Message);
    }

    return availableOfferData;
}

Exemplo de código completo

O exemplo de código a seguir demonstra as seguintes tarefas:

  • Obtenha um token MSA token para o usuário atual.
  • Obtenha todas as ofertas direcionadas para o usuário atual usando o método Obter ofertas direcionadas.
  • Compre o complemento que está associado a uma oferta direcionada.

Este exemplo exige a biblioteca Json.NET da Newtonsoft. O exemplo usa esta biblioteca para serializar e desserializar dados formatados em JSON.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net.Http;
using System.Net.Http.Headers;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Windows.Services.Store;
using Windows.Security.Authentication.Web.Core;

namespace DocumenationExamples
{
    public class TargetedOffersExample
    {
        private const string storeOffersUri = "https://manage.devcenter.microsoft.com/v2.0/my/storeoffers/user";
        private const string jsonMediaType = "application/json";
        private static string[] productKinds = { "Durable", "Consumable", "UnmanagedConsumable" };
        private static StoreContext storeContext = StoreContext.GetDefault();

        public async void DemonstrateTargetedOffers()
        {
            // Get the Microsoft Account token for the current user.
            string msaToken = await GetMicrosoftAccountTokenAsync();

            if (string.IsNullOrEmpty(msaToken))
            {
                System.Diagnostics.Debug.WriteLine("Microsoft Account token could not be retrieved.");
                return;
            }

            // Get the targeted Store offers for the current user.
            List<TargetedOfferData> availableOfferData =
                await GetTargetedOffersForUserAsync(msaToken);

            if (availableOfferData == null || availableOfferData.Count == 0)
            {
                System.Diagnostics.Debug.WriteLine("There was an error retrieving targeted offers," +
                    "or there are no targeted offers available for the current user.");
                return;
            }

            // Get the product ID of the add-on that is associated with the first available offer
            // in the response data.
            TargetedOfferData offerData = availableOfferData[0];
            string productId = offerData.Offers[0];

            // Get the Store ID of the add-on that has the matching product ID, and then purchase the add-on.
            List<String> filterList = new List<string>(productKinds);
            StoreProductQueryResult queryResult = await storeContext.GetAssociatedStoreProductsAsync(filterList);
            foreach (KeyValuePair<string, StoreProduct> result in queryResult.Products)
            {
                if (result.Value.InAppOfferToken == productId)
                {
                    await PurchaseOfferAsync(result.Value.StoreId);
                    return;
                }
            }

            System.Diagnostics.Debug.WriteLine("No add-on with the specified product ID could be found " +
                "for the current app.");
            return;
        }

        private async Task<string> GetMicrosoftAccountTokenAsync()
        {
            var msaProvider = await WebAuthenticationCoreManager.FindAccountProviderAsync(
                "https://login.microsoft.com", "consumers");

            WebTokenRequest request = new WebTokenRequest(msaProvider, "devcenter_implicit.basic,wl.basic");
            WebTokenRequestResult result = await WebAuthenticationCoreManager.RequestTokenAsync(request);

            if (result.ResponseStatus == WebTokenRequestStatus.Success)
            {
                return result.ResponseData[0].Token;
            }
            else
            {
                return string.Empty;
            }
        }

        private async Task<List<TargetedOfferData>> GetTargetedOffersForUserAsync(string msaToken)
        {
            if (string.IsNullOrEmpty(msaToken))
            {
                System.Diagnostics.Debug.WriteLine("Microsoft Account token is null or empty.");
                return null;
            }

            HttpClient httpClientGetOffers = new HttpClient();
            httpClientGetOffers.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", msaToken);
            List<TargetedOfferData> availableOfferData = null;

            try
            {
                string getOffersResponse = await httpClientGetOffers.GetStringAsync(new Uri(storeOffersUri));
                availableOfferData = 
                    Newtonsoft.Json.JsonConvert.DeserializeObject<List<TargetedOfferData>>(getOffersResponse);
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine(ex.Message);
            }

            return availableOfferData;
        }

        private async Task PurchaseOfferAsync(string storeId)
        {
            if (string.IsNullOrEmpty(storeId))
            {
                System.Diagnostics.Debug.WriteLine("storeId is null or empty.");
                return;
            }

            // Purchase the add-on for the current user. Typically, a game or app would first show
            // a UI that prompts the user to buy the add-on; for simplicity, this example
            // simply purchases the add-on.
            StorePurchaseResult result = await storeContext.RequestPurchaseAsync(storeId);

            // Capture the error message for the purchase operation, if any.
            string extendedError = string.Empty;
            if (result.ExtendedError != null)
            {
                extendedError = result.ExtendedError.Message;
            }

            switch (result.Status)
            {
                case StorePurchaseStatus.AlreadyPurchased:
                    System.Diagnostics.Debug.WriteLine("The user has already purchased the product.");
                    break;

                case StorePurchaseStatus.Succeeded:
                    System.Diagnostics.Debug.WriteLine("The purchase was successful.");
                    break;

                case StorePurchaseStatus.NotPurchased:
                    System.Diagnostics.Debug.WriteLine("The purchase did not complete. " +
                        "The user may have cancelled the purchase. ExtendedError: " + extendedError);
                    break;

                case StorePurchaseStatus.NetworkError:
                    System.Diagnostics.Debug.WriteLine("The purchase was unsuccessful due to a network error. " +
                        "ExtendedError: " + extendedError);
                    break;

                case StorePurchaseStatus.ServerError:
                    System.Diagnostics.Debug.WriteLine("The purchase was unsuccessful due to a server error. " +
                        "ExtendedError: " + extendedError);
                    break;

                default:
                    System.Diagnostics.Debug.WriteLine("The purchase was unsuccessful due to an unknown error. " +
                        "ExtendedError: " + extendedError);
                    break;
            }
        }
    }

    public class TargetedOfferData
    {
        [JsonProperty(PropertyName = "offers")]
        public IList<string> Offers { get; } = new List<string>();

        [JsonProperty(PropertyName = "trackingId")]
        public string TrackingId { get; set; }
    }
}