應用程式內購買和試用版

Windows SDK 提供可讓您用來實作下列功能的 API,從您的通用 Windows 平台 (UWP) 應用程式提高獲利:

  • 應用程式內購買 無論您的應用程式是否免費,都可以從應用程式內直接從應用程式內銷售內容或新的應用程式功能 (例如解除鎖定遊戲的下一個關卡)。

  • 試用版功能 如果您在合作夥伴中心將您的應用程式設定為免費試用,您可以藉由在試用期間排除或限制某些功能,吸引客戶購買完整版的應用程式。 您也可以在客戶購買您的應用程式之前,啟用只在試用期間顯示的功能,例如橫幅或浮水印。

本文提供 UWP 應用程式內購買和試用版運作方式的概觀。

選擇要使用的命名空間

您可以使用兩個不同的命名空間將應用程式內購買和試用版功能新增至您的 UWP 應用程式,視您的應用程式以哪個 Windows 10 或 Windows 11 版本為目標而定。 雖然這些命名空間中的 API 可達成相同的目標,但它們的設計方式大不相同,而且兩個 API 之間的程式碼不相容。

重要

Windows.ApplicationModel.Store 命名空間不再以新功能更新,建議您盡可能針對應用程式使用 Windows.Services.Store 命名空間。 Windows.ApplicationModel.Store 命名空間在使用傳統型橋接器 的 Windows 傳統型應用程式中,或在合作夥伴中心使用開發沙箱的應用程式或遊戲中 (例如,這是指任何與 Xbox Live 整合的遊戲) 並不受支援。

基本概念

市集中提供的每個項目通常稱為「產品」。 大部分的開發人員只能使用下列類型的產品:應用程式和附加元件

附加元件是您在應用程式內容中提供給客戶的產品或功能:例如,要用於應用程式或遊戲的貨幣、遊戲的新地圖或武器、能夠在沒有廣告的情況下使用您的應用程式,或是能夠提供該內容類型之應用程式的音樂或視訊等數位內容。 每個應用程式和附加元件都有相關聯的授權,指出使用者是否有權使用應用程式或附加元件。 如果使用者有權使用作為試用版的應用程式或附加元件,授權也會提供試用版的其他資訊。

若要為應用程式中的客戶提供附加元件,您必須在合作夥伴中心定義應用程式的附加元件,讓市集知道它的存在。 然後,您的應用程式可以使用 Windows.Services.StoreWindows.ApplicationModel.Store 命名空間中的 API,將附加元件作為應用程式內購買提供給使用者。

UWP 應用程式可以提供下列類型的附加元件。

附加元件類型 描述
持久 可保存您在合作夥伴中心指定的存留期的附加元件。

根據預設,耐久性附加元件永遠不會過期,在此情況下,只能購買一次。 如果您為附加元件指定特定持續時間,使用者可以在附加元件到期後重新購買附加元件。
開發人員管理的消耗性產品 可供購買、使用,然後在取用之後再次購買的附加元件。 您必須負責追蹤附加元件所代表項目的使用者餘額。

當使用者取用與附加元件相關聯的任何項目時,您必須負責維護使用者的餘額,並在使用者取用所有項目之後,向市集將附加元件的購買回報為已履行。 使用者必須等到您的應用程式回報先前的附加元件購買已履行,才能再次購買附加元件。

例如,如果您的附加元件在遊戲中代表 100 枚硬幣,且使用者取用 10 枚硬幣,則您的應用程式或服務必須為使用者維持 90 枚硬幣的新剩餘餘額。 使用者取用全部 100 枚硬幣之後,您的應用程式必須將附加元件回報為已履行,然後使用者才能再次購買 100 枚硬幣附加元件。
市集管理的消耗性產品 可供隨時購買、使用及再次購買的附加元件。 市集會追蹤附加元件所代表細目的使用者餘額。

當使用者取用與附加元件相關聯的任何項目時,您必須負責向市集將這些項目回報為已履行,而市集會更新使用者的餘額。 使用者可以購買附加元件的次數不限 (他們不需要先取用項目)。 您的應用程式可以隨時查詢使用者的目前餘額。

例如,如果您的附加元件代表遊戲中 100 枚硬幣的初始數量,且使用者取用 50 枚硬幣,則您的應用程式會向市集回報已履行 50 個單位的附加元件,而市集會更新剩餘餘額。 如果使用者接著重新購買您的附加元件以取得 100 枚硬幣,他們現在總共會有 150 枚硬幣。

