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

# 快速入门

> PlayFab Economy v2 快速入门，用于设置 Catalog v2、配置权限、添加物品并在 Game Manager 中启用收据验证。

# 目录 v2 快速入门

<Info>
  Economy v2 现已正式发布。如需支持和反馈，请访问 [PlayFab 论坛](https://community.playfab.com)。
</Info>

熟悉 Game Manager 后，你可以：

1. 设置 v2 目录的权限、设置和物品。
2. 设置收据验证
3. 演示购买物品

有关 Unity 的详细演练，请参见 [Unity 特定教程](/services/playfab/economy-monetization/economy-v2/tutorials/getting-started-with-unity-and-android)。

## 第 1 部分：目录概览

### 步骤 1 – 获取权限

第一步是在 Game Manager UI 中的 ⚙️ **Title Settings** > **Economy (V2)** 下的设置页面中启用目录。你可以使用 `UpdateCatalogConfig` API 并将 `IsCatalogEnabled` 标志设置为 true。

要与目录交互，你要么需要登录 GameManger 并使用站点工具，要么获取用于使用 API 的实体令牌。获取实体令牌的最简单方法是使用 [GetEntityToken](https://learn.microsoft.com/en-us/rest/api/playfab/authentication/authentication/get-entity-token) API。

<Note>
  要以管理员或授权服务身份调用 API（在创建第一个目录物品之前需要执行此操作），你需要包含带有 title secret key 的 X-SecretKey 头。你可以在 Game Manager UI 中的 ⚙️ **Title Settings** > **Secret Keys** 下创建 title secret key。
</Note>

#### API

```bash theme={null}
curl \
  -H "X-SecretKey: {{SecretKey}}" \
  -H "Content-Type: application/json" \
  -X POST https://{{titleId}}.playfabapi.com/Authentication/GetEntityToken \
  -d "{\"CustomTags\": {\"user\": \"{{email}}\"}}"
```

#### C# SDK

```csharp theme={null}
// ENABLE_PLAYFABSERVER_API symbol denotes this is an admin-level game server and not a game client.
private static async Task PlayFabEconomyv2QuickStart()
{
#if ENABLE_PLAYFABSERVER_API
    string systemGUID = Environment.GetEnvironmentVariable("SYSTEM_GUID", EnvironmentVariableTarget.Process);
    PlayFabSettings.staticSettings.DeveloperSecretKey =
        Environment.GetEnvironmentVariable("PLAYFAB_SECRET_KEY", EnvironmentVariableTarget.Process);

#endif
    PlayFabSettings.staticSettings.TitleId =
        Environment.GetEnvironmentVariable("PLAYFAB_TITLE_ID", EnvironmentVariableTarget.Process);
    PlayFab.EconomyModels.EntityKey gameEntityKey = new()
    {
        Type = "title",
        Id = PlayFabSettings.staticSettings.TitleId
    };

    PlayFabResult<GetEntityTokenResponse> gameTokenRequest = null;
    try
    {
        gameTokenRequest = await PlayFabAuthenticationAPI.GetEntityTokenAsync(new GetEntityTokenRequest()
        {
            CustomTags = new Dictionary<string, string>
            {
#if ENABLE_PLAYFABSERVER_API
                { "server", systemGUID }
#endif
            }
        });
        if (gameTokenRequest.Error != null)
        {
            throw new Exception(gameTokenRequest.Error.GenerateErrorReport());
        }
    }
    catch (Exception e)
    {
        Console.WriteLine(string.Format("PlayFab Auth Error: {0}", e));
        return;
    }

    PlayFabAuthenticationContext gameAuthContext = new()
    {
        EntityToken = gameTokenRequest.Result.EntityToken,
    };
}
```

***

<Tip>
  最佳做法是，在以 Title 的管理员身份调用（即没有来自用户登录的 [SessionTicket](https://learn.microsoft.com/en-us/rest/api/playfab/server/authentication/authenticate-session-ticket)）时，包含一个 *CustomTags* 条目来记录谁在进行调用——无论是你、服务器还是自动脚本。这使得在查询你的 PlayFab 日志时更容易跟踪更改和识别问题。
</Tip>

### 步骤 2 - 配置目录设置

[目录设置](/services/playfab/economy-monetization/economy-v2/settings) 包括许多不同的配置，从内容类型到用户生成的内容。你可以通过 API 更新和检索它们，并在 Game Manager 中轻松可视化其中许多设置。

#### Game Manager

1. 在 [Game Manager](/services/playfab/live-service-management/gamemanager) 中，导航到 ⚙️ **Title Settings** > **Economy**。
2. 在 **Catalog (V2)** 选项卡下，转到 **Catalog Settings**
3. 创建默认的 *Content Type*（创建"Game Item"类型是一个好的起点）。

#### API

调用 [Catalog/GetCatalogConfig](https://learn.microsoft.com/en-us/rest/api/playfab/economy/catalog/get-catalog-config) 方法，然后 [UpdateCatalogConfig](https://learn.microsoft.com/en-us/rest/api/playfab/economy/catalog/update-catalog-config) 目录 ContentTypes 数组，其中包含一个 Catalog Type。

```bash theme={null}
curl \
  -H "X-SecretKey: {{SecretKey}}" \
  -H "X-EntityToken: {{EntityToken}}" \
  -H "Content-Type: application/json" \
  -X POST https://{{TitleId}}.playfabapi.com/Catalog/GetCatalogConfig \
  -d "{\"CustomTags\": {\"user\": \"{{Email}}\"}}"

curl \
  -H "X-EntityToken: {{EntityToken}}" \
  -H "Content-Type: application/json" \
  -X POST https://{{TitleId}}.playfabapi.com/Catalog/UpdateCatalogConfig \
  -d "{\"Config\": {{{CatalogConfig}}}, \"CustomTags\": {\"user\": \"{{Email}}\"}}"
```

具有 Catalog 和 UGC 的一些内容类型的 title 的示例返回负载：

```json theme={null}
{
    "code": 200,
    "status": "OK",
    "data": {
        "Config": {
            "IsCatalogEnabled": true,
            "AdminEntities": [...],
            "Catalog": {
                "ContentTypes": [
                    "gameitem",
                    "enemy",
                    "weapon",
                    "armor",
                    "levelupstats"
                ],
                "Tags": [...]
            },
            "DeepLinkFormats": [],
            "DisplayPropertyIndexInfos": [
                {
                    "Name": "TestSearchable",
                    "Type": "SearchString"
                }
            ],
            "ReviewerEntities": [],
            "UserGeneratedContent": {
                "ContentTypes": [
                    "weapon",
                    "armor"
                ],
                "Tags": [...]
            },
            ...
        }
    }
}
```

***

### 步骤 3 - 将物品发布到目录

#### GameManager

导航到 **Economy** > **Catalog (V2)**。

在 **Items** 选项卡下，选择 **New Item**。

填写所需的元数据——只有四个必需属性（*Creator Type*、*Title*、*Start date* 和 *Content type*）。选择 **Publish**。

<Tip>
  Creator Type 默认为"title"——尽管在某些情况下玩家可能会为你的游戏创建物品。在这种情况下，你会选择"title\_player\_account"。带有 *Edit JSON* 选项的字段由元数据（例如本地化语言）键入，默认为"neutral"。所有日期都是 UTC。
</Tip>

```json theme={null}
{
  "NEUTRAL": "My Game Item",
  "en-US": "My Game Item"
}
```

#### API

通过调用 [CreateDraftItem](https://learn.microsoft.com/en-us/rest/api/playfab/economy/catalog/create-draft-item) 端点创建"Draft"目录物品：

* 在 X-EntityToken 头中的 EntityToken（来自 GetEntityToken 或其他 PlayFab `login` 调用）
* 物品 CreatorEntity.Id 中的 PlayFab Title ID

```bash theme={null}
curl \
  -H "X-EntityToken: {{EntityToken}}" \
  -H "Content-Type: application/json" \
  -X POST https://{{TitleId}}.playfabapi.com/Catalog/CreateDraftItem \
  -d "{{Data}}"
```

Data:

```json theme={null}
{
  "Item": {
    "CreatorEntity": {
      "Id": "{{TitleID}}",
      "Type": "title"
    },
    "Type": "catalogItem",
    "ContentType": "gameitem",
    "Title": {
      "NEUTRAL": "My Amazing Fire Sword",
      "en-US": "My Lit Lit Sword"
    },
    "StartDate": "2023-07-27T00:00:00.000Z",
    "Tags": [
      "weapon"
    ]
  },
  "Publish": true,
  "CustomTags": {
    "user": "{{Email}}"
  }
}
```

#### C# SDK

```csharp theme={null}
private static async Task PlayFabEconomyv2QuickStart()
{
    // Continued from above example...
    CreateDraftItemRequest gameFireItem = new()
    {
        AuthenticationContext = gameAuthContext,
        Item = new CatalogItem()
        {
            CreatorEntity = gameEntityKey,
            Type = "catalogItem",
            ContentType = "gameitem",
            Title = new Dictionary<string, string>
            {
                { "NEUTRAL", "My Amazing Fire Sword" },
                { "en-US", "My Lit Lit Sword" }
            },
            StartDate = DateTime.Now,
            Tags = new List<string>
            {
              "weapon"
            }
        },
        Publish = true,
        CustomTags = new Dictionary<string, string>
        {
            { "server", systemGUID }
        }
    };
    PlayFabResult<CreateDraftItemResponse> gameDraftItemResponse = null;
    try
    {
        gameDraftItemResponse = await PlayFabEconomyAPI.CreateDraftItemAsync(gameFireItem);
        if (gameDraftItemResponse.Error != null)
        {
            throw new Exception(gameDraftItemResponse.Error.GenerateErrorReport());
        }
    }
    catch (Exception e)
    {
        Console.WriteLine(string.Format("PlayFab CreateDraftItem Error: {0}", e));
        return;
    }
    Console.WriteLine(string.Format("PlayFab CreateDraftItem Success: {0}",
        JsonConvert.SerializeObject(gameDraftItemResponse.Result, Formatting.Indented)));
}
```

***

<Note>
  将物品置于 Draft 状态不是必需的——Draft 意味着当你希望在某段时间内迭代元数据时使用。我们支持参数"publish"，当设置为"true"时，将立即发布该物品。根据你的模式，这可能会为你节省一些调用量。
</Note>

一旦物品处于 Draft 状态，你就可以使用 [PublishDraftItem](https://learn.microsoft.com/en-us/rest/api/playfab/economy/catalog/publish-draft-item) 端点将其推送到"Published"状态（此步骤在 GameManager 中不可见处理）。物品发布后，就可以搜索并公开可用。你需要使用从 CreateDraftItem 响应返回的 ItemId 才能发布。

### 步骤 4 - 进行搜索

发布调用成功后，可以使用先前发布的 ItemId 和 [SearchItems](https://learn.microsoft.com/en-us/rest/api/playfab/economy/catalog/search-items) 端点搜索该物品。Catalog/Search API 使用提供给 API 的一组参数对已发布的目录执行搜索，返回一组分页结果。

#### Game Manager

Game Manager 搜索是不言自明的，并且存在于每个 Catalog v2 页面上。*Published* 和 *Draft* 过滤器在顶部。选择 *Search* 按钮旁边的 *Filters (Funnel)* 图标以查看过滤器列表。选择 `Enter ODATA filter` 来添加 OData 过滤器。

#### API

```bash theme={null}
curl \
  -H "X-EntityToken: {{EntityToken}}" \
  -H "Content-Type: application/json" \
  -X POST https://{{TitleId}}.playfabapi.com/Catalog/SearchItems \
  -d "{{Data}}"
```

```json theme={null}
{
  "Search": "Fire",
  "Filter": "tags/any(t:t eq 'desert') and contentType eq 'gameitem'",
  "OrderBy": "lastModifiedDate asc",
  "ContinuationToken": "abc=",
  "Count": 2
}
```

保存返回的 ID，供本快速入门稍后使用。

***

<Note>
  Catalog/search 的 filter、orderBy 和 select 字段使用 [OData](https://learn.microsoft.com/en-us/odata/concepts/queryoptions-overview) 作为查询标准。
</Note>

## 第 2 部分：库存和虚拟货币概览

库存物品和虚拟货币是 PlayFab 为玩家实体支持的两个游戏内虚拟商品"桶"。过程为：

1. 设置初始虚拟货币
2. 创建带有虚拟货币成本的物品
3. 将物品添加到玩家的库存

### 步骤 1：创建货币

虚拟货币是游戏内经济的基础。可以向玩家和角色授予这些货币，然后可以用来购买或交易物品。

物品可以以虚拟货币或真钱为成本。每个游戏可以支持多种任意虚拟货币。货币为你的游戏提供了实现你所需的任何交换媒介的灵活性（例如，金币、宝石、心或星际信用点数）。

#### Game Manager

1. 打开 Game Manager 并转到 **Economy** > **Catalog (V2)**。
2. 选择 **Currency** 选项卡。
3. 选择 **New Currency**，设置 *Start date*、用于"neutral"键的可读 *Title*，并在 *Friendly ID* 字段中输入此货币的唯一货币代码。
4. 选择 **Save as draft**。物品 ID 用作草稿货币代码。
5. 通过在货币列表中单击选择 **Draft** 过滤器来查看你的新货币。
6. 再次编辑货币并选择 **Save and publish**。Friendly ID 用作已发布货币代码。

#### API

通过调用类型设置为"currency"的 [CreateDraftItem](https://learn.microsoft.com/en-us/rest/api/playfab/economy/catalog/create-draft-item) 端点，使用以下内容创建草稿货币目录物品：

* 具有目录权限的 EntityToken
* Entity.Id 作为物品"Creator"
* PlayFab Title ID
* 物品应为"Currency"类型的捆绑包，包含 Title 和 Description

使用从 CreateDraftItem 返回的 ItemId 调用 PublishItem。

```bash theme={null}
curl \
  -H "X-EntityToken: {{EntityToken}}" \
  -H "Content-Type: application/json" \
  -X POST https://{{TitleId}}.playfabapi.com/Catalog/CreateDraftItem \
  -d "{{Data}}"
```

Data:

```json theme={null}
{ 
  "Item": {
    "CreatorEntity": {
      "Id": "{{TitleID}}",
      "Type": "title"
    },
    "Type": "currency",
    "ContentType": "gameitem",
    "AlternateIds": [
      { 
        "Type": "FriendlyId",
        "Value": "TC"
      } 
    ],
    "Title": {
      "NEUTRAL": "My Amazing Test Currency",
      "en-US": "My Test Coin"
    },
    "StartDate": "2023-07-27T00:00:00.000Z"
  },
  "Publish": true,
  "CustomTags": {
    "user": "{{Email}}"
  }
}
```

***

<Tip>
  对类型为"currency"的 Catalog/Search 将返回你定义的所有货币。
</Tip>

### 步骤 2 - 授予货币

#### Game Manager

你的实体玩家需要虚拟货币才能进行购买。

1. 打开 GameManager，导航到 Players，然后选择 **Search** 以检索玩家列表。
2. 选择你要授予货币的 Player ID。
3. 选择 **Inventory (V2)** 选项卡。
4. 过滤到"Currency" **Type** 并选择 **Pick multiple items** 以查看完整的货币列表。
5. 选择你创建的 *Currency* 并为实体 *Player* 输入新的数量。
6. 选择 **Save**。

<Warning>
  暴露玩家货币授予的页面目前不在 GameManager 中。
</Warning>

#### API

你可以调用 [AddInventoryItems](https://learn.microsoft.com/en-us/rest/api/playfab/economy/inventory/add-inventory-items) 向实体钱包添加货币。默认情况下，你需要使用 Title Level Entity Auth 任意地向玩家的库存中添加虚拟货币。

***

<Note>
  *AddInventoryItems* 被认为是 Title 管理员调用，通常不是游戏客户端直接调用的内容。
</Note>

### 步骤 3 - 更新目录物品

物品必须具有货币值，才能使用虚拟货币购买。

#### GameManager

1. 打开 Game Manager 并导航到 **Economy**。
2. 选择 **Catalog (V2)** 选项卡，并确保你已过滤到 **Published** 物品。
3. 选择你之前创建的物品的标题。
4. 选择 **Edit draft item**。
5. 选择 **➕ Add new price** 并通过选择你创建的 Currency 物品来设置 *Amount*。选择 **Add** 以完成。
6. 选择 **Save and Publish**。

#### API

通过调用 [GetDraftItem](https://learn.microsoft.com/en-us/rest/api/playfab/economy/catalog/get-draft-item) 端点获取目录物品的草稿。然后使用 [UpdateDraftItem](https://learn.microsoft.com/en-us/rest/api/playfab/economy/catalog/update-draft-item) 端点更新草稿，使用：

* 在 X-EntityToken 头中的 EntityToken（来自 GetEntityToken 或其他 PlayFab `login` 调用）
* 物品 EntityKey.Id 中来自上一个调用的 Entity.Id

```bash theme={null}
curl \
  -H "X-EntityToken: {{EntityToken}}" \
  -H "Content-Type: application/json" \
  -X POST https://{{TitleId}}.playfabapi.com/Catalog/GetDraftItem \
  -d "{{Data}}"
```

Data:

```json theme={null}
{
  "Id": "{{EntityID}}",
  "CustomTags": {
    "user": "{{Email}}"
  }
}
```

```bash theme={null}
curl \
  -H "X-EntityToken: {{EntityToken}}" \
  -H "Content-Type: application/json" \
  -X POST https://{{TitleId}}.playfabapi.com/Catalog/UpdateDraftItem \
  -d "{{Data}}"
```

```json theme={null}
{
  "Item": {
    "Id": "{{EntityID}}",
    "CreatorEntity": {
      "Id": "{{TitleID}}",
      "Type": "title"
    },
    "Type": "catalogItem",
    "ContentType": "gameitem",
    "Title": {
      "NEUTRAL": "My Amazing Fire Sword",
      "en-US": "My Lit Lit Sword"
    },
    "StartDate": "2023-07-27T00:00:00.000Z",
    "Tags": [
      "weapon"
    ]
    "PriceOptions": {
      "Prices": [
        {
          "Amounts": [
            {
              "ItemId": "{{CurrencyID}}",
              "Amount": 15
            }
          ]
        }
      ]
    }
  },
  "Publish": true,
  "CustomTags": {
    "user": "{{Email}}"
  }
}
```

如果你没有将 `Publish` 设置为 `true`，那么你必须使用 [PublishDraftItem](https://learn.microsoft.com/en-us/rest/api/playfab/economy/catalog/publish-draft-item) 将其推送到已发布状态。物品发布后，就可以搜索并公开可用。你需要使用从 GetDraftItem 响应返回的"itemId"才能发布。

## 另请参阅

* [Economy v2 概览](/services/playfab/economy-monetization/economy-v2/overview)
* [设置](/services/playfab/economy-monetization/economy-v2/settings)
* [商店](/services/playfab/economy-monetization/economy-v2/catalog/stores)


## Related topics

- [Android 快速入门](/zh-CN/services/playfab/sdks/c/quickstart-android.md)
- [iOS 快速入门](/zh-CN/services/playfab/sdks/c/quickstart-ios.md)
- [Linux 快速入门](/zh-CN/services/playfab/sdks/c/quickstart-linux.md)
- [Win32 快速入门](/zh-CN/services/playfab/sdks/c/quickstart-win32.md)
- [GDK 快速入门](/zh-CN/services/playfab/sdks/c/quickstart-gdk.md)
