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

# Jeu d'artisanat, partie 3 - Codage

> Partie 3 du tutoriel sur le jeu d'artisanat de PlayFab Economy V2 : écrivez du code C# qui appelle l'API Economy V2 pour gérer les inventaires, les recettes et les objets fabriqués.

# Partie 3 - Codage + exemples

Maintenant que votre environnement est prêt et que vous connaissez Game Manager, nous pouvons commencer à coder notre jeu.

## Prérequis

1. [Partie 1 - Configuration de l'environnement](/fr-CA/services/playfab/economy-monetization/economy-v2/tutorials/craftingGame/crafting-game-environment)
2. [Partie 2 - Utilisation de Game Manager](/fr-CA/services/playfab/economy-monetization/economy-v2/tutorials/craftingGame/crafting-game-game-manager)

## Étape 1 - Configurer les paramètres de l'environnement

La première chose que nous vous recommandons de faire lorsque vous commencez à coder est de configurer les paramètres de votre environnement. Ainsi, vous avez l'assurance que chaque appel que vous effectuez sera lié à votre titre et utilisera votre clé secrète de développeur.

Pour régler cette étape, vous pouvez spécifier n'importe où dans votre code (idéalement à un endroit facile à retrouver pour vous) les variables TitleId et DeveloperSecretKey, puis leur attribuer vos valeurs.

Pour ce faire, ajoutez deux lignes de code distinctes comme suit :

```csharp theme={null}
PlayFabSettings.staticSettings.TitleId = "{Your Title ID}";
PlayFabSettings.staticSettings.DeveloperSecretKey = "{Your Developer Secret Key}";
```

## Étape 2 - S'authentifier

Une fois l'environnement configuré, le package NuGet PlayFab installé et configuré dans votre projet, et votre studio ainsi que votre titre créés, nous pouvons commencer à coder notre authentification.

<Note>
  Un utilisateur peut s'authentifier de plusieurs façons. Dans cet exemple, nous allons utiliser la méthode **LoginWithCustomId**. Il existe d'autres façons de s'authentifier, y compris des méthodes propres à certaines plateformes. Pour plus d'information, consultez [Notions de base sur la connexion](/fr-CA/services/playfab/identity/player-identity/login/login-basics-best-practices).
</Note>

Voici un exemple de code en C# dans lequel nous authentifions un utilisateur à l'aide de **LoginWithCustomID**, qui est considéré comme une connexion anonyme. Avant d'appeler l'API pour l'authentification, nous devons d'abord déclarer une variable globale dans laquelle nous stockons l'**EntityKey** générée dans le cadre du processus de connexion.

L'**EntityKey** est utilisée pour effectuer tout type d'appel à l'API et c'est elle qui lie chaque requête et chaque réponse à l'utilisateur connecté.

La déclaration de la variable globale EntityKey est la suivante :

```csharp theme={null}
private static PlayFab.ClientModels.EntityKey entityKey;
```

***

Ensuite, la logique pour authentifier un utilisateur est la suivante :

### SDK C\#

```csharp theme={null}
var request = new LoginWithCustomIDRequest { CustomId = username };
var loginTask = PlayFabClientAPI.LoginWithCustomIDAsync(request);
entityKey = loginTask.Result.Result.EntityToken.Entity;
```

### API

```json theme={null}
{
  "CustomId": "{{Username}}",
  "CreateAccount": false,
  "TitleId": "{{TitleId}}"
}
```

***

Le code ci-dessus recherche les joueurs existants liés à votre titre de jeu. Toutefois, il échoue s'il n'existe aucun utilisateur ayant un nom d'utilisateur correspondant. Pour contourner ce problème, nous pouvons ajouter un paramètre « CreateAccount = true » au corps de la requête. Ainsi, PlayFab crée un nouveau joueur s'il n'y a aucune correspondance pour le nom d'utilisateur envoyé. Le code ressemblerait alors à ceci :

### SDK C\#

```csharp theme={null}
var request = new LoginWithCustomIDRequest { CustomId = username, CreateAccount = true };
var loginTask = PlayFabClientAPI.LoginWithCustomIDAsync(request);
entityKey = loginTask.Result.Result.EntityToken.Entity;
```

### API

```json theme={null}
{
  "CustomId": "{{Username}}",
  "CreateAccount": true,
  "TitleId": "{{TitleId}}"
}
```

***

Après une connexion réussie, l'API retourne certains ensembles de données, comme le **SessionTicket**, le **PlayFab ID** de l'utilisateur et l'**EntityToken**. Vous pouvez les voir dans la réponse directe de l'API, détaillée ci-dessous.

```json theme={null}
{
    "code": 200,
    "status": "OK",
    "data": {
        "SessionTicket": "{{SessionTicket}}",
        "PlayFabId": "{{PlayFabID}}",
        "NewlyCreated": false,
        "SettingsForUser": {
            "NeedsAttribution": false,
            "GatherDeviceInfo": true,
            "GatherFocusInfo": true
        },
        "LastLoginTime": "2023-08-01T17:09:54.508Z",
        "EntityToken": {
            "EntityToken": "{{EntityToken}}",
            "TokenExpiration": "2023-08-04T21:20:35Z",
            "Entity": {
                "Id": "{{Player ID}}",
                "Type": "title_player_account",
                "TypeString": "title_player_account"
            }
        },
        "TreatmentAssignment": {
            "Variants": [],
            "Variables": []
        }
    }
}
```

***

Dès que l'API vous retourne `"code":200` ou que vous obtenez de l'information dans `loginTask` dans l'exemple C# ci-dessus, vous êtes authentifié et prêt à passer à l'étape suivante!

## Étape 3 - Configurer votre inventaire de départ

Maintenant que vous êtes connecté avec un joueur valide (ou que vous avez créé un nouveau joueur), votre première étape devrait être de définir l'inventaire de départ de ce joueur. Pour cela, nous utiliserons l'appel d'API [ExecuteInventoryOperations](https://learn.microsoft.com/en-us/rest/api/playfab/economy/inventory/execute-inventory-operations).

<Note>
  L'appel ExecuteInventoryOperations nous permet d'exécuter plusieurs [InventoryOperations](https://learn.microsoft.com/en-us/rest/api/playfab/economy/inventory/execute-inventory-operations) (en lot) sur l'inventaire du joueur. Les types d'opérations pris en charge sont : - Add - Delete - Purchase - Subtract - Transfer - Update
</Note>

Pour cet exemple, nous allons ajouter les objets correspondant à notre jeu. Il s'agit de trois instances de Stone, d'une instance de Cream et d'une instance de Gold (cela suppose que vous avez créé d'autres objets; sinon, veuillez le faire avant de continuer). Mais au lieu d'utiliser simplement l'opération **Add**, nous utilisons l'opération **Purchase** et nous achetons gratuitement les instances requises.

<Note>
  Pour que cette étape fonctionne, vous devez d'abord avoir créé les objets dans votre titre dans Game Manager.
</Note>

Les extraits ci-dessous vous montrent comment effectuer ces appels en bloc, à la fois en C# et à l'aide de l'API de PlayFab.

### SDK C\#

Dans cet exemple C#, vous pouvez voir que nous commençons par définir purchasePrice comme valeur standard pour toutes les transactions, car nous allons leur attribuer à toutes un prix de 0.

Un même objet peut avoir plusieurs prix, c'est pourquoi la variable `purchasePrice` est de type `List<PurchasePriceAmount>`.

Vous remarquerez ensuite que la requête prend, en plus de la liste d'`InventoryOperation`, une entité (Entity). Nous en créerons une nouvelle à l'aide des valeurs obtenues lors de la connexion effectuée précédemment.

Enfin, chaque `InventoryOperation` prend une valeur `Purchase`, bien qu'il puisse s'agir de n'importe laquelle des opérations disponibles dans l'appel **ExecuteInventoryOperations** (Add, Delete, Purchase, Subtract, Transfer et Update). Dans ce cas, nous utilisons l'identificateur `Purchase`; nous avons donc besoin d'un `new PurchaseInventoryItemsOperation`.

Vous devez aussi indiquer clairement quel objet vous souhaitez acheter. Pour ce faire, utilisez `InventoryItemReference`, qui prend l'ID de l'objet comme unique paramètre.

Dans notre code, nous avons une méthode appelée **SearchItem(\{itemName})**, mais vous pouvez facilement la remplacer par une chaîne représentant l'ID de l'objet. Assurez-vous de faire correspondre le nom (ou l'ID) de chaque objet avec la quantité correspondante.

```csharp theme={null}
var purchasePrice = new List<PurchasePriceAmount> { new PurchasePriceAmount { ItemId = freeItemId, Amount = 0 } };
var request = new ExecuteInventoryOperationsRequest 
{ 
    Entity = new PlayFab.EconomyModels.EntityKey { Id = entityKey.Id, Type = entityKey.Type },
    Operations = new List<InventoryOperation> {
        new InventoryOperation
        {
            Purchase = new PurchaseInventoryItemsOperation { 
                Item = new InventoryItemReference {AlternateId = new AlternateId { Type = "FriendlyId", Value = "Stone" } }, 
                Amount = 3, 
                PriceAmounts = purchasePrice
            }
        },
        new InventoryOperation
        {
            Purchase = new PurchaseInventoryItemsOperation {
                Item = new InventoryItemReference { AlternateId = new AlternateId { Type = "FriendlyId", Value = "Gold" } },
                Amount = 1,
                PriceAmounts = purchasePrice
            }
        },``
        new InventoryOperation
        {
            Purchase = new PurchaseInventoryItemsOperation {
                Item = new InventoryItemReference {AlternateId = new AlternateId { Type = "FriendlyId", Value = "Cream" }},
                Amount = 1,
                PriceAmounts = purchasePrice
            }
        }
    }
};
await PlayFabEconomyAPI.ExecuteInventoryOperationsAsync(request);
```

Dans le code ci-dessus, pour utiliser correctement `AlternateId` et `FriendlyId` dans votre code, ces valeurs doivent être configurées pour vos objets dans Game Manager. Pour ce faire, je vous suggère de consulter [Partie 2 - Utilisation de Game Manager](/fr-CA/services/playfab/economy-monetization/economy-v2/tutorials/craftingGame/crafting-game-game-manager), où nous détaillons les étapes à suivre.

### API

Appelez le point de terminaison d'API **ExecuteInventoryOperations** avec le corps de requête présenté ci-dessous, en remplaçant les ID par les valeurs correspondantes. Notez que `Operations` est un tableau; vous pouvez y inclure plusieurs types d'opérations simultanément.

Il est important de comprendre que pour chaque appel d'API que vous effectuez, vous devez définir un en-tête `X-EntityToken` avec l'**EntityToken** propre à votre session active ou à l'utilisateur connecté. Autrement dit, avant d'effectuer des appels d'API, vous devez d'abord appeler **LoginWithCustomID** (dans cet exemple) et, à partir du message de retour, obtenir l'**EntityToken** à utiliser comme en-tête dans tous les appels d'API.

```json theme={null}
{
  "Operations": [
    {
      "Purchase": {
            "Item": {
                "Id": {Stone ID}
            },
            "Amount": 3,
            "PriceAmounts": [
                {
                "ItemId": {Free Item ID},
                "Amount": 0
                }
            ]
        }
    },
    {
      "Purchase": {
            "Item": {
                "Id": {Gold ID}
            },
            "Amount": 1,
            "PriceAmounts": [
                {
                "ItemId": {Free Item ID},
                "Amount": 0
                }
            ]
        }
    },
    {
      "Purchase": {
            "Item": {
                "Id": {Cream ID}
            },
            "Amount": 1,
            "PriceAmounts": [
                {
                "ItemId": {Free Item ID},
                "Amount": 0
                }
            ]
        }
    }
  ]
}
```

Le JSON suivant est un exemple de message de retour réussi après l'appel ci-dessus. Vous verrez trois ID de transaction distincts, car les ID sont attribués par modification, ce qui ne signifie pas pour autant qu'il y a trois transactions distinctes. Au contraire, le tout est traité comme une seule transaction comportant trois modifications; nous ne retournons donc qu'un seul résultat de réussite ou d'échec pour l'ensemble de la transaction, peu importe le nombre de modifications.

```json theme={null}
{
    "code": 200,
    "status": "OK",
    "data": {
        "IdempotencyId": {Idempotency ID},
        "TransactionIds": [
            "200",
            "201",
            "202"
        ],
        "ETag": "1/MjAy"
    }
}
```

***

## Étape 4 - Créer un ensemble

Les ensembles (bundles) vous permettent de regrouper plusieurs objets en un seul. Pour plus d'information sur les ensembles, consultez notre **documentation sur les ensembles** en suivant [ce lien](/fr-CA/services/playfab/economy-monetization/economy-v2/catalog/bundles).

Dans notre exemple, nous utiliserons un **ensemble** pour regrouper les objets retournés par la **Kitchen**, ce qui nous aide à conserver l'objet **Icebox**. L'idée derrière la glacière (Icebox) est qu'elle soit un objet non consommable lors de l'achat d'une crème glacée, même si elle fait partie des matériaux requis.

Voici un aperçu général du fonctionnement. Imaginez un joueur qui possède une Cream et une Icebox dans son inventaire. En accédant au magasin Kitchen, ce joueur doit utiliser ces deux objets pour acheter ou fabriquer une Ice Cream. Puisque l'Icebox n'est pas consommable, le résultat attendu est un inventaire contenant une Ice Cream et une Icebox, seule la Cream ayant été consommée.

En coulisse, nous gérons cela à l'aide d'un ensemble dont le prix est d'une Icebox et d'une Cream, et dont les objets retournés sont une Ice Cream et une Icebox. Cela signifie que l'Icebox présente dans l'inventaire du joueur sera consommée, mais que la même transaction qui la consomme en retourne une autre, ce qui donne au joueur l'impression que l'Icebox est toujours dans l'inventaire, alors qu'en réalité les instances d'Icebox sont différentes, mais invisibles pour le joueur.

Pour créer un ensemble, vous devez accéder à la section **Economy** de votre titre, comme vous l'avez fait lors de la création d'un nouvel objet. Vous y trouverez un onglet appelé **Bundles** à côté de **Items**, **Currency** et d'autres. Une fois cet onglet sélectionné, un bouton bleu **New bundle** apparaît dans le coin supérieur droit de l'écran.

Un formulaire semblable à celui de création d'un nouvel objet s'affiche alors, à la différence près que, si vous faites défiler vers le bas, vous trouverez une section intitulée **Items**. Vous pouvez y ajouter les objets que l'ensemble doit contenir, qui seront transférés dans l'inventaire du joueur lors de l'achat.

Après avoir cliqué sur le bouton **Add**, une liste consultable de tous les objets de votre catalogue s'affiche; vous pouvez y sélectionner les objets à inclure dans l'ensemble. Dès que vous avez sélectionné et ajouté vos objets, vous pouvez choisir **Save and publish**, et votre ensemble sera alors actif et sélectionnable dans les magasins comme prix d'achat.

## Étape 5 - Créer un magasin

Selon notre exemple de jeu d'artisanat, le joueur doit acheter des objets dans un magasin. Il y aura trois magasins distincts (dans ce cas, des emplacements) : la **Science Machine**, l'**Alchemy Engine** et la **Kitchen**.

Nous nous concentrerons sur la **Kitchen**. Les joueurs peuvent y acheter une **Ice Cream** (nouvel objet à créer) au prix de **1 Cream** et **1 Icebox** (nouvel objet à créer). Ce cas a été choisi parce qu'il illustre comment les **ensembles** fonctionnent avec les magasins et les transactions.

Les magasins ne peuvent être créés qu'à partir de [Game Manager](https://developer.playfab.com) : accédez à la section **Economy** dans la barre de navigation de gauche, puis, parmi les différents onglets, choisissez **Stores** et sélectionnez le bouton bleu **New store**.

Un formulaire semblable à celui utilisé pour créer de nouveaux objets s'affiche, dans lequel les seuls champs obligatoires sont la date de début (Start Date) et le titre que vous souhaitez donner à votre magasin. En faisant défiler vers le bas, vous

## Étape 6 - Ajouter un ensemble à un magasin

Maintenant que votre ensemble et votre magasin sont créés et publiés, vous pouvez ajouter l'ensemble comme objet retournable dans votre magasin. Pour ce faire, ouvrez votre magasin, faites défiler jusqu'au titre **Items** et sélectionnez le bouton **Add**.

La liste des objets du catalogue s'affiche. À gauche de la barre de recherche se trouve un menu déroulant contenant les différents types d'objets, comme **Items**, **UGC Items**, **Bundles** et **Subscription**. Si vous choisissez **Bundles**, la liste est filtrée pour n'afficher que les objets de type ensemble; vous devriez y voir l'ensemble créé précédemment. Une fois que vous avez sélectionné le bouton **Add** à côté du nom de l'ensemble, puis le bouton **Add** au bas de la fenêtre, l'ensemble est ajouté comme objet de transaction possible pour ce magasin.

Il reste une dernière étape avant de continuer : définir un prix pour votre ensemble. Ce prix fonctionne comme tout autre prix d'objet, en ce sens que le joueur doit posséder dans son inventaire les objets exigés comme prix avant que l'achat soit accepté. Pour définir un prix, sélectionnez le bouton **Add new price** à droite de votre ensemble et, dans la liste des objets, sélectionnez les objets qui constitueront le prix. Dans notre cas, nous voulons que le prix soit de **1 Icebox** et **1 Cream**.

Maintenant que votre ensemble a été ajouté à votre magasin et que son prix a été défini, nous pouvons passer à l'étape suivante.

## Étape 7 - Acheter un ensemble

Une fois votre ensemble et votre magasin créés, et votre ensemble lié à votre magasin, vous pouvez maintenant acheter cet ensemble et obtenir les objets qui en résultent dans votre inventaire.

Pour acheter un ensemble du point de vue du joueur, vous pouvez utiliser **PurchaseInventoryItems** de l'API PlayFab, qui fonctionne non seulement avec les ensembles, mais aussi avec les objets individuels.

### API

Dans le cas suivant, nous voulons acheter **1 ensemble** au prix de **1 Icebox** et **1 Cream**. Nous allons utiliser les propriétés de tableau de **PriceAmount** pour définir plus d'un objet comme prix. Assurez-vous simplement d'avoir attribué un **FriendlyId** à votre ensemble.

```json theme={null}
{
  "Item": {
    "AlternateId": {
        "Type": "FriendlyId",
        "Value": "Ice Cream and Ice Box"
    }
  },
  "Amount": 1,
  "PriceAmounts": [
    {
        "ItemId": "0d2ab329-2fc5-4ae1-9e3c-19f9fc9bbf86",
        "Amount": 1
    },
    {
        "ItemId": "e5276289-f839-4bde-acce-309ea7959e45",
        "Amount": 1
    }
  ],
  "DeleteEmptyStacks": true,
  "StoreId": "f116f1d4-64f9-4be7-9660-a3c1f021100b"
}
```

L'extrait suivant présente le retour attendu après un appel d'API réussi.

```json theme={null}
{
    "code": 200,
    "status": "OK",
    "data": {
        "ETag": "1/MjEz",
        "IdempotencyId": "d710508f-defc-4382-bbd1-a3576417b3f7",
        "TransactionIds": [
            "212",
            "213"
        ]
    }
}
```

<Note>
  Vous remarquerez dans la réponse que vous obtenez 2 `TransactionIds` différents. C'est parce que la propriété `DeleteEmptyStacks` est traitée comme une transaction supplémentaire. Dans l'exemple précédent, la transaction 212 correspond à l'achat de l'ensemble, et la transaction 213 à la suppression de la pile de Cream vide (en supposant que vous n'aviez qu'une seule Cream dans votre inventaire).
</Note>

### SDK C\#

Pour ce qui est de l'allure du code C#, vous trouverez ci-dessous un extrait de notre exemple.

```csharp theme={null}
var purchaseRequest = new PurchaseInventoryItemsRequest
{
    Entity = new PlayFab.EconomyModels.EntityKey { Id = entityKey.Id, Type = entityKey.Type },
    Item = new InventoryItemReference { Id = "34167d9f-c8d7-4e17-9a87-b6af1fc389b2" }, //bundle id
    Amount = 1,
    PriceAmounts = new List<PurchasePriceAmount>() { 
        new PurchasePriceAmount { 
            ItemId = "e5276289-f839-4bde-acce-309ea7959e45", 
            Amount = 1 
        }, //cream id and quantity
        new PurchasePriceAmount { 
            ItemId =  "0d2ab329-2fc5-4ae1-9e3c-19f9fc9bbf86", 
            Amount = 1 
        } //icebox id and quantity
    }, 
    StoreId = "f116f1d4-64f9-4be7-9660-a3c1f021100b",
    DeleteEmptyStacks = true
};

var result = await PlayFabEconomyAPI.PurchaseInventoryItemsAsync(purchaseRequest);
```

***

## Voir aussi

* [Vue d'ensemble d'Economy v2](/fr-CA/services/playfab/economy-monetization/economy-v2/overview)
* [Paramètres](/fr-CA/services/playfab/economy-monetization/economy-v2/settings)
* [Magasins d'Economy v2](/fr-CA/services/playfab/economy-monetization/economy-v2/catalog/stores#creating-a-store)


## Related topics

- [Jeu d'artisanat, partie 1 - Configuration](/fr-CA/services/playfab/economy-monetization/economy-v2/tutorials/craftingGame/crafting-game-environment.md)
- [Jeu d'artisanat, partie 2 - Game Manager](/fr-CA/services/playfab/economy-monetization/economy-v2/tutorials/craftingGame/crafting-game-game-manager.md)
- [Jeu d'artisanat - Contexte](/fr-CA/services/playfab/economy-monetization/economy-v2/tutorials/craftingGame/game-context.md)
- [Vue d'ensemble d'Economy v2](/fr-CA/services/playfab/economy-monetization/economy-v2/overview.md)
- [Échange avec la place de marché Steam](/fr-CA/services/playfab/economy-monetization/economy-v2/marketplace/marketplace-redemption/steam.md)