注意 若要使用市集管理的消耗性產品,您的應用程式在 Visual Studio 中必須以 Windows 10 年度版 (10.0;組建 14393) 或更新版本為目標,而且必須使用 Windows.Services.Store 命名空間,而不是 Windows.ApplicationModel.Store 命名空間。
訂用帳戶 耐久性附加元件,客戶會以週期性間隔持續付費,以便繼續使用附加元件。 客戶可以隨時取消訂用帳戶,以避免產生後續收費。

注意 若要使用定用帳戶附加元件,您的應用程式在 Visual Studio 中必須以 Windows 10 年度版 (10.0;組建 14393) 或更新版本為目標,而且必須使用 Windows.Services.Store 命名空間,而不是 Windows.ApplicationModel.Store 命名空間。

注意

其他類型的附加元件,例如具有套件的耐久性附加元件 (也稱為可下載的內容或 DLC) 僅適用於一組有限的開發人員,而且本文中未涵蓋。

使用 Windows.Services.Store 命名空間的應用程式內購買和試用版

本節提供 Windows.Services.Store 命名空間的重要工作和概念概觀。 此命名空間僅適用於在 Visual Studio 中以 Windows 10 年度版 (10.0;組建 14393) 或更新版本 (這對應於 Windows 10 版本 1607) 為目標的應用程式。 我們建議應用程式盡可能使用 Windows.Services.Store 命名空間,而不是 Windows.ApplicationModel.Store 命名空間。 如需 Windows.ApplicationModel.Store 命名空間的相關資訊,請參閱本文

本節內容

開始使用 StoreContext 類別

Windows.Services.Store 命名空間的主要進入點是 StoreContext 類別。 這個類別提供的方法可讓您用來取得目前應用程式及其可用附加元件的資訊,取得目前應用程式或其附加元件的授權資訊,為目前使用者購買應用程式或附加元件,以及執行其他工作。 若要取得 StoreContext 物件,請進行下列其中一項動作:

  • 在單一使用者應用程式中 (也就是只在啟動應用程式的使用者內容中執行的應用程式),使用靜態 GetDefault 方法來取得 StoreContext 物件,您可以用此物件存取使用者的 Microsoft Store 相關資料。 大部分通用 Windows 平台 (UWP) 應用程式都是單一使用者應用程式。

    Windows.Services.Store.StoreContext context = StoreContext.GetDefault();
    
  • 多使用者應用程式中,使用靜態 GetForUser 方法來取得 StoreContext 物件,您可以用此物件來存取在使用應用程式時使用其 Microsoft 帳戶登入之特定使用者的 Microsoft Store 相關資料。 下列範例會取得第一個可用使用者的 StoreContext 物件。

    var users = await Windows.System.User.FindAllAsync();
    Windows.Services.Store.StoreContext context = StoreContext.GetForUser(users[0]);
    

注意

使用傳統型橋接器的 Windows 傳統型應用程式必須先執行其他步驟來設定 StoreContext 物件後,才能使用此物件。 如需詳細資訊,請參閱本節

擁有 StoreContext 物件之後,您可以開始呼叫這個物件的方法,以取得目前應用程式及其附加元件之市集產品資訊、擷取目前應用程式及其附加元件授權資訊、購買目前使用者的應用程式或附加元件,以及執行其他工作。 如需您可以使用這個物件執行之一般工作的詳細資訊,請參閱下列文章:

如需示範如何在 Windows.Services.Store 命名空間中使用 StoreContext 和其他類型的範例應用程式,請參閱市集範例

實作應用程式內購買

若要使用 Windows.Services.Store 命名空間,為應用程式中的客戶提供應用程式內購買:

  1. 如果您的應用程式提供客戶可購買的附加元件,請在合作夥伴中心為您的應用程式建立附加元件提交

  2. 在您的應用程式中撰寫程式碼,以擷取應用程式或應用程式所提供之附加元件產品資訊,然後判斷授權是否為作用中 (也就是使用者是否有使用應用程式或附加元件授權)。 如果授權不在作用中,請顯示 UI,以應用程式內購買的形式向使用者提供銷售的應用程式或附加元件。

  3. 如果使用者選擇購買您的應用程式或附加元件,請使用適當的方法來購買產品:

  4. 請遵循本文中的測試指引來測試您的實作。

實作試用版功能

若要使用 Windows.Services.Store 命名空間來排除或限制應用程式試用版中的功能:

  1. 在合作夥伴中心將您的應用程式設定為免費試用

  2. 在您的應用程式中編寫程式碼,以擷取應用程式或應用程式所提供之附加元件的產品資訊,然後判斷與應用程式相關聯的授權是否為試用版授權

  3. 如果這是試用版,請排除或限制您應用程式中的某些功能,然後在使用者購買完整授權時啟用這些功能。 如需詳細資訊和程式碼範例,請參閱實作應用程式的試用版

  4. 請遵循本文中的測試指引來測試您的實作。

