# Signature

{% hint style="info" %}
After creating an API key, you need to use the key to sign the request parameters, and the signature is only valid for 10 seconds.
{% endhint %}

## Requested signature example

{% tabs %}
{% tab title="Python" %}

```python
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad
import hashlib
import time


def create_order():
    data = {
        "out_order_id": "orderid123123",
        "order_user_key": "admin@qq.com",
        "actual_amount": 2.9,
        "currency": "USDT_TRC20",
        "pass_through_info": "{'tes3t': '1'}",
        "notify_url": "http://localhost:8000/api/orders/check/AJIOTKS2N34Bw2tCWG",
        "redirect_url": "http://localhost:8000/pay/tokenpay/return_url?order_id=AJIHK72N34BR2CWG"
    }
    timestamp = int(time.time())
    data["timestamp"] = timestamp
    sorted_data = sorted(data.items())
    params_str = "&".join([f"{key}={value}" for key, value in sorted_data if key != 'signature'])  # 排除签名字段

    secret_key = "api key"

    encrypted_signature = encrypt_data(params_str, secret_key)

    data['signature'] = encrypted_signature

    # 发送POST请求
    url = "http://localhost:8000/sandbox/api/v1/orders/create-order"  # 替换为实际的接口URL
    headers = {
        "Content-Type": "application/json",
        "merchant-code": "",
        "app-code": ""
    }

    response = requests.post(url, headers=headers, data=json.dumps(data))



def encrypt_data(data: str, key: str) -> str:
    key = key.ljust(16, '0')
    iv = b'0000000000000000'
    cipher = AES.new(key.encode('utf-8'), AES.MODE_CBC, iv)
    padded_data = pad(data.encode('utf-8'), AES.block_size)
    encrypted = cipher.encrypt(padded_data)
    return hashlib.md5(encrypted.hex().encode()).hexdigest()
```

{% endtab %}
{% endtabs %}

***

## Webhook signature verification

{% tabs %}
{% tab title="Python" %}

```python
async def webhook(request: Request, data: dict):
    headers = request.headers
    signature = headers.get("signature")
    sandbox = headers.get("sandbox")
    if sandbox:
        token = "sandbox_key"
    else:
        token = "production_key"

    result = verify_signature(data, signature, token)
    return result


def verify_signature(received_data: dict, received_signature: str, api_key: str):
    sorted_data = sorted(received_data.items())
    signature_str = "&".join([f"{key}={value}" for key, value in sorted_data])
    
    expected_signature = hmac.new(
        key=api_key.encode(),
        msg=signature_str.encode(),
        digestmod=hashlib.sha256
    ).hexdigest()

    return hmac.compare_digest(received_signature, expected_signature)
```

{% 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://kodecrypto-document.gitbook.io/kodecrypto/quick-start/signature.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.
