订阅管理 API
用户订阅管理接口,包括查询当前订阅详情、变更套餐、取消续订和恢复续订。
路由前缀:/billing
源码:apps/backend/src/routes/billing-subscription.ts
认证
所有接口需要 JWT 认证:
Authorization: Bearer <JWT>权限要求:查询接口(GET)仅需团队成员身份;写入接口(POST)需要团队 owner 或 admin 角色。
端点
1. 获取当前订阅
GET /billing/subscription获取当前团队的订阅详情和积分余额。
查询参数:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
teamId | string | 否 | 团队 ID(未提供时回退到用户的第一个团队) |
示例请求:
bash
curl -X GET "https://block2-api.wainao.chat/billing/subscription?teamId=xxx" \
-H "Authorization: Bearer <JWT>"响应 200 OK:
json
{
"success": true,
"data": {
"subscription": {
"id": "uuid",
"planCode": "pro",
"billingPeriod": "monthly",
"status": "active",
"monthlyCredits": 100000,
"currentPeriodStart": "2026-03-01T00:00:00.000Z",
"currentPeriodEnd": "2026-04-01T00:00:00.000Z",
"cancelAtPeriodEnd": false,
"canceledAt": null,
"scheduledPlanCode": null
},
"balance": {
"totalCredits": 85000,
"grantCredits": 80000,
"purchaseCredits": 5000,
"periodEnd": "2026-04-01T00:00:00.000Z",
"periodGrantedCredits": 100000
}
}
}提示
subscription 或 balance 可能为 null(例如新团队尚未创建订阅记录时)。
错误码:
| HTTP | 错误码 | 说明 |
|---|---|---|
| 400 | NO_TEAM | 用户不在任何团队中 |
| 500 | — | 服务端错误 |
2. 变更套餐
POST /billing/subscription/change-plan申请变更订阅计划。升级时返回支付指引(需先创建支付订单);降级时设置 scheduledPlanCode,在当前计费周期末自动生效。
请求体:
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
teamId | string | 是 | 团队 ID |
targetPlanCode | string | 是 | 目标计划代码(如 pro、free) |
billingPeriod | string | 是 | 计费周期(如 monthly、yearly) |
示例请求:
bash
curl -X POST "https://block2-api.wainao.chat/billing/subscription/change-plan" \
-H "Authorization: Bearer <JWT>" \
-H "Content-Type: application/json" \
-d '{"teamId": "xxx", "targetPlanCode": "pro", "billingPeriod": "monthly"}'响应 200 OK:
json
{
"success": true,
"data": {
"action": "downgrade_scheduled",
"scheduledPlanCode": "free",
"effectiveAt": "2026-04-01T00:00:00.000Z"
}
}错误码:
| HTTP | 错误码 | 说明 |
|---|---|---|
| 400 | BAD_REQUEST | 缺少 teamId |
| 400 | — | 缺少 targetPlanCode 或 billingPeriod |
| 400 | NO_TEAM | 用户不在该团队中 |
| 403 | FORBIDDEN | 无权限(非 owner/admin) |
| 500 | — | 服务端错误 |
3. 取消续订
POST /billing/subscription/cancel-renewal取消自动续费。订阅在当前周期结束后不再续期。
请求体:
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
teamId | string | 是 | 团队 ID |
示例请求:
bash
curl -X POST "https://block2-api.wainao.chat/billing/subscription/cancel-renewal" \
-H "Authorization: Bearer <JWT>" \
-H "Content-Type: application/json" \
-d '{"teamId": "xxx"}'响应 200 OK:
json
{
"success": true
}错误码:
| HTTP | 错误码 | 说明 |
|---|---|---|
| 400 | BAD_REQUEST | 缺少 teamId |
| 400 | NO_TEAM | 用户不在该团队中 |
| 403 | FORBIDDEN | 无权限(非 owner/admin) |
| 500 | — | 服务端错误 |
4. 恢复续订
POST /billing/subscription/resume-renewal恢复已取消的自动续费。
请求体:
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
teamId | string | 是 | 团队 ID |
示例请求:
bash
curl -X POST "https://block2-api.wainao.chat/billing/subscription/resume-renewal" \
-H "Authorization: Bearer <JWT>" \
-H "Content-Type: application/json" \
-d '{"teamId": "xxx"}'响应 200 OK:
json
{
"success": true
}错误码:
| HTTP | 错误码 | 说明 |
|---|---|---|
| 400 | BAD_REQUEST | 缺少 teamId |
| 400 | NO_TEAM | 用户不在该团队中 |
| 403 | FORBIDDEN | 无权限(非 owner/admin) |
| 500 | — | 服务端错误 |