> For the complete documentation index, see [llms.txt](https://docs.jgopay.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.jgopay.com/jian-ti-zhong-wen/rate-limiting.md).

# 频率限制

为保障服务稳定性，所有 API 接口按商户维度限制请求频率。已认证的请求按商户 ID 统计，未认证的请求按 IP 地址统计。

## 限额

| 接口                       | 限制    | 窗口   |
| ------------------------ | ----- | ---- |
| `POST /auth/token`       | 5 次   | 1 分钟 |
| `POST /payment/request`  | 100 次 | 1 分钟 |
| `POST /payment/withdraw` | 50 次  | 1 分钟 |
| 其他接口                     | 100 次 | 1 分钟 |

限额按滑动窗口方式重置。

## 超出限制

超出频率限制时，API 返回 HTTP `429 Too Many Requests`：

```json
{
  "statusCode": 429,
  "message": "Too Many Requests",
  "error": "Too Many Requests",
  "timestamp": "2026-02-04T10:30:00.000Z",
  "path": "/api/v1/payment/request",
  "correlationId": "abc-123-def-456"
}
```

## 响应头

每个 API 响应都包含频率限制相关的响应头：

| 响应头                     | 说明                   |
| ----------------------- | -------------------- |
| `X-RateLimit-Limit`     | 当前窗口允许的最大请求数         |
| `X-RateLimit-Remaining` | 当前窗口剩余的请求数           |
| `X-RateLimit-Reset`     | 窗口重置的 Unix 时间戳（秒）    |
| `Retry-After`           | 重试前需等待的秒数（仅 429 时返回） |

存在 `Retry-After` 时请优先使用它 — 比通过 `X-RateLimit-Reset` 计算更准确。

## 推荐的退避策略

使用带随机抖动的指数退避，避免瞬时并发冲击：

```javascript
async function requestWithBackoff(fn, maxRetries = 3) {
  for (let attempt = 0; attempt <= maxRetries; attempt++) {
    const response = await fn();

    if (response.status !== 429) return response;

    if (attempt === maxRetries) throw new Error('Rate limit exceeded after retries');

    // 指数退避：1s、2s、4s + 最多 1s 的随机抖动
    const delay = Math.pow(2, attempt) * 1000 + Math.random() * 1000;
    await new Promise((resolve) => setTimeout(resolve, delay));
  }
}
```

## 最佳实践

* **缓存访问令牌** — 令牌有效期 1 小时。获取一次后复用，不要每次调用 API 都重新获取。
* **客户端排队** — 批量处理支付时，请排队并遵守每分钟限额，不要一次性全部发出。
* **不要重试 4xx 错误** — 仅在 `429`（频率限制）和 `5xx`（服务器错误）时重试。重试 `400` 或 `422` 只会得到相同结果。
* **善用 `correlationId`** — 联系客服时附上它，可加快问题定位。


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## 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, and the optional `goal` query parameter:

```
GET https://docs.jgopay.com/jian-ti-zhong-wen/rate-limiting.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

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.
