# 奖品配置

抽奖类游戏（Spin the Wheel、Gachapon、Grid Box、Scratch Card、Card Pull 与 Claw Machine）使用奖品配置系统。本指南说明如何设置、管理与监控奖品。

## 奖品类型

每个奖品槽位必须为六种类型之一：

| 类型 | 玩家获得什么 | 履约方式 |
| ------------------ | --------------------------------------------- | ------------------------------------ |
| **Voucher Set** | 从受管理集合中抽取的唯一代码 | 自动（可追踪） |
| **Voucher** | 固定代码字符串（例如「SAVE20」） | 直接向玩家展示 |
| **Item** | 命名的实体/数字奖品 | 手动（由您履约） |
| **External Link** | 玩家另行兑换的 URL | 玩家点击链接 |
| **Custom Voucher** | 由外部提供方发放的代码 | 通过 webhook 自动（您的系统） |
| **No Prize** | 「再试一次」— 不发放奖励 | 不适用 |

![奖品配置](/img/prize/prize-customization-voucher.jpg)

### 何时使用各类型

- **Voucher Set** — 最适合有大量唯一代码（每位中奖者一个）的活动。代码从库存自动分配并追踪。
- **Voucher** — 用于所有中奖者看到的同一个共享代码（例如通用折扣码）。
- **Item** — 需要手动履约的实体商品、免费产品或服务升级。
- **External Link** — 将流量导向落地页、合作方优惠或兑换门户。
- **Custom Voucher** — 最适合代码存放在其他平台（例如电商商店或忠诚度系统）的情况。DailyPlay 在领取时通过 webhook 向您的提供方请求代码，库存保留在您自己的系统中。
- **No Prize** — 平衡概率所必需。没有「再试一次」槽位时，每次游玩都会中奖。

---

## Custom Voucher（Webhook 连接）

Custom Voucher 类型将履约委托给**外部提供方**。不是从 DailyPlay 兑换码集抽取代码，而是玩家领取时触发向您提供方的 webhook，由提供方返回真实代码。当代码在 DailyPlay 之外管理时使用此类型。

:::note[前提条件]
仅当组织管理员已设置 **voucher webhook connection** 后，Custom Voucher 奖品才可用。若无连接，奖品编辑器中不会出现该选项。请参阅 [Connections](/zh/connections/overview) 进行设置。
:::

### Provider 与 Connection

此奖品类型背后有两层：

| 层级 | 是什么 |
| -------------- | ------------------------------------------------------------------------------------------------------------------ |
| **Provider** | 定义提供方所需字段及其 webhook 形态的模板（例如商店集成）。 |
| **Connection** | 您组织对该提供方的已配置、带凭据的实例 — 实际的 webhook URL 与凭据。 |

Provider 是定义；Connection 是您对其的已配置对接。一个组织可以对同一提供方拥有多个连接（例如分别的「Staging」与「Production」商店）。

### 选择 Connection

在奖品 **Type** 选择器中，每个有效的 voucher webhook connection 会作为独立按钮与标准类型并排显示。选择一个后：

- 将奖品绑定到该连接及其提供方
- 若名称仍为空，自动用连接名称填充奖品名称
- 显示 **Voucher fulfillment** 面板，用于提供方设置与数量

若组织有多个连接，每个都会显示为单独按钮，以便您精确选择由哪个履约。

### 提供方设置（字段）

部分提供方需要按奖品额外配置 — 例如折扣或购物车规则标识符。选择连接后，这些字段会自动显示在 **Provider settings** 下。每个字段可能是：

- 文本、数字或是/否值
- 标记为**必填**（未填写则无法保存奖品）
- 受最小值/最大值、长度或格式（例如邮箱）约束

DailyPlay 会在编辑器中及服务端保存前验证这些字段，并再次检查您的组织是否仍可访问该提供方。

### 数量与库存

