# PHP调用Mefree.NET API

本指南将详细介绍如何通过PHP实现对Mefree.NET的API调用，包括生成签名的方法、请求的构建以及接口调用的完整流程。

***

#### **1. 签名规则概述**

Mefree.NET API 的身份验证通过签名机制进行，签名的生成逻辑如下：

**1.1 签名字符串规则**

签名使用以下格式的字符串：

```
sign = timestamp + method + requestPath
```

* **timestamp**：UTC 时间，格式为 ISO 8601（例如：`2024-11-26T12:34:56.789Z`）。
* **method**：HTTP 方法，如 `GET` 或 `POST`。
* **requestPath**：API 请求路径（包括查询参数），例如：
  * `/api/config`
  * `/api/order?quantity=65000&target_address=TRON_ADDRESS&period=1`

**1.2 签名生成流程**

1. 使用 **HMAC-SHA256** 算法，用 API 的 **Secret Key** 对拼接的字符串进行加密。
2. 将加密结果用 **Base64** 编码，得到签名值。

**1.3 请求头参数**

每次请求需要添加以下 HTTP 头：

* `Content-Type: application/json`
* `MF-ACCESS-KEY`: 您的 API Key。
* `MF-ACCESS-SIGN`: 生成的签名值。
* `MF-ACCESS-TIMESTAMP`: 当前的 UTC 时间戳。

***

#### **2. PHP实现签名方法**

**2.1 签名生成函数**

```php
/**
 * 生成 Mefree API 的签名
 * @param string $timestamp UTC 时间戳 (ISO 8601 格式)
 * @param string $method HTTP 方法 (GET/POST)
 * @param string $request_path API 请求路径（含参数）
 * @param string $secret_key API 的 Secret Key
 * @return string 返回 Base64 编码的签名
 */
function generate_signature($timestamp, $method, $request_path, $secret_key) {
    // 拼接待签名字符串
    $string_to_sign = $timestamp . $method . $request_path;

    // 使用 HMAC-SHA256 算法对字符串进行加密
    $hash = hash_hmac('sha256', $string_to_sign, $secret_key, true);

    // 返回 Base64 编码的签名
    return base64_encode($hash);
}
```

***

#### **3. API 请求构建**

**3.1 基础配置**

配置 API 的基础信息：

```php
// API 配置信息
$base_url = "https://api.mefree.net";        // Mefree API 基础地址
$api_key = "your_api_key";              // 替换为实际的 API Key
$secret_key = "your_secret_key";        // 替换为实际的 Secret Key
```

**3.2 发起请求的函数**

使用 `CURL` 构建通用的 HTTP 请求函数：

```php
/**
 * 发起 Mefree API 请求
 * @param string $method HTTP 方法 (GET/POST)
 * @param string $request_path API 请求路径（含查询参数）
 * @param string $base_url API 基础 URL
 * @param string $api_key API Key
 * @param string $secret_key API Secret Key
 * @return mixed 返回 API 响应内容
 */
function send_request($method, $request_path, $base_url, $api_key, $secret_key) {
    // 当前 UTC 时间戳
    $timestamp = gmdate("Y-m-d\TH:i:s.v\Z");

    // 生成签名
    $signature = generate_signature($timestamp, $method, $request_path, $secret_key);

    // 设置请求头
    $headers = [
        "Content-Type: application/json",
        "MF-ACCESS-KEY: {$api_key}",
        "MF-ACCESS-SIGN: {$signature}",
        "MF-ACCESS-TIMESTAMP: {$timestamp}",
    ];

    // 初始化 CURL
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $base_url . $request_path); // 设置 URL
    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);        // 设置请求方法
    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);          // 设置请求头
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);          // 返回响应内容

    // 执行请求
    $response = curl_exec($ch);
    $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);      // 获取 HTTP 状态码
    curl_close($ch);

    // 返回结果
    return [
        "status_code" => $http_code,
        "response" => $response
    ];
}
```

***

#### **4. 示例接口调用**

**4.1 获取账户信息**

**接口描述**：

* 请求路径：`/api/config`
* HTTP 方法：`GET`

**调用代码**：

```php
// 获取账户信息
$request_path = "/api/config"; // API 请求路径
$response = send_request("GET", $request_path, $base_url, $api_key, $secret_key);

// 处理返回结果
if ($response['status_code'] == 200) {
    echo "账户信息：\n";
    echo $response['response'];
} else {
    echo "请求失败，HTTP 状态码：" . $response['status_code'] . "\n";
    echo "响应内容：" . $response['response'];
}
```

***

**4.2 创建订单**

**接口描述**：

* 请求路径：`/api/order?quantity=65000&target_address=TRON_ADDRESS&period=1`
* HTTP 方法：`POST`

**调用代码**：

```php
// 创建订单
$request_path = "/api/order?quantity=65000&target_address=TRON_ADDRESS&period=1"; // API 请求路径
$response = send_request("POST", $request_path, $base_url, $api_key, $secret_key);

// 处理返回结果
if ($response['status_code'] == 200) {
    echo "订单已创建：\n";
    echo $response['response'];
} else {
    echo "请求失败，HTTP 状态码：" . $response['status_code'] . "\n";
    echo "响应内容：" . $response['response'];
}
```

***

**4.3 查询订单状态**

**接口描述**：

* 请求路径：`/api/order/{pay_hash}`
* HTTP 方法：`GET`

**调用代码**：

```php
// 查询订单状态
$pay_hash = "abcd1234"; // 替换为实际订单的 pay_hash
$request_path = "/api/order/" . $pay_hash; // API 请求路径
$response = send_request("GET", $request_path, $base_url, $api_key, $secret_key);

// 处理返回结果
if ($response['status_code'] == 200) {
    echo "订单状态：\n";
    echo $response['response'];
} else {
    echo "请求失败，HTTP 状态码：" . $response['status_code'] . "\n";
    echo "响应内容：" . $response['response'];
}
```

***

#### **5. 常见问题**

**5.1 签名无效 (401 Unauthorized)**

* 确认 `MF-ACCESS-KEY` 是否正确。
* 确保签名按照规则生成：
  * 拼接顺序为：`timestamp + method + requestPath`。
  * 时间戳需为 UTC 格式，格式示例：`2024-11-26T12:34:56.789Z`。
  * 使用正确的 `SECRET_KEY` 生成签名。

**5.2 请求参数错误 (400 Bad Request)**

* 检查请求路径是否正确，尤其是查询参数是否完整。
* 确认 `Content-Type` 是否为 `application/json`。

**5.3 请求速率限制 (429 Too Many Requests)**

* Mefree API 对请求频率有限制，需避免在短时间内发起大量请求。
* 添加合理的请求间隔（例如每秒最多 2 次请求）。

***

#### **6. 总结**

通过以上文档，您可以使用 PHP 高效实现对 Mefree.NET API 的调用，包括生成签名、发送请求以及解析响应数据。对重要操作（如下单）时，建议加上重试机制以提高稳定性。如有疑问，请联系 Mefree 官方支持团队。


---

# 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.mefree.net/zh/getting-started/how-to-buy-energy/php.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.
