コンシューマブルなアプリ内製品購入の有効化Enable consumable in-app product purchases

ストアの商取引プラットフォームを使ってコンシューマブルなアプリ内製品 (購入、使用、再購入が可能なアイテム) をサポートすると、堅牢かつ信頼性の高いアプリ内購入エクスペリエンスを顧客に提供できます。Offer consumable in-app products—items that can be purchased, used, and purchased again—through the Store commerce platform to provide your customers with a purchase experience that is both robust and reliable. これは、購入して、特定のパワーアップを購入するために使うことができるゲーム内通貨 (ゴールド、コインなど) 用に特に便利です。This is especially useful for things like in-game currency (gold, coins, etc.) that can be purchased and then used to purchase specific power-ups.

重要

この記事では、Windows.ApplicationModel.Store 名前空間のメンバーを使って、コンシューマブルなアプリ内製品の購入を有効化する方法について説明します。This article demonstrates how to use members of the Windows.ApplicationModel.Store namespace to enable consumable in-app product purchases. この名前空間は更新されなくなり、新機能も追加されないため、代わりに Windows.Services.Store 名前空間を使用することをお勧めします。This namespace is no longer being updated with new features, and we recommend that you use the Windows.Services.Store namespace instead. Windows.Services.Store名前空間が消耗アドオンの管理対象の Store や、サブスクリプションなど、最新のアドオン型をサポートしているしは将来の種類の製品とパートナーによってサポートされる機能に対応するように設計されていますCenter とストア。The Windows.Services.Store namespace supports the latest add-on types, such as Store-managed consumable add-ons and subscriptions, and is designed to be compatible with future types of products and features supported by Partner Center and the Store. Windows.Services.Store 名前空間は、Windows 10 バージョン 1607 で導入され、Visual Studio で、Windows 10 Anniversary Edition (10.0、ビルド 14393) 以降のリリースをターゲットとするプロジェクトでのみ使用できます。The Windows.Services.Store namespace was introduced in Windows 10, version 1607, and it can only be used in projects that target Windows 10 Anniversary Edition (10.0; Build 14393) or a later release in Visual Studio. Windows.Services.Store 名前空間を使用したコンシューマブルなアプリ内製品購入の有効化について詳しくは、この記事をご覧ください。For more information about enabling consumable in-app product purchases using the Windows.Services.Store namespace, see this article.

前提条件Prerequisites

  • このトピックでは、コンシューマブルなアプリ内製品の購入とフルフィルメントの完了報告について説明します。This topic covers the purchase and fulfillment reporting of consumable in-app products. アプリ内製品に詳しくない場合は、「アプリ内製品購入の有効化」を読んで、ライセンス情報と、ストアでアプリ内製品を適切に一覧表示する方法を確かめてください。If you are unfamiliar with in-app products, please review Enable in-app product purchases to learn about license information, and how to properly list in-app products in the Store.
  • 新しいアプリ内製品のコード記述やテストを初めて行うときは、CurrentApp オブジェクトではなく、CurrentAppSimulator オブジェクトを使う必要があります。When you code and test new in-app products for the first time, you must use the CurrentAppSimulator object instead of the CurrentApp object. そうすることで、実稼働サーバーを呼び出すのではなく、ライセンス サーバーへのシミュレートされた呼び出しを使って、ライセンス ロジックを検証できます。This way you can verify your license logic using simulated calls to the license server instead of calling the live server. これを行うには、%userprofile% WindowsStoreProxy.xml をという名前のファイルをカスタマイズする必要があります\AppData\ローカル\パッケージ\<パッケージ名>\LocalState\Microsoft\Windows ストア\ApiData します。To do this, you need to customize the file named WindowsStoreProxy.xml in %userprofile%\AppData\local\packages\<package name>\LocalState\Microsoft\Windows Store\ApiData. このファイルは、アプリを初めて実行するときに Microsoft Visual Studio シミュレーターによって作られます。カスタマイズされたファイルを実行時に読み込むこともできます。The Microsoft Visual Studio simulator creates this file when you run your app for the first time—or you can also load a custom one at runtime. 詳しくは、「CurrentAppSimulator での WindowsStoreProxy.xml ファイルの使用」をご覧ください。For more info, see Using the WindowsStoreProxy.xml file with CurrentAppSimulator.
  • このトピックでは、ストア サンプルで提供されているコード例も参照します。This topic also references code examples provided in the Store sample. このサンプルを利用すると、ユニバーサル Windows プラットフォーム (UWP) アプリに提供されるさまざまな収益化オプションを体験できます。This sample is a great way to get hands-on experience with the different monetization options provided for Universal Windows Platform (UWP) apps.

