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

# 从你的服务管理消耗品产品

> 介绍如何构建一个健壮的系统来在游戏服务上管理消耗品，包括管理已消费物品的用户退款。

对于基于消耗品的经济系统，请使用可信的后端服务来验证和管理交易。服务到服务调用比客户端管理的履约更安全、更可靠，客户端管理可能会受到篡改或网络中断的影响。

本文介绍如何管理消耗品并对退款进行对账，以减少欺诈和收入损失。

若要管理消耗品产品并处理退款，从你的服务调用以下 Microsoft Store API。有关调用与解析结果的具体信息，请参阅相应的文档页面。

| Microsoft Store API                                                                                                   | 功能                                            |
| --------------------------------------------------------------------------------------------------------------------- | --------------------------------------------- |
| [collections.mp.microsoft.com/v8.0/collections/consume](/reference/microsoft-store-apis/xstore-v8-consume)            | 消费或履约用户拥有的消耗品产品。                              |
| [purchase.mp.microsoft.com/v8.0/b2b/orders/query](/reference/microsoft-store-apis/xstore-v8-clawbackv1)               | 购买订单 – 报告用户在过去 90 天内进行的消耗品购买。                 |
| [purchase.mp.microsoft.com/v8.0/b2b/clawback/sastoken](/reference/microsoft-store-apis/xstore-v8-clawbackv2-sastoken) | 提供 SAS 令牌，用于查询 Clawback 事件服务消息队列中与你产品相关的退款事件。 |

