# Signature Validation

The lean.x signature authentication adds an additional security layer for API requests by generating a unique signature for each request. This signature ensures the authenticity and integrity of the requests made to the API. Each signature is valid only for 5 minutes within the timestamp and is tied to the specific API key. Merchants have the **option to enable or disable this feature based on their security needs.**

## **Enable or Disable Feature**

You may find this feature under **API** > **API Key** > **Edit API Key** > **X-Signature**. Refer screen shot below as reference.&#x20;

<figure><img src="/files/NPVBB6kG7ZHlKOz5VLN2" alt=""><figcaption><p>Enabling or Disabling Signature Validation Feature</p></figcaption></figure>

## Flow Process

1. **Message Construction**:
   * When the feature is enabled, the system will automatically authenticate every API request send to the system. The signature will be a concatenation of the following elements in this specific order:
     * **HTTP\_METHOD**: The HTTP method used for the request (GET, POST, PUT, DELETE, PATCH).
     * **UUID**: The unique identifier (UUID) associated with the API key. Can be retrieved from Merchant Portal
     * **URL\_PATH**: The endpoint path of the API request.
     * **TIME\_STAMP**: The current Unix timestamp in seconds.
     * **AUTH\_TOKEN**: The authentication token associated with the API key.Can be retrieved from Merchant Portal
     * **NONCE**: A unique random number or string, typically a UUID4, to ensure the request's uniqueness.
2. **HMAC Generation**:
   * Our system will require your application to generate an HMAC (SHA256) signature of the constructed message using the Hash Key as the **secret key** , which can be retrieved from Merchant Portal. This HMAC output serves as the X-Signature.
3. **Request Header Injection**:
   * The generated X-Signature, along with the timestamp and nonce, is included in the request headers. The headers will include:
     * `x-signature`: The HMAC-SHA256 signature.
     * `x-timestamp`: The Unix timestamp used in the signature.
     * `x-nonce`: The unique nonce used in the signature.
4. **Validation**:
   * On the server-side, the received X-Signature is validated by reconstructing the message and comparing the signature with the one received in the header. If they match, the request is authenticated and processed.

## Sample Header

A typical API request header with HMAC signature with additional header will look like this

```
POST /api/v1/merchant/create-bill-page HTTP/1.1
Host: api.leanx.dev
Content-Type: application/json
auth-token : LP-44D9FDC8-MM|f11bb37b-dc4a-45cf-9607d68f31e96e7c.....
x-signature: 23ef4f5c2683c915902c7b2b4f17ecd82ca66d53ed4ec0552ca3b42e7eeebe82
x-timestamp: 1723540529
x-nonce: 45fe2c14-1905-4617-917b-6c50159a1722
```

This process ensures that each API request is securely authenticated and is valid for a short time, reducing the risk of replay attacks. Merchants should enable this feature to enhance the security of their API transactions.

## Resources

This code snippet collection will help you with HMAC generation from your system

{% tabs %}
{% tab title="Postman Script" %}

```javascript
const CryptoJS = require('crypto-js')

const UUID = pm.environment.get("UUID");
const AUTH_TOKEN = pm.environment.get("AUTHTOKEN");
const HASH_KEY = pm.environment.get("HASHKEY");

// Define the HTTP method and URL path
const HTTP_METHOD = pm.request.method;
let URL_PATH = pm.request.url.getPath();

// Replace placeholders with actual values
const PLATFORM = "api";
const API_VERSION = "v1";

// Replace placeholders if necessary
URL_PATH = URL_PATH.replace("{{PLATFORM}}", PLATFORM).replace("{{API_VERSION}}", API_VERSION);


// Get the current timestamp in seconds
const TIME_STAMP = Math.floor(Date.now() / 1000);

// Generate a random UUID for the nonce
const NONCE = uuidv4();

// Create the message to be hashed
const message = `${HTTP_METHOD}|${UUID}|${URL_PATH}|${TIME_STAMP}|${AUTH_TOKEN}|${NONCE}`;

// Generate the HMAC signature using SHA256
const hmacSignature = CryptoJS.HmacSHA256(message, HASH_KEY).toString(CryptoJS.enc.Hex);

// Set the headers in Postman
pm.request.headers.add({key: "x-signature",value: hmacSignature});
pm.request.headers.add({key: "x-timestamp",value: TIME_STAMP});
pm.request.headers.add({key: "x-nonce",value: NONCE});

// Function to generate UUID v4
function uuidv4() {
    return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
        const r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
        return v.toString(16);
    });
}

```

{% endtab %}

{% tab title="PHP" %}

```php
<?php

class LeanxSignatureGenerationAdapter
{
    public static function generateSignature($UUID, $AUTH_TOKEN, $HASH_KEY, $HTTP_METHOD, $URL_PATH)
    {
        // Replace placeholders with actual values
        $PLATFORM = "api";
        $API_VERSION = "v1";

        // Replace placeholders in the URL path
        $URL_PATH = str_replace("{{PLATFORM}}", $PLATFORM, $URL_PATH);
        $URL_PATH = str_replace("{{API_VERSION}}", $API_VERSION, $URL_PATH);

        // Get the current timestamp in seconds
        $TIME_STAMP = time();

        // Generate a random UUID for the nonce
        $NONCE = self::generateUuidV4();

        // Create the message to be hashed
        $message = "{$HTTP_METHOD}|{$UUID}|{$URL_PATH}|{$TIME_STAMP}|{$AUTH_TOKEN}|{$NONCE}";

        // Generate the HMAC signature using SHA256
        $hmacSignature = hash_hmac('sha256', $message, $HASH_KEY);

        // Return the headers
        return [
            'x-signature' => $hmacSignature,
            'x-timestamp' => $TIME_STAMP,
            'x-nonce' => $NONCE
        ];
    }

    private static function generateUuidV4()
    {
        return sprintf('%04x%04x-%04x-4%03x-%04x-%04x%04x%04x',
            mt_rand(0, 0xffff), mt_rand(0, 0xffff),
            mt_rand(0, 0xffff),
            mt_rand(0, 0x0fff) | 0x4000,
            mt_rand(0, 0x3fff) | 0x8000,
            mt_rand(0, 0xffff), mt_rand(0, 0xffff), mt_rand(0, 0xffff)
        );
    }
}
```

{% endtab %}
{% endtabs %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.leanx.io/api-docs/signature-validation.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