手順 1:購入要求を行うStep 1: Making the purchase request

最初の購買要求は、ストアを通じて行われた他の購入と同様に、RequestProductPurchaseAsync を使って行います。The initial purchase request is made with RequestProductPurchaseAsync like any other purchase made through the Store. コンシューマブルなアプリ内製品に関する違いとして、購入が成功した後、その購入に対するフルフィルメントが正常に完了したことをアプリがストアに通知するまで、顧客は同じ製品をもう一度購入することができません。The difference for consumable in-app products is that after a successful purchase, a customer cannot purchase the same product again until the app has notified the Store that the previous purchase was successfully fulfilled. アプリは、購入されたコンシューマブルのフルフィルメントを処理し、ストアにフルフィルメントの完了を通知する責任を負います。It's your app's responsibility to fulfill purchased consumables and notify the Store of the fulfillment.

次の例は、コンシューマブルなアプリ内製品の購入要求を示しています。The following example shows a consumable in-app product purchase request. コードのコメントに、購入要求が成功した場合と同じ製品の購入のフルフィルメントが完了していないことが原因で購入要求が成功しなかった場合の 2 つの異なるシナリオについて、アプリがコンシューマブルなアプリ内製品のローカル フルフィルメントをいつ完了する必要があるかが示されています。You'll notice code comments indicating when your app should conduct its local fulfillment of the consumable in-app product for two different scenarios—when the request is successful, and when the request is not successful because of an unfulfilled purchase of that same product.

PurchaseResults purchaseResults = await CurrentAppSimulator.RequestProductPurchaseAsync("product1");
switch (purchaseResults.Status)
{
    case ProductPurchaseStatus.Succeeded:
        product1TempTransactionId = purchaseResults.TransactionId;

        // Grant the user their purchase here, and then pass the product ID and transaction ID to
        // CurrentAppSimulator.ReportConsumableFulfillment to indicate local fulfillment to the
        // Windows Store.
        break;

    case ProductPurchaseStatus.NotFulfilled:
        product1TempTransactionId = purchaseResults.TransactionId;

        // First check for unfulfilled purchases and grant any unfulfilled purchases from an
        // earlier transaction. Once products are fulfilled pass the product ID and transaction ID
        // to CurrentAppSimulator.ReportConsumableFulfillment to indicate local fulfillment to the
        // Windows Store.
        break;
}

手順 2:ローカルの調達、消耗品の追跡Step 2: Tracking local fulfillment of the consumable

コンシューマブルなアプリ内製品へのアクセスを顧客に許可するとき、フルフィルメントの対象になっている製品 (productId) と、フルフィルメントが関連付けられているトランザクション (transactionId) を追跡することが重要です。When granting your customer access to the consumable in-app product, it's important to keep track of which product is fulfilled (productId), and which transaction that fulfillment is associated with (transactionId).

重要

アプリは、ストアにフルフィルメントの完了を正確に報告する必要があります。Your app is responsible for the accurately reporting fulfillment to the Store. この手順は、顧客が体験する公正で信頼できる購入エクスペリエンスを維持するために必要です。This step is essential to maintaining a fair and reliable purchase experience for your customers.

