# 兑换码系统

兑换码系统让您管理促销代码集合，并在玩家中奖时自动发放。每个代码从创建到领取均单独追踪。

## 什么是兑换码集？

兑换码集是为活动或促销组织的命名唯一代码集合：

- 节日折扣码
- 礼品卡代码
- 产品试用密钥
- 活动专属优惠

每个集合包含：

| 属性 | 说明 | 必填 |
| ----------- | ----------------------------------------------- | -------- |
| Name | 描述性标签（例如「Summer Sale 20% Off」） | 是 |
| Description | 关于集合用途的内部备注 | 否 |
| Expiry Date | 集合中所有代码的过期时间 | 否 |

单个兑换码集可同时关联到**多个游戏** — 面板会显示当前使用每个集合的游戏。

---

## 创建兑换码集

1. 前往您的 **Organization** 面板
2. 在侧边栏点击 **Vouchers**
3. 点击 **Create Set**
4. 输入名称、可选描述与可选过期日期
5. 点击 **Create**

集合现已准备好添加代码。

<video autoplay loop muted playsinline preload="none">
  <source src="/vdo/prize/create-voucher.mp4" type="video/mp4" />
</video>

---

## 添加代码

填充兑换码集有两种方式：

### 上传 CSV

上传每行一个代码的 `.csv` 或 `.txt` 文件：

1. 在集合上点击 **Upload CSV**
2. 选择文件或将代码粘贴到文本区域
3. 点击 **Upload**

**接受的格式**（纯文本，每行一个代码）：

```
SUMMER2024-001
SUMMER2024-002
SUMMER2024-003
```

也接受多列 CSV — 仅使用第一列。所有代码会自动转换为**大写**，重复项会被静默忽略。

您也可以直接将代码粘贴到上传文本区域（每行一个），无需文件。

<video autoplay loop muted playsinline preload="none">
  <source src="/vdo/prize/add-code-voucher.mp4" type="video/mp4" />
</video>

### 生成代码

自动生成唯一、易读的代码：

1. 在集合上点击 **Generate**
2. 配置设置：

| 设置 | 范围 | 说明 |
| ----------------- | ----------- | -------------------------------------- |
| Count | 1–1,000 | 要创建的代码数量 |
| Prefix | 0–10 个字符 | 可选前缀（例如 `PROMO`） |
| Random Length | 4–16 个字符 | 随机部分的长度 |

3. 预览示例代码
4. 点击 **Generate**

**示例输出**（前缀 `PROMO`，长度 8）：

```
PROMO-A8K2M9X1
PROMO-B3N5P7Q2
PROMO-C1R4S6T8
```

<video autoplay loop muted playsinline preload="none">
  <source src="/vdo/prize/generate-code-voucher.mp4" type="video/mp4" />
</video>

:::tip[可读性]
生成的代码会排除易混淆字符（I、O、1、0）— 随机部分仅使用 `ABCDEFGHJKLMNPQRSTUVWXYZ23456789`。
:::

---

## 兑换码状态

每个代码有四种状态之一：

| 状态 | 颜色 | 说明 |
| ------------- | ------ | -------------------------------------------------- |
| **Available** | 绿色 | 准备被赢取并发放 |
| **Claimed** | 琥珀色 | 已被玩家赢取 — 包含玩家 ID 与时间戳 |
| **Expired** | 灰色 | 已过过期日期，不再可发放 |
| **Disabled** | 红色 | 已手动停用 |

**状态转换：**

- `available` → `claimed` — 当玩家赢得关联奖品时
- `available` → `expired` — 过期日期过后自动转换
- 仅 `available` 兑换码可单独删除

---

## 管理兑换码

### 面板视图

每个兑换码集显示：

- 一目了然的 **Total / Available / Claimed** 计数
- **Linked games** — 当前将此集合用作奖品的游戏
- 带状态徽章的全部单个代码可展开列表

![兑换码面板](/img/prize/dashbaord-voucher.jpg)

### 复制代码

点击任意代码旁的复制图标，将其复制到剪贴板。

### 导出

将集合中的所有代码下载为 CSV：

1. 在集合上点击 **Export**
2. 下载名为 `{set-name}-vouchers.csv` 的文件

**导出格式：**

```csv
code,status
PROMO-A8K2M9X1,available
PROMO-B3N5P7Q2,claimed
PROMO-C1R4S6T8,expired
```

![导出兑换码](/img/prize/export-voucher.jpg)

### 删除

- **单个代码** — 点击删除图标（仅 `available` 代码可用；已领取代码不可删除）
- **整个集合** — 点击集合标题上的删除

![删除兑换码](/img/prize/delete-voucher.jpg)

:::caution[永久操作]
删除兑换码集将永久移除所有代码 — 包括已领取代码及其历史。此操作无法撤销。
:::

---

## 过期

DailyPlay 支持**两级**过期：

| 级别 | 范围 | 效果 |
| ------------- | ------------------------ | ------------------------------------------------ |
| **Set-level** | 集合中的所有代码 | 创建集合时设置一次 |
| **Per-code** | 单个兑换码 | 覆盖特定代码的集合级过期 |

当集合或代码过期时：

- 状态变为 `expired` — 代码不再可发放
- 若玩家尝试从已过期集合领取奖品，系统会阻止领取
- 过期日期在面板中以红色显示

---

## 关联到游戏

兑换码集通过奖品配置连接到游戏：

1. 在游戏编辑器中打开 **Prizes** 部分
2. 添加类型为 **Voucher Set** 的奖品槽位
3. 从下拉菜单选择您的兑换码集
4. 设置中奖概率（0–100%）
5. 发布游戏

**将兑换码集与游戏一起设置：**

<video autoplay loop muted playsinline preload="none">
  <source src="/vdo/prize/game-code-voucher.mp4" type="video/mp4" />
</video>

**兑换码页面中的结果：**

![兑换码关联到游戏的结果](/img/prize/result-voucher.png)

### 自动发放流程

当玩家赢得兑换码集奖品时：

1. 服务器从集合中按 FIFO 顺序选取下一个可用代码
2. 代码状态 → `claimed`，附带玩家 UUID 与时间戳
3. 玩家在结果界面看到其唯一代码
4. 触发连接集成（Zapier、webhooks 等）

单个兑换码集可服务多个游戏 — 无论哪个游戏触发中奖，代码都从共享池中抽取。

---

## 领取追踪

每个已领取兑换码会记录：

| 字段 | 说明 |
| -------------------- | --------------------------------------- |
| Player UUID | 匿名浏览器指纹玩家 ID |
| Claimed At | 中奖的确切时间戳 |
| Play ID | 触发领取的游戏会话 |

这些数据可通过 API 与导出获得 — 适用于对账、防欺诈与分析。

---

## 最佳实践

### 命名约定

使用清晰、针对活动的名称：

- `Summer-Sale-2024-20%Off`
- `Launch-Event-Free-Trial-7d`
- `VIP-Early-Access`

避免使用 `Codes1` 或 `Test` 等通用名称 — 随着时间推移您会有多个集合。

### 代码前缀

前缀让代码一目了然，并有助于外部追踪：

| 前缀 | 活动 |
| ----------- | ----------------------- |
| `SUMMER24-` | 夏季促销 |
| `LAUNCH-` | 产品发布 |
| `VIP-` | 专属/忠诚度代码 |
| `GIFT-` | 礼品卡代码 |

### 库存规划

| 活动规模 | 建议代码数 | 理由 |
| ------------------------ | --------------- | ------------------------------------- |
| 小型（< 500 次游玩） | 150–250 | 约 30% 中奖率 + 20% 缓冲 |
| 中型（500–5,000 次游玩） | 500–1,500 | 随预期流量扩展 |
| 大型（5,000+ 次游玩） | 2,000+ | 每日监控，必要时补充 |

:::tip[避免缺货]
当兑换码集没有可用代码时，关联的奖品槽位将变为无效。玩家可能抽中却一无所获。请始终保持缓冲 — 监控 Available 数量，并在活动高峰前添加更多代码。
:::

### 过期策略

- 将过期日期设置在活动结束日期**之后**（给玩家留出兑换时间）
- 对于持续促销，可不填过期日期并手动管理
- 删除集合前先导出代码，以便保留记录

---

## 故障排除

### 「No vouchers available」

集合为空，或所有代码已领取/过期。

**解决方法：** 向集合上传或生成更多代码。

### 代码未在游戏中出现

1. 确认兑换码集已关联到奖品槽位（检查集合中的「Linked games」）
2. 核实集合未过期
3. 确保至少有一个代码状态为 `available`

### 玩家未收到代码

1. 展开兑换码集并搜索最近已领取的代码
2. 检查奖品抽取与领取是否都已完成（网络问题可能中断）
3. 若代码已领取，将显示玩家 UUID 与时间戳

### 重复代码被忽略

系统在上传时会静默跳过重复代码。若导入数量低于预期，说明部分代码已存在于集合中。

---

## 下一步

- [配置奖品槽位 →](/zh/rewards/prizes)
- [创建带兑换码奖品的游戏](/zh/creating-games/overview)