# 签名

## 请求签名示例

{% 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": "merchant_order_id",
        "order_user_key": "admin@email.com",
        "actual_amount": 12.9,
        "currency": "USDT_TRC20",
        "pass_through_info": "{'user_id': '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

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

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

    print("Response Status Code:", response.status_code)
    print("Response Text:", response.text)


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通知签名校验

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

```python
async def webhook(request: Request, data: dict = Body()):
    headers = request.headers
    signature = headers.get("signature")
    sandbox = headers.get("sandbox")
    if sandbox:
        token = "sandbox_api_key"
    else:
        token = "production_api_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/cn/qian-ming.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.