次の例では、前の手順の RequestProductPurchaseAsync 呼び出しの PurchaseResultsプロパティを使って、フルフィルメントの対象となる、購入された製品を識別しています。The following example demonstrates use of the PurchaseResults properties from the RequestProductPurchaseAsync call in the previous step to identify the purchased product for fulfillment. ローカル フルフィルメントが成功したことを確かめるために、コレクションを使って後で参照できる場所に製品情報が保存されます。A collection is used to store the product information in a location that can later be referenced to confirm that local fulfillment was successful.

private void GrantFeatureLocally(string productId, Guid transactionId)
{
    if (!grantedConsumableTransactionIds.ContainsKey(productId))
    {
        grantedConsumableTransactionIds.Add(productId, new List<Guid>());
    }
    grantedConsumableTransactionIds[productId].Add(transactionId);

    // Grant the user their content. You will likely increase some kind of gold/coins/some other asset count.
}

次の例では、前の例の配列を使って、後でストアにフルフィルメントを報告するときに使われる製品 ID とトランザクション ID のペアにアクセスする方法を示しています。This next example shows how to use the array from the previous example to access product ID/transaction ID pairs that are later used when reporting fulfillment to the Store.

重要

フルフィルメントの追跡と確認のために使っている方法を問わず、アプリは、顧客が受け取っていないアイテムに対して課金されることのないように適正評価を行う必要があります。Whatever methodology your app uses to track and confirm fulfillment, your app must demonstrate due diligence to ensure that your customers are not charged for items they haven't received.

private Boolean IsLocallyFulfilled(string productId, Guid transactionId)
{
    return grantedConsumableTransactionIds.ContainsKey(productId) &&
        grantedConsumableTransactionIds[productId].Contains(transactionId);
}

手順 3:ストアへのレポート製品フルフィルメントStep 3: Reporting product fulfillment to the Store

ローカル フルフィルメントが完了した後、アプリは、productId と製品購入が含まれるトランザクションを含む ReportConsumableFulfillmentAsync 呼び出しを行う必要があります。After local fulfillment is completed, your app must make a ReportConsumableFulfillmentAsync call that includes the productId and the transaction the product purchase is included in.

重要

フルフィルメントが完了したコンシューマブルなアプリ内製品をストアに報告しなかった場合、ユーザーは、前回の購入のフルフィルメントが報告されるまで、その製品をもう一度購入することができなくなります。Failure to report fulfilled consumable in-app products to the Store will result in the user being unable to purchase that product again until fulfillment for the previous purchase is reported.

FulfillmentResult result = await CurrentAppSimulator.ReportConsumableFulfillmentAsync(
    "product2", product2TempTransactionId);

手順 4:条件を満たさなく購入を識別します。Step 4: Identifying unfulfilled purchases

アプリでは、GetUnfulfilledConsumablesAsync メソッドを使って、コンシューマブルなアプリ内製品に対するフルフィルメントの未完了をいつでも確認することができます。Your app can use the GetUnfulfilledConsumablesAsync method to check for unfulfilled consumable in-app products at any time. このメソッドは、ネットワーク接続の中断やアプリの終了など、予期しないアプリのイベントが原因でフルフィルメントが完了していないコンシューマブルを調べるために、定期的に呼び出す必要があります。This method should be called on a regular basis to check for unfulfilled consumables that exist due to unanticipated app events like an interruption in network connectivity or app termination.

次の例に、GetUnfulfilledConsumablesAsync を使ってフルフィルメントが未完了のコンシューマブルを列挙する方法と、アプリでこの一覧を反復処理してローカル フルフィルメントを完了する方法を示します。The following example demonstrates how GetUnfulfilledConsumablesAsync can be used to enumerate unfulfilled consumables, and how your app can iterate through this list to complete local fulfillment.

private async void GetUnfulfilledConsumables()
{
    products = await CurrentApp.GetUnfulfilledConsumablesAsync();

    foreach (UnfulfilledConsumable product in products)
    {
        logMessage += "\nProduct Id: " + product.ProductId + " Transaction Id: " + product.TransactionId;
        // This is where you would pass the product ID and transaction ID to
        // currentAppSimulator.reportConsumableFulfillment to indicate local fulfillment to the Windows Store.
    }
}