> ## 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 du jeu d'artisanat 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 êtes familiarisé avec Game Manager, nous pouvons commencer à coder notre jeu.

## Prérequis

1. [Partie 1 - Configuration de l'environnement](/fr/services/playfab/economy-monetization/economy-v2/tutorials/craftingGame/crafting-game-environment)
2. [Partie 2 - Utilisation de Game Manager](/fr/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 spécifique.

Pour régler cette étape, vous pouvez spécifier n'importe où dans votre code (de préférence à un endroit facile à retrouver) les variables TitleId et DeveloperSecretKey, et 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 et 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'informations, consultez [Notions de base de la connexion](/fr/services/playfab/identity/player-identity/login/login-basics-best-practices).
</Note>

Voici un exemple de code écrit en C# dans lequel nous authentifions un utilisateur à l'aide de **LoginWithCustomID**, qui est classé comme une connexion anonyme. Avant d'appeler l'API d'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 permettant d'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. Mais il échoue s'il n'existe aucun utilisateur dont le nom correspond. 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'existe aucune correspondance avec ce que l'utilisateur envoie comme nom d'utilisateur. 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 renvoie plusieurs ensembles de données, tels que le **SessionTicket**, l'**ID PlayFab** 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": []
        }
    }
}
```

***

Une fois que l'API renvoie `"code":200` ou que vous obtenez des informations 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 doit consister à définir l'inventaire de départ de ce joueur. Pour cela, nous allons utiliser 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) (par 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, une instance de Cream et une instance de Gold (en supposant que vous avez créé d'autres objets ; si ce n'est pas le cas, faites-le 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 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 également indiquer clairement l'objet que 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. Veillez à 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/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 simultanément plusieurs types d'opérations.

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é. En d'autres termes, avant d'effectuer tout appel d'API, vous devez d'abord appeler **LoginWithCustomID** (dans cet exemple) et, à partir du message de retour, récupérer 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 renvoyés, car les ID sont attribués par modification, ce qui ne signifie pas pour autant qu'il y ait trois transactions distinctes. Au contraire, l'ensemble est traité comme une seule transaction comportant trois modifications ; c'est pourquoi nous ne renvoyons qu'un seul succès ou échec pour l'ensemble de la transaction, quel que soit 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 bundle

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

Dans notre exemple, nous allons utiliser un **bundle** pour regrouper les objets renvoyés par la **Kitchen**, ce qui nous permet de conserver l'objet **Icebox**. L'idée est que la glacière (Icebox) soit un objet non consommable lors de l'achat d'une glace (Ice Cream), même si elle fait partie des matériaux requis.

Voici une vue d'ensemble de ce 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/fabriquer une Ice Cream. Comme 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 coulisses, nous gérons cela à l'aide d'un bundle dont le prix est d'une Icebox et d'une Cream, et dont les objets renvoyés sont une Ice Cream et une Icebox. Cela signifie que l'Icebox de l'inventaire du joueur sera consommée, mais la même transaction qui la consomme en renvoie 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 de manière invisible pour le joueur.

Pour créer un bundle, vous devez accéder à la section **Economy** de votre titre, comme vous l'avez fait pour créer un nouvel objet. Un onglet appelé **Bundles** s'y trouve, à 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 essentielle que, si vous faites défiler vers le bas, vous trouverez une section intitulée **Items**. Vous pouvez y ajouter les objets que le bundle 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 le bundle. Dès que vous avez sélectionné et ajouté vos objets, vous pouvez cliquer sur **Save and publish** : votre bundle est alors actif et peut être sélectionné dans les magasins comme prix d'achat.

## Étape 5 - Créer un magasin

Dans 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 lieux) : la **Science Machine**, l'**Alchemy Engine** et la **Kitchen**.

Nous allons nous concentrer sur la **Kitchen**. Ici, les joueurs peuvent acheter une **Ice Cream** (nouvel objet à créer) au prix d'**1 Cream** et d'**1 Icebox** (nouvel objet à créer). Ce cas particulier a été choisi parce qu'il montre comment les **bundles** fonctionnent avec les magasins et les transactions.

Les magasins ne peuvent être créés qu'à partir de [Game Manager](https://developer.playfab.com) en accédant à la section **Economy** dans la barre de navigation de gauche, puis, parmi les différents onglets, en choisissant **Stores** et en sélectionnant 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 bundle à un magasin

Maintenant que votre bundle et votre magasin sont créés et publiés, vous pouvez ajouter le bundle en tant qu'objet pouvant être renvoyé 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, tels que **Items**, **UGC Items**, **Bundles** et **Subscription**. Si vous choisissez **Bundles**, la liste est filtrée pour n'afficher que les objets de type bundle ; vous devriez y voir le bundle créé précédemment. Une fois que vous avez sélectionné le bouton **Add** à côté du nom du bundle, puis le bouton **Add** en bas de la fenêtre, le bundle est ajouté en tant qu'objet de transaction possible pour ce magasin.

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

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

## Étape 7 - Acheter un bundle

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

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

### API

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

```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 correspond au 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. En effet, la propriété `DeleteEmptyStacks` est traitée comme une transaction supplémentaire. Dans l'exemple précédent, la transaction 212 correspond à l'achat du bundle, et la transaction 213 à la suppression de la pile de Cream vide (en supposant que vous n'aviez qu'1 Cream dans votre inventaire).
</Note>

### SDK C\#

Pour ce qui est de l'apparence 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/services/playfab/economy-monetization/economy-v2/overview)
* [Paramètres](/fr/services/playfab/economy-monetization/economy-v2/settings)
* [Magasins Economy v2](/fr/services/playfab/economy-monetization/economy-v2/catalog/stores#creating-a-store)


## Related topics

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