測試您的應用程式內購買或試用版實作

如果您的應用程式使用 Windows.Services.Store 命名空間中的 API 來實作應用程式內購買或試用版功能,您必須將應用程式發佈至市集,並將應用程式下載至您的開發裝置,以使用其授權進行測試。 請遵循此程序來測試您的程式碼:

  1. 如果您的應用程式尚未在市集中發佈和提供,請確定您的應用程式符合最低的 Windows 應用程式認證套件需求、在合作夥伴中心提交您的應用程式,並確定您的應用程式通過認證程序。 您可以設定應用程式,使其在您進行測試時在市集中不可供探索。 請注意套件發行小眾測試版的適當組態。 設定不正確的套件發行小眾測試版可能會無法下載。

  2. 接下來,確定您已完成下列動作:

  3. 在 Visual Studio 中開啟專案後,按一下 [專案] 功能表,指向 [ 市集],然後按一下 [建立應用程式與市集的關聯]。 完成精靈中的指示,將應用程式專案與您在合作夥伴中心帳戶中要用於測試的應用程式建立關聯。

    注意

    如果您未將專案與市集中的應用程式建立關聯,StoreContext 方法會將其傳回值的 ExtendedError 屬性設定為錯誤碼值 0x803F6107。 這個值表示市集對應用程式一無所知。

  4. 如果您尚未這麼做,請從您在上一個步驟中指定的市集安裝應用程式、執行應用程式一次,然後關閉此應用程式。 這可確保將應用程式的有效授權安裝到您的開發裝置。

  5. 在 Visual Studio 中,開始執行或對您的專案進行偵錯。 您的程式碼應該從與您本機專案相關聯的市集應用程式擷取應用程式和附加元件資料。 如果系統提示您重新安裝應用程式,請依照指示執行或對您的專案進行偵錯。

    注意

    完成這些步驟之後,您可以繼續更新應用程式的程式碼,然後在開發電腦上對更新的專案進行偵錯,而無需將新的應用程式套件提交至市集。 您只需要將應用程式的市集版本下載到開發電腦一次,就可取得本機授權,並將其用於測試。 完成測試之後,您只需要將新的應用程式套件提交至市集,而且建議您將應用程式內購買或試用版相關功能提供給客戶使用。

如果您的應用程式使用 Windows.ApplicationModel.Store 命名空間,您可以在將應用程式提交至市集之前,先在應用程式中使用 CurrentAppSimulator 類別來模擬授權資訊。 如需詳細資訊,請參閱 開始使用 CurrentApp 和 CurrentAppSimulator 類別

注意

Windows.Services.Store 命名空間不提供類別,您可以在測試期間用來模擬授權資訊。 如果您使用 Windows.Services.Store 命名空間來實作應用程式內購買或試用版,您必須將應用程式發佈至市集,並將應用程式下載至您的開發裝置,以使用其授權進行測試,如上所述。

應用程式內購買的收據

Windows.Services.Store 命名空間不提供可讓您用來取得交易收據,以在應用程式的程式碼中成功購買的 API。 這與使用 Windows.ApplicationModel.Store 命名空間的應用程式不同,該命名空間可以使用用戶端 API 來擷取交易收據

如果您使用 Windows.Services.Store 命名空間實作應用程式內購買,而且您想要驗證指定的客戶是否已購買應用程式或附加元件,您可以使用 Microsoft Store 集合 REST API 中的查詢產品方法。 這個方法的傳回資料會確認指定的客戶是否具有指定產品的權利,並提供使用者取得產品之交易的資料。 Microsoft Store 集合 API 會使用 Azure AD 驗證來擷取此資訊。

使用 StoreContext 類別搭配傳統型橋接器

使用傳統型橋接器的傳統型應用程式可以使用 StoreContext 類別來實作應用程式內購買和試用版。 不過,如果您有 Win32 傳統型應用程式或具有與轉譯架構 (例如 WPF 或 Windows 應用程式 SDK 應用程式) 相關聯之視窗控點 (HWND) 的傳統型應用程式,您的應用程式必須設定 StoreContext 物件,以指定哪個應用程式視窗是物件所顯示之強制回應對話方塊的擁有者視窗。

許多 StoreContext 成員 (以及透過 StoreContext 物件存取的其他相關類型成員) 都會向使用者顯示強制回應對話方塊,以進行市集相關作業,例如購買產品。 如果傳統型應用程式未將 StoreContext 物件設定為指定強制回應對話方塊的擁有者視窗,則此物件會傳回不正確的資料或錯誤。

