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

# 管理 External Reference ID

**External reference ID** 是你為 Fluz 使用者設定的自有識別碼。它讓你能用系統中已存在的 ID 來操作 Fluz API——而不必為每位使用者儲存或傳遞 Fluz 的內部 `userId` 與 `accountId`。

當使用者授權你的應用程式時，你會將自己的識別碼附加到該授權上。Fluz 會儲存你的識別碼與該使用者的 Fluz 帳戶之間的配對關係，且侷限於你的應用程式範圍內。從此之後，你在產生權杖、發送轉帳，以及對應 webhook 事件時，都可以用你自己的 ID 來引用該使用者。

> 📘 **你會在哪裡看到它**
>
> 此欄位在 OAuth 授權 URL 中為 `external_id`，在 GraphQL API 與 webhook 負載中為 `externalReferenceId`。它們代表相同的值。

## 它可以是什麼？

| Property   | Rule                                                                                       |
| ---------- | ------------------------------------------------------------------------------------------ |
| Type       | 任何字串。Fluz 不強制格式。                                                                           |
| Uniqueness | 在**你的應用程式內**必須對每位使用者唯一。一個 external reference ID 只對應到一位 Fluz 使用者。                           |
| Scope      | 侷限於你的 OAuth 用戶端。相同的 Fluz 使用者在其他開發者的應用程式中可以擁有不同的 external reference ID，而其他應用程式無法看見或使用你的 ID。 |
| Stability  | 視為不可變。請使用你的系統中的穩定識別碼——例如內部使用者 ID 或 UUID。                                                   |

> ⚠️ **請勿使用 PII 作為 external reference ID**
>
> 避免使用電子郵件、電話號碼或姓名。這些可能會隨時間改變，導致對應失效，且不必要地在 URL 與權杖中傳送個資。UUID 或你的資料庫主鍵才是正確選擇。

## 我們在哪裡使用它？

External reference ID 會出現在四個面向：

| Surface                             | Field                             | Direction  |
| ----------------------------------- | --------------------------------- | ---------- |
| OAuth authorization URL             | `external_id` query parameter     | You → Fluz |
| `generateUserAccessToken` mutation  | `externalReferenceId` argument    | You → Fluz |
| Wallet transfers (`createTransfer`) | `destination.externalReferenceId` | You → Fluz |
| Webhook event payloads              | `externalReferenceId`             | Fluz → You |

它也會被嵌入到發給使用者的 OAuth access token 中，因此在更新權杖期間關聯仍會持續存在。

## 我們如何使用它？

### 1. 在 OAuth 授權流程中指定它

當你引導終端使用者前往授權 URL（參見 [Client facing OAuth grant flow](/client-facing-o-auth-grant-flow)），將你的識別碼以 `external_id` 查詢參數附加上去：

```text theme={null}
https://uni.staging.fluzapp.com/authorize?response_type=code&client_id=<CLIENT_ID>&redirect_uri=<REDIRECT_URI>&scopes=MAKE_DEPOSIT%20LIST_PAYMENT&external_id=usr_8f3d2a91
```

當使用者完成授權後，Fluz 會將 `usr_8f3d2a91` 記錄在該使用者對你應用程式的授權上。啟動嵌入式元件時也適用相同參數——請參見 [Widget Overview](/developers/widgets)。

> 🚧 **Widget 應用程式為必填**
>
> 所有 widget 應用程式類型（deposit、payouts、payins、virtual card、gift card catalog、bill pay，以及 external payout widgets）在建立使用者工作階段時都**必須**提供 external reference ID。若遺漏，請求會以 `External reference ID is required for <type> applications` 被拒絕。對於標準 OAuth 應用程式則為選填，但強烈建議提供。

### 2. 用它產生使用者 access token

一旦關聯建立，`generateUserAccessToken` 可接受 `externalReferenceId` 來取代 `userId` 與 `accountId`：

```graphql theme={null}
mutation {
  generateUserAccessToken(
    externalReferenceId: "usr_8f3d2a91"
    scopes: [MAKE_DEPOSIT, LIST_PAYMENT]
  ) {
    token
    refreshToken
    scopes
  }
}
```

