> ## Documentation Index
> Fetch the complete documentation index at: https://devdocs.xbox.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Opérations de base du magasin

> Implémentez un magasin intégré au jeu avec les API XStore, notamment pour déterminer ce que les utilisateurs peuvent acheter, vérifier les droits d'utilisation et effectuer des achats.

Un magasin intégré au jeu implique généralement trois opérations de base :

1. [Déterminer ce que les utilisateurs peuvent acheter](#1-determining-what-users-can-purchase)
2. [Évaluer les produits que l'utilisateur possède ou auxquels il a droit](#2-evaluating-what-products-the-user-owns-or-is-entitled-to)
3. [Acheter des produits admissibles](#3-purchasing-eligible-products)

Cet article présente un exemple de code pour chaque opération, tiré de l'exemple InGameStore, qui est continuellement mis à jour pour refléter les meilleures pratiques.

## Préparation de l'appel des API XStore

Toutes les API `XStore` fonctionnent sur un `XStoreContextHandle` créé à l'aide de [XStoreCreateContext](/fr-CA/reference/system/xstore/xstore_members).

Ce contexte vous permet d'effectuer des opérations de magasin dans le contexte de l'utilisateur spécifié sur console et de l'utilisateur par défaut disponible sur un PC. Sur console, un événement de suspension ou de Quick Resume invalide le contexte. Pour gérer ces conditions de façon sécuritaire, fermez le `XStoreContextHandle` et recréez-le chaque fois que le jeu reprend après un état suspendu.

## 1. Déterminer ce que les utilisateurs peuvent acheter

Ce qu'un jeu offre habituellement à l'achat, ce sont ses extensions. Le code suivant illustre l'appel de base à l'API [XStoreQueryAssociatedProductsAsync](/fr-CA/reference/system/xstore/xstore_members) nécessaire pour que le jeu sache quels produits sont disponibles.

Cette requête retourne automatiquement uniquement les extensions **achetables** associées au jeu. Des produits non liés associés au même éditeur (c'est-à-dire configurés avec le même compte Partner Center) peuvent également être retournés par cet appel, à condition que le jeu soit configuré avec une relation « peut vendre » envers ce produit dans la section **Configuration des relations de produits** de Partner Center.

Pour en savoir plus sur la configuration des relations de produits, consultez [Configurer les relations de produits pour un jeu](/fr-CA/publishing/game-publishing/tutorial-xbox-managed/how-to-create-product-relationships).

```cpp theme={null}
bool CALLBACK ProductEnumerationCallback(const XStoreProduct* product, void* context)
{
    // Handle adding the product to the game

    printf("%s %s %u\n", product->title, product->storeId, product->productKind);

    return true;
}

void QueryCatalog()
{
    auto async = new XAsyncBlock{};
    async->queue = m_asyncQueue;
    async->callback = [](XAsyncBlock* async)
    {
        XStoreProductQueryHandle queryHandle = nullptr;

        HRESULT hr = XStoreQueryAssociatedProductsResult(async, &queryHandle);
        if (SUCCEEDED(hr))
        {
            hr = XStoreEnumerateProductsQuery(queryHandle, async->context, ProductEnumerationCallback);

            if (SUCCEEDED(hr))
            {
                // TODO: Check for more pages to process
                printf("Enumeration complete\n");
            }

            XStoreCloseProductsQueryHandle(queryHandle);
            delete async;
        }
    };

    XStoreProductKind typeFilter =
        XStoreProductKind::Consumable |
        XStoreProductKind::Durable |
        XStoreProductKind::Game;

    HRESULT hr = XStoreQueryAssociatedProductsAsync(
        m_xStoreContext,
        typeFilter,
        UINT8_MAX,  // placeholder maximum, see Paging
        async)

    if (FAILED(hr))
    {
        delete async;
    }
}
```

### Points à noter

* Seuls les produits achetables sont retournés par `XStoreQueryAssociatedProductsAsync`; les produits qui sont uniquement accordés dans des ensembles ou qui ne sont pas configurés pour être achetables individuellement ne sont pas retournés. Pour ces derniers, utilisez `XStoreQueryProductsAsync`.
* Le nombre de produits retournés n'est pas connu à l'avance; le décompte doit donc être cumulé.

### Pagination

La gestion de la pagination n'est pas facultative lors de la requête de produits associés ou de droits d'utilisation. Le nombre de pages retournées par le service, et le nombre d'éléments retournés par page, peuvent varier selon les environnements et la charge du service. Pour un exemple de gestion de la pagination, consultez [XStoreQueryAssociatedProductsAsync](/fr-CA/reference/system/xstore/xstore_members).

### Autres options

[XStoreQueryProductsAsync](/fr-CA/reference/system/xstore/xstore_members) peut être utilisé pour interroger des produits précis, si le `storeId` est connu ou si d'autres `actionFilters` sont souhaités. Les « actions » sont des scénarios d'utilisation qui s'appliquent à un produit, qui comprennent des verbes comme `Purchase`, `License`, `Gift` et `Redeem`.

[XStoreQueryAssociatedProductsForStoreIdAsync](/fr-CA/reference/system/xstore/xstore_members) peut être utilisé pour interroger les produits associés à d'autres jeux, ce qui peut être utile pour la vente croisée des extensions d'un autre titre.

[XStoreQueryProductForCurrentGameAsync](/fr-CA/reference/system/xstore/xstore_members) sert à interroger uniquement le produit du jeu en cours d'exécution.

[XStoreShowAssociatedProductsUIAsync](/fr-CA/reference/system/xstore/xstore_members) amène l'utilisateur dans l'application Microsoft Store, vers un affichage des produits associés, filtrés par type de produit. Cette API est une solution de rechange à l'énumération des produits disponibles pour les présenter dans une interface intégrée au jeu.

<img src="https://mintcdn.com/microsoft-4404708b/hprF_XHEe0cnRr8N/images/xstore/addonsforthisgame.webp?fit=max&auto=format&n=hprF_XHEe0cnRr8N&q=85&s=63d12502a1154059b4041a6556f4773e" alt="Extensions pour ce jeu" width="1914" height="1061" data-path="images/xstore/addonsforthisgame.webp" />

## 2. Évaluer les produits que l'utilisateur possède ou auxquels il a droit

Cette étape fait appel en grande partie au même code que celui présenté précédemment, mais avec les remplacements suivants :

* [XStoreQueryAssociatedProductsAsync](/fr-CA/reference/system/xstore/xstore_members) → [XStoreQueryEntitledProductsAsync](/fr-CA/reference/system/xstore/xstore_members)
* [XStoreQueryAssociatedProductsResult](/fr-CA/reference/system/xstore/xstore_members) → [XStoreQueryEntitledProductsResult](/fr-CA/reference/system/xstore/xstore_members)

Les API `QueryEntitledProducts` retournent les produits auxquels l'utilisateur a droit. Avoir droit signifie que l'utilisateur possède directement le produit, qu'il obtient le droit d'utilisation par l'entremise d'autres produits (comme des ensembles et des abonnements), ou qu'il obtient le droit d'utilisation grâce à un droit partagé par un autre utilisateur.

De plus, les résultats de [XStoreQueryAssociatedProductsAsync](/fr-CA/reference/system/xstore/xstore_members) (et des fonctions connexes) déterminent le droit d'utilisation. La structure [XStoreProduct](/fr-CA/reference/system/xstore/xstore_members) contient un champ `isInUserCollection` qui est défini à true lorsque l'utilisateur y a droit.

### Possession des consommables

La quantité de consommables est indiquée dans `XStoreProduct.skus[i].collectionData.quantity`. Habituellement, il n'y a qu'une seule SKU pour un produit consommable.

Vous pouvez également utiliser [XStoreQueryConsumableBalanceRemainingAsync](/fr-CA/reference/system/xstore/xstore_members) pour vous informer de la quantité, mais évitez de l'utiliser individuellement pour un grand nombre de consommables, car chaque appel entraîne un appel au service.

Pour préserver l'intégrité des écosystèmes basés sur les consommables, utilisez la validation et l'échange des consommables côté service. Pour plus d'informations, consultez [Écosystèmes basés sur les consommables](/fr-CA/publishing/xstore-commerce/xstore-consumables).

### Possession des produits durables

Il ne suffit pas de vérifier si le compte possède le produit pour déterminer que l'utilisateur a le droit d'utiliser le produit dans le jeu. Les produits durables doivent respecter la politique de partage de contenu décrite dans [Modèle de partage de produits pour les jeux](/fr-CA/publishing/xstore-commerce/xstore-product-sharing).

Utilisez [XStoreAcquireLicenseForPackageAsync](/fr-CA/reference/system/xstore/xstore_members) pour un **produit durable avec package** afin de déterminer s'il peut faire l'objet d'une licence selon les règles de partage de contenu.

Utilisez [XStoreAcquireLicenseForDurablesAsync](/fr-CA/reference/system/xstore/xstore_members) pour un **produit durable sans package** afin de faire de même.

Utilisez [XStoreQueryAddOnLicensesAsync](/fr-CA/reference/system/xstore/xstore_members) pour un jeu sous licence **numérique** afin de retourner la liste des produits durables sans package pouvant faire l'objet d'une licence.

Pour plus d'informations, consultez [Gérer le contenu téléchargeable et en accorder la licence](/fr-CA/publishing/xstore-commerce/xstore-dlc) et [Comment utiliser un produit durable sans package](/fr-CA/publishing/xstore-commerce/xstore-dwob).

## 3. Acheter des produits admissibles

Pour afficher le flux d'achat d'un produit achetable, passez le `storeId` à l'API [XStoreShowPurchaseUIAsync](/fr-CA/reference/system/xstore/xstore_members) :

```cpp theme={null}
void MakePurchase(const char* storeId)
{
    auto async = new XAsyncBlock{};
    async->context = &storeId;
    async->queue = m_asyncQueue;
    async->callback = [](XAsyncBlock *async)
    {
        const char* = reinterpret_cast<const char*>(async->context);

        HRESULT hr = XStoreShowPurchaseUIResult(async);
        if (SUCCEEDED(hr))
        {
            printf("Purchase succeeded (%s)\n", storeId);

            // Refresh ownership and update game
        }
        else
        {
            printf("Purchase failed (%s) 0x%x\n", storeId, hr);

            if (hr == E_GAMESTORE_ALREADY_PURCHASED)
            {
                printf("Already own this\n");
            }
        }

        delete async;
    };

    HRESULT hr = XStoreShowPurchaseUIAsync(
        m_xStoreContext,
        storeId,
        nullptr,    // Can be used to override the title bar text
        nullptr,    // Can be used to provide extra details to purchase
        async);

    if (FAILED(hr))
    {
        delete async;
        printf("Error calling XStoreShowPurchaseUIAsync : 0x%x\n", hr);
        return;
    }
}
```

Les joueurs peuvent également effectuer des achats en dehors du jeu en passant explicitement au Microsoft Store, sur Xbox.com, sur PC, dans les applications mobiles ou dans d'autres points de vente. Par conséquent, prévoyez un endroit dans votre jeu qui actualise de façon fiable la possession des produits sur demande. Le flux de connexion initial est l'endroit idéal, mais ajoutez également l'actualisation lors de la transition vers le magasin intégré au jeu ou quelque part dans les paramètres.

## Documentation de référence de l'API

* [XStore (contenu de l'API)](/fr-CA/reference/system/xstore/xstore_members)
  * Fonctions
    * [XStoreCreateContext](/fr-CA/reference/system/xstore/xstore_members)
    * [XStoreQueryAssociatedProductsAsync](/fr-CA/reference/system/xstore/xstore_members)
    * [XStoreQueryProductsAsync](/fr-CA/reference/system/xstore/xstore_members)
    * [XStoreQueryAssociatedProductsForStoreIdAsync](/fr-CA/reference/system/xstore/xstore_members)
    * [XStoreQueryProductForCurrentGameAsync](/fr-CA/reference/system/xstore/xstore_members)
    * [XStoreShowAssociatedProductsUIAsync](/fr-CA/reference/system/xstore/xstore_members)
    * [XStoreQueryEntitledProductsAsync](/fr-CA/reference/system/xstore/xstore_members)
    * [XStoreQueryAssociatedProductsResult](/fr-CA/reference/system/xstore/xstore_members)
    * [XStoreQueryEntitledProductsResult](/fr-CA/reference/system/xstore/xstore_members)
    * [XStoreQueryConsumableBalanceRemainingAsync](/fr-CA/reference/system/xstore/xstore_members)
    * [XStoreAcquireLicenseForPackageAsync](/fr-CA/reference/system/xstore/xstore_members)
    * [XStoreAcquireLicenseForDurablesAsync](/fr-CA/reference/system/xstore/xstore_members)
    * [XStoreQueryAddOnLicensesAsync](/fr-CA/reference/system/xstore/xstore_members)
    * [XStoreShowPurchaseUIAsync](/fr-CA/reference/system/xstore/xstore_members)
  * Structures
    * [XStoreProduct](/fr-CA/reference/system/xstore/xstore_members)

## Voir aussi

[Vue d'ensemble du commerce](/fr-CA/publishing/xstore-commerce/xstore-commerce-overview)

[Activation du développement et des tests XStore](/fr-CA/publishing/xstore-commerce/xstore-product-testing-setup)

[Référence de l'API XStore](/fr-CA/reference/system/xstore/xstore_members)


## Related topics

- [Aperçu du portage](/fr-CA/paths/porting/overview.md)
- [Vue d'ensemble du portage](/fr/paths/porting/overview.md)
- [Aperçu de XBOX Series X|S](/fr-CA/paths/series-xs/overview.md)
- [Aperçu de Windows et ROG XBOX Ally](/fr-CA/paths/windows/overview.md)
- [Aperçu d'Unity](/fr-CA/paths/unity/overview.md)
