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

# Economy v2 中的幂等交易和重试模式

> 在 PlayFab Economy v2 库存写入上使用 IdempotencyId，可以在网络故障后安全地重试并防止重复的购买或授予。

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

网络故障、超时和重复请求在实时游戏中是不可避免的。Economy v2 提供 **IdempotencyId** 以防止重复交易。此功能确保即使同一请求发送多次，操作也只被处理一次。

有关乐观并发控制（确保只有当自你上次读取库存以来库存未更改时写入才成功），请参见 [ETag 和并发控制](/services/playfab/economy-monetization/economy-v2/tutorials/etags-and-concurrency-control)。

## 先决条件

* 一个 [PlayFab 开发者账户](https://developer.playfab.com/en-us/sign-up)。
* 在 [Game Manager](https://developer.playfab.com/) 中创建的 title。
* 至少一个已发布的目录物品和一种虚拟货币。

## 工作原理

当你在库存写入请求中包含 `IdempotencyId` 时，PlayFab 会将该 ID 存储 **14 天**。如果具有相同 `IdempotencyId` 的另一个请求到达，PlayFab 将返回原始请求的结果，而不会再次处理操作。

## 支持的 API

所有库存写入 API 都支持 `IdempotencyId`：

* [AddInventoryItems](https://learn.microsoft.com/en-us/rest/api/playfab/economy/inventory/add-inventory-items)
* [SubtractInventoryItems](https://learn.microsoft.com/en-us/rest/api/playfab/economy/inventory/subtract-inventory-items)
* [PurchaseInventoryItems](https://learn.microsoft.com/en-us/rest/api/playfab/economy/inventory/purchase-inventory-items)
* [TransferInventoryItems](https://learn.microsoft.com/en-us/rest/api/playfab/economy/inventory/transfer-inventory-items)
* [DeleteInventoryItems](https://learn.microsoft.com/en-us/rest/api/playfab/economy/inventory/delete-inventory-items)
* [UpdateInventoryItems](https://learn.microsoft.com/en-us/rest/api/playfab/economy/inventory/update-inventory-items)
* [ExecuteInventoryOperations](https://learn.microsoft.com/en-us/rest/api/playfab/economy/inventory/execute-inventory-operations)

## 示例：带重试的安全购买

在此场景中，玩家购买了一把 Laser Sword。客户端在发送请求之前生成一个唯一的 `IdempotencyId`（例如 GUID）：

```json theme={null}
{
    "Entity": {
        "Type": "title_player_account",
        "Id": "{{PlayerID}}"
    },
    "Item": {
        "Id": "{{LaserSwordID}}"
    },
    "Amount": 1,
    "PriceAmounts": [
        {
            "ItemId": "{{DiamondCurrencyID}}",
            "Amount": 5
        }
    ],
    "IdempotencyId": "b7e3f1a2-9c4d-4e8f-a1b2-3c4d5e6f7a8b"
}
```

如果客户端没有收到响应（例如网络超时），它可以安全地使用相同的 `IdempotencyId` 重试完全相同的请求。PlayFab 识别重复项并返回原始结果。玩家仅被收费一次。

## 最佳做法

* **每个逻辑操作生成一个唯一的 ID** — 使用 GUID 或 UUID。不要为不同的操作重用相同的 ID。
* **在第一次尝试之前在客户端生成 ID** — 此做法确保所有重试使用相同的 ID。
* **不要在重试之间更改请求正文** — 使用相同的 `IdempotencyId` 但不同的请求正文会导致冲突错误。
* **ID 在 14 天后过期** — 之后，相同的 ID 可以再次用于新的操作。

## Redeem API 自动幂等

市场兑换 API（`RedeemAppleAppStoreInventoryItems`、`RedeemGooglePlayInventoryItems`、`RedeemMicrosoftStoreInventoryItems`、`RedeemSteamInventoryItems`）不需要 `IdempotencyId`。它们本质上是幂等的。每个市场收据或令牌只能兑换一次。使用相同收据的第二次调用返回成功，但不授予任何内容。

## 常见场景

| 场景             | 推荐方法                                             |
| -------------- | ------------------------------------------------ |
| 客户端购买（玩家购买物品）  | 在第一次尝试之前生成 GUID，在超时时使用相同的 ID 重试。                 |
| 服务器端奖励授予（任务完成） | 使用从任务和玩家派生的确定性 ID（例如 `questId-playerId`）以防止双重授予。 |
| 市场兑换           | 无需 `IdempotencyId` — 兑换 API 自动幂等。                |

## 另请参阅

* [ETag 和并发控制](/services/playfab/economy-monetization/economy-v2/tutorials/etags-and-concurrency-control)
* [库存概览](/services/playfab/economy-monetization/economy-v2/inventory#idempotency)
* [欺诈防范](/services/playfab/economy-monetization/economy-v2/fraud-prevention)
* [ExecuteInventoryOperations](https://learn.microsoft.com/en-us/rest/api/playfab/economy/inventory/execute-inventory-operations)


## Related topics

- [Economy v2 中的 ETag 和并发控制](/zh-CN/services/playfab/economy-monetization/economy-v2/tutorials/etags-and-concurrency-control.md)
- [Economy v2 中的掉落表和随机战利品](/zh-CN/services/playfab/economy-monetization/economy-v2/tutorials/drop-tables-and-randomized-loot.md)
- [Economy v2 概览](/zh-CN/services/playfab/economy-monetization/economy-v2/overview.md)
- [调用 XBOX 服务的最佳实践](/zh-CN/services/xbox-services/develop/best-practices/live-best-practices-calling-xbl.md)
- [交易](/zh-CN/services/playfab/economy-monetization/economy/trading/index.md)
