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

# 驗證與簽章機制

> 產生請求簽章以驗證並保護 QFPay API 呼叫安全性。

所有 API 請求皆必須包含數位簽章，以確保請求來源的真實性與資料完整性。

除非 API 文件另有說明，簽章應放置於 HTTP Header 中：

```http HTTP theme={null}
X-QF-SIGN: <your_signature>
```

***

## 簽章產生流程說明

簽章產生流程如下：

1. 收集所有請求參數
2. 依參數名稱排序
3. 在字串尾端附加 `client_key`
4. 對最終字串進行雜湊（Hash）
5. 將簽章結果加入 HTTP Header

***

## 步驟 1：排序參數

將所有請求參數依 **參數名稱（Parameter Name）** 以 **ASCII 升冪排序**。

範例：

| Parameter | Value      |
| --------- | ---------- |
| mchid     | ZaMVg12345 |
| txamt     | 100        |
| txcurrcd  | HKD        |

排序後組合為：

```text TEXT theme={null}
mchid=ZaMVg12345&txamt=100&txcurrcd=HKD
```

***

## 步驟 2：附加 client\_key

將您的 `client_key` 直接附加在字串最後（不加符號）。

假設：

```text TEXT theme={null}
client_key = abcd1234
```

則最終字串為：

```text TEXT theme={null}
mchid=ZaMVg12345&txamt=100&txcurrcd=HKDabcd1234
```

***

## 步驟 3：進行雜湊

對最終字串進行雜湊計算。

* 建議使用 **SHA256**
* 某些支付通道可能要求 **MD5**，請依 API 規範為準

範例：

```text TEXT theme={null}
SHA256("mchid=ZaMVg12345&txamt=100&txcurrcd=HKDabcd1234")
```

***

## 步驟 4：加入簽章至 Header

將雜湊結果加入請求 Header：

```http HTTP theme={null}
X-QF-SIGN: <generated_signature>
```

***

## 重要規則

* 必須依參數名稱進行 ASCII 升冪排序
* 不可包含空值（null 或空字串）參數
* 不可將簽章欄位本身納入簽章字串
* 參數名稱與數值皆區分大小寫
* 建立簽章字串時請使用 UTF-8 編碼
* 不可加入空白、換行或額外字元

<Note>
  僅當 `mchid` 為請求參數之一時，才需納入簽章計算。
</Note>

***

## 範例（Node.js）

```javascript Node.js theme={null}
const crypto = require("crypto");

const payload = {
  txamt: "10",
  txcurrcd: "HKD"
};

const key = "client_key_here";

// 排序並組合參數
const ordered = Object.keys(payload)
  .sort()
  .map(k => `${k}=${payload[k]}`)
  .join("&");

// 產生簽章（此範例使用 MD5）
const signature = crypto
  .createHash("md5")
  .update(ordered + key)
  .digest("hex")
  .toUpperCase();

console.log(signature);
```
