对外接口文档(Open API)
本文档面向接入方,用于将客户端/服务端接入本系统的开放 API(/api 前缀)。管理后台接口(/admin)不在此文档范围内。
1. 概述
- Base URL:
https://{your-domain}/api(示例:https://api.example.com/api) - 协议:HTTPS(生产环境建议)
- 数据格式:请求与响应均为 JSON,请求头需带
Content-Type: application/json。
2. 鉴权说明
2.1 应用鉴权(AppKey)
所有 /api 下的接口均需在请求头中携带应用密钥,用于标识接入方应用并做隔离与风控。
| 请求头 | 必填 | 说明 |
|---|---|---|
X-App-Key | 是 | 由管理后台为该应用分配的 AppKey,需保密。 |
- 未携带或无效:返回
401,code: "AUTH_UNAUTHORIZED"。 - 应用状态非
online:返回403,code: "APP_OFFLINE"。
2.2 用户鉴权(Token)
部分接口需要“已登录用户”身份,通过 Cookie 传递 Token:
- 登录成功时,服务端通过
Set-Cookie下发user_token(HttpOnly,建议 SameSite)。 - 后续请求需在同一域名/跨域配置下自动携带该 Cookie;Token 与 AppKey 绑定,跨应用无效。
- 未携带或 Token 无效/过期:返回
401,code: "AUTH_UNAUTHORIZED"。 - Token 与当前请求的 AppKey 所属应用不一致:返回
403,code: "AUTH_FORBIDDEN"。
3. 通用约定
3.1 分页
支持分页的接口使用查询参数:
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
limit | int | 20 | 每页条数,范围 1–200 |
offset | int | 0 | 偏移量,≥ 0 |
响应中通常包含:
items:当前页数据列表total:符合条件的总条数
3.2 错误响应
HTTP 状态码非 2xx 时,响应体为:
{
"code": "ERROR_CODE",
"message": "可读错误说明"
}
常见错误码示例:
| code | HTTP | 说明 |
|---|---|---|
AUTH_UNAUTHORIZED | 401 | 未登录、Token 无效或缺少 AppKey |
AUTH_FORBIDDEN | 403 | 无权限或 App 下线 |
APP_OFFLINE | 403 | 应用已下线 |
INVALID_REQUEST | 400 | 参数错误、格式错误 |
SYSTEM_ERROR | 500 | 服务端内部错误 |
业务错误码在各接口中单独说明。
4. 接口列表
4.1 应用与版本
获取当前应用最新版本
仅需 AppKey,无需用户登录。
- URL:
GET /api/app/version/latest - 鉴权:
X-App-Key - 响应:
200 OK
{
"version": "1.0.0",
"download_url": "https://cdn.example.com/app/1.0.0.apk"
}
4.2 VIP 套餐(公开)
获取 VIP 套餐列表
- URL:
GET /api/app/vip/plans - 鉴权:
X-App-Key - 响应:
200 OK
{
"items": [
{
"ID": 1,
"AppID": 1,
"Name": "月卡",
"Price": "18.00",
"OriginPrice": "25.00",
"DurationDays": 30,
"DeviceLimit": 1,
"Status": "active",
"CreatedAt": "2025-01-01T00:00:00Z",
"UpdatedAt": "2025-01-01T00:00:00Z"
}
]
}
4.3 用户(注册 / 登录 / 登出 / Token / 密码)
用户注册
- URL:
POST /api/user/register - 鉴权:
X-App-Key - 请求体:
{
"email": "user@example.com",
"phone": "+8613800138000",
"password": "your_password"
}
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| string | 是* | 邮箱(与 phone 二选一) | |
| phone | string | 否 | 手机号 |
| password | string | 是 | 密码 |
- 成功:
200 OK
{
"user_id": 10001
}
- 错误:
400,code: "USER_ALREADY_EXISTS"表示该账号已存在。
用户登录
- URL:
POST /api/user/login - 鉴权:
X-App-Key - 请求体:
{
"email": "user@example.com",
"phone": "",
"password": "your_password"
}
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| string | 否* | 邮箱(与 phone 二选一) | |
| phone | string | 否* | 手机号 |
| password | string | 是 | 密码 |
*登录方式为邮箱或手机号其一,与注册时一致。
可选请求头(用于风控/统计,非必填):
| 请求头 | 说明 |
|---|---|
X-Device-ID | 设备标识 |
X-Region | 地区 |
- 成功:
200 OK,并设置 Cookieuser_token=...(HttpOnly)
{
"ok": true,
"user_info": {
"id": 10001,
"name": "张三",
"avatar": "",
"phone": "+8613800138000",
"email": "user@example.com",
"status": "active"
}
}
- 失败:
401,code: "AUTH_UNAUTHORIZED"(账号或密码错误等)。
用户登出
- URL:
POST /api/user/logout - 鉴权:
X-App-Key+ Cookieuser_token - 响应:
200 OK,服务端清除 Token
{
"ok": true
}
刷新 Token
- URL:
POST /api/user/refresh - 鉴权:
X-App-Key+ Cookieuser_token - 响应:
200 OK,通过Set-Cookie下发新的user_token
{
"ok": true
}
修改密码
- URL:
PUT /api/user/password - 鉴权:
X-App-Key+ Cookieuser_token - 请求体:
{
"old_password": "old_password",
"new_password": "new_password"
}
- 成功:
200 OK,{"ok": true} - 失败:
401,code: "AUTH_UNAUTHORIZED",message如 "invalid old password"。
4.4 用户 VIP 状态
查询当前用户 VIP 状态
- URL:
GET /api/user/vip - 鉴权:
X-App-Key+ Cookieuser_token - 响应:
200 OK
未开通或已过期:
{
"expired_at": null
}
有效期内:
{
"expired_at": "2025-12-31T23:59:59Z"
}
4.5 订单
当前用户订单列表
- URL:
GET /api/user/orders - 鉴权:
X-App-Key+ Cookieuser_token - 查询参数:
limit、offset(见 3.1) - 响应:
200 OK
{
"items": [
{
"ID": 1,
"OrderNo": "ORDxxx",
"UserID": 10001,
"AppID": 1,
"VIPPlanID": 1,
"Amount": "18.00",
"Status": "paid",
"CreatedAt": "2025-01-01T00:00:00Z",
"UpdatedAt": "2025-01-01T00:00:00Z"
}
],
"total": 10
}
当前用户订单详情
- URL:
GET /api/user/orders/:id - 鉴权:
X-App-Key+ Cookieuser_token - 路径参数:
id为订单 ID(数字) - 成功:
200 OK,单条订单对象(结构同上列表中一项) - 错误:
400,code: "ORDER_NOT_FOUND"表示订单不存在或不属于当前用户。
创建订单(下单)
- URL:
POST /api/user/orders - 鉴权:
X-App-Key+ Cookieuser_token - 请求体:
{
"vip_plan_id": 1
}
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| vip_plan_id | uint64 | 是 | 来自「获取 VIP 套餐列表」的套餐 ID |
- 成功:
200 OK,返回创建的订单对象(结构同订单列表项) - 错误:
400,code: "VIP_PLAN_NOT_FOUND"表示套餐不存在或不属于当前 App。
4.6 优惠券
兑换优惠券
- URL:
POST /api/coupon/redeem - 鉴权:
X-App-Key+ Cookieuser_token - 请求体:
{
"code": "PROMO2025"
}
- 成功:
200 OK
{
"type": "duration",
"value": "7",
"expired_at": "2025-02-07T23:59:59Z"
}
| 字段 | 说明 |
|---|---|
| type | 优惠类型:duration 表示增加会员天数,discount 表示折扣等 |
| value | 面值/天数等,字符串 |
| expired_at | 仅当 type 为 duration 时存在,为当前用户 VIP 新的到期时间(ISO 8601) |
- 错误:
| code | HTTP | 说明 |
|---|---|---|
COUPON_INVALID | 400 | 券码不存在或无效 |
COUPON_NOT_ACTIVE | 400 | 优惠券未启用 |
COUPON_EXPIRED | 400 | 已过期 |
COUPON_USED | 400 | 已使用(含重复兑换) |
当前用户兑换记录
- URL:
GET /api/coupon/records - 鉴权:
X-App-Key+ Cookieuser_token - 查询参数:
limit、offset(见 3.1) - 响应:
200 OK
{
"items": [
{
"coupon_name": "新年礼包",
"coupon_code": "PROMO2025",
"used_at": "2025-01-01T12:00:00Z"
}
],
"total": 5
}
5. 接入流程简要
- 在管理后台创建应用,获取 AppKey,并确保应用状态为「上线」。
- 所有请求加上请求头:
X-App-Key: <your_app_key>。 - 需要用户身份的接口:先调用
POST /api/user/login,在后续请求中携带服务端下发的user_tokenCookie(浏览器环境自动带;非浏览器需自行保存并随请求携带 Cookie 头)。 - 按业务需要调用 VIP 套餐、订单、优惠券等接口;错误时根据
code与message做提示或重试逻辑。
6. 附录:接口速查表
| 方法 | 路径 | 鉴权 | 说明 |
|---|---|---|---|
| GET | /api/app/version/latest | AppKey | 应用最新版本 |
| GET | /api/app/vip/plans | AppKey | VIP 套餐列表 |
| POST | /api/user/register | AppKey | 用户注册 |
| POST | /api/user/login | AppKey | 用户登录 |
| POST | /api/user/logout | AppKey + Token | 登出 |
| POST | /api/user/refresh | AppKey + Token | 刷新 Token |
| PUT | /api/user/password | AppKey + Token | 修改密码 |
| GET | /api/user/vip | AppKey + Token | 当前用户 VIP 状态 |
| GET | /api/user/orders | AppKey + Token | 用户订单列表 |
| GET | /api/user/orders/:id | AppKey + Token | 订单详情 |
| POST | /api/user/orders | AppKey + Token | 创建订单 |
| POST | /api/coupon/redeem | AppKey + Token | 兑换优惠券 |
| GET | /api/coupon/records | AppKey + Token | 用户兑换记录 |
文档版本:基于当前后端实现整理,如有变更以实际服务为准。