Custom Voucher 奖品使用与其他可赢取奖品类型相同的 **Prize limits** 控件（见下方[数量与库存](#quantity-and-inventory)）：

| 字段 | 说明 |
| ------------------ | -------------------------------------------------------------------------------------------------------------------- |
| **Total quantity** | 该奖品在整个活动期间可被赢取的最大次数。留空为不限（最大 1,000,000）。 |
| **Daily limit** | 每个组织日历日的最大中奖次数。在组织时区午夜重置。留空为不限。 |
| **Remaining** | 只读。显示 `remaining / total`。新奖品时与总量相同；保存后反映实时中奖情况。 |
| **Remaining today**| 只读。设置每日限制时显示 `remaining today / daily limit`。 |

当 Custom Voucher 奖品达到总量或每日上限时，会从抽取中排除，直到库存重置（总量）或下一个组织日（每日限制）。概率在其余合格奖品间重新分配 — 与其他奖品类型完全相同。

### 履约如何工作

1. 玩家赢得 Custom Voucher 奖品并领取
2. DailyPlay 向已连接的提供方发送 webhook，包含奖品的提供方设置与玩家上下文
3. 提供方返回实际兑换码
4. 代码返回给玩家

---

## 设置奖品

### 在游戏编辑器中

创建或编辑抽奖类游戏时，会进入编辑器的 **Prizes** 步骤。每个奖品是您添加并配置的「槽位」。单个槽位的核心流程是：

1. 点击 **Add Prize Slot** — 出现新的槽位卡片
2. 输入 **Name** — 玩家看到的显示名称（例如「10% Off」）
3. 选择 **Type** — 选择奖品类型之一（Voucher Set、Voucher、Item、External Link、Custom Voucher 或 No Prize）
4. 设置 **Win Chance (%)** — 该槽位在抽取中的概率
5. 为每个奖品重复，并确保所有概率合计为 100%

类型特定字段（兑换码集、外部 URL、提供方设置等）会在选择匹配类型后自动出现。

**示例：如何在游戏中设置兑换码奖品：**

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

**示例：如何在游戏中设置物品奖品：**

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

### 奖品槽位字段

| 字段 | 说明 | 必填 |
| ------------------ | -------------------------------------------------------------------------------------------------------------------- | -------- |
| Name | 向玩家显示的名称（最多 50 个字符） | 是 |
| Description | 附加详情（最多 200 个字符） | 否 |
| Type | 上述 6 种奖品类型之一 | 是 |
| Win Chance (%) | 赢取该槽位的概率（1–100%） | 是 |
| Total quantity | 活动范围中奖上限（留空为不限；最大 1,000,000）。**No Prize** 不显示。 | 否 |
| Daily limit | 每个组织日历日最大中奖次数（在组织时区午夜重置；留空为不限）。**No Prize** 不适用。 | 否 |
| Min Score | 获得资格所需的最低分数 | 否 |
| Voucher Set | 从哪个集合抽取代码（仅 voucher set 类型） | 条件必填 |
| External URL | 兑换链接（仅 external link 类型） | 条件必填 |
| Image | 自定义奖品图片（最大 10 MB，调整为 256×256） | 否 |

### 显示顺序

您在编辑器中排列奖品的顺序直接控制它们在游戏中的显示方式（例如转盘扇区、网格格子）。使用 Move Up/Down 按钮排列。显示顺序**不影响**中奖概率 — 只有概率百分比决定赔率。

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

---

## 概率规则

游戏中所有奖品概率合计必须为 **100% 或更低**。

### 验证规则

- 每个槽位的概率必须大于 0%
- 所有槽位合计不能超过 100%
- DailyPlay 会在编辑器中及服务端保存前进行验证

当合计无效时，编辑器会显示行内警告，并阻止您继续，直到修复。

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

### 示例：Spin the Wheel（8 个槽位）

| 槽位 | 奖品 | 类型 | 概率 | 总量 | 每日限制 |
| ---- | -------------- | ----------- | ------ | ----- | ----------- |
| 1 | $50 Gift Card | Voucher Set | 5% | 10 | 2 |
| 2 | 20% Off | Voucher Set | 10% | 50 | Unlimited |
| 3 | 10% Off | Voucher | 15% | Unlimited | Unlimited |
| 4 | Try Again | No Prize | 20% | — | — |
| 5 | Free Shipping | Voucher | 10% | Unlimited | Unlimited |
| 6 | Try Again | No Prize | 15% | — | — |
| 7 | Visit Our Blog | External Link | 15% | Unlimited | Unlimited |
| 8 | Try Again | No Prize | 10% | — | — |
| — | **Total** | | **100%** | | |

### 示例：Gachapon（6 个扭蛋）

| 扭蛋 | 奖品 | 类型 | 概率 | 总量 | 每日限制 |
| ------- | ----------- | ----------- | ------ | ----- | ----------- |
| Gold | $50 Voucher | Voucher Set | 2% | 10 | 1 |
| Silver | $20 Voucher | Voucher Set | 8% | 50 | 5 |
| Bronze | $10 Voucher | Voucher Set | 20% | 100 | Unlimited |
| Blue | 10% Off | Voucher | 30% | Unlimited | Unlimited |
| Green | 5% Off | Voucher | 25% | Unlimited | Unlimited |
| Gray | Try Again | No Prize | 15% | — | — |

:::caution[无效配置]
若概率超过 100%，DailyPlay 将阻止保存。若合计低于 100%，剩余百分比在抽取中成为隐式的「未中奖」结果。
:::

---

## 最低分数要求

对于结合技巧与运气的游戏，您可为每个奖品槽位设置**最低分数**。玩家必须至少达到该分数，该奖品才会在抽取中具有资格。

**工作方式：**

1. 玩家以某个分数完成游戏
2. 服务器筛选奖品 — 仅包含 `min_score ≤ 玩家分数` 的奖品
3. 仅在合格奖品中进行加权随机抽取

**示例：**

| 奖品 | 概率 | 最低分数 |
| ------------ | ------ | --------- |
| Grand Prize | 5% | 1000 |
| Runner Up | 15% | 500 |
| Consolation | 30% | 0 |
| Try Again | 50% | 0 |

得分 750 的玩家有资格获得 Runner Up、Consolation 与 Try Again — 但不能获得 Grand Prize。

![最低分数配置](/img/prize/minimum-score-voucher.jpg)

:::tip[分数门槛]
使用最低分数奖励技巧更好的玩家，让他们有机会获得更高等级奖品，同时仍让所有人有机会获得较小奖品。
:::

### Highest Tier Only

对于支持最低分数的游戏，奖品编辑器顶部会出现 **Highest Tier Only** 开关。启用后，玩家仅从**其符合资格的最高分数档位**中抽取，而不是从所有合格档位合并抽取。

- **Off（默认）：** 所有 `min_score ≤ 玩家分数` 的奖品合并在一起进行抽取。
- **On：** 仅玩家解锁的最高单一档位中的奖品有资格 — 较低档位被排除。

当您希望顶尖表现者只竞争最佳奖励，而不是被安慰奖稀释赔率时，使用此选项。

![Highest Tier Only 开关](/img/prize/highest-tier-only.png)

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

---

## 数量与库存

除 **No Prize** 外的每种奖品类型在编辑器中都有 **Prize limits** 部分，包含两个可选上限与两个只读计数器。

| 字段 | 说明 |
| ------------------- | -------------------------------------------------------------------------------------------------------------------- |
| **Total quantity** | 活动范围最大中奖次数。留空为不限（最大 1,000,000）。 |
| **Daily limit** | 每个组织日历日的最大中奖次数。在您的**组织时区**午夜重置。留空为不限。 |
| **Remaining** | 设置总量上限时只读显示 `remaining / total`。 |
| **Remaining today** | 设置每日限制时只读显示 `remaining today / daily limit`。 |

:::tip[将高价值奖品分散到多天]
可只用每日限制、不设总量上限来控制节奏（例如「每天 5 个大奖」）。两者结合可限制整个活动并节流每日量（例如总量 100，每天 10）。
:::

### 验证规则

- 每个限制在设置时必须为正整数，或留空表示不限
- 两者都设置时，**Daily limit** 不能超过 **Total quantity**
- 限制适用于所有可赢取奖品类型（Voucher Set、Voucher、Item、External Link、Custom Voucher）— 不适用于 **No Prize**

### 有限数量（总量）

为高价值或有限库存奖品设置总量：

- 每次中奖时 `remaining_quantity` 递减
- 达到 0 时，该奖品从后续抽取中排除，直到您提高上限
- 其余奖品的概率按比例自动调整

### 每日限制

设置每日限制，以限制单个组织日内某奖品可被赢取的次数：

- 中奖从组织时区的午夜到午夜计数
- 达到每日上限后，该奖品在当天剩余时间被跳过
- 计数器在下一个组织午夜自动重置 — 总库存不变
- 适用于控制闪购活动节奏或保护履约能力

### 不限量奖品

两个字段都留空，表示您始终可以履约的奖品：

- 数字代码、库存充足的兑换码集、外部链接
- 无需库存或每日追踪

### 达到上限时会发生什么

1. 抽取时跳过已达上限的奖品（总量耗尽或每日限制触达）
2. 系统在其余合格奖品间重新分配概率
3. 若**所有**奖品都不合格，游戏返回无奖品
4. 因**每日限制**被阻止的奖品，若总库存仍有剩余，在组织午夜后再次合格

---

## 有效 / 无效奖品

每个奖品有一个 `is_active` 标志：

- **Active** — 包含在抽取中，面板中显示绿色徽章
- **Inactive** — 从抽取中排除，显示灰色徽章

用此可临时停用奖品而不删除（例如暂停促销、活动中途更换奖品）。

---

## 抽取如何工作

DailyPlay 使用**服务端加密抽取** — 奖品选择无法从前端操纵：

1. 游戏使用游戏 ID 调用抽取端点
2. 服务器获取所有有效、合格的奖品（库存、每日限制与分数检查）
3. **加权随机选择**根据概率百分比选出获胜者
4. 生成包含结果的**已签名令牌**（HMAC-SHA256）
5. 令牌有效期为 **30 分钟**
6. 玩家领取时，服务器在发放前验证令牌签名

### 按类型的领取处理

| 奖品类型 | 领取时发生什么 |
| -------------- | --------------------------------------------------------------- |
| Voucher Set | 分配下一个可用代码，兑换码标记为 `claimed` |
| Voucher | 将固定代码字符串返回给玩家 |
| Item | 显示奖品名称，玩家填写领取表单 |
| External Link | 返回 URL，玩家跳转到外部兑换 |
| Custom Voucher | 向您的提供方发送 webhook，将返回的代码展示给玩家 |
| No Prize | 显示「再试一次」消息 |

### 连接事件

每次奖品领取都会在已配置时触发出站集成：

- Zapier、Braze、Mailchimp、HubSpot、Salesforce、Segment 或自定义 webhooks
- 事件载荷包含：游戏 ID、玩家 UUID、分数、奖品名称、奖品类型、兑换码

更多信息见 [Connections](/zh/connections/overview)。

---

## 奖品面板

从 **Organization → Prizes** 访问，监控所有奖品活动。

### 统计卡片

| 指标 | 说明 |
| ---------------- | ----------------------------------- |
| Total Prizes | 所有已配置的奖品槽位 |
| Active Prizes | 当前有资格参与抽取的槽位 |
| Total Wins | 历史累计发放的奖品 |
| Wins Today | 过去 24 小时发放的奖品 |
| Vouchers Awarded | 已发放的兑换码 |

### 按游戏明细

每个游戏显示：

- 已配置的奖品槽位数量
- 总概率百分比（100% 为绿色，超过为红色）
- 可折叠表格，含所有奖品：名称、类型、概率 %、剩余数量、今日剩余（如已设置）、有效状态
- 跳转到游戏编辑器的快速编辑链接

---

## 最佳实践

### 概率平衡

**推荐的玩家互动分布：**

| 档位 | 概率范围 | 目的 |
| ------------ | ------------ | ----------------------------- |
| 高价值 | 2–10% | 创造兴奋与向往 |
| 中等 | 15–30% | 让玩家感到有收获 |
| 低价值 | 25–40% | 频繁小奖 |
| 无奖品 | 20–40% | 为重试创造期待 |

:::tip[中奖率]
总体中奖率建议 50–70%（某种奖品，哪怕很小）。若「无奖品」占比过高，玩家会很快流失。
:::

### 视觉吸引力

- 为每个奖品上传自定义图片 — 玩家在游戏 UI 中会看到它们
- 带有吸引力图片的高价值奖品能带来更多互动
- 图片会自动调整为 256×256px

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

### 上线前测试

1. 在预览模式中多次游玩游戏
2. 确认所有奖品类型正确显示（代码、链接、名称）
3. 检查兑换码集奖品确实能发放代码
4. 确认总量与每日限制正确递减（检查 **Remaining** 与 **Remaining today**）
5. 使用低于与高于 min_score 门槛的分数进行测试（如使用）

---

## 故障排除

### 玩家中奖但未显示代码

1. 检查关联的兑换码集是否仍有 `available` 代码
2. 核实集合未过期
3. 奖品可能已达到**总量**或**每日**限制 — 在编辑器中检查 **Remaining** 与 **Remaining today**

### 概率看起来不对

- 在编辑器中确认合计等于 100%
- 小样本量自然会显得偏斜 — 用 50+ 次游玩测试
- 若部分奖品已耗尽或达到每日上限，其余奖品实际概率会更高

### 奖品未在游戏中显示

1. 确认奖品有效（非无效/已停用）
2. 检查 **Remaining** 不为 0，且 **Remaining today** 不为 0（如设置了每日限制）
3. 确保游戏已发布（非草稿模式）
4. 若使用 min_score，核实玩家分数达到门槛

### 领取时「Token expired」

抽取令牌有效期为 30 分钟。若玩家在看到结果与领取之间等待过久，令牌会过期。正常游玩中很少见。

---

## 下一步

- [设置兑换码集 →](/zh/rewards/vouchers) 为奖品提供代码
- 配置奖品后[分享您的游戏 →](/zh/sharing/share)