47 KiB
短视频应用接口文档
- 版本:v1.0
- 日期:2026-10-14
- Base URL:
https://api.example.com/api/v1
注意:App 不硬编码 Base URL。启动时优先解析
txt.256kb.top的 DNS TXT 记录获取真实 API 域名;解析失败时按md5(yyyyMM) + "_jsnbhh.vip"计算兜底域名(详见《01-开发文档》5.5 节)。本文示例域名仅为占位。
1. 通用说明
1.1 请求头
| Header | 必填 | 说明 |
|---|---|---|
| Content-Type | 是 | application/json(文件上传为 multipart/form-data) |
| Authorization | 登录接口必填 | Bearer <access_token> |
| X-Device-ID | 是 | 设备唯一标识(游客计费依赖,首启生成 UUID 持久化) |
| X-App-Version | 是 | App 版本号(如 1.2.0),用于版本检查与灰度 |
| X-Platform | 是 | 平台标识:ios / android |
| X-Request-ID | 建议 | 客户端请求唯一 ID,用于幂等与链路追踪 |
1.2 统一响应结构
{
"code": 0,
"message": "ok",
"data": {},
"request_id": "8f3c2a1e-..."
}
code = 0表示成功;非 0 为错误码,message为可展示的错误文案- HTTP 状态码:业务错误统一 200 + 业务 code;401/403/429/500 使用标准语义
1.3 通用错误码
| code | 说明 |
|---|---|
| 0 | 成功 |
| 1001 | 参数错误 |
| 1002 | 未登录或 Token 无效/过期 |
| 1003 | 无权限(功能需登录/已被封禁) |
| 1004 | 验证码错误或已过期 |
| 1005 | 请求过于频繁(限流) |
| 1006 | 资源不存在 |
| 1009 | 账号已注销(冻结期内登录可撤销) |
| 2001 | 积分不足 |
| 2002 | 今日免费观看次数已用完(游客需登录) |
| 2003 | 视频不存在或未发布 |
| 2004 | 已是终身会员,无需再开通 |
| 3001 | 订单不存在 |
| 3002 | 订单状态异常(已支付/已关闭) |
| 3003 | 支付金额不匹配 |
| 5000 | 服务器内部错误 |
| 4001 | 无管理员权限或角色不允许该操作 |
| 4002 | 该操作必须填写原因(reason) |
| 2101 | 邀请码无效或不可绑定(已绑定/绑定自己/同设备已注册) |
| 2102 | 资产余额不足 |
| 2103 | 低于最低提现额度 |
| 2104 | 已有审核中的提现申请 |
| 2105 | 内容包含敏感词 |
| 2106 | 请勿重复举报 |
| 2107 | 无权操作(非作者本人) |
1.4 分页约定
- Feed 流:游标分页。请求
cursor(首次不传)+limit;响应返回next_cursor(null 表示没有更多) - 普通列表:
page(从 1 开始)+page_size(默认 20,最大 50),响应含total
2. 接口总览
| # | 模块 | 方法 | 路径 | 说明 | 登录 |
|---|---|---|---|---|---|
| 1 | 认证 | POST | /auth/sms/send | 发送短信验证码 | 否 |
| 2 | 认证 | POST | /auth/email/send | 发送邮箱验证码 | 否 |
| 3 | 认证 | POST | /auth/register | 注册(手机/邮箱,可填邀请码,可配置赠送体验会员) | 否 |
| 4 | 认证 | POST | /auth/login | 登录 | 否 |
| 5 | 认证 | POST | /auth/token/refresh | 刷新令牌 | 否(带refresh) |
| 6 | 认证 | POST | /auth/logout | 退出登录 | 是 |
| 7 | 认证 | POST | /auth/password/reset | 找回密码 | 否 |
| 8 | 用户 | GET | /users/me | 获取个人信息 | 是 |
| 9 | 用户 | PUT | /users/me | 修改资料 | 是 |
| 10 | 用户 | POST | /users/me/avatar | 上传头像 | 是 |
| 11 | 用户 | GET | /users/me/wallet | 钱包/积分余额 | 是 |
| 12 | 用户 | GET | /users/me/points/records | 积分明细 | 是 |
| 13 | 用户 | POST | /users/me/deactivate | 注销账号(7天冻结期) | 是 |
| 14 | 用户 | GET | /users/{user_id} | 用户公开主页 | 否 |
| 15 | 用户 | GET | /users/{user_id}/videos | 他人作品列表 | 否 |
| 16 | 视频 | GET | /videos/feed | 推荐视频流(支持 recommend/latest/hot) | 否 |
| 17 | 视频 | GET | /videos/{video_id} | 视频详情(登录返回续播进度) | 否 |
| 18 | 视频 | POST | /videos/{video_id}/watch | 观看上报(计费,可带播放进度) | 否 |
| 19 | 视频 | POST | /videos/{video_id}/watch/complete | 完整观看上报(创作收益计数) | 否 |
| 20 | 视频 | POST | /videos/upload/token | 获取上传凭证 | 是 |
| 21 | 视频 | POST | /videos | 发布视频(上传完成回调) | 是 |
| 22 | 视频 | PUT | /videos/{video_id} | 编辑视频(仅作者) | 是 |
| 23 | 视频 | DELETE | /videos/{video_id} | 删除视频(仅作者,软删除) | 是 |
| 24 | 视频 | GET | /users/me/videos | 我的作品 | 是 |
| 25 | 视频 | GET | /videos/categories | 分类列表 | 否 |
| 26 | 视频 | GET | /tags/{tag_name}/videos | 标签视频列表 | 否 |
| 27 | 视频 | GET | /videos/search | 视频搜索 | 否 |
| 28 | 视频 | GET | /search/hot | 热搜榜 | 否 |
| 29 | 互动 | POST | /videos/{video_id}/like | 点赞/取消点赞 | 是 |
| 30 | 互动 | POST | /videos/{video_id}/favorite | 收藏/取消收藏 | 是 |
| 31 | 互动 | GET | /videos/{video_id}/comments | 评论列表 | 否 |
| 32 | 互动 | POST | /videos/{video_id}/comments | 发表评论 | 是 |
| 33 | 互动 | DELETE | /comments/{comment_id} | 删除评论 | 是 |
| 34 | 互动 | GET | /users/me/favorites | 我的收藏 | 是 |
| 35 | 互动 | GET | /users/me/history | 观看历史 | 是 |
| 36 | 会员 | GET | /membership/plans | 会员套餐列表 | 否 |
| 37 | 会员 | GET | /membership/me | 我的会员状态 | 是 |
| 38 | 会员 | POST | /membership/redeem | 积分开通会员 | 是 |
| 39 | 支付 | GET | /payments/packages | 充值套餐列表(后台可配) | 是 |
| 40 | 支付 | POST | /payments/recharge | 创建充值订单 | 是 |
| 41 | 支付 | GET | /payments/orders/{order_no} | 查询订单状态 | 是 |
| 42 | 支付 | POST | /payments/orders/{order_no}/cancel | 取消订单 | 是 |
| 43 | 回调 | POST | /callbacks/alipay | 支付宝异步通知 | 平台调用 |
| 44 | 回调 | POST | /callbacks/wechat | 微信支付异步通知 | 平台调用 |
| 45 | 激励 | GET | /referral/me | 我的邀请信息 | 是 |
| 46 | 激励 | POST | /referral/bind | 绑定邀请码 | 是 |
| 47 | 激励 | GET | /assets/me | 资产钱包 | 是 |
| 48 | 激励 | GET | /assets/records | 资产流水 | 是 |
| 49 | 激励 | POST | /assets/withdraw | 申请提现 | 是 |
| 50 | 激励 | GET | /assets/withdraw/records | 提现记录 | 是 |
| 51 | 推广归因 | POST | /invite/click | 推广点击埋点(H5 落地页打开即上报) | 否 |
| 52 | 推广归因 | POST | /invite/match | App 首启归因匹配 | 否 |
| 53 | 推广归因 | GET | /r/{code} | H5 推广落地页(根路径,非 /api/v1 前缀) | 否 |
| 54 | 通用 | GET | /app/version | 版本检查 | 否 |
| 55 | 消息 | GET | /notifications | 通知列表 | 是 |
| 56 | 消息 | GET | /notifications/unread_count | 未读数 | 是 |
| 57 | 消息 | POST | /notifications/read | 标记已读 | 是 |
| 58 | 通用 | POST | /reports | 提交举报 | 是 |
| 59~90 | 后台管理 | * | /admin/** | 登录、看板、审核、视频/评论管理、用户、积分、订单、补单、套餐、赠送、提现审核、推荐风控、举报处理、敏感词、平台配置、日志,见第 11 章 | 管理员 |
3. 认证模块
3.1 发送短信验证码 POST /auth/sms/send
请求参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| phone | string | 是 | 手机号,11 位 |
| scene | string | 是 | 场景:register / login / reset |
请求示例
{ "phone": "13800138000", "scene": "register" }
响应示例
{ "code": 0, "message": "ok", "data": { "expire_seconds": 300, "retry_after": 60 } }
限制:同号码 60 秒 1 条,同号码每天 10 条;注册场景下已注册号码返回错误码 1001("该手机号已注册")。
3.2 发送邮箱验证码 POST /auth/email/send
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| string | 是 | 邮箱地址 | |
| scene | string | 是 | register / login / reset |
响应同 3.1,expire_seconds=600。
3.3 注册 POST /auth/register
请求参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| type | string | 是 | phone 或 email |
| phone | string | type=phone 时必填 | 手机号 |
| string | type=email 时必填 | 邮箱 | |
| code | string | 是 | 验证码 |
| password | string | 是 | 密码,8-32 位,须含字母和数字 |
| nickname | string | 否 | 昵称,默认"用户+随机尾号" |
| invite_code | string | 否 | 推荐人邀请码(App 解析分享口令自动预填;未填时服务端取首启模糊归因结果,见 9.7~9.9) |
请求示例
{ "type": "phone", "phone": "13800138000", "code": "825314", "password": "abc12345", "nickname": "小明" }
响应示例
{
"code": 0,
"message": "ok",
"data": {
"user_id": 100023,
"access_token": "eyJhbGciOi...",
"refresh_token": "d9f2...",
"expires_in": 7200,
"user": { "user_id": 100023, "nickname": "小明", "avatar_url": "", "is_member": true },
"trial_granted": { "plan_code": "trial", "plan_name": "体验会员", "days": 1, "end_at": "2026-10-15 12:00:00" }
}
}
trial_granted:注册赠送的体验会员;后台关闭赠送开关(register_gift_trial.enabled=0)时为null,is_member相应为 false
错误码:1004 验证码错误;1001 手机号/邮箱已注册。
3.4 登录 POST /auth/login
请求参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| type | string | 是 | phone_password / phone_code / email_password |
| phone | string | 手机方式必填 | |
| string | 邮箱方式必填 | ||
| password | string | 密码方式必填 | |
| code | string | 验证码方式必填 |
请求示例
{ "type": "phone_password", "phone": "13800138000", "password": "abc12345" }
响应:同 3.3。连续失败 5 次锁定 15 分钟(错误码 1005)。
3.5 刷新令牌 POST /auth/token/refresh
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| refresh_token | string | 是 | 刷新令牌 |
响应:同 3.3 的 token 部分;refresh_token 旋转(旧值立即失效)。
3.6 退出登录 POST /auth/logout(需登录)
无参数。响应 { "code": 0 }。服务端将 access_token 的 jti 加入黑名单并删除 refresh 白名单。
3.7 找回密码 POST /auth/password/reset
通过已验证的手机号/邮箱 + 验证码重置密码。重置成功后该用户所有旧 Token(access + refresh)立即失效,需重新登录。
请求参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| type | string | 是 | phone 或 email |
| phone | string | type=phone 时必填 | 手机号 |
| string | type=email 时必填 | 邮箱 | |
| code | string | 是 | 验证码(scene=reset) |
| new_password | string | 是 | 新密码,8-32 位,须含字母和数字 |
请求示例
{ "type": "phone", "phone": "13800138000", "code": "825314", "new_password": "newabc123" }
响应:{ "code": 0, "message": "密码已重置,请重新登录" }
错误码:1004 验证码错误或已过期;1001 账号不存在。
4. 用户模块
4.1 获取个人信息 GET /users/me(需登录)
响应示例
{
"code": 0,
"data": {
"user_id": 100023,
"phone": "138****8000",
"email": null,
"nickname": "小明",
"avatar_url": "https://cdn.example.com/avatar/100023.jpg",
"bio": "",
"is_member": true,
"member_plan": "monthly",
"member_expire_at": "2026-11-13 12:00:00",
"points": 86
}
}
4.2 修改资料 PUT /users/me(需登录)
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| nickname | string | 否 | 2-20 字 |
| bio | string | 否 | ≤200 字 |
| gender | int | 否 | 0/1/2 |
响应返回更新后的完整用户对象(同 4.1)。
4.3 上传头像 POST /users/me/avatar(需登录)
multipart/form-data,字段名file,jpg/png,≤ 5MB- 响应:
{ "code": 0, "data": { "avatar_url": "https://..." } }
4.4 钱包信息 GET /users/me/wallet(需登录)
响应示例
{
"code": 0,
"data": {
"points": 86,
"total_recharge": 100,
"total_earned": 6,
"total_consumed": 20,
"comment_reward_progress": { "current": 4, "target": 10, "today_rewarded": 1, "daily_limit": 5 }
}
}
4.5 积分明细 GET /users/me/points/records(需登录)
查询参数:page、page_size、biz_type(可选:1充值 2观看 3评论奖励 4会员 5赠送 6调整 7扣回)
响应示例
{
"code": 0,
"data": {
"total": 35,
"list": [
{ "id": 9001, "change_amount": -1, "balance_after": 86, "biz_type": 2, "remark": "观看视频", "created_at": "2026-10-14 12:01:00" },
{ "id": 8990, "change_amount": 1, "balance_after": 87, "biz_type": 3, "remark": "评论奖励", "created_at": "2026-10-14 11:30:00" }
]
}
}
4.6 注销账号 POST /users/me/deactivate(需登录)
用户主动注销。提交后进入 7 天冻结期:期间再次登录即自动撤销注销;到期后账号匿名化(手机号/邮箱置空释放、昵称头像清空、作品全部下架、钱包余额清零作废),Token 立即失效。
请求参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| password | string | 是 | 当前登录密码(二次确认) |
// 响应
{ "code": 0, "data": { "deactivate_at": "2026-10-22 12:00:00", "revoke_before": "2026-10-22 12:00:00" } }
说明:冻结期内登录返回错误码 1009 并附带 can_revoke=true,App 弹窗询问是否撤销注销。
4.7 用户公开主页 GET /users/{user_id}(游客可)
{
"code": 0,
"data": {
"user_id": 100023,
"nickname": "小明",
"avatar_url": "https://...",
"bio": "",
"video_count": 12,
"total_likes": 3456
}
}
4.8 他人作品列表 GET /users/{user_id}/videos(游客可)
仅返回"已发布"状态作品。
查询参数:page、page_size
响应:list 结构同 Feed 单条,含 total。
5. 视频模块
5.1 推荐视频流 GET /videos/feed(游客可)
查询参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| cursor | string | 否 | 上一页返回的 next_cursor |
| limit | int | 否 | 默认 10,最大 20 |
| category_id | int | 否 | 分类筛选 |
| type | string | 否 | 策略:recommend(默认,个性化)/ latest / hot |
响应示例
{
"code": 0,
"data": {
"next_cursor": "eyJwIjoxNzYwfQ==",
"list": [
{
"video_id": 88001,
"title": "海边日落",
"cover_url": "https://cdn.example.com/hls/88001/cover.jpg",
"video_url": "https://cdn.example.com/hls/88001/index.m3u8",
"duration": 32,
"author": { "user_id": 100023, "nickname": "小明", "avatar_url": "https://..." },
"view_count": 12034,
"like_count": 456,
"comment_count": 78,
"favorite_count": 90,
"tags": ["日落", "海边"],
"is_liked": false,
"is_favorited": false
}
]
}
}
is_liked/is_favorited仅登录用户返回真实值,游客恒为 false。recommend 策略:以"当天日期 + 用户/设备"为随机种子每日重排(同一用户每天的推荐顺序不同、同一天内多次刷新顺序稳定);当日已观看的视频尽量不再出现(候选不足时放开过滤兜底);个性化基于近 7 天观看/点赞/收藏视频的标签偏好加权,游客及新用户退化为热度排序。
5.2 视频详情 GET /videos/{video_id}(游客可)
响应字段同 Feed 单条,另含 description、category、published_at。
登录用户额外返回 my_position(本人上次观看进度,秒;无记录为 0),用于断点续播。
错误码:2003 视频不存在或未发布。
5.3 观看上报(计费接口)POST /videos/{video_id}/watch(游客可)
开始播放时调用。客户端本地按 video_id+日期 去重,同日同视频只上报一次。
请求参数(身份取自 Token 或 X-Device-ID)
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| position | int | 否 | 当前播放进度(秒),服务端记录用于续播 |
响应示例(扣费场景)
{
"code": 0,
"data": {
"cost_type": 1,
"cost_points": 1,
"remaining_points": 86,
"free_remaining_today": 0
}
}
cost_type 说明
| 值 | 含义 | cost_points |
|---|---|---|
| 0 | 占用今日免费额度 | 0 |
| 1 | 积分扣减 | 1 |
| 2 | 会员免费 | 0 |
| 3 | 重复观看/本人作品,不计费 | 0 |
错误响应(游客超限)
{ "code": 2002, "message": "今日免费观看次数已用完,登录后继续观看", "data": { "need_login": true } }
错误响应(积分不足)
{ "code": 2001, "message": "积分不足,请充值或开通会员", "data": { "points": 0 } }
5.4 完整观看上报 POST /videos/{video_id}/watch/complete(游客可)
播放进度 ≥95% 或自然播完时调用,用于创作者收益计数(每 1000 次完整观看 = 1 资产)。服务端校验 watch_duration 合理性(不得明显低于视频时长),同一用户/设备同一视频每日仅首次有效。
请求参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| watch_duration | int | 是 | 本次实际观看时长(秒) |
// 请求
{ "watch_duration": 31 }
// 响应
{ "code": 0, "data": { "credited": true } }
credited=false:今日已计数、观看的是本人作品、或时长校验未通过。
5.5 获取上传凭证 POST /videos/upload/token(需登录)
请求参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| file_name | string | 是 | 原始文件名 |
| file_size | int | 是 | 字节数,≤ 配置上限 |
| upload_mode | string | 否 | raw(默认,服务端转码) / hls(已转码的m3u8包) |
响应示例
{
"code": 0,
"data": {
"upload_type": "oss_sts",
"sts": { "access_key_id": "STS.xxx", "access_key_secret": "xxx", "security_token": "xxx", "expiration": "2026-10-14T13:00:00Z" },
"object_key": "upload/tmp/20261014/uuid.mp4",
"bucket": "video-upload",
"endpoint": "https://oss-cn-hangzhou.aliyuncs.com"
}
}
小部署环境可返回
upload_type: "server",客户端改用POST /videos/upload/file(multipart)经服务端中转。
5.6 发布视频 POST /videos(需登录)
上传完成后调用,创建视频记录并进入转码/审核流程。
请求参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| object_key | string | 是 | 5.4 返回的 object_key(raw 模式) |
| m3u8_url | string | hls 模式必填 | 已上传 m3u8 的地址 |
| title | string | 是 | 1-100 字 |
| description | string | 否 | ≤500 字 |
| category_id | int | 是 | 分类 ID |
| duration | int | hls 模式必填 | 时长(秒) |
| tags | array[string] | 否 | 标签,0 |
请求示例
{ "object_key": "upload/tmp/20261014/uuid.mp4", "title": "海边日落", "description": "拍摄于青岛", "category_id": 3, "tags": ["日落", "海边"] }
响应示例
{
"code": 0,
"data": { "video_id": 88001, "status": 0, "status_text": "转码中", "is_priority": true }
}
status:0转码中 1待审核 2已发布 3拒绝 4下架 5转码失败。会员 is_priority=true 进入优先转码队列。
5.7 我的作品 GET /users/me/videos(需登录)
查询参数:page、page_size、status(可选)。
响应列表项同 Feed 单条,另含 status、status_text、reject_reason。
5.8 分类列表 GET /videos/categories
{ "code": 0, "data": [ { "category_id": 1, "name": "生活" }, { "category_id": 2, "name": "美食" } ] }
5.9 标签视频列表 GET /tags/{tag_name}/videos(游客可)
播放页点击标签后跳转页面调用本接口。
路径参数:tag_name — 标签名(URL 编码)
查询参数:page、page_size、sort(hot 默认 / latest)
响应示例
{
"code": 0,
"data": {
"tag": "日落",
"total": 236,
"list": [
{
"video_id": 88001,
"title": "海边日落",
"tags": ["日落", "海边"],
"cover_url": "https://cdn.example.com/hls/88001/cover.jpg",
"video_url": "https://cdn.example.com/hls/88001/index.m3u8",
"author": { "user_id": 100023, "nickname": "小明", "avatar_url": "https://..." },
"view_count": 12034, "like_count": 456, "comment_count": 78, "favorite_count": 90
}
]
}
}
5.10 视频搜索 GET /videos/search(游客可)
查询参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| keyword | string | 是 | 关键词,1-30 字;命中敏感词返回空结果 |
| sort | string | 否 | hot(默认)/ latest |
| page | int | 否 | 页码 |
| page_size | int | 否 | 默认 20,最大 50 |
响应:list 结构同 Feed 单条,另含 total;搜索行为计入热搜统计(Redis search:hot)。
5.11 热搜榜 GET /search/hot(游客可)
{ "code": 0, "data": { "words": ["日落", "美食教程", "猫咪"] } }
返回 Top 10 热搜词,来源于 Redis ZSet search:hot(搜索计数,定时衰减)。
5.12 编辑视频 PUT /videos/{video_id}(需登录,仅作者)
请求参数(均可选,传哪个改哪个)
| 参数 | 类型 | 说明 |
|---|---|---|
| title | string | 1-100 字 |
| description | string | ≤500 字 |
| category_id | int | 分类 ID |
| tags | array[string] | 标签,0 |
响应:{ "code": 0, "data": { "video_id": 88001 } }
错误码:2107 无权操作(非作者本人);2003 视频不存在。
5.13 删除视频 DELETE /videos/{video_id}(需登录,仅作者)
软删除,立即下架不可见;互动计数保留用于后台审计。
响应:{ "code": 0 }
错误码:2107 无权操作(非作者本人);2003 视频不存在。
6. 互动模块
6.1 点赞/取消 POST /videos/{video_id}/like(需登录)
无 body,切换式接口(已点赞则取消)。
响应示例
{ "code": 0, "data": { "is_liked": true, "like_count": 457 } }
6.2 收藏/取消 POST /videos/{video_id}/favorite(需登录)
{ "code": 0, "data": { "is_favorited": true, "favorite_count": 91 } }
6.3 评论列表 GET /videos/{video_id}/comments(游客可)
查询参数:page、page_size、parent_id(查二级回复时传父评论 ID)
响应示例
{
"code": 0,
"data": {
"total": 78,
"list": [
{
"comment_id": 55001,
"user": { "user_id": 100030, "nickname": "阿花", "avatar_url": "https://..." },
"content": "拍得真好",
"like_count": 12,
"reply_count": 3,
"created_at": "2026-10-14 10:00:00"
}
]
}
}
6.4 发表评论 POST /videos/{video_id}/comments(需登录)
请求参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| content | string | 是 | 1-500 字;≥5 字才计入积分奖励进度 |
| parent_id | int | 否 | 回复某评论时传其 ID |
| reply_to_user_id | int | 否 | 被回复人 ID |
请求示例
{ "content": "这个日落太美了,求定位!" }
响应示例
{
"code": 0,
"data": {
"comment_id": 55010,
"reward_progress": { "current": 5, "target": 10, "rewarded_this_time": false }
}
}
当 current 满 10 时服务端自动发放 1 积分并清零进度,此时返回 rewarded_this_time: true, reward_points: 1。
6.5 删除评论 DELETE /comments/{comment_id}(需登录)
本人评论或本人视频下的评论可删。已计入奖励进度的评论删除时进度回退(奖励已发的扣回)。
响应:{ "code": 0, "data": { "reward_progress": { "current": 4, "target": 10 } } }
6.6 我的收藏 GET /users/me/favorites(需登录)
分页列表,结构同 Feed 单条。
6.7 观看历史 GET /users/me/history(需登录)
分页列表,每项:video(同 Feed 单条)+ watched_at + cost_type。
7. 会员模块
7.1 套餐列表 GET /membership/plans(游客可)
响应示例(价格来自服务端配置,前端不硬编码)
{
"code": 0,
"data": [
{ "plan_code": "trial", "name": "体验会员", "days": 1, "points": 5, "enabled": true, "desc": "1天体验,活动同享" },
{ "plan_code": "monthly", "name": "月卡", "days": 30, "points": 300, "enabled": true, "desc": "30天无限观看" },
{ "plan_code": "yearly", "name": "年卡", "days": 365, "points": 3650, "enabled": true, "desc": "365天无限观看" },
{ "plan_code": "lifetime", "name": "终身卡", "days": 0, "points": 10000, "enabled": true, "desc": "永久无限观看" }
],
"benefits": ["无限观看视频", "优先上传(转码/审核优先)"]
}
7.2 我的会员 GET /membership/me(需登录)
{
"code": 0,
"data": {
"is_member": true,
"is_lifetime": false,
"current_plan": "monthly",
"plan_name": "月卡",
"expire_at": "2026-11-13 12:00:00",
"remaining_days": 30,
"history": [
{ "order_no": "M20261014120001", "plan_name": "月卡", "points_cost": 300, "start_at": "2026-10-14 12:00:00", "end_at": "2026-11-13 12:00:00", "source": 1 }
]
}
}
7.3 积分开通会员 POST /membership/redeem(需登录)
请求参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| plan_code | string | 是 | trial/monthly/yearly/lifetime |
请求示例
{ "plan_code": "monthly" }
响应示例
{
"code": 0,
"message": "ok",
"data": {
"order_no": "M20261014120001",
"plan_name": "月卡",
"points_cost": 300,
"remaining_points": 86,
"expire_at": "2026-11-13 12:00:00"
}
}
规则:有效期内重复开通时长叠加;终身卡用户调用返回错误码 2004;积分不足返回 2001。
8. 支付模块
8.1 充值套餐 GET /payments/packages(需登录)
{
"code": 0,
"data": {
"packages": [
{ "id": 1, "amount_yuan": 10, "points": 100, "bonus": 0 },
{ "id": 2, "amount_yuan": 30, "points": 300, "bonus": 0 },
{ "id": 3, "amount_yuan": 100, "points": 1000, "bonus": 50 },
{ "id": 4, "amount_yuan": 200, "points": 2000, "bonus": 150 }
],
"custom": { "enabled": true, "min_yuan": 1, "max_yuan": 10000, "points_per_yuan": 10 },
"pay_methods": [
{ "method": 1, "name": "支付宝" },
{ "method": 2, "name": "微信支付" },
{ "method": 3, "name": "USDT (TRC20)" }
],
"usdt_rate": 7.2
}
}
充值档位由管理后台实时维护(增删改/上下架/排序),前端不硬编码;
points = amount_yuan × points_per_yuan,自定义金额同样按此汇率换算。
8.2 创建充值订单 POST /payments/recharge(需登录)
请求参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| amount_yuan | int | 是 | 充值金额(元),须为后台已上架档位,或 custom.enabled=true 时的自定义金额 |
| pay_method | int | 是 | 1支付宝 2微信 3USDT |
请求示例
{ "amount_yuan": 30, "pay_method": 1 }
响应示例(支付宝)
{
"code": 0,
"data": {
"order_no": "R20261014123000001",
"pay_method": 1,
"amount_yuan": 30,
"points": 300,
"expire_at": "2026-10-14 13:00:00",
"pay_params": { "order_string": "alipay_sdk=alipay-sdk-php-dynamic&app_id=..." }
}
}
响应示例(微信):pay_params 含 appid/partnerid/prepayid/package/noncestr/timestamp/sign,供 App SDK 调起。
响应示例(USDT)
{
"code": 0,
"data": {
"order_no": "R20261014123000002",
"pay_method": 3,
"amount_yuan": 30,
"points": 300,
"usdt_rate": 7.2,
"usdt_amount": "4.167",
"receive_address": "TXYz...abc",
"network": "TRC20",
"expire_at": "2026-10-14 13:00:00"
}
}
USDT 金额含随机尾差用于订单匹配;用户须按显示金额精确转账,满 19 个区块确认后自动到账。
8.3 查询订单 GET /payments/orders/{order_no}(需登录)
App 调起支付后每 2 秒轮询,直至 status != 0 或超过 30 次。
响应示例
{
"code": 0,
"data": {
"order_no": "R20261014123000001",
"status": 1,
"status_text": "已支付",
"points": 300,
"paid_at": "2026-10-14 12:35:20",
"wallet_points": 386
}
}
status:0待支付 1已支付 2已关闭 3已退款。
8.4 取消订单 POST /payments/orders/{order_no}/cancel(需登录)
仅"待支付"可取消。响应 { "code": 0 }。
8.5 支付宝回调 POST /callbacks/alipay(平台 → 服务端)
- Content-Type:
application/x-www-form-urlencoded - 服务端处理:RSA2 验签 → 校验
out_trade_no/total_amount→ 幂等入账 → 返回纯文本success - App 不直接调用本接口
8.6 微信支付回调 POST /callbacks/wechat(平台 → 服务端)
- V3 回调:验签(
Wechatpay-Signature头)→ AES-GCM 解密resource→ 幂等入账 → 返回{ "code": "SUCCESS" }
8.7 USDT 到账说明
USDT 无支付平台回调,由服务端每 15 秒轮询 TronGrid:
匹配条件 = 收款地址一致 + 金额(含尾差)精确相等 + 转账时间在订单有效期内 + 确认数 ≥ 19。
匹配成功即入账(tx_hash 写入 third_trade_no,唯一索引保证幂等);超时未匹配订单自动关闭。
9. 激励模块
资产体系:10 资产 = 1 元,资产存放于资产钱包,可申请提现(后台人工审核打款)。推荐奖励与充值返利仅在推荐人为会员时发放(发放时点校验会员身份)。
9.1 我的邀请 GET /referral/me(需登录)
响应示例
{
"code": 0,
"data": {
"invite_code": "K7X2M9",
"invite_url": "https://app.example.com/r/K7X2M9",
"eligible": true,
"total_invitees": 12,
"activated_count": 8,
"reward_points_total": 80,
"rebate_assets_total": 150.0
}
}
eligible:当前是否会员(false 时被推荐人仍可绑定,但不产生奖励)
9.2 绑定邀请码 POST /referral/bind(需登录)
注册时未填邀请码的用户,注册后 24 小时内可补绑一次(每人仅能绑定一次)。
请求参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| invite_code | string | 是 | 推荐人邀请码 |
// 请求
{ "invite_code": "K7X2M9" }
// 响应
{ "code": 0, "data": { "bound": true, "status": 0, "status_text": "待激活" } }
错误码:2101(邀请码无效 / 已绑定过 / 绑定自己 / 同设备已注册其他账号)
被推荐人激活(72h 内累计观看 ≥3 个视频且次日有登录)后,推荐人获得 10 积分(可配置,不限量)。被推荐人此后每次充值成功,推荐人获得"充值积分 × 5%"的资产(不限量)。
9.3 资产钱包 GET /assets/me(需登录)
响应示例
{
"code": 0,
"data": {
"assets": 236.5,
"assets_value_yuan": 23.65,
"total_earned": 400.0,
"total_withdrawn": 163.5,
"min_withdraw_assets": 100,
"has_pending_withdraw": false
}
}
9.4 资产流水 GET /assets/records(需登录)
查询参数:page、page_size、biz_type(可选:1充值返利 2完整观看收益 3点赞收益 4提现 5提现退回 6返利扣回 7后台调整)
响应示例
{
"code": 0,
"data": {
"total": 21,
"list": [
{ "id": 301, "change_amount": 1.0, "balance_after": 236.5, "biz_type": 2, "remark": "视频完整观看收益(视频88001)", "created_at": "2026-10-14 15:00:00" },
{ "id": 300, "change_amount": 15.0, "balance_after": 235.5, "biz_type": 1, "remark": "推荐用户充值返利", "created_at": "2026-10-14 14:20:00" }
]
}
}
9.5 申请提现 POST /assets/withdraw(需登录)
请求参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| assets | number | 是 | 提现资产数,≥100(可配置),按 10 资产 = 1 元折算 |
| channel | int | 是 | 1支付宝 2微信 3USDT |
| account | string | 是 | 收款账号(支付宝账号/微信号/USDT 地址) |
// 请求
{ "assets": 150, "channel": 1, "account": "user@example.com" }
// 响应
{ "code": 0, "data": { "withdraw_no": "W20261014153000001", "assets": 150.0, "amount_yuan": 15.0, "status": 0, "status_text": "待审核" } }
错误码:2102 资产余额不足;2103 低于最低提现额度;2104 已有审核中的提现申请。
提交即冻结扣减资产,后台人工审核后打款;审核拒绝资产自动退回资产钱包。
9.6 提现记录 GET /assets/withdraw/records(需登录)
响应示例
{
"code": 0,
"data": {
"total": 2,
"list": [
{ "withdraw_no": "W20261014153000001", "assets": 150.0, "amount_yuan": 15.0, "channel": 1, "status": 0, "status_text": "待审核", "created_at": "2026-10-14 15:30:00" }
]
}
}
9.7 推广点击埋点 POST /invite/click(无需登录)
H5 推广落地页(9.9)打开时自动调用,记录「邀请码 + IP + UA」用于后续归因。同 IP+code 60 秒内重复上报自动去重。
请求参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| code | string | 是 | 推广链接中的邀请码(8 位,自动转大写) |
// 请求
{ "code": "K7X2M9AB" }
// 响应
{ "code": 0, "data": { "recorded": true } }
IP 取自
X-Real-IP头(Nginx 反代透传)或直连来源;点击记录存 Redis 24h 有效。
9.8 首启归因匹配 POST /invite/match(无需登录)
App 首次启动且剪贴板无分享口令时调用一次(每安装仅一次)。服务端按 IP 取最近 24h 内最近点击的邀请码,命中则按 device_id 缓存 7 天;用户注册时自动消费该缓存完成推荐绑定(客户端无需也无法回传)。
请求参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| device_id | string | 是 | 设备指纹(与 X-Device-ID 一致) |
// 请求
{ "device_id": "a1b2c3d4-..." }
// 响应(未命中)
{ "code": 0, "data": { "matched": false } }
// 响应(命中)
{ "code": 0, "data": { "matched": true, "invite_code": "K7X2M9AB" } }
命中后重复调用直接返回缓存结果(幂等);注册绑定优先级:显式 invite_code(口令/手填)> 本接口归因缓存。
9.9 H5 推广落地页 GET /r/{code}(浏览器访问,HTML)
分享推广链接指向的落地页(根路径,非 /api/v1 前缀),返回 HTML:
- 页面展示邀请人昵称、"复制邀请口令"按钮(口令格式
#短视频邀请码{code}#,供被邀请人首启剪贴板解析) - system_configs
app.download_url已配置时展示"下载 APP"按钮 - 页面加载即自动调用 9.7 完成点击埋点
无效邀请码正常渲染通用页面(不报错),保证分享链接永可用。
10. 通用与消息模块
10.1 版本检查 GET /app/version(游客可)
App 启动时调用,检查版本更新与公告。
查询参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| platform | string | 是 | ios / android |
| version_code | int | 是 | 当前 App 版本号 |
响应示例
{
"code": 0,
"data": {
"latest_version": "1.2.0",
"latest_version_code": 12,
"force_update": false,
"update_url": "https://app.example.com/download",
"notice": "新版本优化了播放体验"
}
}
force_update=true 时 App 弹强制更新弹窗(不可跳过)。
10.2 通知列表 GET /notifications(需登录)
查询参数:type(可选:1审核结果 2提现进度 3系统公告 4评论回复)、page、page_size
响应示例
{
"code": 0,
"data": {
"total": 3,
"list": [
{ "id": 701, "type": 1, "title": "视频审核通过", "content": "你发布的《海边日落》已通过审核", "biz_id": "88001", "is_read": false, "created_at": "2026-10-14 15:00:00" }
]
}
}
10.3 未读数 GET /notifications/unread_count(需登录)
{ "code": 0, "data": { "unread": 3 } }
App 我的页消息入口红点依赖本接口(直接读 Redis notif:unread:{user_id})。
10.4 标记已读 POST /notifications/read(需登录)
请求参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| ids | array[int] | 否 | 通知 ID 数组;与 all 二选一 |
| all | bool | 否 | true 表示全部标记已读 |
响应:{ "code": 0 }
10.5 提交举报 POST /reports(需登录)
请求参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| target_type | int | 是 | 1视频 2评论 |
| target_id | int | 是 | 举报对象 ID |
| reason_type | int | 是 | 1色情低俗 2暴力血腥 3侵权 4广告营销 5其他 |
| remark | string | 否 | 补充说明,≤200 字 |
// 请求
{ "target_type": 1, "target_id": 88001, "reason_type": 1, "remark": "包含不适内容" }
// 响应
{ "code": 0, "message": "已收到举报,我们会尽快处理" }
错误码:2106 请勿重复举报(同一用户对同一对象仅一次有效举报,唯一索引 uk_user_target 保证);限流 10 次/天。
11. 管理后台接口
通用约定:
- 前缀
/api/v1/admin,统一响应结构同 App 接口 - 认证:
Authorization: Bearer <admin_token>(Token payloadtype="admin",有效期 12h,与 App 用户体系互不相通) - 角色:
super(全部)/reviewer(仅审核)/operator(套餐、活动、看板);越权返回 4001 - 所有写操作记录操作日志;标注【敏感】的接口
reason必填,缺失返回 4002
11.1 管理员登录 POST /admin/auth/login
// 请求
{ "username": "admin", "password": "xxxx" }
// 响应
{ "code": 0, "data": { "admin_token": "eyJ...", "expires_in": 43200, "admin": { "id": 1, "name": "超管", "role": "super" } } }
11.2 仪表盘 GET /admin/dashboard
{
"code": 0,
"data": {
"today": { "dau": 1520, "new_users": 86, "recharge_yuan": 4600, "points_issued": 46000, "points_consumed": 12300, "views": 30211 },
"pending_review_count": 17,
"total": { "users": 50210, "videos": 8200, "recharge_yuan": 128000 }
}
}
11.3 待审核视频列表 GET /admin/videos/pending
查询参数:page、page_size。响应列表项含视频全部字段(含 video_url 供在线预览)+ 作者信息。
11.4 审核视频 POST /admin/videos/{video_id}/review
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| action | string | 是 | approve / reject |
| reason | string | reject 时必填 | 拒绝原因(回显给作者) |
// 请求
{ "action": "approve" }
// 响应
{ "code": 0, "data": { "video_id": 88001, "status": 2, "status_text": "已发布" } }
11.5 下架视频 POST /admin/videos/{video_id}/offline【敏感】
{ "reason": "内容违规" }
11.6 用户列表 GET /admin/users
查询参数:keyword(ID/手机号/邮箱)、status、page、page_size。
响应列表项:用户基础信息 + points + is_member + video_count。
11.7 用户详情 GET /admin/users/{user_id}
响应:用户信息 + 钱包 + 会员状态 + 近 10 条积分流水 + 作品数/获赞数。
11.8 封禁/解封用户 PUT /admin/users/{user_id}/status【敏感】
{ "status": 2, "reason": "发布违规内容" }
status:1 正常 / 2 封禁。封禁后该用户 Token 立即失效(Redis 白名单剔除)。
11.9 积分调整 POST /admin/points/adjust【敏感】
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| user_id | int | 是 | 目标用户 |
| change_amount | int | 是 | 正=加,负=减 |
| reason | string | 是 | 调整原因 |
// 响应
{ "code": 0, "data": { "user_id": 100023, "change_amount": 100, "balance_after": 486 } }
11.10 积分流水查询 GET /admin/points/records
查询参数:user_id、biz_type、page、page_size。响应结构同 App 端积分明细。
11.11 充值订单查询 GET /admin/orders
查询参数:order_no、user_id、pay_method、status、start_date、end_date、page。
响应列表项:订单全字段(含 usdt_amount / third_trade_no)。
11.12 人工补单 POST /admin/orders/{order_no}/resettle【敏感】
用于"用户已付款但回调未到账"的异常单。核实支付平台/链上确已收款后调用,走与回调相同的幂等入账流程。
{ "reason": "微信回调丢失,商户后台已核实收款", "third_trade_no": "4200001234567890" }
11.13 充值套餐列表 GET /admin/packages
返回全部套餐(含下架),字段同 App 端 8.1 的 packages 项 + status、sort。
11.14 新增套餐 POST /admin/packages
// 请求(points 由服务端按汇率计算,也可显式传入覆盖)
{ "amount_yuan": 50, "bonus_points": 20, "sort": 10 }
// 响应
{ "code": 0, "data": { "id": 5, "amount_yuan": 50, "points": 500, "bonus_points": 20, "sort": 10, "status": 1 } }
11.15 修改套餐 PUT /admin/packages/{package_id}
可改 amount_yuan / bonus_points / sort / status,实时生效。
11.16 删除套餐 DELETE /admin/packages/{package_id}
物理删除或下架(存在历史订单引用的套餐仅允许下架)。
11.17 赠送会员/积分 POST /admin/gift【敏感】
// 请求:赠送体验会员
{ "user_ids": [100023, 100024], "gift_type": "membership", "plan_code": "trial", "reason": "国庆活动" }
// 请求:赠送积分
{ "user_ids": [100023], "gift_type": "points", "points": 100, "reason": "客服补偿" }
// 响应
{ "code": 0, "data": { "success": 2, "failed": 0 } }
赠送会员写入 membership_orders(source=2,points_cost=0);赠送积分写积分流水(biz_type=5)。
11.18 操作日志 GET /admin/logs
查询参数:admin_id、action、page。仅 super 可查。
11.19 提现列表 GET /admin/withdrawals
查询参数:status、user_id、page、page_size。
响应列表项:提现单全字段 + 用户昵称。
11.20 提现审核 POST /admin/withdrawals/{withdraw_no}/review【敏感】
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| action | string | 是 | approve(已完成线下打款,确认)/ reject(拒绝并退回资产) |
| reason | string | reject 时必填 | 拒绝原因 |
// 请求
{ "action": "reject", "reason": "收款账号信息有误" }
// 响应
{ "code": 0, "data": { "withdraw_no": "W20261014153000001", "status": 2, "refunded_assets": 150.0 } }
11.21 推荐关系列表 GET /admin/referrals
查询参数:inviter_id、status、risk_flag、page、page_size。
响应列表项:推荐关系全字段 + 双方用户昵称。
11.22 推荐风控处理 POST /admin/referrals/{referral_id}/review【敏感】
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| action | string | 是 | release(解冻,恢复待激活流程)/ invalid(判无效,奖励不发放) |
| reason | string | 是 | 处理说明 |
{ "action": "invalid", "reason": "同设备批量注册小号" }
11.23 平台配置列表 GET /admin/configs
返回 system_configs 全部键值。
{
"code": 0,
"data": {
"list": [
{ "config_key": "register_gift_trial.enabled", "config_value": "1", "description": "注册赠送体验会员开关(1开/0关)", "updated_at": "2026-10-14 10:00:00" },
{ "config_key": "register_gift_trial.days", "config_value": "1", "description": "注册赠送体验会员天数", "updated_at": "2026-10-14 10:00:00" }
]
}
}
11.24 修改平台配置 PUT /admin/configs/{config_key}
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| value | string | 是 | 新配置值 |
// 请求:关闭注册赠送体验会员
{ "value": "0" }
// 响应
{ "code": 0, "data": { "config_key": "register_gift_trial.enabled", "config_value": "0" } }
修改实时生效(服务端配置缓存 60s 自动失效),操作写入 admin_logs。
11.25 视频列表 GET /admin/videos
查询参数:keyword(ID/标题)、status、author_id、page、page_size。
响应列表项:视频全字段 + 作者昵称。
11.26 评论列表 GET /admin/comments
查询参数:video_id、user_id、keyword(评论内容)、page、page_size。
响应列表项:评论全字段 + 用户昵称 + 视频标题。
11.27 删除评论 DELETE /admin/comments/{comment_id}【敏感】
{ "reason": "垃圾广告" }
删除后触发评论奖励回退(已计入进度回退、已发奖励扣回),与作者自删逻辑一致。
11.28 举报列表 GET /admin/reports
查询参数:status、target_type、page、page_size。
响应列表项:举报全字段 + 举报人昵称 + 被举报对象摘要(视频标题/评论内容)。
11.29 举报处理 POST /admin/reports/{report_id}/review【敏感】
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| action | string | 是 | offline_video(下架视频)/ delete_comment(删除评论)/ reject(驳回举报) |
| reason | string | 是 | 处理说明 |
// 请求
{ "action": "offline_video", "reason": "核实违规,下架处理" }
// 响应
{ "code": 0, "data": { "report_id": 301, "status": 1, "status_text": "已处理" } }
处理结果通过站内通知(type=1)告知举报人;下架/删除动作复用对应业务流程(含作者通知、评论奖励回退)。
11.30 敏感词列表 GET /admin/sensitive-words
查询参数:keyword、page、page_size。
{ "code": 0, "data": { "total": 120, "list": [ { "id": 1, "word": "违禁词", "created_at": "2026-10-14 10:00:00" } ] } }
11.31 添加敏感词 POST /admin/sensitive-words
// 请求
{ "word": "新违禁词" }
// 响应
{ "code": 0, "data": { "id": 121, "word": "新违禁词" } }
重复添加返回错误码 1001;添加后 Redis 词库缓存(words:sensitive)失效重建,实时生效。
11.32 删除敏感词 DELETE /admin/sensitive-words/{id}
响应 { "code": 0 },同样触发词库缓存重建。
12. App 端关键调用时序
12.1 启动与域名发现
App 启动 → 解析 txt.256kb.top 的 DNS TXT 记录(DoH)
├─ 成功 → 以 TXT 内容作为 API Base URL(写入本地缓存)
└─ 失败/为空 → 计算 md5(yyyyMM) + "_jsnbhh.vip" 作为 Base URL
→ 进入首页拉取 Feed;缓存域名连续请求失败达阈值时重新执行发现流程
12.2 播放计费
App 滑入视频 → 本地查"今日已上报"集合
├─ 已上报 → 直接播放
└─ 未上报 → POST /videos/{id}/watch
├─ code=0 → 记录已上报;若 cost_type=1 弹 Toast"本次消耗 1 积分"
├─ code=2002 → 弹登录引导(游客)
└─ code=2001 → 弹"积分不足"(去充值 / 开通会员)
12.3 充值
选套餐+支付方式 → POST /payments/recharge → 按 pay_method:
支付宝/微信 → 调起 SDK → 返回 App → 轮询 GET /payments/orders/{order_no} → 成功刷新钱包
USDT → 展示金额/地址/二维码+倒计时 → 用户转账 → 轮询订单 → 到账刷新钱包
12.4 开通会员
GET /membership/plans → 选择套餐 → POST /membership/redeem
├─ code=0 → 刷新 /users/me 与会员状态
└─ code=2001 → 跳充值页(带回跳)