如常以你應用程式的 Basic 認證來驗證此呼叫——請參見 [Generate a User Access Token](/recipes/generate-user-access-token)。

你可以同時傳入 `userId`/`accountId` 與 `externalReferenceId`，但它們必須與該 external reference ID 解析出的使用者相符。若不相符，請求將被拒絕。

### 3. 用它指定轉帳的目標

當建立轉帳到另一個 Fluz 錢包時（參見 [Transfer to Another Fluz Account](/features/transfer-to-another-fluz-wallet)），目標可以用 external reference ID 來識別，而不必使用 Fluz 的帳戶 ID：

```graphql theme={null}
mutation {
  createTransfer(input: {
    idempotencyKey: "1f7c5a2e-9b14-4c6d-8e3f-2a90d4b7c1aa"
    amount: 25.00
    destination: { externalReferenceId: "usr_8f3d2a91" }
  }) {
    transferId
  }
}
```

請提供 `destination.accountId` 或 `destination.externalReferenceId` 其中之一——切勿同時提供。目標使用者必須已授權你的應用程式；否則轉帳會被拒絕。

### 4. 將 webhook 事件對應回你的使用者

Webhook 負載包含 `externalReferenceId`，因此你可以將 Fluz 事件與你的使用者紀錄相關聯，而無需維護 Fluz ID 的對照表：

```json theme={null}
{
  "userId": "5070d5a1-d71a-4190-91b0-f116eec51771",
  "accountId": "9c2e1b44-7a3d-4f08-b6e5-d18a3c7f0e22",
  "externalReferenceId": "usr_8f3d2a91",
  "eventType": "DEPOSIT_COMPLETE",
  "amount": 100.00
}
```

關於 webhook 的設定與傳遞細節，請參見 [Configure App Widget](/developers/configure-app-widget)。

> 📘 **隱私注意事項**
>
> 當使用者的授權沒有關聯任何 external reference ID，或事件被標記為私有時，webhook 負載中會省略 `externalReferenceId`。

## 驗證規則與錯誤

| Scenario                                                 | Result                                                                                   |
| -------------------------------------------------------- | ---------------------------------------------------------------------------------------- |
| 權杖請求同時未提供 `externalReferenceId` 與 `userId` + `accountId` | `Provide either externalReferenceId or both userId and accountId.`                       |
| 在你的應用程式範圍內找不到 `externalReferenceId`                      | `No user found with externalReferenceId <value>.`                                        |
| 與 `externalReferenceId` 一同提供的 `userId` 指向不同使用者           | `Provided userId does not match the user associated with the externalReferenceId.`       |
| 與 `externalReferenceId` 一同提供的 `accountId` 指向不同帳戶         | `Provided accountId does not match the account associated with the externalReferenceId.` |
| 轉帳目標同時提供 `accountId` 與 `externalReferenceId`             | `Provide either destination.accountId or destination.externalReferenceId, not both.`     |
| 轉帳目標使用者未授權你的應用程式                                         | `Destination account has not authorized this application.`                               |
| 未提供 external reference ID 即建立 widget session             | `External reference ID is required for <type> applications`                              |

## 為現有授權新增 external reference ID

若使用者在你採用 external reference ID 之前已授權你的應用程式，你可以在後續的授權或權杖請求中提供一個，Fluz 會將它回填到現有的授權上——前提是該授權尚未具有 external reference ID。既有的 external reference ID 永遠不會被覆寫。

## 什麼不是 external reference ID

* 它**不是** Fluz 的 `userId` 或 `accountId`。那些是 Fluz 核發的 UUID；external reference ID 是由你核發。
* 它**不是**在提款紀錄或 API 其他地方之已連結資金來源上出現的 `external_id` 或外部帳戶識別碼。那些是指銀行與處理方的紀錄，而非使用者。\[TBD：請確認這些是否公開於公開綱要中，並是否應在此交互參照]

<StickyContactSalesBanner />

<br />
