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

# Authentication & Signature

> Generate request signatures to authenticate and secure QFPay API calls.

All API requests must include a digital signature to ensure authenticity and data integrity.

Unless otherwise specified, include the signature in the HTTP header:

```
X-QF-SIGN: <your_signature>
```

***

## How signature generation works

1. Collect request parameters
2. Sort parameters by name
3. Append your `client_key`
4. Hash the final string
5. Send the signature in the request header

***

## Step 1: Sort parameters

Sort all request parameters by **parameter name** in **ASCII ascending order**.

Example:

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

Sorted result:

```
mchid=ZaMVg12345&txamt=100&txcurrcd=HKD
```

***

## Step 2: Append your client key

Append your secret `client_key` to the end of the string.

If:

```
client_key = abcd1234
```

Result:

```
mchid=ZaMVg12345&txamt=100&txcurrcd=HKDabcd1234
```

***

## Step 3: Hash the string

Hash the final string.

**SHA256 is recommended.**\
**MD5 may be required by certain channels — follow the API specification.**

Example:

```
SHA256("mchid=ZaMVg12345&txamt=100&txcurrcd=HKDabcd1234")
```

***

## Step 4: Add signature to header

Include the hash result in the request header:

```
X-QF-SIGN: <generated_signature>
```

***

## Important Rules

* Sort parameters alphabetically by name.
* Do **not** include empty or null parameters.
* Do **not** include the signature itself in the signing string.
* Parameter names and values are case-sensitive.
* Use UTF-8 encoding when building the string.
* Do not include spaces, line breaks, or extra characters.

<Note>
  Include `mchid` in the signature only if it is part of the request parameters.
</Note>

***

## Example (Node.js)

```javascript 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("&");

const signature = crypto
  .createHash("md5")
  .update(ordered + key)
  .digest("hex")
  .toUpperCase();

console.log(signature);
```

***
