> ## 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 而非供應商，且在三個禮品卡連接器中皆相同。在切換之前請先閱讀此頁面。

## 驗證與帳戶範圍

每個連接器都使用你的 Fluz API 金鑰進行 HTTP Basic 驗證：

```text theme={null}
Authorization: Basic <FLUZ-API-Key>
```

一把金鑰只對應一個 Fluz 帳戶。使用該金鑰下的每筆訂單都由該帳戶出資，且所有讀取範圍也限定於該帳戶。

你的供應商用來在次帳戶間路由的欄位，例如 Tango 的 `accountIdentifier`，在此不會用來選擇次帳戶。若你營運多個帳戶，請為每個帳戶申請一把金鑰。

## 訂單狀態值

訂單上的 `status` 欄位（InComm 為 `OrderStatus`）攜帶的是 Fluz 的值，而非你的供應商的：

| 狀態            | 意義       |
| :------------ | :------- |
| `PENDING`     | 已接受，尚未開始 |
| `IN_PROGRESS` | 正在履行     |
| `COMPLETED`   | 已履行，憑證可用 |
| `FAILED`      | 未履行      |
| `CANCELED`    | 履行前已取消   |

<Callout icon="⚠️">
  你的供應商狀態字串不會沿用。以供應商值撰寫的判斷，例如 `status === "COMPLETE"`，不會匹配 `COMPLETED`。在切換前請更新所有狀態比較。
</Callout>

## 時間

**Tango Card 和 InComm** 以同步方式建立訂單，且總是執行至完成。呼叫在購買完成前不會回傳，可能長達 150 秒，因此請將用戶端的讀取逾時設定高於此值。

**Runa** 預設為非同步。`POST /v2/order` 會立刻回傳 `202` 與參考 ID，你之後再讀取該訂單。傳送 `X-Execution-Mode: sync` 可阻塞至購買完成並取得完整結果，就像 Tango 與 InComm 一樣。

## 讀取訂單

一筆訂單在購買完成後即可讀取。在此之前讀取參考 ID 會回傳錯誤而非擱置中的狀態，因此請將新建立的非同步訂單上出現的錯誤視為仍在處理，並稍後再讀取。

列表端點會在單一回應中回傳該帳戶最近的 100 筆訂單，最新的在最前。

## 錯誤回應

錯誤使用 Fluz 的包覆格式，而非你的供應商錯誤結構：

```json theme={null}
{ "error": "<message>" }
```

| 代碼    | 時機                                                |
| :---- | :------------------------------------------------ |
| `401` | 憑證遺失或無效                                           |
| `429` | 觸發速率限制。內文為 `{ "message": "Rate limit exceeded" }` |
| `500` | 其他所有失敗情況，包括被連接器拒絕的請求                              |

被拒絕的請求與伺服器故障都會回傳 `500`。請讀取 `error` 訊息以區分：若為拒絕，表示請求需要更改；若為故障，則可安全重試。

## 速率限制

每把 API 金鑰與每個來源 IP 各自每秒 20 次請求。超出任一限制將封鎖該金鑰或 IP 10 秒，因此在收到 `429` 後請至少退避該時長。

每把金鑰的限額為共享，因此多台主機使用同一把金鑰會共用同一預算。

## 餘額

餘額讀取會回報你的 API 金鑰所屬 Fluz 帳戶的可用餘額。Tango 回傳為 `currentBalance`，Runa 為 `balance`；InComm 會在 `availableBalance` 之外另外回傳 `prepaidBalance`，其涵蓋禮品卡本身的餘額。

餘額讀取一律限定於你的金鑰所屬帳戶，因此你供應商餘額呼叫中的辨識子不會進一步縮小範圍：Tango 的 `:accountId`、InComm 的 `:programId` 與 Runa 的 `?currency=` 會被接受，以維持你的既有請求結構相容性。

需要注意的一點：帶任何查詢字串的餘額呼叫會回傳單一物件，而不帶查詢字串的呼叫會回傳包含一個元素的陣列。若你的用戶端會對回應呼叫 `.map()`，請不要附帶查詢字串。

## 品牌代碼

三個連接器都會針對同一個 Fluz 目錄解析品牌代碼，無論它們在哪個欄位：Tango 的 `utid`、InComm 的 `Sku`、Runa 的 `items[].products.value`。你的供應商產品代碼不會沿用，且 Fluz 無法識別的代碼會回傳錯誤。

<Callout icon="⚠️">
  在切換前，請將你的完整品牌清單對照 Fluz 目錄進行映射。解析到錯誤 Fluz 方案的代碼會在沒有錯誤的情況下交付錯誤的卡片。
</Callout>

## 請求限制

連接器會接受你的供應商請求結構，但部分值是固定的。違反以下任一項的請求會被拒絕。

| 連接器        | 限制                                                                      |
| :--------- | :---------------------------------------------------------------------- |
| Tango Card | `sendEmail` 必須存在且設定為 `false`                                            |
| Runa       | `payment_method` 必須為 `{ "type": "ACCOUNT_BALANCE", "currency": "USD" }` |
| Runa       | `products.type` 必須為 `SINGLE`                                            |
| Runa       | `items[]` 中的每個項目都必須相同。混合購物籃會被拒絕。請針對每種不同項目分別送出訂單                         |
| InComm     | `Recipients[]` 中只能有一個項目                                                 |
| InComm     | `Products[]` 中只能有一個項目                                                   |
| InComm     | `DeliverEmail` 不得為 `true`                                               |

Fluz 會直接在訂單回應中回傳禮品卡憑證，這也是為何上述電子郵件旗標必須關閉：寄送給收件人的流程仍由你掌控。
