feat: add staged subscription rollout mode

This commit is contained in:
QiuSW
2026-07-22 15:13:28 +08:00
parent e3b90ccea5
commit 2604a59d67
17 changed files with 551 additions and 87 deletions
+31 -1
View File
@@ -41,7 +41,37 @@ T-305 已实现扫码充值下单与轮询基线:`POST /api/v1/recharge/create
T-629 已完成:软件套餐订单使用独立 `SoftwareOrder`、`POST /api/v1/software-orders/callback/wechat` 与 `GET /api/v1/software-orders/status`,只发放/续订软件权益,绝不兑换点数或触碰 `RechargeOrder` / `PointsLedger`。订阅微信下单必须配置独立 `SOFTWARE_WECHAT_PAY_NOTIFY_URL`,不得复用充值回调地址。
T-630 已完成:蝦皮圈产品专属接口按 API Key 对应用户查询 `SoftwareEntitlement`,默认允许同一账号在多台电脑使用;设备登记、设备会话和历史凭证不再作为授权前置条件。`GET /api/v1/cmshopee/subscription/status` 返回 `product_code`、`status`(`active` / `expired` / `required`)、`allowed`、`code` 和套餐到期信息。`CMSHOPEE_SUBSCRIPTION_ENFORCEMENT=false` 时保持兼容并只记录影子授权结果;开启后产品专属生成入口对无订阅或已过期账号返回 403,通用生成接口不受影响。
T-630/T-632 已完成:蝦皮圈产品专属接口按 API Key 对应用户查询 `SoftwareEntitlement`,默认允许同一账号在多台电脑使用;设备登记、设备会话和历史凭证不再作为授权前置条件。`CMSHOPEE_SUBSCRIPTION_MODE` 支持 `open`(开发测试统一放行)、`shadow`(放行并记录真实权益)和 `enforce`(按真实权益拦截);通用生成接口不受影响。旧 `CMSHOPEE_SUBSCRIPTION_ENFORCEMENT` 仅在新配置缺失时作为兼容回退。
`GET /api/v1/cmshopee/subscription/status` 使用 API Key 鉴权。响应中的 `status` / `allowed` 表示当前模式下的最终访问结果,`entitlement_status` 表示数据库真实权益状态;二者在 `open` / `shadow` 下可能不同。示例:
```json
{
"product_code": "cmshopee",
"status": "active",
"allowed": true,
"code": null,
"account": {
"display_name": "cmhub_user",
"username": "cmhub_user"
},
"plan": {
"code": "development-open",
"display_name": "开发测试长期会员",
"name": "开发测试长期会员",
"expires_at": "2099-12-31T23:59:59+00:00",
"grace_expires_at": null
},
"expires_at": "2099-12-31T23:59:59+00:00",
"grace_expires_at": null,
"manage_url": "https://cmhub.example.com/subscription",
"notice_id": "cmshopee-subscription-open-required-v1",
"access_source": "open_mode",
"entitlement_status": "required"
}
```
`plan.name`、`plan.expires_at`、`plan.grace_expires_at` 是 T-630 旧客户端兼容字段;新客户端使用 `plan.code` / `plan.display_name` 和顶层有效期。`access_source` 取 `open_mode`、`shadow_fallback` 或 `entitlement`。真实权益已进入宽限期时 `status` / `entitlement_status` 为 `grace`;无权益和过期在 `enforce` 模式分别返回 `required` / `expired`,对应产品 submit 的 `subscription_required` / `subscription_expired` 403。
T-306 已实现对外 API 安全加固:`image_url` 下载只允许 `http` / `https` 公网地址,拒绝私有/回环/链路本地/保留等地址,重定向后重新校验并限制响应大小;全局 DRF 默认认证为空且默认权限为 `IsAuthenticated`,外部 API 与用户端 API 必须显式 opt-in 认证类;生成接口按 API Key / 用户限流,认证失败按 IP 限流;充值创建有 `RECHARGE_MAX_AMOUNT_CNY` 单笔上限。