<Note>
  **沙盒限制：** 在开发沙盒中消费开发者管理的消耗品产品时，仅支持 XSTS 令牌身份验证。User Store ID 或 Microsoft Entra ID 身份验证不适用于沙盒环境中的开发者管理消耗品消费调用。请据此规划测试。有关更多信息，请参阅 [Consume API 的先决条件部分](/reference/microsoft-store-apis/xstore-v8-consume#prerequisites)。
</Note>

## 使用 Microsoft.StoreServices .NET 库和示例

若要帮助演示本文所述的原理和流程，请参阅 Microsoft.StoreServices 示例，它提供：

* 使用 Microsoft.StoreServices 库管理身份验证并调用 Microsoft Store 服务。
* 用于管理消耗品产品、跟踪待处理消费请求、对已退款的购买进行对账、续订过期的 User Store ID 等的示例逻辑。
* 包含本文中如何为该身份验证方法配置和设置 Microsoft Entra ID 步骤的配置指南。
* [Microsoft.StoreServices (GitHub)](https://github.com/microsoft/Microsoft-Store-Services)
* [Microsoft.StoreServices 示例 (GitHub)](https://github.com/microsoft/Microsoft-Store-Services-Sample)

## 管理消耗品

### 消耗品管理服务的推荐轮廓

使用单一的服务端流程来验证所有权、履约用途并对退款进行对账。以下轮廓保持这些职责明确且重试安全。

| 阶段    | 服务操作                             |
| ----- | -------------------------------- |
| 请求接入  | 接收客户端使用或购买带有消耗品货币的项目的请求。         |
| 身份验证  | 对 Microsoft Store 服务 API 进行身份验证。 |
| 余额检查  | 从商店验证用户对该消耗品产品的余额。               |
| 履约    | 从用户余额中消费或履约所需数量。                 |
| 重试安全  | 跟踪待处理的消费请求，并在响应丢失时安全地重试。         |
| 发放余额  | 将购买产品的余额授予用户账户。                  |
| 记录交易  | 保留与用户相关的消费和授予交易的跟踪数据库。           |
| 客户端响应 | 将交易结果或授予的物品返回给游戏客户端。             |
| 对账    | 处理已退款的消耗品交易并采取纠正措施。              |

### 在你的服务与 Microsoft Store 之间管理用户余额

Store 管理的消耗品产品可以完全在你的游戏服务上管理，方法是从 Microsoft Store 消费任何非零余额。或者，用户的消耗品余额可以通过 Microsoft Store 管理，仅在用于游戏内物品时消费数量。但开发者管理的消耗品产品需要在游戏服务上管理。有关开发者管理与 Microsoft Store 管理的消耗品的更多信息，请参阅[选择合适的产品类型](/publishing/xstore-commerce/xstore-choosing-product-type)。

最常见的方法是在你的服务上跟踪用户的有效货币余额。在这种设计中，你的服务查询非零消耗品余额、消费它们，并将等值的游戏内货币计入用户账户。此流程减少了履约后对商店 API 的重复调用，简化了跨平台的余额处理，并为支持团队提供了余额调整的中心系统。

典型设置：将每个货币层级配置为独立的 Store 管理消耗品，每次购买授予数量 `1`，然后将每个产品映射到其游戏内价值。示例：一个“500 金币”消耗品将商店数量增加到 `1`；消费后，商店数量归为 `0`，你的服务发放 500 金币。

Store 管理的消耗品可以在购买时直接将完整值授予商店数量（例如，每次购买 500）。在该模型中，商店跟踪余额增长，而你的服务在用户在游戏中花费货币时扣除数量。但是，将所有层级作为单一产品 ID 下的 SKU 会限制某些功能，例如分层级的促销定价和 5x5 兑换令牌。请参阅[提供游戏内货币的最佳实践](/publishing/xstore-commerce/xstore-consumables#best-practices-for-offering-in-game-currency)。

### 使用 TrackingId 作为消耗验证的冗余系统

在每个消费请求中包含 `TrackingId`。如果响应丢失，使用相同的 `TrackingId`、用户、`productId` 和数量重试，以确认原始消费是否成功。此重试请求可防止双重发放，同时仍允许安全重试。

以下流程展示了重试安全的消费模式。

产品 A（500 游戏内金币）是一款消耗品，配置为在商店中授予数量 1。

1. 用户购买产品 A，此时调用查询服务时该产品数量为 `1`。
2. 游戏服务通过 Microsoft Store 查询 API 查询用户的消耗品余额，看到用户余额为 `1`。
3. 游戏服务生成 TrackingID，创建消费请求以消费一个产品数量，并将请求信息添加到待处理交易列表。
4. 游戏服务将请求发送到 Microsoft Store 消费 API。
5. 游戏服务未能收到消费 API 响应（网络丢包、服务中断、断电等）。此时，服务无法确认交易是否完成。单独查询库存可能存在歧义，因为用户可能在中断期间重新购买。使用待处理交易列表并使用相同的请求值重试。
6. 游戏服务决定何时应重试已消费的请求。
7. 游戏服务使用相同的用户、ProductId、TrackingId 和数量重新创建消费请求。
8. 游戏服务将请求发送到 Microsoft Store 消费 API。
9. 游戏服务收到请求成功的响应，用户的新余额为 “0”。
10. 游戏服务将 500 金币加到服务端跟踪的用户货币余额中。
11. 游戏服务从待处理交易列表中移除该消费请求，因为该物品已被消费、验证，并在服务上向用户授予了正确的游戏内货币。

### Microsoft Store 消费 API 在验证先前交易请求时的行为

如果请求中带有不同的值，API 会将其视为新的消费请求。

如果 API 检测到使用相同的 `TrackingId`、用户、数量和 `productId` 的重试，则不会二次消费。相反，它会返回带有当前剩余余额的成功响应。由于此行为，只要请求值相同，重放超时请求是安全的。

如果你对消费 API 使用 X-Token 身份验证，只要新的 X-Token 是针对与之前请求相同的 XBOX 用户，就可以更新并获取新的 X-Token。

### 使用 Clawback 事件服务缓解消耗品退货和退款欺诈

为帮助防止消耗品产品的滥用和欺诈性退货或退款，你的服务应使用 Clawback 事件服务。Clawback 可让你的服务在消耗品产品被退货或退款时接收事件。你的服务应从用户账户中移除该消耗品的附加价值。

若要对 Clawback 事件采取行动，请确保在 [collections.mp.microsoft.com/v8.0/collections/consume](/reference/microsoft-store-apis/xstore-v8-consume) 的消费请求中使用 `"includeOrderIds": TRUE` 选项。你的服务应使用以下变量存储 API 响应中的消费交易数据：

| 变量                | 来源                                                                                | 说明                                                                                                                            |
| ----------------- | --------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- |
| `Key / Unique ID` | \[OrderID]:\[LineItemID]:\[ProductID]:\[TrackingId]                               | 包含 `ProductID`，因为捆绑包可以在不同产品间复用同一 `OrderID` 和 `LineItemID`。如果消耗品授予数量大于 `1`，包含 `TrackingId` 以区分各个消费操作。                          |
| `ProductId`       | 消费请求中的 ProductId                                                                  | 由于同一 orderID 和 orderLineItemID 可能在通过捆绑包购买授予的不同产品间共享，你也应跟踪消费物品的 ProductID。                                                     |
| `UserId`          | 你的系统用来标识被授予消耗品价值用户的 UserId                                                        | Clawback 事件不提供 userId，因此你必须在系统中跟踪接收内容的用户，才能采取对账操作。                                                                            |
| `OrderID`         | orderTransactions -> orderId（在 /consume 请求中使用 "includeOrderIds": true 时）          | 用于履约全部或部分消费请求的用户购买订单的 ID。示例：与购物车整体购买相关的 ID。                                                                                   |
| `LineItemID`      | orderTransactions -> orderLineItemId（在 /consume 请求中使用 "includeOrderIds": true 时）  | 代表用户购买订单中用于履约消费请求的唯一产品的 ID。示例：与购买时购物车中唯一物品相关的 ID。                                                                             |
| `Qty`             | orderTransactions -> quantityConsumed（在 /consume 请求中使用 "includeOrderIds": true 时） | 由此特定 OrderId/LineItemId 履约的数量。注意：在标准消耗品配置中应为 1，但如果你的消耗品配置为每次购买授予大于 1 的数量，则可以大于 1。                                             |
| `Status`          | 你系统中该消费交易的当前状态，供自身跟踪                                                              | 有助于你标记消费交易何时与 Clawback 事件对账。也需要用于 Chargeback 和 Chargeback 撤销。例如，如果由于 Chargeback 事件对账导致物品被撤销，则在发生 ChargebackReversal 时可以撤销该操作。 |

尽早设置此跟踪数据库，最好在 Clawback 队列接入之前。早期数据可为你提供未来对账的历史交易，以及衡量 Clawback 处理效果的干净基线。

有关更多信息，请参阅[从你的服务管理退款和拒付](/publishing/xstore-commerce/xstore-managing-refunds)。

## 另请参阅

[商务概述](/publishing/xstore-commerce/xstore-commerce-overview)

[基于消耗品的生态系统](/publishing/xstore-commerce/xstore-consumables)

[从你的服务管理退款和拒付](/publishing/xstore-commerce/xstore-managing-refunds)

[Microsoft Store 服务 API](/reference/microsoft-store-apis/index)

[Microsoft.StoreServices 库 (GitHub)](https://github.com/microsoft/Microsoft-Store-Services)

[Microsoft.StoreServices 示例 (GitHub)](https://github.com/microsoft/Microsoft-Store-Services-Sample)


## Related topics

- [基于消耗品的生态系统](/zh-CN/publishing/xstore-commerce/xstore-consumables.md)
- [为服务到服务身份验证请求 User Store ID](/zh-CN/publishing/xstore-commerce/xstore-requesting-userstoreid.md)
- [选择合适的产品类型](/zh-CN/publishing/xstore-commerce/xstore-choosing-product-type.md)
- [在 PC 上处理商店账号不匹配的场景](/zh-CN/publishing/xstore-commerce/xstore-mismatched-accounts.md)
- [从你的服务管理订阅产品](/zh-CN/publishing/xstore-commerce/xstore-managing-subscriptions.md)
