Designing and Implementing an In Game Store for Xbox One
Cameron Goodwin and James Lenell, Advanced Technology Group
Updated July 19th, 2017
In this topic
Introduction
Terminology guide
Anatomy of a product group
Content types
Ownership and entitlement
Hidden versus visible products
Enumerating products
Anatomy of product availabilities
User inventory
Initiating the purchase of a product
Using consumable content
Summary
Introduction
The Xbox stores have been refreshed with many new capabilities, features, and services. This refresh helps enable flexibility around product creation, organization, availability, and pricing.
When enumerating content on Xbox 360, broad filters are available based on the types of content enumerated via XMarketplaceCreateOfferEnumerator. The order in which the data is returned cannot be pre-sorted by the back end or filtered on any other criteria.
The stores for Xbox One allow you to better present personalized content to the user. The new stores also allow better integration of business models designed around micro-transactions and other content types.
On Xbox 360, the stores are centered on individual offers. When a player purchases an offer, the player is purchasing a license to the content. You can present a piece of content with up to 16 different offers, but these offers are unaware of each other. The best example of this behavior is the Season Pass. On Xbox 360, an offer to download a piece of premium downloadable content (DLC) through a Season Pass is different than an offer to purchase the same piece of content directly through one of the Xbox stores. Although both offers give users access to the same content, the offers appear independently and are purchased separately.
On Xbox 360, users who have purchased a Season Pass are eligible to download free, hidden versions of DLC packages that would otherwise have to be purchased through the Xbox stores. However, because the content offers are not linked by the system, a user with a Season Pass could inadvertently pay for the same content twice by purchasing both the Season Pass (which includes the hidden DLC) and the individual piece of DLC from the Xbox store. For this reason, Xbox 360 requires title developers to gate access to the free Season Pass content offers.
On Xbox One, content and the offers for that particular piece of content are linked and aware of each other. When a player purchases an offer for a piece of content, the player is granted an entitlement to, or the ability to use, that content. Using the Season Pass example, when a player purchases a Season Pass, the player is granted individual entitlements to each of the DLC packages that are included in the Season Pass. When that player looks at the DLC packages available in the Xbox stores, any content that is available through the Season Pass will be displayed as already belonging to the player, thereby preventing a double-purchase scenario.
When integrating the Xbox stores into your title, you can choose from three methods to interact with the Xbox stores:
- Using the shell UI APIs to open the default store flow.
- Using the Microsoft.Xbox.Services.Marketplace APIs (“Xbox Service APIs”).
- Calling the RESTful Marketplace services directly through HTTPS by using an Xbox Secure Token Service (XSTS) token.
In most scenarios, we recommend that you use the Xbox Service APIs because they are wrapped versions of RESTful calls to the service. The APIs are easy to integrate, can handle the XSTS token retrieval, have retry logic built in, and do not require your title to have its own HTTPS handler.
The precompiled libraries and source code for the Xbox Service APIs are provided with the Xbox One Development Kit (XDK). You can modify the code to fit any specific needs or scenarios within your title. However, direct handling of the HTTPS and RESTful calls to the service might give you a more flexible and customized option for your design.
Terminology guide
Some terms in the Xbox stores are familiar from Xbox 360; however, some of the meanings have expanded or changed. Please familiarize yourself with the following definitions.
| Term |
Definition |
| Product |
Content available for purchase within the Xbox stores (for example, games, DLC, and consumables). Products contain static information related to the item (for example, description and art) and are ingested into the catalog of the Xbox stores. |
| Product group or franchise |
A set of products (including titles and DLC) defined within the Xbox Developer Portal (XDP) that share a common genre, a common intellectual property, or the same Product Group ID. |
| Entitlement |
A right of access to a product. An entitlement indicates that the user has access to a product in the current state or situation. An entitlement does not imply that the user has direct ownership of that product. |
| Purchase |
The process of accepting an offer and thus the entry into a purchase and sale agreement. In addition to a monetized transaction, a purchase can be for $0 or via a 5×5 token (or its QR code). |
| Inventory |
A list of entitlements with supporting information that the user is currently entitled to access (includes quantity of consumable products). |
| Sandbox |
An authorization group defined in XDP that gives users, consoles, and titles access and visibility to different configurations, settings, and products. |
| Availabilities |
Similar to what an offer represented in Xbox 360. An availability is determined by a set of purchasing rules for the user, including pricing, region, and quantity of a consumable. The availability is what a user is actually purchasing that gives them an entitlement to the product. |
Anatomy of a product group
You can set up a product group through XDP, and a product group defines a group of related or similar products. These products might be from the same game series or genre. A product group can also be referenced as a franchise.
After you have created a product group, you will be able to create individual products within that group such as a game, DLC, or a consumable. You can relate products within a product group to each other; however, you cannot relate products from separate product groups.
For example, you would relate an expansion pack DLC to a specific title within the same product group. Consumables can relate to multiple titles, and, therefore, a consumable could be used within any title within the product group.
Another example would be where you have a product group that contains a title and all DLC for the title. When releasing a sequel to this game, you can define the sequel as an additional product within this same product group, or you can define the sequel as a new product within a new product group specific to this new title.
Examples of where you might want to create a new product group for the sequel are a reboot of the franchise or when shifting to a different genre from the previous title. When setting up a new title, discuss with your developer account manager whether the title would best fit within a new product group or as an addition to an existing product group.
Content types
The content types supported by the Xbox One stores are different than the content types you might be familiar with from the Xbox 360 stores. If you are unsure of which type of content to use for your title or scenario, discuss these options with your developer account manager.
| Content type |
Description |
| Game |
A game is also known as a title. Unlike the Xbox 360 stores, the Xbox One stores do not make a distinction between an Arcade title and a Retail title. A game or title consists of an app that runs within the GameOS portion of the console resources. A game is built with the Xbox One XDK.
Examples: Halo and Forza. |
| App |
An app runs within the selective portion of the console resources. Apps are built with the Xbox One Application Development Kit (ADK).
Examples: Skype and Internet Explorer. |
| Durable |
A durable is a DLC product used to extend a title. A durable has an associated ContentID package that users must download to the console in order to access the content contained in the durable. This is the type of DLC most commonly used on Xbox 360. Durables can only be purchased once by a single user.
Examples: Map pack and game expansion. |
| Consumable |
A consumable is a product that the user can purchase and exchange for a limited-use item or an effect within the game. Consumables have a quantity, which reflects the number of that particular product available to the user.
The same user can purchase consumables multiple times in order to increase his or her quantity of the consumable product. The user’s quantity of the consumable is stored on Xbox Live and can be retrieved through the Inventory service. When the user uses a quantity of the consumable product in-game, the title reports this quantity to Xbox Live, and the amount consumed is then deducted from the user’s inventory.
Examples: In-game currency, limited-time stats boost, and special weapon ammunition. |
| Season Pass |
A Season Pass is a product that grants access to a set of released and/or to-be-released products. Usually the set of products encompassed by the Season Pass includes durables at a combined discounted price. A Season Pass is not considered a bundled product because its purpose is to have users buy in to content before the content is released or announced—rather than buying in to a specific set of products that have already been released.
Example: All released and yet-to-be released first-year map packs for a shooter, or all episodic content to be released for a title. |
Ownership and entitlement
When a user purchases an offer for a particular piece of content, the user is granted an entitlement to that content. This entitlement is tied to the user’s Xbox Live account, which makes this content available on whatever Xbox One console the user is signed in to. A user can also designate a specific console as a “home console”; this console is also granted an entitlement to the product such that any user signed in to that console can use the product.
On Xbox One, there is a difference between ownership of a product and an entitlement to the product. An entitlement to a product can come from direct ownership or from using the entitlement to the product of the current console.
Hidden versus visible products
On Xbox 360, the stores support both hidden and visible offers. On Xbox One, the system supports the same concept of a hidden product (or availability) and a visible one. A visible product is any product that you want to be displayed when browsing the Xbox stores or any product that you want to be returned from a catalog browse request.
A hidden product is defined as a product or availability that is available for users to purchase but is not displayed or advertised in the Xbox stores and is not returned in catalog browse requests. You can access these products and their availabilities by using the Catalog Details service, and you can then display the products directly through an in-game UI. Alternatively, you can redeem tokens for hidden products.
Common examples of hidden products are pre-order bonus DLC that only users with a redeem code can access, or products that you prefer to advertise only in-game or only to specific users.
If you are unsure whether your product should be visible or hidden, please discuss the issue with your developer account manager.
Enumerating products
When building an in-game store to enable users to purchase content for your title, you must first enumerate the products that are available. With the Xbox stores, there are currently two methods of presenting products for the user to purchase:
- Xbox One shell store UI
- Custom in-game store UI
Xbox One shell store UI
The lowest-cost solution is to have the Xbox One shell store UI enumerate your products and provide the UI for browsing and selecting content to purchase. To use this method, call the ShowMarketplaceAsync API within your title.
When you call this API, the shell UI will display your title’s content and guide the user through the selection and purchase process. After the UI is closed (either because of a successful purchase or because the player dismisses it), control is returned to the title.
With this method, you have no control over the user experience, but this method provides a low-cost, simple way for you to integrate a related-products store within your title.
Note: The Xbox One shell store UI will not show any hidden products that your title might have.
Custom in-game store UI
The other option is to implement your own in-game store with a customized UI, which can more closely fit the experience of your title. Although this option requires more investment because your title has to query and display the data from the Xbox catalog, implementing an integrated in-game store has proven to increase visibility of content, increase user attach rate, and increase content sales.
To enumerate the content details from the Xbox One catalog, you can either use the Xbox Service APIs or call the Xbox One catalog RESTful services directly.
First, you should use the Browse service to obtain a list of items and also basic information to display in your UI, such as the name and description of the products. Currently, a browse request will not return the availabilities for a product, including the price for the user. To get this additional information, call the Details service with the results from a browse request.
Alternatively, you can use the Browse service to get basic information for your UI, and then use the shell store API, ShowDetailsAsync, to bring up the shell UI directly for a specific product. The shell UI will show the price, availabilities, and the rest of the purchase flow.
If your title has hidden products (described earlier in this document), you will want to display their information through your in-game store. A catalog browse request will not return hidden products, but you can obtain their information and availabilities through a details request, or you can display these details with the ShowDetailsAsync API.
To obtain the details of a hidden offer, you will need a separate service to provide the required ProductID for the hidden product. This service can be title-managed storage, custom web services, or another external delivery method.
Xbox Service APIs
IAsyncOperation<BrowseCatalogResult^>^
CatalogService::BrowseCatalogAsync(
__in Platform::String^ titleId,
__in Xbox::Services::Marketplace::MediaItemType parentMediaType,
__in Xbox::Services::Marketplace::MediaItemType childMediaType,
__in CatalogSortOrder orderBy,
__in uint32 skipItems,
__in uint32 maxItems)
IAsyncOperation< IVectorView<CatalogItemDetails^ >^ >^
CatalogService::GetCatalogItemDetailsAsync(
__in IVectorView<Platform::CatalogItem^>^ products)
These asynchronous APIs allow your title to browse for products and obtain their details related to your title.
The advantages of using the Xbox Service APIs include easier implementation, automatic handling of the HTTPS traffic, error handling with retry attempts, and handling of the XSTS token retrieval. The source code for these APIs is included as part of the Xbox One XDK, so you can expand or modify the APIs as you need. In most scenarios, we recommend that you use these APIs rather than implementing the RESTful calls.
Xbox catalog RESTful services
If you call the Xbox catalog services directly through RESTful HTTPS requests, you must obtain a few additional objects to properly construct the URI and headers required to browse for content.
First, you will need to determine the language-locale code (for example, EN-US or FR-CA) for the user, and you will need to retrieve an Xbox One XSTS token. You must include the Xbox One XSTS token in the HTTPS request’s Authorization header. You can obtain the token through the GetTokenAndSignatureAsync method.
The results returned from the catalog are JSON or XML objects that you can also page if specified in the request. Please refer to the Web Services sample (available on the Samples page on Xbox Game Developer [XGD]) for an example that shows how to obtain a user’s XSTS token and how to call a RESTful service from within your game.
RESTful browse API
The browse API allows clients to browse for items within a single media group. You can access pages of data non-sequentially via the skipItems parameter.
| Name |
Value / Example |
| URI |
https://eds.xboxlive.com/media/{locale}/browse |
| URI Example |
https://eds.xboxlive.com/media/en-us/browse?orderBy=releaseDate&desiredMediaItemTypes=DGame |
| Methods |
GET |
| Response body schema |
```json
{
"Items":
[
{
"MediaGroup": string,
"MediaItemType": string,
"ID":string,
"Name":string,
"ReleaseDate":string,
"TitleId":string,
"VuiDisplayName":string,
"Genres": [],
"Images": [],
"SortName":string,
"RelatedMedia": [],
"LegacyIds":[]
}
]
}
```
|
| Genre schema |
```json
{ "Name":string }
```
|
| Images schema |
```json
{
"ID":string,
"ResizeUrl":string,
"Purposes":string[],
"Purpose":string,
"Height":int,
"Width":int
}
```
|
| Related media schema |
```json
{
"ID":string
}
```
|
| Legacy ID schema |
```json
{
"IdType":string,
"Value":string
}
```
</table>
By default, the browse API will return only the following fields:
- Media group
- MediaItemType
- ID
- Name
To get more information, you can obtain additional fields by using a *fields* descriptor, which is described later in this section.
To prevent unnecessary network traffic, we recommended that you request the minimum amount of information necessary to present the results to the user. To get more information, such as pricing, see the [details API](#restful-details-api).
| Query string parameters | Common values (not a complete list) |
| ----------------------- | ----------------------------------- |
| **Id** | If provided, restricts results to the children of the provided ID. |
| **DesiredMediaItemType** | Required: • DGame (this is the equivalent of the same product type as GameV2 when querying the Inventory service) • DApp • DConsumable • DDurable • DGameDemo |
| **OrderBy** | Required: • Release data • Most popular • Critic rating |
| **SkipItems** | Zero-based index of items to skip. Not supplying this parameter or passing **skipItems=0** begins from the start of the list of results. Passing **skipItems=3** skips the first three items and begins with the fourth item. |
| **Desired** | A list of the desired fields in the form of ```field1.field2.field3``` |
| **Fields** | A value return from the fields utility API. Cannot be used at the same time as the *desired* field. |
#### RESTful details API
You can obtain additional information about a specific product from the details API, including availabilities for the product.
| Name |
Value / Example |
</tr
| URI |
https://eds.xboxlive.com/media/{locale}/browse |
| URI |
https://eds.xboxlive.com/media/en-us/browse?orderBy=releaseDate&desiredMediaItemTypes=DGame |
| Methods |
GET |
| Response body schema |
```json
{
"Items":
[
{
"MediaGroup":string,
"MediaItemType":string,
"ID":string,
"Name":string,
"Description":string,
"ReleaseDate":string,
"TitleId":string,
"VuiDisplayName":string,
"Genres":[See Browse],
"Images":[See Browse],
"SortName":string,
"LegacyIds":[See Browse],
"Availabilities":[See Anatomy of an Availability],
"ProductId":string,
"SandboxId":string
}
],
"ImpressionGuid":string
}
```
|
</table>
Within the availabilities, you will have access to the offers and content pricing.
| Query string parameters | Common values (not a complete list) |
| ----------------------- | ----------------------------------- |
| **IDs** | Required list of up to 10 Ids that you want details for. Ids containing characters illegal for a URL must be URL encoded. |
| **DesiredMediaItemTypes** | Media type of all provided *Ids*. You must use a separate call to the Details service for each media type. |
| **MediaGroup** | Some of the available options for this parameter are: • Apps • EnhancedContent • Games |
| **Desired** | A list of the desired fields in the form of ```field1.field2.field3``` |
| **Fields** | A return value from the fields utility API. Cannot be used at the same time as the *desired* field. |
#### Fields
You can use the desired field mentioned previously to expand on the data that is returned; however, using this field can lead to bloated RESTful calls. To simplify the results, use the fields API to generate a small token value that can specify the *desired* fields in the results. This token is cacheable. If you choose to cache the token, cache the value only for the duration of the user’s session. Then pass the returned token by appending ```fields={value}``` to the desired API call.
| Name |
Value / Example |
</tr
| URI |
https://eds.xboxlive.com/media/{locale}/fields?desired={field names} |
| Methods |
GET. Returns a value that represents all desired fields. |
| Response body schema |
```json
{
"Fields": string,
"InfoImpressionGuid": string
}
```
|
</table>
| Query string parameters |
Values |
</tr
| Desired |
A list of the desired fields in the form of
```field1.field2.field3``` |
</td>
## Anatomy of product availabilities
When a user is browsing the Xbox stores, each product will have a set of availabilities defined by the following structure:
| Name |
Value / Example |
</tr
| Availability JSON schema |
```json
"Availabilities":
[
{
"ContentId":string,
"OfferDisplayData":
{
"acceptablePaymentInstrumentTypes\":[strings]
"availabilityDescription\":string,
"currencyCode":string,
"displayPrice":string,
"displayListPrice":string,
"distributionType":string
"isPurchasable":boolean,
"listPrice":float,
"price":float,
"promotionalText":string
},
"SignedOffer":string
},
]
```
|
</table>
An availability is a container for a set of rules around content availability, pricing, and other restrictions. The other restrictions determine whether a user can browse, receive a purchase offer, purchase, or fulfill (download, install, or license) a product.
Availabilities of a product can differ for many reasons, such as restrictions based on country. For example, for a country where the content of a product might violate local laws, you can create a specific availability that delivers different content (XVC of the game) that omits the offending content. Another example is if your product has multiple translations, you can set availabilities for each language pack rather than deliver a larger language-agnostic package containing all translations.
For consumables, you can use different availabilities to provide different quantities of the same product. This method can be useful for presenting different options to the user, allowing a user to purchase a larger quantity of a consumable in a single transaction at a lower price per consumable.
For example:
- Consumable Product Gold
- Availability 1 (100 gold)—$.99
- Availability 2 (500 gold)—$2.99
- Availability 3 (1500 gold)—$4.99
## User inventory
After the list of available products has been enumerated, the next step is to get the user’s inventory from the service to identify what content the user has already purchased. On Xbox 360, this information is provided by enumerating through an **asset** or **offer** enumerator.
On Xbox One, you obtain this information through the Inventory service. The inventory items returned represent the user’s entitlements (as outlined earlier in this document). Compare the *ProductIDs* from the catalog items to the inventory items in order to determine whether you should advertise an item to the user or the user is already entitled to it.
A user’s inventory results might include items that the user does not own directly but has temporary access to as a result of the content-sharing model on Xbox One. For example, when multiple users are signed in on the same console—such as when a user signs in on a friend’s home console—their entitlements are combined and shared among all users as long as they remain signed in on that same physical console. The home console has an entitlement by default to all the content its owner has. It then shares that entitlement to anyone who is signed in on it. This is reflected in the Inventory service results, so if your game design has features or added bonuses that should only be granted to their direct owners, you should check for direct ownership of an item by filtering out any shared items so that only items with direct ownership will be displayed in the user inventory.
> **Note**: Although the inventory does contain some items that might be currently shared to the user, your title should never gate access to durable DLC within your title through the inventory results. If the user owns a Season Pass, only the ProductID for the Season Pass will show up in the inventory, unless your title is using the Inventory service APIs with the ability to expand satisfying entitlements. If you do not request the satisfying entitlements to be expanded, the individual ProductIDs of DLC included in the Season Pass are not returned in the results. Therefore, it is critical that to allow access to DLC within a title you should always check the package’s license with CheckLicense(). For more information about this subject, refer to the white paper, “Creating and Using Downloadable Content on Xbox One,” available for download on the Xbox One white papers page on GDN.
You can call the Inventory service through the Xbox Service APIs, or you can call the service directly with HTTPS REST–based services.
### Inventory service APIs
In the August 2015 XDK, new overloaded versions of the Inventory service APIs were added that allow your title to retrieve satisfying entitlements as well as more easily search for pre-order products in the user’s inventory. The previous APIs are still available, but we recommend that you use the new overloaded API listed here:
```cpp
Windows::Foundation::IAsyncOperation<InventoryItemsResult^>^ GetInventoryItemsAsync(
__in IVectorView<Platform::String^>^ productIds,
__in bool expandSatisfyingentitlments
);
Windows::Foundation::IAsyncOperation<InventoryItemsResult^>^ GetInventoryItemsAsync(
__in Marketplace::MediaItemType mediaItemType
__in bool expandSatisfyingentitlments,
__in bool includeAllItemStatesAndAvailabilities
);
Windows::Foundation::IAsyncOperation<InventoryItem^>^ GetInventoryItemAsync(
__in Marketplace::InventoryItem^ inventoryItem
);
```
To obtain a list of the user’s inventory items, use **GetInventoryItemsAsync**; otherwise, for a single item use **GetInventoryItemAsync** (notice that **Item** is singular in the second instance). The overloaded version of **GetInventoryItemsAsync** allows additional query parameters, including *itemState, availability*, and a *containerID*.
Currently, the **GetInventoryItemsAsync** method will return the user’s owned inventory items as well as any shared items through the Home Console setting of the console that the user is currently signed in on. To get results for all shared items including those from other currently signed in users, use the **GetInventoryItemsForAllUsersAsync** equivalent of the API.
An example of how to use the Inventory service APIs can be seen in the Consumable Content and In-Game Store samples (available on the [Samples](https://developer.microsoft.com/en-us/games/xbox/partner/development-education-samples) page on XGD).
### RESTful Inventory service calls
| Name |
Value / Example |
</tr
| URI |
https://inventory.xboxlive.com/users/me |
| URI |
https://inventory.xboxlive.com/users/me/{itemId} |
| Methods |
GET. Retrieve the current inventory of the user. |
| Response body schema |
```json
{
"pagingInfo": {
"continuationToken": string,
"totalItems": int
},
"items": [ Item* ]
}
```
|
| Item schema |
```json
{
"url": string,
"itemType": string,
"productId": string,
"TitleId": string,
"containers": [ string* ],
"obtained": string,
"startDate": string,
"endDate": string,
("consumable": {”url”: string, ”quantity”: int})
}
```
|
</table>
To call the Inventory service directly, an Xbox One XSTS token is required for the user. Depending on whether or not you add a UserHash to the XSTS token, you can get the combined inventory of everyone signed in to the console, or the inventory filtered to a specific user. Note, however, that the home console shared entitlements will always be included in these calls unless the shared content is filtered out of the results (see Shared option later in this topic). See the Web Services sample (available on the [Samples](https://developer.microsoft.com/en-us/games/xbox/partner/development-education-samples) page on GDN) for information about how to obtain an XSTS token and how to call Xbox RESTful services directly.
You can add additional filters and parameters to further refine the inventory results. You can also page the results returned if specified in the request.
| Query string parameters | Common values (not a complete list) |
| ----------------------- | ----------------------------------- |
| **itemType** | • GameConsumable • GameContent • GameV2 (full game product)**
Note**: Some of the values are currently being shared with Xbox 360 terms and are subject to change in a future XDK. |
| **state** | • all (default) • Enabled • Suspended • Expired • Cancelled • Renewed |
| **container** | If specified, only items that have the specified container in their set will be returned. |
| **availability** | • **Available (default)**. Items for which the current date falls inside the start and end date range. • **All**. Returns all items. • **Unavailable**. Items for which the current date falls outside start and end date range. |
| **productIds** | If specified, can filter the inventory results returned to a pre-set list of ProductIds provided by this parameter. The ProductId list is comma separated between each ProductId. |
| **expandSatisfyingEntitlements** | If specified and set to “true,” includes all satisfying entitlements from bundles, Xbox 360 entitlements, etc. in the results. |
Alternatively, if you want to just check the status of one item, you can specify the *itemID* within the URI as defined previously.
If the item is a consumable, then the item will include an additional section in the **Item** schema named *consumable*, which includes values specific to that type of content.
## Initiating the purchase of a product
Purchasing content on Xbox One is always handled through the console shell UI. To initiate the purchase of a specific product, use the **ShowPurchaseAsync** API. This method is similar to Xbox 360, on which you use the **XShowMarketplace*** APIs to bring up the **System Guide** to complete a transaction.
After the user has selected a specific availability of a product, call the **ShowPurchaseAsync** with the signed offer string from the selected availability. When the shell purchase UI is displayed, your title will not have focus and will be in constrained mode until the purchase is complete or until the user cancels the purchase.
You can also bring up the shell UI to redeem a 5×5 token or a QR code by using the **ShowRedeemCodeAsync** API. This API allows the user to easily enter or scan a code in order to purchase specific content. You can distribute codes in multiple ways, such as through marketing, retail packaging, or pre-orders.
Although codes will be redeemable through the Xbox One Home UI, if you are going to use codes, we recommended that you provide a UI option that allows access to the shell UI (**ShowRedeemCodeAsync** API) in your game. This access will help tailor the experience and provide users with reliable instructions for using their codes through your title.
## Using consumable content
For Xbox One, you can use a consumable, such as in-game currency or items, across multiple titles within a product group. For example, you can allow in-game currency or power-ups purchased for a previous title to be consumable in the next title in the franchise. If you’re unsure of how you can use consumables across titles, ask your developer account manager.
You can obtain information about the user’s consumable inventory through the Inventory service, which is outlined in the previous section. The Inventory service also provides the functionality to consume an item on behalf of the user. After the item is consumed through the Xbox Service calls, you are responsible for taking the proper action and recording state or game-save information to reflect the use of the consumable.
For example, a game franchise sells a healing potion as a consumable product that can be used in any of its released titles. The player is allowed to add the potion to the currently loaded character’s inventory, but after that point the potion cannot be transferred to another character.
When the player adds the potion to his or her current character’s inventory, the game would consume a single quantity of the product through the Xbox Inventory service. At this point, the player’s consumable count for the item is decreased by one, and the remaining result is communicated to the game. The game is now responsible for ensuring that the quantity of potions available for transfer is updated and that the potion is added to the character’s inventory.
When using a consumable, you must supply a transaction ID. The transaction ID is a unique identifier for each consumption request that you defined. The Inventory service will process transactions with the same ID only once, but subsequent calls using the same transaction ID will return with a successful response and the up-to-date quantity for that item.
This practice helps prevent a collision of requests and unintentional deductions from the user’s quantity in case a response is delayed or is not received by the title and then a retry is sent for the same transaction.
For a consume call to be successful, the user must have enough inventory to consume the specified amount and the amount must be deducted from the inventory. When a request succeeds, the response will include the new quantity of the item. If there is an issue with the request, you can gather additional information from the HTTPS response information or from the Xbox Service APIs.
### Consuming items with the Xbox Service APIs
```cpp
IAsyncOperation<ConsumeInventoryItemResult^>^ ConsumeInventoryItemAsync(
__in Marketplace::InventoryItem^ inventoryItem,
__in uint32 quantityToConsume,
__in Platform::String^ transactionId);
```
When you use the Xbox Service APIs to consume items, if you encounter an error in communication or if the transaction fails, the service APIs will automatically retry the call again with the same *transactionId*. If the retry calls are unsuccessful, an exception will be thrown within the scope of the task created from the result of **ConsumeInventoryItemAsync**.
You can retrieve additional information for the error code and response by setting an **XboxServiceCallRoutedEventArgs** event handler within the settings of the **XboxLiveContext** object used. To see an example of how to consume assets and to get additional details as described earlier with the Xbox Service APIs, see the Consumable Content sample (available on the [Samples](https://developer.microsoft.com/en-us/games/xbox/partner/development-education-samples) page on GDN).
### Consuming items with a RESTful service call
| Name |
Value / Example |
</tr
| URI |
https://inventory.xboxlive.com/users/me/consumables/{consumableId} |
| Methods |
GET. Retrieves the current status of the consumable. POST. Consumes the quantity specified. |
| Request body schema |
```json
{
“transactionId”: string
“removeQuantity”: int
}
```
|
| Response body schema |
```json
{
“transactionId”: string
“url”: string
“newQuantity”: int
}
```
|
</table>
When you use the RESTful service directly, we recommend that you retry a consume request with the same *transactionID* if an error or HTTP status is in the 500 range. We also recommend an exponential retry policy where subsequent retry calls are spaced out with increasing time delays.
## Summary
You should now have a solid foundation to start designing a marketplace experience within your game and know how to implement marketplace UI and consumable products by using the Catalog and
Inventory services for Xbox One. Specifically, you should know how to:
- Differentiate between Durable and Consumable content products.
- Browse the catalog for available items to purchase.
- Query the inventory for items the user already owns or is entitled to use.
- Remove a quantity of a consumable product from the user’s inventory.
- Use Xbox Service APIs to implement your own game-rendered UI for available products.
- Use System APIs to instigate purchase within your title or display the Xbox Marketplace App, if not rendering your own in-game store UI.
- Use Restful HTTPS URIs to interact with the Catalog and Inventory services if not using the Xbox Service APIs.
|