若要在使用傳統型橋接器的傳統型應用程式中設定 StoreContext 物件,請遵循下列步驟。

對於 .NET 6 或更新版本

如果您的應用程式是使用 .NET 6 或更新版本以 C# 撰寫,請遵循下列步驟。

  1. 請確定專案檔案中的 TargetFramework 屬性設定為特定的 Windows SDK 版本以存取 Windows 執行階段 API,這可讓您存取 WinRT.Interop 命名空間。 例如:

    <PropertyGroup>
      <!-- You can also target other versions of the Windows SDK and .NET, e.g. "net6.0-windows10.0.19041.0" -->
      <TargetFramework>net6.0-windows10.0.22000.0</TargetFramework>
    </PropertyGroup>
    
  2. 使用 GetDefault 方法取得 StoreContext 物件 (如果您的應用程式是多使用者應用程式,則為 GetForUser),如本文稍早所述。 若要使用指定的視窗控點初始化對話方塊,請使用 WinRT.Interop.WindowNative.GetWindowHandleWinRT.Interop.InitializeWithWindow.Initialize 方法 (請參閱擷取視窗控點 (HWND)顯示相依於 CoreWindow 的 WinRT UI 物件)。

    StoreContext context = StoreContext.GetDefault();
    // Obtain window handle by passing in pointer to the window object
    var hwnd = WinRT.Interop.WindowNative.GetWindowHandle(windowObject);
    // Initialize the dialog using wrapper funcion for IInitializeWithWindow
    WinRT.Interop.InitializeWithWindow.Initialize(context, hwnd); 
    

對於早期版本的 .NET 或 C++

