购买与兑换码 API
baozi 用户通过这套接口:
- 下单购买套餐 → 拿订单号
- 查看自己的订单历史
- 用兑换码充值(无需下单)
鉴权
所有接口都需要 baozi 用户登录(OIDC)。
1. 模拟下单(仅前端 dashboard 用)
POST /api/purchase/mock
⚠️ 此端点仅用于前端 dashboard 演示流程,不会真实扣款。真实下单走第三方集成(见 third-party.md)。
请求 body:
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
package_id |
string | 是 | 套餐 ID |
tier_id |
string | 否 | 套餐 tier ID(多档套餐必填) |
period |
string | 否 | month / year,默认 month |
payment_method |
string | 否 | mock(默认) / wechat / alipay |
响应 200:
{
"success": true,
"data": {
"order_id": "ord-20260827-001",
"status": "paid",
"package_id": "pkg-daily-chat",
"amount_yuan": 28,
"quota_added": 5000,
"created_at": 1730000000000
}
}
错误码:
| HTTP | code | 含义 |
|---|---|---|
| 400 | MISSING_PACKAGE_ID |
未传 package_id |
| 400 | INVALID_PERIOD |
period 不是 month / year |
| 404 | PACKAGE_NOT_FOUND |
套餐不存在或已禁用 |
| 400 | MISSING_TIER_ID |
多档套餐未指定 tier |
2. 查询我的订单
GET /api/purchase/orders
查询参数:
| 参数 | 类型 | 默认 | 说明 |
|---|---|---|---|
limit |
number | 20 | 最多返回条数 |
offset |
number | 0 | 跳过条数 |
status |
string | - | 过滤:paid / pending / refunded |
响应 200:
{
"success": true,
"data": {
"items": [
{
"id": "ord-20260827-001",
"package_id": "pkg-daily-chat",
"package_name": "日常聊天",
"amount_yuan": 28,
"quota_added": 5000,
"status": "paid",
"period": "month",
"created_at": 1730000000000,
"paid_at": 1730000000000
}
],
"total": 1
}
}
3. 用兑换码充值
POST /api/topup/redeem
请求 body:
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
code |
string | 是 | 兑换码(区分大小写) |
示例:
curl -X POST https://baozi.ohoooho.com/api/topup/redeem \
-H "Authorization: Bearer $BAOZI_TOKEN" \
-H "Content-Type: application/json" \
-d '{"code": "BAOZI-2026-ABCD-XYZ1"}'
响应 200:
{
"success": true,
"data": {
"quota_added": 10000,
"code": "BAOZI-2026-ABCD-XYZ1",
"expires_at": 1732592000000
}
}
错误码:
| HTTP | code | 含义 |
|---|---|---|
| 400 | MISSING_CODE |
未传 code |
| 400 | INVALID_CODE |
兑换码不存在 |
| 400 | CODE_ALREADY_USED |
已被使用 |
| 400 | CODE_EXPIRED |
兑换码已过期 |
⚠️ 每个兑换码仅可使用 1 次。
4. 管理员:生成兑换码
POST /api/v1/admin/redemption
请求 body:
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
quota |
number | 是 | 兑换码包含的配额 tokens |
count |
number | 否 | 批量生成数量,默认 1 |
expires_at |
number | 否 | Unix 毫秒;-1=永不过期 |
note |
string | 否 | 内部备注(用户不可见) |
响应 200:
{
"success": true,
"data": {
"codes": [
"BAOZI-2026-ABCD-XYZ1",
"BAOZI-2026-ABCD-XYZ2"
]
}
}
GET /api/v1/admin/redemption
查看所有已生成的兑换码(含使用情况)。
5. 管理员:退款
POST /api/v1/admin/refund-purchase
请求 body:
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
order_id |
string | 是 | 订单 ID |
reason |
string | 否 | 退款原因(内部记录) |
响应 200:
{ "success": true, "data": { "order_id": "...", "status": "refunded", "refunded_at": 1730000000000 } }
错误码:
| HTTP | code | 含义 |
|---|---|---|
| 404 | ORDER_NOT_FOUND |
订单不存在 |
| 400 | ALREADY_REFUNDED |
已退款,不可重复 |
6. 管理员:补单 / 赠送配额
POST /api/v1/admin/grant-quota
直接给用户赠送配额(无需下单)。
请求 body:
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
username |
string | 是 | 目标用户 |
quota |
number | 是 | 配额 tokens |
reason |
string | 否 | 内部原因(必填建议) |
联系 baozi
文档不全?发邮件到 support@ohoooho.com 或在飞书群里 @ 闲云。