啟用消耗性應用程式內產品購買

透過市集商務平台提供消耗性應用程式內產品 (提供可以再次購買、使用及購買的項目),為客戶提供健全且可靠的購買體驗。 這對於可以購買的遊戲內貨幣 (金幣、硬幣等),之後用於特定道具等事項特別有用。

重要

本文示範如何使用 Windows.ApplicationModel.Store 命名空間的成員來啟用消耗性應用程式內產品購買。 此命名空間不再以新功能更新,建議您改用 Windows.Services.Store 命名空間。 Windows.Services.Store 命名空間支援最新的附加元件類型,例如市集管理的消耗性附加元件和訂用帳戶,其設計目的是與合作夥伴中心和市集支援的未來產品和功能類型相容。 Windows.Services.Store 命名空間是在 Windows 10 版本 1607 中引進的,而且在 Visual Studio 中只能用於以 Windows 10 年度版本 (10.0;組建 14393) 或更新版本為目標的專案。 如需使用 Windows.Services.Store 命名空間啟用消耗性應用程式內產品購買的詳細資訊,請參閱本文

必要條件

  • 本主題涵蓋消耗性應用程式內產品的購買和履行報告。 如果您不熟悉應用程式內產品,請檢閱啟用應用程式內產品購買以了解授權資訊,以及如何在市集中適當列出應用程式內產品。
  • 當您第一次撰寫並測試新的應用程式內產品時,您必須使用 CurrentAppSimulator 物件,而不是 CurrentApp 物件。 如此一來,您就可以對授權伺服器使用模擬呼叫來驗證授權邏輯,而不是呼叫即時伺服器。 若要這麼做,您必須在 %userprofile%\AppData\local\packages\<套件名稱>\LocalState\Microsoft\Windows Store\ApiData 中自訂名為 WindowsStoreProxy.xml 的檔案。 當您第一次執行應用程式時,Microsoft Visual Studio 模擬器會建立此檔案,您也可以在執行時間載入自訂檔案。 如需詳細資訊,請參閱 搭配 CurrentAppSimulator 使用 WindowsStoreProxy.xml 檔案
  • 本主題也會參考市集範例中提供的程式碼範例。 此範例是獲得實際操作體驗的絕佳方式,其中包含針對通用 Windows 平台 (UWP) 應用程式提供的不同獲利選項。

步驟 1:提出購買要求

就像透過市集進行的任何其他購買一樣,初始購買要求是使用 RequestProductPurchaseAsync 提出的。 消耗性應用程式內產品的差異在於,在成功購買之後,客戶必須等到應用程式通知市集先前購買已成功履行後,才能再次購買相同的產品。 您的應用程式有責任履行已購買的消耗性產品,並在履行後通知市集。

下列範例顯示消耗性應用程式內產品購買要求。 您會注意到程式碼註解指出,應用程式何時應針對兩個不同的案例進行消耗性應用程式內產品的本機履行,即當要求成功時,以及當要求因相同的產品購買未履行而未成功時。

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:追蹤消耗性產品的本機履行

授與客戶對消耗性應用程式內產品的存取權時,請務必追蹤哪些產品已履行 (productId),以及履行相關聯的交易 (transactionId)。

重要

您的應用程式負責在履行後正確地向市集回報。 此步驟對於為客戶維護公平且可靠的購買體驗至關重要。

下列範例示範使用上一個步驟中 RequestProductPurchaseAsync 呼叫中的 PurchaseResults 屬性,以識別要履行的已購買產品。 會使用集合將產品資訊儲存在稍後可參考的位置,以確認本機履行是否成功。

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

接下來這個範例示範如何使用上一個範例中的陣列來存取產品識別碼/交易識別碼組,這稍後會在向市集回報履行時用到。

重要

無論您的應用程式使用何種方法來追蹤和確認履行,您的應用程式都必須展現盡職盡責,以確保未向您的客戶未收取的項目收費。

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

步驟 3:向市集報告產品履行

完成本機履行之後,您的應用程式必須進行 ReportConsumableFulfillmentAsync 呼叫,其中包含 productId 和內含產品購買的交易。

重要

若未能向市集回報已履行的消耗性產品,使用者將無法再次購買該產品,直到回報先前購買已履行為止。

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

步驟 4:識別未履行的購買

您的應用程式可以使用 GetUnfulfilledConsumablesAsync 方法來隨時檢查未履行的消耗應用程式內產品。 應該定期呼叫此方法,以檢查因未預期的應用程式事件而存在的未履行消耗性產品,例如網路連線中斷或應用程式終止。

下列範例示範如何使用 GetUnfulfilledConsumablesAsync 來列舉未履行的消耗性產品,以及您的應用程式如何逐一查看此清單以完成本機履行。

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