如果您的應用程式是以舊版 .NET 或 C++ 撰寫,請遵循下列步驟。

  1. 執行下列其中一項動作,讓您的應用程式能夠存取 IInitializeWithWindow 介面:

    • 如果您的應用程式是以 C# 或 Visual Basic 等受控語言撰寫 (在 .NET 6 之前),請使用 ComImport 屬性在應用程式的程式碼中宣告 IInitializeWithWindow 介面,如下列 C# 範例所示。 此範例假設您的程式碼檔案具有 System.Runtime.InteropServices 命名空間的 using 陳述式。

      [ComImport]
      [Guid("3E68D4BD-7135-4D10-8018-9FB6D9F33FA1")]
      [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
      public interface IInitializeWithWindow
      {
          void Initialize(IntPtr hwnd);
      }
      
    • 如果您的應用程式是以 C++ 撰寫,請在程式碼中新增 shobjidl.h 標頭檔的參考。 此標頭檔包含 IInitializeWithWindow 介面的宣告。

  2. 使用 GetDefault 方法取得 StoreContext 物件 (如果您的應用程式是多使用者應用程式,則為 GetForUser),如本文稍早所述,並將這個物件轉換成 IInitializeWithWindow 物件。 然後,呼叫 IInitializeWithWindow.Initialize 方法,並對於 StoreContext 方法所顯示之任何強制回應對話方庫傳遞您想要成為擁有者的視窗控點。 下列 C# 範例示範如何將應用程式主視窗的控點傳遞至該方法。 另請參閱擷取視窗控制代碼 (HWND)顯示相依於 CoreWindow 的 WinRT UI 物件

    StoreContext context = StoreContext.GetDefault();
    IInitializeWithWindow initWindow = (IInitializeWithWindow)(object)context;
    initWindow.Initialize(System.Diagnostics.Process.GetCurrentProcess().MainWindowHandle);
    

產品、SKU 和可用性

市集中的每個產品至少有一個「SKU」,而且每個 SKU 至少有一個「可用性」。 這些概念已從合作夥伴中心的大部分開發人員抽象化,而大多數開發人員永遠不會為其應用程式或附加元件定義 SKU 或可用性。 不過,由於 Windows.Services.Store 命名空間中市集產品的物件模型包含 SKU 和可用性,因此對這些概念有基本的了解在某些情況下會很有幫助。

Object 描述
產品 「產品」是指市集中可用的任何類型的產品,包括應用程式或附加元件。

市集中的每個產品都有對應的 StoreProduct 物件。 此類別提供您可以用來存取資料的屬性,例如產品的 Store ID、市集清單的影像和影片,以及定價資訊。 它也提供您可用來購買產品的方法。
SKU 「SKU」是特定版本的產品,包含其專屬描述、價格和其他獨特的産品詳細資料。 每個應用程式或附加元件都有預設 SKU。 大多數開發人員唯一會針對應用程式擁有多個 SKU 的時刻是,假如他們發佈其應用程式的完整版本和試用版 (在市集目錄中,每個版本都是相同應用程式的不同 SKU) 的話。

某些發行者能夠定義自己的 SKU。 例如,大型遊戲發行者可能會發行一款遊戲,其中一個 SKU 在不允許紅血的市場中顯示綠血,另一個 SKU 在其他所有市場中顯示紅血。 或者,銷售數位視訊內容的發行者可能會針對影片發佈兩個 SKU、一個針對高畫質版本的 SKU,以及另一個針對標準定義版本的 SKU。

市集中的每個 SKU 都有對應的 StoreSku 物件。 每個 StoreProduct 都有一個 Skus 屬性,您可以用來存取產品的 SKU。
可用性 「可用性」是 SKU 的特定版本,具有專屬的定價資訊。 每個 SKU 都有預設可用性。 有些發行者能夠定義自己的可用性,為指定的 SKU 引進不同的價格選項。

市集中的每個可用性都有對應的 StoreAvailability 物件。 每個 StoreSku 都有一個 Availabilities 屬性,您可以用來存取 SKU 可用性。 對於大多數開發人員,每個 SKU 都有單一預設可用性。

Store ID

市集中的每個應用程式、附加元件或其他產品都有相關聯的 Store Id (這有時也稱為「產品 Store ID」)。 許多 API 都需要 Store ID,才能在應用程式或附加元件上執行作業。

市集中任何產品的 Store ID 是 12 個字元的英數字串,例如 9NBLGGH4R315。 在市集中取得產品的 Store ID 有數種不同的方式:

  • 針對應用程式,您可以在合作夥伴中心的 [應用程式識別] 頁面上取得 Store ID。
  • 針對附加元件,您可以在合作夥伴中心的附加元件概觀頁面上取得 Store ID。
  • 針對任何產品,您也可以使用代表產品的 StoreProduct 物件的 StoreId 屬性,以程式設計方式取得 Store ID。

對於具有 SKU 和可用性的產品,SKU 和可用性也有專屬的 Store ID,格式不同。

Object Store ID 格式
SKU SKU 的 Store ID 格式為 <product Store ID>/xxxx,其中 xxxx 是 4 個字元的英數字串,可識別產品的 SKU。 例如:9NBLGGH4R315/000N。 此識別碼是由 StoreSku 物件的 StoreId 屬性傳回,有時稱為「SKU Store ID」
可用性 可用性的 Store ID 格式為 <product Store ID>/xxxx/yyyyyyyyyyyy,其中 xxxx 是 4 個字元的英數字串,可識別產品的 SKU,而 yyyyyyyyyyyy 是 12 個字元的英數字串,可識別 SKU 的可用性。 例如:9NBLGGH4R315/000N/4KW6QZD2VN6X。 此識別碼是由 StoreAvailability 物件的 StoreId 屬性傳回,有時稱為「可用性 Store ID」

如何在程式碼中使用附加元件的產品識別碼

如果您想要在應用程式內容中為客戶提供附加元件,當您在合作夥伴中心建立附加元件提交時,必須為附加元件輸入唯一產品識別碼。 您可以使用此產品識別碼來參考程式碼中的附加元件,不過您可以使用產品識別碼的特定案例取決於您在應用程式中用於應用程式內購買的命名空間。

注意

您在附加元件合作夥伴中心輸入的產品識別碼與附加元件 Store ID 不同。 Store ID 是由合作夥伴中心產生。

使用 Windows.Services.Store 命名空間的應用程式

如果您的應用程式使用 Windows.Services.Store 命名空間,您可以使用產品識別碼輕鬆地識別代表附加元件的 StoreLicense 或代表附加元件授權的 StoreProduct。 產品識別碼是由 StoreProduct.InAppOfferTokenStoreLicense.InAppOfferToken 屬性公開。

注意

雖然產品識別碼是識別程式碼中附加元件的實用方式,但 Windows.Services.Store 命名空間中的大部分作業都會使用附加元件的 Store ID,而不是產品識別碼。 例如,若要以程式設計方式擷取應用程式的一或多個已知附加元件,請將附加元件之 Store ID (而非產品識別碼) 傳遞至 GetStoreProductsAsync 方法。 同樣地,若要將消耗性附加元件回報為已履行,請將附加元件 (而非產品識別碼) 的 Store Id 傳遞至 ReportConsumableFulfillmentAsync 方法。

使用 Windows.ApplicationModel.Store 命名空間的應用程式

如果您的應用程式使用 Windows.ApplicationModel.Store 命名空間,您必須針對大部分作業使用合作夥伴中心指派給附加元件的產品識別碼。 例如: