feat: 通用授权后台、离线证、Waffo 支付页与仪表盘加强
支持多产品计划展示、LICOFF 离线签发、支付独立配置与调试,以及分析看板;同步更新 README 与集成文档。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
1 parent
0966375076
commit
8cc2c83f9d
41 files changed
+3177
-332
No files matched your search
@@ -0,0 +1,69 @@
|
||||
# OpsXShell / 多产品授权模型
|
||||
|
||||
管理端 `opsx-licence` 与客户端(PC / Web / 移动)的最小合理授权结构。目标:在线可座位管理,离线可自包含验签,支付与发证解耦;**产品维度通用**,不绑死单一桌面端。
|
||||
|
||||
## 核心实体
|
||||
|
||||
| 实体 | 含义 |
|
||||
|------|------|
|
||||
| **Product** | 可售卖产品(如 `opsxshell`;可扩展更多) |
|
||||
| **Plan** | 定价档位(SKU),不是用户手里的证 |
|
||||
| **Customer** | 客户(邮箱 / 公司) |
|
||||
| **License** | 许可证实例(在线 `LIC-…` 或离线 `LICOFF-…`) |
|
||||
| **Activation** | 设备座位(在线多座位;离线签发时绑 1 台) |
|
||||
| **Order** | 支付订单;Waffo 只收款,**发证统一走 License** |
|
||||
|
||||
> 「客户权益 Entitlement」仍可能被订单履约写入,但管理菜单已移除独立权益页——运营以 **订单 + License** 为准。
|
||||
|
||||
## 三档 Plan(OpsXShell 默认)
|
||||
|
||||
| plan_type | 显示名 | 时长 | 设备数 |
|
||||
|-----------|--------|------|--------|
|
||||
| `trial` | 体验 | 180 天 | 1 |
|
||||
| `yearly` | 包年 | 365 天 | 2 |
|
||||
| `perpetual` | 永久 | 0=永久 | 5 |
|
||||
|
||||
管理端 **定价计划** 列表必须展示所属 **产品**;启动时 seed 会同步中文名。
|
||||
|
||||
## 在线 vs 离线
|
||||
|
||||
### 在线证(`LIC-…`)
|
||||
|
||||
- 服务端签发与激活;座位在 `activations`
|
||||
- 客户端:`/api/v1/license/activate|verify|heartbeat|deactivate`
|
||||
- 支持 trial / yearly / perpetual;永久仅在线
|
||||
|
||||
### 离线证(`LICOFF-1.<payload>.<sig>`)
|
||||
|
||||
- Ed25519 自包含;载荷含 `device_id`、`plan_type`、`iat`/`exp`
|
||||
- **最长 365 天**;仅 trial / yearly;**禁止永久离线证**
|
||||
- **必须绑定对方提供的 device_id**(换机无效)
|
||||
- **不可「续期」**:到期后重新签发新序列号(可同设备)
|
||||
- 管理端独立页:`/offline-licenses`
|
||||
- 环境变量:`OFFLINE_LICENSE_SEED`(派生密钥);公钥可供客户端嵌入
|
||||
|
||||
## 支付边界
|
||||
|
||||
- 配置入口:**支付** 菜单(非系统设置)
|
||||
- Product ID 使用可扩展映射表(多 SKU)
|
||||
- 调试:`POST /api/payment/waffo/debug`
|
||||
- 详见 [waffo-integration.md](./waffo-integration.md)
|
||||
|
||||
## 客户端约定
|
||||
|
||||
- API Base:`https://l123.91ai.io/api`(或自建域名 + `/api`)
|
||||
- 激活识别:`LIC-…` → 在线;`LICOFF-…` → 本地验签
|
||||
- 激活请求建议带 `device_info` JSON(`platform` / `country` 等),便于仪表盘「平台 / 地理」分布
|
||||
|
||||
## 仪表盘指标
|
||||
|
||||
- License 总数、已过期、在线设备(约 5 分钟心跳)
|
||||
- 本月 / 累计收入、License 增长趋势
|
||||
- 产品分布、地理/网络粗分、客户端形态(pc/web/mobile)
|
||||
|
||||
## 废弃 / 避免
|
||||
|
||||
- 计划英文渣名面向运营(`Trial 180d` 等)
|
||||
- 旧 `opsx1.` 令牌、客户端粘贴商户私钥当激活码
|
||||
- 永久离线证、未绑设备的万能离线串
|
||||
- 把支付私钥写进仓库或前端
|
||||
@@ -0,0 +1,45 @@
|
||||
# Waffo 支付与授权服务器打通
|
||||
|
||||
依据官方文档:[AI Integration](https://docs.waffo.ai/zh/integrate/ai-integration)
|
||||
|
||||
## 正确闭环
|
||||
|
||||
```text
|
||||
客户端 Checkout
|
||||
→ opsx-licence 创建本地订单 ORD-…
|
||||
→ API Key / Store Slug → POST https://api.waffo.ai/v1/actions/checkout/create-session
|
||||
orderMerchantExternalId=ORD-…, metadata, successUrl
|
||||
→ 用户付款
|
||||
→ Webhook POST /api/v1/webhooks/waffo(order.completed)
|
||||
→ 按 orderMerchantExternalId 标记 paid 并发 License
|
||||
→ successUrl / deep link 回客户端
|
||||
```
|
||||
|
||||
**不要**只拼 `pancake.waffo.ai/store/.../product/...` 托管页:无法可靠写入 `orderMerchantExternalId`,会导致本地订单一直 pending。
|
||||
|
||||
## 管理端配置(推荐)
|
||||
|
||||
打开 **支付** 页(`/payments`),填写:
|
||||
|
||||
| 项 | 说明 |
|
||||
|----|------|
|
||||
| 商户 ID | `MER_…`(不是 Store ID) |
|
||||
| Store ID / Store Slug | 商店标识 |
|
||||
| 环境 | test / live |
|
||||
| API 私钥 | 只写不回显;保存后点「测试连接」调用 `POST /api/payment/waffo/debug` |
|
||||
| Product ID 映射表 | `plan_type`(或自定义 key)→ Waffo `product_id`,可增删多行 |
|
||||
|
||||
配置优先读 DB,`.env` 仅兜底。Webhook 只读提示一般为:
|
||||
|
||||
`https://你的域名/api/v1/webhooks/waffo`(Raw JSON,事件至少 `order.completed`,尽量 HTTPS)。
|
||||
|
||||
## `.env` 兜底变量
|
||||
|
||||
见仓库根目录 `.env.example`:`WAFFO_MERCHANT_ID`、`WAFFO_PRIVATE_KEY` / `_BASE64`、`WAFFO_STORE_SLUG`、`WAFFO_PRODUCT_ID_*`、`SUCCESS_URL` 等。
|
||||
|
||||
## 验收
|
||||
|
||||
1. 支付页「测试连接」成功(私钥已配置且签名可用)
|
||||
2. Checkout 返回的 `checkoutUrl` 来自 session(含 `/checkout/cs_…`)
|
||||
3. 付完后本地订单 `paid` 并自动有 License
|
||||
4. Webhook 载荷含 `data.orderMerchantExternalId` = 本地 `ORD-…`
|
||||
Reference in new issue
Block a user