# 識別碼 (Identifier) 和 參考 ID (ReferenceId)

*注意：本頁的代碼應視為偽碼 (pseudocode)。有關詳細資訊和完全正确的範例，請參閱說明文件中描述特定功能的頁面。*

## <mark style="color:blue;">重要事項</mark>

* 存款地址會永久映射至其建立時的識別碼 (`identifier`)
* 傳送至此類地址的交易總會包含識別碼 (`identifier`)
* `referenceId` 在存款請求中是可選的。如果您同時管理存款請求，它可以讓您進一步識別用戶存入的是哪筆存款。
  * 注意：`referenceId` 會在 24 小時後過期。存款仍可存入相關地址，但 `referenceId` 將不會出現在回調中。
    * 您可以在[回調設置](https://docs.akashicpay.com/traditional-chinese/yi-biao-ban/kai-fa-zhe#cun-kuan-qing-qiu-you-xiao-qi-xian)中調整此到期時間範圍。
  * 如果您使用相同的識別碼 (`identifier`) 和[網路](https://docs.akashicpay.com/traditional-chinese/jian-jie/shu-yu#wang-lu)新增多個 `referenceId`，只要它們尚未過期，就會依序傳回，最舊的先傳回。(除非使用不同的[請求金額](https://docs.akashicpay.com/traditional-chinese/zhi-nan/yao-qiu-de-jinehe-huo-bi-requested-amount-currency)）
* 在出款請求中，`referenceId` 為必填欄位，可用於識別單筆付款交易。

強烈建議在使用者和存款地址之間保持一對一的對應關係。

#### <mark style="color:blue;">為什麼？</mark>

* 永久分配的存款地址意味著每次啟動存款（或通過某種演算法從預先產生的池中選擇）時都不必創建新的錢包。為一個識別碼 (identifier) 請求一個存款地址後，您知道該識別碼 (identifier) 和地址是永遠相連的，因此不需要再為該識別碼 (identifier) 請求存款地址。如果您仍想檢查地址，AP 只需在資料庫中查找該錢包，而不是在區塊鏈上創建一個新錢包 - 這可能是一個冗長的過程，因此仍然更有效率。
* 如果您管理的是一組用戶，您會更容易追蹤哪個用戶有哪個地址用於存款（因為只有一個，而且總是同一個）。同樣地，您的用戶只需處理一個地址（或確實是每個網絡一個）用於存款，將存款進入錯誤錢包的任何風險降至最低。

## <mark style="color:blue;">詳細說明</mark>

在文件和程式碼中，您會遇到「識別碼」 (identifier)的概念。識別碼 (identifier) 就是唯一識別存款地址。通常，識別碼 (identifier) 會是 userId 或類似的東西，但如何使用則由您決定。

如果您管理存款請求，您可以將您的存款 ID 傳給 「referenceId」，以進一步識別用戶存入的是哪筆存款。

如果您管理出款請求，您可以直接將您的出款 ID 傳給 「referenceId」，它將在回調中作為參考 ID 「referenceId」 返回。

## <mark style="color:blue;">存款</mark>

### <mark style="color:blue;">建立存款地址</mark>

您最先遇到識別碼 (identifier) 的地方通常是為您的軟體[建立錢包](https://docs.akashicpay.com/traditional-chinese/sdk/han-shi-functions/getdepositaddress)（存款地址）時，也許是讓您的某位使用者將資金存入錢包。如果您控制著許多使用者，您很可能會以一些獨特的屬性（例如 ID 或使用者名稱）儲存他們的資料。這可以用來取得存款地址：

```typescript
AkashicPay.getDepositAddress("TRX", "user1");
// -> 'TTVkK6hGoAFhaLh1NTkUDHjcFFXKmWcSdb'
```

回調的地址 (上例中為 TTVkK6hGoAFhaLh1NTkUDHjcFFXKmWcSdb) 現在永久指定給識別碼 `'user1'`。之後任何相同函式 (function) 的回調都會傳回相同的地址：

```typescript
AkashicPay.getDepositAddress("TRX", "user1");
// -> 'TTVkK6hGoAFhaLh1NTkUDHjcFFXKmWcSdb'
```

如果您變更網路或識別碼 (identifier)，自然會得到不同的地址：

```typescript
AkashicPay.getDepositAddress("TRX", "user2");
// -> 'TDkteGBASJSvoHSeAAwej3LAfFLj7zhhaE'

AkashicPay.getDepositAddress("ETH", "user1");
// -> '0x159cA92b12F67E5676d82C238f4906692618A555' (diffrent format on Ethereum)
```

如果您需要將存款對應到您的存款請求，您需要將存款請求 ID 傳給 referenceId

```javascript
AkashicPay.getDepositAddress("TRX", "user2", "order1");
// -> 'TDkteGBASJSvoHSeAAwej3LAfFLj7zhhaE'

AkashicPay.getDepositAddress("ETH", "user1", "order2");
// -> '0x159cA92b12F67E5676d82C238f4906692618A555' (diffrent format on Ethereum)
```

> 請注意，兩次操作均返回相同的地址。目前有兩筆 「訂單」 等待處理，將依建立順序完成。這意味著：首次向錢包存款將觸發回調函式，其中 `"referenceId": "order1"`， 第二次向該地址存款將觸發回調函式，其中`"referenceId": "order2"`此情況假設所有訂單均未過期（預設建立後24小時失效）。

### <mark style="color:blue;">存款回調</mark>

如果我們已經識別為 `user1` 的用戶現在決定向錢包 `TTVkK6hGoAFhaLh1NTkUDHjcFFXKmWcSdb` 入金，您將收到一個[回調](https://docs.akashicpay.com/traditional-chinese/hui-diao/cun-kuan-hui-diao-deposit-callback)到您在 AkashicPay.com 上設定的 URL。回調物件中會有一個標題為識別碼 (`identifier`) 的欄位，其值為 `user1`。這可以讓您輕鬆地將存款與其所屬的用戶相識別。當然，如果您願意的話，也可以將地址 (TTV...) 儲存在資料庫中，然後用它來代替。

如果您在 getDepositAddress 中傳入 `referenceId`，您也會在回調中收到 `referenceId`。

## <mark style="color:blue;">出款/提款</mark>

### <mark style="color:blue;">處理出款（提款）</mark>

對於[出款/提款](https://docs.akashicpay.com/traditional-chinese/sdk/han-shi-functions/ti-kuan-ti-bi-payout)，必須在函式呼叫中包含 `referenceId`。`referenceId` 必須能用來識別該筆付款交易。

```typescript
AkashicPay.payout('tx1', 'TAzsQ9Gx8eqFNFSKbeXrbi45CuVPHzA8wr', '10', 'TRX', 'USDT')

AkashicPay.payout('tx2', 'TAzsQ9Gx8eqFNFSKbeXrbi45CuVPHzA8wr', '5', 'TRX', 'USDT')
```

這將在 Tron (TRX) 網絡上啟動一筆從 AkashicPay 到外部錢包 TAzsQ... 的交易，價值為 10 USDT。由於 AkashicPay 的工作方式，提款可能會從許多錢包中的一個發送。因此，不能保證（事實上，不太可能）取款是從用來存款的相同地址發送的，您絕對不應該相信這一點。

但是，基於上述原因，我們強烈建議存款時不要使用此方法。

### <mark style="color:blue;">出款回調</mark>

當使用上述功能觸發提款時，您將再次收到一個[回調](https://docs.akashicpay.com/traditional-chinese/hui-diao/ti-kuan-ti-bi-hui-diao-payout-callback)到您在 AkashicPay.com 上設置的 URL。當您收到出款回調時，交易已經被確認，並且可以安全地將款項存入用戶的賬號中。

## <mark style="color:blue;">特殊案例</mark>

### <mark style="color:blue;">付款時沒有 referenceId？</mark>

根據您的使用情況，有些情況下可能不需要包含 `referenceId`。例如，向特殊錢包進行內部交易或進行利潤出款時。一般而言，對於這些與任何使用者無關的出款，`referenceId` 基本上是多餘的。但是，我們仍然要求所有交易都要有`referenceId`，以確保所有交易都能被清楚追蹤。這是由於沒有安全的方法來分開兩個交易，否則在技術上有可能同時發生兩個原本相等的交易。因此，我們鼓勵您使用合理的`referenceId` 記錄所有交易。例如：

```typescript
AkashicPay.payout('INTERNAL_TRANSFER', 'TAzsQ9Gx8eqFNFSKbeXrbi45CuVPHzA8wr', '10', 'TRX', 'USDT')

AkashicPay.payout('PROFIT_PAYOUT', 'TDprmTxVAkC7a8RuFNFB3ukysRMeGELXsM', '1000', 'TRX', 'USDT')
```

當然，任何字串參數 (string-argument) 都是允許的，所以如果您絕對確定不想透過`referenceId`來追蹤交易，您可以直接提供任何隨機字串 (string)，然後馬上忘記它：

**注意！**&#x8ACB;勿使用空字串 (string)！

```typescript
AkashicPay.payout('foo', 'TAzsQ9Gx8eqFNFSKbeXrbi45CuVPHzA8wr', '10', 'TRX', 'USDT')

AkashicPay.payout('NaN', 'TAzsQ9Gx8eqFNFSKbeXrbi45CuVPHzA8wr', '10', 'TRX', 'USDT')
```

### <mark style="color:blue;">多個存款地址？</mark>

當然，沒有什麼可以阻止您在系統中為「user1」提供多個存款地址。也許一個地址會用於特別促銷或其他情況。在這種情況下，您可以簡單地做以下事情：

```typescript
AkashicPay.getDepositAddress("TRX", "user1-normal");
// -> 'TDprmTxVAkC7a8RuFNFB3ukysRMeGELXsM'
AkashicPay.getDepositAddress("TRX", "user1-special");
// -> 'TRMzP9A18iQNvaFn33zkhhnN5exmLWZ5Ad'
```

或許您可以將此儲存於您的使用者，例如：

```
{
    userId: 'user1',
    wallets: [{address: 'TDprmTxVAkC7a8RuFNFB3ukysRMeGELXsM',
            identifier: 'user1-normal'},
             {address: 'TRMzP9A18iQNvaFn33zkhhnN5exmLWZ5Ad',
              identifier: 'user1-special'}]
}
```

像往常一樣，任何存入上述兩個地址的存款現在都會返回各自的識別碼 (identifier)。

這是一個展示如何使用 AkashicPay 的範例。但是，我們建議在用戶和存款地址之間始終保持一對一的映射，以獲得最高的效率和最小的混淆可能性。
