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

# 總覽

> 閱讀商家目錄、理解固定與可變優惠、購買禮品卡並揭示其內容——完整的禮品卡流程，以及每個步驟應閱讀的頁面。

透過 Fluz 購買禮品卡共有四個步驟，每一步都有對應的頁面。這是導覽圖。

<Steps>
  <Step title="尋找優惠">
    取用目錄，或查詢單一商家的最佳費率。→ [閱讀目錄](#reading-the-catalog)
  </Step>

  <Step title="確認可購買的金額">
    固定或可變、現貨或即時產生。→ [固定 vs. 可變](#fixed-vs-variable-offers)
  </Step>

  <Step title="購買">
    一次 mutation、一張卡、一個冪等鍵。→ [購買](#buying-a-card)
  </Step>

  <Step title="揭示">
    取得代碼、PIN 或 URL，並正確呈現。→ [揭示](#revealing-the-card)
  </Step>
</Steps>

<Warning>
  **費率不斷變動。** Fluz 會持續重新定價以提供最佳可用優惠，且你的費率會針對你的帳戶客製化。切勿快取一個費率並稍後再依該費率購買——請在購買前立即重新確認。
</Warning>

***

## 詞彙

本節主要使用五個術語，其中有三個聽起來很像。

| Term                | What it is                                                                        |
| :------------------ | :-------------------------------------------------------------------------------- |
| **Merchant**        | 品牌——Starbucks、Best Buy。具有 `merchantId` 與可讀的 `slug`。                               |
| **Offer**           | 來自該商家的特定可購買優惠，具有自己的 `offerId`。單一商家可有多個。                                           |
| **Offer rate**      | 與優惠綁定的獎勵——現金回饋、加成、可用面額、允許的付款方式。                                                   |
| **Denomination**    | 卡片的票面金額。可從預設清單中選擇，或在一個範圍內任選金額。                                                    |
| **Delivery format** | 卡片的交付方式：`URL`、`CODES`、`PIN_AS_CODE`、`PIN_WITH_URL` 或 `CODE_WITH_PREFIX`。決定你的呈現方式。 |

兩個識別碼容易混淆：`merchantId` 代表品牌，`offeringMerchantId` 代表提供該筆優惠的一方。你會針對 `offerId` 或 `slug` 下單，從不會針對 `merchantId` 下單。

***

## Reading the catalog

三種進入方式，對應三種工作。

| Approach                       | Query                         | Use when                  |
| :----------------------------- | :---------------------------- | :------------------------ |
| **Full catalog**               | `getMerchants`                | 你在建立可瀏覽的店面、同步本地目錄，或跨品牌比較時 |
| **Best rate for one merchant** | `getOfferQuote`               | 你已知道品牌與金額，只想取得今日最佳費率時     |
| **CSV export**                 | Dashboard → **Stores** → 產生匯出 | 做分析、財務，或有人想要試算表時          |

將 `getMerchants` 過濾為僅包含禮品卡：`offerTypes: { giftCardOffer: true, cardLinkedOffer: false }`。卡片連結型優惠會出現在目錄中，但目前透過 API 僅能購買禮品卡與專屬優惠。

<Note>
  **完整目錄是一個快取檔案，每日更新兩次。** `getOfferQuote` 是即時資料。若購買時精準費率很重要——通常都很重要——請在購買前進行報價，而不要信任今天早上的目錄拉取。促銷費率會在兩者中反映，包括促銷期間產生的 CSV 匯出。
</Note>

這兩個查詢都受速率限制，請分頁拉取完整目錄，而非一次請求全部。→ [Get Catalog](/get-catalog) · [Get Gift Card Offers](/get-gift-card-offers) · [Get the Best Offer](/get-best-offer)

### 專屬優惠

費率會依帳戶客製化。若你的帳戶有協議費率，它們會以 `type: "EXCLUSIVE_RATE_OFFER"` 的優惠出現，並帶有 `exclusiveRateId`。在 `purchaseGiftCard` 傳入該 ID 可強制使用該費率；若省略，Fluz 會挑選最佳可用的。

***

## 固定 vs. 可變優惠

這個區別最影響你的建置方式，而且同一個商家可以同時擁有兩種。

<CardGroup cols={2}>
  <Card title="FIXED" icon="lock">
    卡片採用**預設面額**——$25、$50、\$100——必須精確購買其中之一。

    經常由 Fluz 持有的**真實庫存**支撐，因此固定優惠通常具有**更佳的費率與更高的購買上限**。

    庫存是有限的。會售罄。
  </Card>

  <Card title="VARIABLE" icon="sliders-horizontal">
    你可以在**最小/最大範圍內任選金額**，卡片會即時產生。

    沒有庫存可耗盡——供應量實質上不受限。

    通常相較於同品牌的固定優惠，**獎勵費率較低**。
  </Card>
</CardGroup>

實務上的取捨：固定優惠回饋較高但可能在執行中途售罄；可變優惠永遠可用但回饋較低。大量下單通常先吃固定庫存，再退回可變。

### 何處讀取可購買的金額

由兩個欄位決定，且其組合決定哪個欄位包含答案。搞錯的話，你會提交優惠無法兌付的金額。

| `denominationsType` | `hasStockInfo` | Purchasable amounts live in           | Meaning                                |
| :------------------ | :------------- | :------------------------------------ | :------------------------------------- |
| `FIXED`             | `true`         | `stockInfo` → `StockInfoFixedType`    | 具可計數 `availableStock` 的特定面額            |
| `FIXED`             | `false`        | `offerRates.denominations`            | 預設面額，未公開庫存限制                           |
| `VARIABLE`          | `true`         | `stockInfo` → `StockInfoVariableType` | `minDenomination`–`maxDenomination` 範圍 |
| `VARIABLE`          | `false`        | `offerRates.denominations`            | 於公布範圍內任意金額                             |

<Warning>
  `stockInfo` 是一個**聯合型別**。你必須以行內片段查詢**兩種**形態，否則其中一種你會拿不到資料：

  ```graphql theme={null}
  stockInfo {
    ... on StockInfoFixedType    { __typename denomination availableStock }
    ... on StockInfoVariableType { __typename description minDenomination maxDenomination }
  }
  ```

  無論你自以為會拿到哪一種，都要同時包含兩個片段。請參考 [How the GraphQL API works](/concepts/graphql)。
</Warning>

注意，「有庫存資訊」不代表「有可計數的庫存」。在可變優惠上，`stockInfo` 回傳的是一個「範圍」，而非數量。只有 `StockInfoFixedType` 會帶有可遞減的 `availableStock` 數字。

填充 `stockInfo` 需要 Fluz 與供應商確認庫存，而供應商回應時間不一——因此請求該欄位會使查詢較慢。只在你即將據此行動時才請求。→ [Get Inventory on Stocked Offers](/get-inventory)

***

## 購買禮品卡

一個 mutation：`purchaseGiftCard`。三個決策。

### 1. 如何選擇優惠

| You pass                         | Behavior                             |
| :------------------------------- | :----------------------------------- |
| `offerId`                        | **固定鎖定。** 購買該筆優惠本身。若售罄則呼叫失敗——不會自動退回。 |
| `merchantSlug`                   | **自動選擇。** 購買該品牌的最佳可用費率，並隨庫存變化自動退回。   |
| `merchantSlug` + `minRewardRate` | 具**底線**的自動選擇。寧可失敗也不會低於你的最低費率購買。      |
| `exclusiveRateId`                | 強制採用特定的協議費率。                         |

固定鎖定可讓你確定費率；自動選擇可讓你確保成交。`merchantSlug` + `minRewardRate` 是折衷，通常是自動化下單的預設正解。

### 2. 如何付款

至少需要一種資金來源，你可以把 Fluz 餘額與另一來源併用。

| Field                                            | What it does                |
| :----------------------------------------------- | :-------------------------- |
| `balanceAmount`                                  | 從你的 Fluz 餘額支付的**金額**        |
| `userCashBalanceId`                              | 該餘額所屬的**消費帳戶**              |
| `bankCardId` / `bankAccountId` / `paypalVaultId` | 外部資金來源                      |
| `defaultToBalance`                               | 若其他方式失敗，是否退回使用餘額。預設為 `true` |

<Warning>
  **若你的帳戶持有多個消費帳戶，請一律明確傳入 `userCashBalanceId`。** 若省略，Fluz 會從被標記為 `isDefault` 的任一帳戶扣款——該標記可能在你的程式碼不變的情況下被更動，默默改變資金來源。這是最常見的「餘額不足」驚訝來源。

  在自動化流程中，也請設定 `defaultToBalance: false`，以便購買要嘛只從你指定的帳戶扣款，要嘛乾脆明確失敗。
</Warning>

### 3. 冪等性

`idempotencyKey` 為必填，這是重試與重複購買的分水嶺。每張預期購買的卡片一個鍵，重試同一張卡時重用同一個鍵。→ [Idempotency](/docs/idempotency-requests)

→ [Purchase Gift Card](/purchase-gift-card)

### 一次購買多張

**一次呼叫只會購買一張卡**、對應一個優惠、以一個費率。沒有數量欄位，也不會跨優惠混購。要十張，就送十次呼叫，使用十個不同的冪等鍵。

當你超過庫存時會發生什麼，取決於你如何選擇優惠：

* **固定鎖定（`offerId`）**——一旦庫存型優惠售罄，剩餘呼叫全部失敗。不會自動退回。
* **自動選擇（`merchantSlug`）**——剩餘呼叫會轉往次佳優惠，通常是費率較低的可變優惠，除非被 `minRewardRate` 阻擋。

→ [Purchase in Bulk](/purchase-in-bulk)

### 大量下單

針對同一個 Fluz 帳戶的購買會**依序**處理。若一次發送大量批次，呼叫會彼此排隊，有時需要數分鐘才回應。

<Note>
  **用戶端逾時不等於取消。** 即使你不再等待，Fluz 仍會持續處理該請求。請將逾時視為「未知結果」，而非失敗。

  解法是使用**相同**的 `idempotencyKey` 重新嘗試——若原始購買已成功，重試會回傳同一結果，且不會重複扣款。為已嘗試過的購買換一個新鍵，正是造成重複下單的作法。

  將用戶端逾時設為約一分鐘，以波段節奏送出請求而非一次全發，並將重量級流量分散到多個帳戶。
</Note>

***

## 揭示卡片

購買會給你一個 `giftCardId`。兌換細節透過第二次呼叫取得。

<Steps>
  <Step title="取得禮品卡">
    若剛完成購買且已持有 `giftCardId`，可略過此步。否則 `getGiftCards` 會列示它們，並附帶 `purchaseId`、`purchaseDisplayId`、`purchaseValue`、`currentValue` 與 `status`——足以在不揭示每張卡的情況下進行對帳。
  </Step>

  <Step title="揭示它">
    `revealGiftCardByGiftCardId` 會回傳 `code`、`pin`、`url` 與 `termsAndConditions`。
  </Step>
</Steps>

三件常見的踩雷點：

* **不是每張卡都有三個欄位。** 有些商家只發一組代碼、沒有 PIN；有些只發 URL。Fluz 會原樣轉交商家提供的內容——請處理 null。
* **依 `deliveryFormat` 與 `barcodeType` 呈現，** 且 `deliveryFormat` 要從 `getGiftCards` 取得，而不是從商家目前的優惠。優惠會變；卡片是依購買當下生效的格式發行。`barcodeType` 可能是 `NONE`、`C128`、`PDF417` 或 `QRCODE`；當為 `NONE` 時，考慮改顯示 `faceplateUrl`。
* **細節可能不會即時就緒。** 請以指數退避輪詢——300ms 起跳、每次加倍、上限三分鐘——並在細節回來時立即停止。

→ [View Gift Cards](/view-gift-card)

***

## 權限範圍

| Scope               | Needed for                        |
| :------------------ | :-------------------------------- |
| `LIST_OFFERS`       | `getMerchants`、`getOfferQuote`    |
| `PURCHASE_GIFTCARD` | `purchaseGiftCard`                |
| `REVEAL_GIFTCARD`   | `revealGiftCardByGiftCardId`      |
| `LIST_PURCHASES`    | `getUserPurchases`、購買歷史           |
| `LIST_PAYMENT`      | `getUserCashBalances`、`getWallet` |

請先在你的應用程式的 **Permissions** 分頁啟用這些權限再開始開發。你請求但未啟用的 scope 會被靜默移除。→ [Configure OAuth App](/configure-o-auth-app)

***

## 當事情失敗時

| Code      | Meaning               |
| :-------- | :-------------------- |
| `GC-0002` | 購買金額或 Fluz Pay 金額不是正數 |
| `GC-0003` | 無法取得禮品卡紀錄             |
| `GC-0004` | 購買失敗——請嘗試其他付款方式       |
| `GC-0006` | 無法揭示卡片                |

完整清單：[Gift Card Error Codes](/gift-card-error-codes)。

在對終端使用者進行退款之前（針對失敗或逾時的購買），**請使用相同的 `idempotencyKey` 重試，或以 ID 查詢該筆購買。** 逾時的請求常常其實已成功，而代碼會在購買被退款之前一直可揭示。

***

## 下一步

<CardGroup cols={2}>
  <Card title="取得目錄" icon="list" href="/get-catalog">
    拉取商家與其優惠。
  </Card>

  <Card title="取得最佳優惠" icon="badge-percent" href="/get-best-offer">
    單一商家與金額的即時報價。
  </Card>

  <Card title="取得庫存" icon="package" href="/get-inventory">
    固定且有庫存的優惠之存量。
  </Card>

  <Card title="購買禮品卡" icon="shopping-cart" href="/purchase-gift-card">
    完整的 mutation。
  </Card>

  <Card title="批次購買" icon="layers" href="/purchase-in-bulk">
    大量下單與售罄時的行為。
  </Card>

  <Card title="檢視禮品卡" icon="eye" href="/view-gift-card">
    揭示代碼、PIN 與 URL。
  </Card>
</CardGroup>
