兑换码
设置 ENABLE_REDEEM_CODE = true 后,系统提供独立的 /redeem 页面,用于校验兑换码和发放权益,不包含支付、订单、库存或发卡逻辑。管理端生成的兑换码可以导出到外部平台销售。未启用时页面入口、管理菜单和相关 API 均不可用。
可选配置 REDEEM_CODE_URL 作为外部获取兑换码的链接;未配置时兑换页面不会展示该入口。
数据库
升级后先在 Admin 数据库页面执行数据库迁移,实际表结构以项目中的迁移文件和 db/schema.sql 为准。
管理端创建时由 Worker 使用 crypto.randomUUID() 生成无固定前缀的 UUID v4 兑换码。code 保存大小写敏感的明文兑换码,便于管理端导出;redeem_type 用于选择业务处理器;value 是由该处理器解析的普通字符串。redeemed、result 和兑换时间由本系统维护,其中 result 使用由 JWT_SECRET 派生的 AES-256-GCM 密钥保存加密后的 JSON 兑换结果。每个兑换码必须设置未来的 expires_at,到期后不能兑换或查询兑换结果。修改 JWT_SECRET 会同时使已有地址凭证和兑换结果失效。
外部平台只负责销售和发放管理端导出的兑换码,本项目不处理支付、订单和库存流程。
支持的权益
角色权益
redeem_type = role
value = viprole 必须存在于 USER_ROLES,且不能是 ADMIN_USER_ROLE。兑换后用户获得该角色配置的前缀、域名、地址数量和发信权限。永久无前缀应通过 prefix: "" 的角色实现。
用户已有非默认且与目标不同的角色时会拒绝覆盖,兑换码不会被消费;并发兑换不同角色也执行此检查。登录用户为本人兑换后,页面自动刷新角色配置和访问令牌。
发信额度
redeem_type = send_balance
value = 100给兑换页面中填写的目标邮箱增加 address_sender.balance。尚未初始化额度的邮箱会先按 DEFAULT_SEND_BALANCE 初始化,再累加兑换额度;已有记录不会重复获得默认额度。额度按邮箱地址管理;已被管理员禁用的发信地址不会因兑换自动启用。
专属邮箱
redeem_type = address_prefix_once
value = vipvalue 仅支持小写字母和数字,也可以为空字符串,并且必须为用户输入至少留出一个 MAX_ADDRESS_LEN 字符。兑换模块将它直接拼接到用户输入之前,再按不启用系统前缀的方式创建地址;地址名称仍执行站点配置的正则和黑名单校验。空字符串表示无前缀。首次兑换创建地址并将完整返回值加密写入 result。页面只展示地址及其访问凭证,不会自动切换或绑定邮箱。之后在有效期内重复兑换返回同一完整结果;若临时地址记录已被清理,兑换结果将不可再查询,系统不会重建该地址。
管理端
管理端的“兑换码”页面支持按类型筛选并显示对应业务列。“批量生成”和“导出”均使用当前筛选的类型;同一批次共用权益参数、启用状态和有效期,每次最多生成 500 个 UUID v4 兑换码,生成成功后会下载仅包含本批结果的 CSV。
列表可按单一类型导出包含真实兑换码的 CSV,导出弹窗必须指定条数,上限为 10,000 条。
API
| 接口 | 用途 |
|---|---|
POST /redeem_api/query | 查询兑换码类型、值及状态 |
POST /redeem_api/result | 查询未过期兑换码的兑换结果 |
POST /redeem_api/redeem | 兑换邮箱地址、更新用户角色或增加发信额度 |
用户侧兑换接口不经过地址、用户或 Admin 认证;兑换码本身即为业务凭证。如果站点设置了访问密码,站点密码仍优先应用。接口使用 IP 限流和访问控制。角色与额度业务写入和消费在同一个 D1 batch 中完成,只会成功消费一次。特殊地址码由首次成功请求固化完整结果,有效期内可重复取回。
扩展类型
新增权益时增加新的 redeem_type 处理器,并为该类型实现严格的 value 校验、预览和业务逻辑即可,无需修改 redeem_codes 表。