Administrar ofertas de destino mediante los servicios de almacenamientoManage targeted offers using Store services

Si crea una oferta de destino en la página participar en > ofertas de destino de su aplicación en el centro de Partners, use la API de ofertas de destino Microsoft Store en el código de la aplicación para recuperar información que le ayude a implementar la experiencia en la aplicación para la oferta de destino.If you create a targeted offer in the Engage > Targeted offers page for your app in Partner Center, use the Microsoft Store targeted offers API in your app's code to retrieve info that helps you implement the in-app experience for the targeted offer. Para obtener más información sobre las ofertas de destino y cómo crearlas en el panel, consulte uso de ofertas de destino para maximizar el compromiso y las conversiones.For more information about targeted offers and how to create them in the dashboard, see Use targeted offers to maximize engagement and conversions.

La API de ofertas de destino es una sencilla API de REST que puede usar para obtener las ofertas de destino que están disponibles para el usuario actual, en función de si el usuario forma parte del segmento de cliente para la oferta de destino.The targeted offers API is a simple REST API that you can use to get the targeted offers that are available for the current user, based on whether or not the user is part of the customer segment for the targeted offer. Para usar esta API en el código de la aplicación, siga estos pasos:To use this API in your app's code, follow these steps:

  1. Obtiene un token de cuenta de Microsoft para el usuario que ha iniciado sesión actualmente de la aplicación.Get a Microsoft Account token for the current signed-in user of your app.
  2. Obtener las ofertas de destino para el usuario actual.Get the targeted offers for the current user.
  3. Implemente la experiencia de compra desde la aplicación para el complemento que está asociado a una de las ofertas de destino.Implement the in-app purchase experience for the add-on that is associated with one of the targeted offers. Para obtener más información sobre la implementación de compras desde la aplicación, consulte este artículo.For more information about implementing in-app purchases, see this article.

Para obtener un ejemplo de código completo en el que se muestren todos estos pasos, consulte el ejemplo de código al final de este artículo.For a complete code example that demonstrates all of these steps, see the code example at the end of this article. En las secciones siguientes se proporcionan más detalles sobre cada paso.The following sections provide more details about each step.

Obtener un token de cuenta de Microsoft para el usuario actualGet a Microsoft Account token for the current user

En el código de la aplicación, obtenga un token de cuenta de Microsoft (MSA) para el usuario que ha iniciado sesión actualmente.In your app's code, get a Microsoft Account (MSA) token for the current signed-in user. Debe pasar este token en el Authorization encabezado de solicitud para la API de Microsoft Store de ofertas de destino.You must pass this token in the Authorization request header for the Microsoft Store targeted offers API. El almacén usa este token para recuperar las ofertas de destino que están disponibles para el usuario actual.This token is used by the Store to retrieve the targeted offers that are available for the current user.

Para obtener el token de MSA, use la clase WebAuthenticationCoreManager para solicitar un token mediante el ámbito devcenter_implicit.basic,wl.basic .To get the MSA token, use the WebAuthenticationCoreManager class to request a token using the scope devcenter_implicit.basic,wl.basic. En el ejemplo siguiente se muestra cómo hacerlo:The following example demonstrates how to do this. Este ejemplo es un extracto del ejemplo completoy requiere instrucciones using que se proporcionan en el ejemplo completo.This example is an excerpt from the complete example, and it requires using statements that are provided in the complete example.

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 obtener más información sobre cómo obtener tokens de MSA, consulte Administrador de cuentas web.For more information about getting MSA tokens, see Web account manager.

Obtener las ofertas de destino para el usuario actualGet the targeted offers for the current user

Después de tener un token MSA para el usuario actual, llame al método GET del https://manage.devcenter.microsoft.com/v2.0/my/storeoffers/user URI para obtener las ofertas de destino disponibles para el usuario actual.After you have an MSA token for the current user, call the GET method of the https://manage.devcenter.microsoft.com/v2.0/my/storeoffers/user URI to get the available targeted offers for the current user. Para obtener más información sobre este método REST, vea obtener ofertas de destino.For more information about this REST method, see Get targeted offers.

Este método devuelve los identificadores de producto de los complementos que están asociados a las ofertas de destino que están disponibles para el usuario actual.This method returns the product IDs of the add-ons that that are associated with the targeted offers that are available for the current user. Con esta información, puede ofrecer al usuario una o varias de las ofertas de destino como una compra desde la aplicación.With this information, you can offer one or more of the targeted offers as an in-app purchase to the user.

En el ejemplo siguiente se muestra cómo obtener las ofertas de destino para el usuario actual.The following example demonstrates how to get the targeted offers for the current user. Este ejemplo es un extracto del ejemplo completo.This example is an excerpt from the complete example. Requiere la biblioteca JSON.net de Newtonsoft y las clases adicionales y las instrucciones using que se proporcionan en el ejemplo completo.It requires the Json.NET library from Newtonsoft and additional classes and using statements that are provided in the complete example.

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

Finalización del ejemplo de códigoComplete code example

En el ejemplo de código siguiente se muestran las siguientes tareas:The following code example demonstrates the following tasks:

  • Obtiene un token de MSA para el usuario actual.Get an MSA token for the current user.
  • Obtener todas las ofertas de destino para el usuario actual mediante el método Get Target offers .Get all of the targeted offers for the current user by using the Get targeted offers method.
  • Compre el complemento asociado a una oferta de destino.Purchase the add-on that is associated with a targeted offer.

Este ejemplo requiere la biblioteca de JSON.net de Newtonsoft.This example requires the Json.NET library from Newtonsoft. En el ejemplo se usa esta biblioteca para serializar y deserializar los datos con formato JSON.The example uses this library to serialize and deserialize JSON-formatted data.

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