パートナー センターのアプリの [] ページで>オファーを作成する場合は、アプリのコードで Microsoft Store 対象オファー API を使用して、対象オファーのアプリ内エクスペリエンスを実装するのに役立つ情報を取得します。 対象オファーの詳細と、ダッシュボードでのオファーの作成方法については、「ターゲット オファーを 使用してエンゲージメントとコンバージョンを最大化する」を参照してください。
対象オファー API は、ユーザーが対象オファーの顧客セグメントに含まれているかどうかに基づいて、現在のユーザーが利用できる対象オファーを取得するために使用できる単純な REST API です。 アプリのコードでこの API を使用するには、次の手順に従います。
- アプリの現在サインインしているユーザーの Microsoft アカウント トークンを取得します。
- 現在のユーザーの対象オファーを取得します。
- 対象となるオファーのいずれかに関連付けられているアドオンのアプリ内購入エクスペリエンスを実装します。 アプリ内購入の実装の詳細については、 この記事を参照してください。
これらの手順をすべて示す完全なコード例については、この記事の最後にある コード例 を参照してください。 以降のセクションでは、各手順の詳細について説明します。
現在のユーザーの Microsoft アカウント トークンを取得する
アプリのコードで、現在サインインしているユーザーの Microsoft アカウント (MSA) トークンを取得します。 このトークンは、Microsoft Store 対象オファー API の Authorization
要求ヘッダーに渡す必要があります。 このトークンは、現在のユーザーが利用できる対象オファーを取得するためにストアによって使用されます。
MSA トークンを取得するには、 WebAuthenticationCoreManager クラスを使用して、スコープ devcenter_implicit.basic,wl.basic
を使用してトークンを要求します。 この方法を次の例に示します。 この例は、
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;
}
}
MSA トークンの取得の詳細については、「 Web アカウント マネージャー」を参照してください。
現在のユーザーの対象オファーを取得する
現在のユーザーの MSA トークンを取得したら、 https://manage.devcenter.microsoft.com/v2.0/my/storeoffers/user
URI の GET メソッドを呼び出して、現在のユーザーに対して使用可能なターゲット オファーを取得します。 この REST メソッドの詳細については、「 対象となるオファーを取得する」を参照してください。
このメソッドは、現在のユーザーが使用できる対象オファーに関連付けられているアドオンの製品 ID を返します。 この情報を使用すると、1 つ以上の対象プランをアプリ内購入としてユーザーに提供できます。
次の例では、現在のユーザーの対象オファーを取得する方法を示します。 この例は、 完全な例からの抜粋です。 Newtonsoft の
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;
}
完全なコード例
次のコード例は、次のタスクを示しています。
- 現在のユーザーの MSA トークンを取得します。
- Get targeted offers メソッドを使用して、現在のユーザーのすべての 対象オファーを取得 します。
- 対象オファーに関連付けられているアドオンを購入します。
この例では、Newtonsoft の Json.NET ライブラリが必要です。 この例では、このライブラリを使用して 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; }
}
}