> ## Documentation Index
> Fetch the complete documentation index at: https://docs.fluz.app/llms.txt
> Use this file to discover all available pages before exploring further.

# 购买礼品卡

一旦确定了您偏好的优惠，使用 `purchaseGiftCard` mutation 来购买礼品卡。此 mutation 需要一个 `PurchaseGiftCardInput` 输入对象。

## 示例 Mutation

以下是开始购买礼品卡的最快方式。您可以从 `UserPurchase` 对象自定义查询。参见 [API 参考](https://storage.googleapis.com/fluz-public-docs/api-reference.html)。

```graphql theme={null}
mutation purchaseGiftCard($input: PurchaseGiftCardInput!) {
  purchaseGiftCard(input: $input) {
    purchaseDisplayId
    purchaseAmount
    giftCard {
      giftCardId
      status
      termsAndConditions
    }
  }
}
```

## 字段

以下字段用于运行此 mutation：

`idempotencyKey` — 必填。由客户端生成的唯一 UUID，确保请求只被处理一次。

`offerId `**或** `merchantSlug` — 必填。使用 [`getOfferQuote`](/get-best-offer) 查询返回的 `offerId` 或 `merchantSlug` 获取最佳优惠。使用 `merchantSlug` 将自动为该商户按最佳费率购买。

`amount` — 必填。您希望购买的礼品卡金额。

***

以下字段二选一即可。您也可以选择将 Fluz 余额与其他资金来源组合支付。

`exclusiveRateId` — 某个专属费率优惠的唯一标识符。提供后，将强制本次购买使用该专属费率；未提供时，系统会自动选择当前可用的最佳费率。在 [`getMerchants`](/get-catalog) 查询的响应中，当您在请求的 `offers` 下提供 `exclusiveRateId` 时，对于类型为 `EXCLUSIVE_RATE_OFFER` 的优惠可以找到 `exclusiveRateId`。

`balanceAmount` — 如果您想使用 Fluz 余额支付礼品卡，请在此处定义余额支付金额。您可以使用 [`getWallet`](/check-account-balance) 查询查看您的余额。

`bankAccountId` — 如果您想用银行账户支付，请定义银行账户 ID。

`bankCardId` — 如果您想用银行卡支付，请定义银行卡 ID。

`paypalVaultId` — 如果您想用 PayPal 账户支付，请定义 PayPal 账户 ID。

`defaultToBalance` — 如果您希望在其他支付方式失败时使用 Fluz 余额作为后备支付方式，请将 `defaultToBalance` 设为 `true`。默认即为 `true`。如果将其改为 `false`，系统将不会尝试使用 Fluz 余额作为备选支付方式。

`minRewardRate` — 当选择 `merchantSlug` 选项时，如果您希望指定可接受的最低奖励费率，请设置此项。

`userCashBalanceId` — 如果您希望指定用于本次购买的现金余额（消费账户），请设置此项。

`memo` — 如果您想为此交易添加备注，请在此处提供自由文本备注。最多 255 个字符。

`transactionCategory` — 如果您想为此交易分类，请提供分类名称。分类会在首次使用时自动创建，并在再次传入相同名称时复用。

`attachmentId` — 如果您想为此交易附加文件，请提供上传端点返回的 ID。参见 [添加费用明细](/features/add-expense-details)。

<Callout icon="📘">
  ### 有关上传附件以及使用备注与类别的完整详情，请参见 [添加费用明细](/features/add-expense-details)。
</Callout>

## PurchaseGiftCardInput

```json theme={null}
{
  "idempotencyKey": "0284be6f-1a69-44f7-9da0-5b5edaf45d19",
  "offerId": "0284be6f-1a69-44f7-9da0-5b5edaf45d19",
  "amount": 987.65,
  "balanceAmount": 123.45,
  "bankAccountId": "0284be6f-1a69-44f7-9da0-5b5edaf45d19",
  "bankCardId": "0284be6f-1a69-44f7-9da0-5b5edaf45d19",
  "paypalVaultId": "0284be6f-1a69-44f7-9da0-5b5edaf45d19",
  "exclusiveRateId": "0284be6f-1a69-44f7-9da0-5b5edaf45d19",
  "merchantSlug": "xyz789",
  "minRewardRate": 5.6,
  "userCashBalanceId": "85de1b3e-4e72-462c-8ed1-a6f4982e22f7"
}
```

## 示例响应

购买完成后，您将获得类似如下的响应：

```json theme={null}
{
  "data": {
    "purchaseGiftCard": {
      "purchaseId": "255f8245-02c7-4817-901e-15fe265f6968",
      "purchaseDisplayId": "1019688",
      "purchaseBankCardId": "255f8245-02c7-4817-901e-15fe265f6968",
      "bankAccountId": "255f8245-02c7-4817-901e-15fe265f6968",
      "purchaseAmount": 123.45,
      "fluzpayAmount": 85.0,
      "seatRewardValue": 0.05,
      "paypalVaultId": "255f8245-02c7-4817-901e-15fe265f6968",
      "createdAt": "2007-12-03T10:15:30Z",
      "giftCard": {
        "giftCardId": "85de8b3e-4e72-462c-8ed1-a6f4982e22f7",
        "purchaserUserId": "85de8b3e-4e72-462c-8ed1-a6f4982e22f7",
        "endDate": "2007-12-03T10:15:30Z",
        "status": "ACTIVE",
        "termsAndConditions": "Except as required by law, Gift Cards cannot be transferred for...",
        "createdAt": "2007-12-03T10:15:30Z",
        "merchant": {
          "merchantId": "85de8b3e-4e72-462c-8ed1-a6f4982e22f7",
          "name": "Starbucks",
          "slug": "starbucks",
          "logoUrl": "https://storage.googleapis.com/.../starbucks-logo.jpg",
          "faceplateUrl": "https://storage.googleapis.com/.../starbucks-faceplate.png",
          "offers": [
            {
              "offeringMerchantId": "85de8b3e-4e72-462c-8ed1-a6f4982e22f7",
              "offerId": "85de8b3e-4e72-462c-8ed1-a6f4982e22f7",
              "type": "GIFT_CARD_OFFER",
              "deliveryFormat": "CODES",
              "barcodeType": "C128",
              "hasStockInfo": false,
              "offerRates": [
                {
                  "maxUserRewardValue": 5.0,
                  "cashbackVoucherRewardValue": 1.0,
                  "boostRewardValue": 0.5,
                  "displayBoostReward": true,
                  "denominations": [25, 50, 100],
                  "allowedPaymentMethods": ["CREDIT_CARD", "PAYPAL"]
                }
              ],
              "denominationsType": "VARIABLE",
              "stockInfo": []
            }
          ]
        }
      }
    }
  }
}
```

<Callout icon="🚧">
  ### **返现费率可能会发生变化。**

  我们尽最大努力始终为客户提供最优优惠。这意味着我们的费率会定期变动。请在购买前务必确认费率。
</Callout>

## 购买多张卡

一次 `purchaseGiftCard` 调用只会购买一张礼品卡、对应一个优惠、按一个费率。没有数量字段，且一次调用不会在多个优惠或费率之间拆分或混合。要购买多张卡，请为每张卡发送一次 mutation，并为每次调用提供唯一的 `idempotencyKey`。

由于每张卡都是一次独立调用，当下单数量超过某个有库存的优惠时，将按每次调用分别处理：

* `offerId `（固定优惠）：一旦该有库存的优惠被售罄，剩余调用将以 `GC-0009` 失败。不会自动回退到其他优惠或费率。
* `merchantSlug `（自动选择）：剩余调用会自动选择下一个可用的更优优惠——通常是奖励率较低的可变优惠——除非 `minRewardRate` 阻止较低费率。

有关逐调用的完整解析、`minRewardRate` 费率下限模式以及 `GC-0009` 响应，请参见 [批量购买](/purchase-in-bulk)。

### 大批量下单：并发、超时与重试

对同一 Fluz 账户进行扣款的购买会被顺序处理。当针对单个账户同时提交大量 `purchaseGiftCard` 调用时，它们会依次排队，单个调用的返回时间可能更长——在高负载下偶尔可达数分钟。未排队的调用通常在数秒内返回。

为在大批量下单时保持可预期的延迟并避免误判失败：

* 控制并发请求节奏。不要一次性对同一账户发起整个批次的请求；请分批次提交，或将量分散到多个账户。这样可保持每次调用的低延迟。
* 使用足够宽松的客户端超时。Fluz 不会在几秒后放弃一笔正在进行的购买——请求可能仍在合法处理中并将返回有效结果。过短的客户端超时（例如 30 秒）可能导致您放弃一笔最终会成功的购买。请将超时时间设置得足够高，以吸收在负载下偶发的多分钟处理。我们建议 1 分钟。
* 客户端超时并非取消。关闭连接不会取消 Fluz 已接受的请求；该请求会继续处理直至完成。将超时视为未知结果，而不是失败。
* 通过使用相同的 `idempotencyKey` 重试来处理超时。用完全相同的请求与相同的 `idempotencyKey` 重新发起。由于该键保证最多处理一次，若原购买已成功，重试将返回原始购买——不会产生重复或第二次扣款。永远不要为已尝试过的购买使用新的 `idempotencyKey`；这么做才会造成重复订单。

<Callout icon="📘">
  ### 如果购买在您这边超时且不确定结果，请使用相同的 `idempotencyKey` 重试，或在退款给终端用户之前通过购买 ID 查询该笔购买。超时的请求在 Fluz 侧往往已成功，且礼品卡代码在退款前仍可被查看。
</Callout>

## 下一步

现在是时候展示礼品卡详情以便使用了。请在此了解如何操作：

[查看礼品卡](/view-gift-card)
