# 價格優惠 (/features/promotions/discounts)



價格優惠 [#價格優惠]

透過價格優惠直接減少顧客的付款金額，吸引新客戶、獎勵老客戶，或進行節慶促銷。

***

固定金額折扣 [#固定金額折扣]

直接折抵固定金額，顧客一眼就能看懂優惠。

運作方式 [#運作方式]

設定固定的折抵金額，無論訂單金額多少都折抵相同金額。

**範例：**

* `SAVE100` - 折抵 NT$100
* `WELCOME50` - 新會員折 NT$50

適用場景 [#適用場景]

* **新客首購優惠** - 吸引新顧客嘗試
* **節慶促銷** - 聖誕節、雙十一等活動
* **會員專屬折扣** - 回饋忠實顧客

設定選項 [#設定選項]

| 選項   | 說明                |
| ---- | ----------------- |
| 折扣金額 | 固定折抵的金額（如 NT$100） |
| 最低消費 | 訂單需達此金額才能使用       |
| 適用商品 | 全部商品或指定商品         |

***

百分比折扣 [#百分比折扣]

依購買金額按比例折扣，金額越高折越多。

運作方式 [#運作方式-1]

設定折扣百分比，系統自動計算折扣金額。

**範例：**

* `VIP20` - 8 折（20% off）
* `ANNUAL10` - 年繳 9 折

適用場景 [#適用場景-1]

* **會員等級折扣** - VIP 專屬優惠
* **大額訂單優惠** - 鼓勵升級高價方案
* **長期合作方案** - 企業客戶優惠

週期性折扣 [#週期性折扣]

百分比折扣可設定持續多個計費週期：

| 設定   | 說明                |
| ---- | ----------------- |
| 僅首次  | 只有第一期有折扣          |
| 指定週期 | 前 N 期有折扣（如前 3 個月） |
| 永久   | 訂閱期間永久有效          |

**範例：**

* 前 3 個月 8 折，第 4 個月起恢復原價
* 永久 9 折（適用於年度合作夥伴）

***

首期特價 [#首期特價]

顧客以特價訂閱第一期，後續自動恢復原價。

運作方式 [#運作方式-2]

設定首期的固定價格，不論原價多少，首期都以此價格收費。

**範例：**

* 首月 $1，第 2 個月起恢復 $299/月
* 首月 $99（原價 $299），第 2 個月起恢復原價

適用場景 [#適用場景-2]

* **免費試用替代** - 用極低價格取代完全免費，篩選有意願的顧客
* **新服務推廣** - 吸引用戶嘗試新功能
* **降低入門門檻** - 減少顧客的決策成本

顧客體驗 [#顧客體驗]

顧客在結帳時會看到：

```
首月特價：$1
原價：$299/月
第 2 個月起將以原價 $299 續訂
```

續約處理 [#續約處理]

* 首期結束前，系統自動發送提醒
* 到期時以原價發起扣款
* 顧客可在 Portal 查看續約價格

***

全額折扣（免綁卡兌換） [#全額折扣免綁卡兌換]

當折扣金額等於商品全價時，結帳金額為 $0。搭配 `collectPaymentMethod: 'if_required'`，用戶可以**不需要輸入信用卡**就完成訂閱，適合教育優惠、員工帳號、合作夥伴兌換等場景。

建立方式 [#建立方式]

使用 &#x2A;*百分比折扣 100%** 或 **固定金額折扣**（金額等於商品價格）都可以達到全額折扣。

**範例：**

* `FREE100` - 百分比折扣 100%（適用所有價格的商品）
* `FREEPRO` - 固定金額折扣 NT$799（精確匹配 Pro 方案月費）

建立 Checkout Session 時帶入 `promotionCode` 和 `collectPaymentMethod: 'if_required'`：

```json
{
  "productId": "prod_pro_monthly",
  "mode": "SUBSCRIPTION",
  "promotionCode": "FREE100",
  "collectPaymentMethod": "if_required",
  "successUrl": "https://your-site.com/success",
  "cancelUrl": "https://your-site.com/cancel"
}
```

完整的參數行為矩陣、程式碼範例與續約注意事項，請參考 [Hosted Checkout - 零元結帳](/guides/checkout/hosted-checkout#零元結帳免綁卡兌換)。

***

建立價格優惠 [#建立價格優惠]

後台操作 [#後台操作]

1. 前往「優惠促銷」
2. 點擊「建立優惠」
3. 選擇優惠類型：
   * 固定金額折扣
   * 百分比折扣
   * 首期特價
4. 填寫設定：
   * **名稱** - 內部識別用
   * **金額/比例** - 折扣數值
   * **有效期限** - 開始與結束日期
   * **使用次數** - 總次數上限
   * **適用商品** - 選擇適用的商品
5. 儲存

代碼格式 [#代碼格式]

推廣碼的格式規則：

* 僅允許大寫英文（A-Z）和數字（0-9）
* 長度 3-20 字元
* 不區分大小寫（自動轉換為大寫）

**有效範例：**

* `SAVE100`
* `2024NEWYEAR`
* `VIP20OFF`

***

限制設定 [#限制設定]

有效期限 [#有效期限]

設定優惠的有效期間：

* **開始日期** - 何時開始生效
* **結束日期** - 何時失效

使用次數 [#使用次數]

* **總次數上限** - 所有顧客共用次數
* **每顧客上限** - 單一顧客可使用次數

適用商品 [#適用商品]

* **所有商品** - 適用於所有商品
* **指定商品** - 僅適用於選擇的商品

最低消費 [#最低消費]

設定門檻金額，訂單需達到此金額才能使用。

顧客資格 [#顧客資格]

限制特定類型的顧客才能使用此優惠：

| 設定         | 說明            | 使用場景         |
| ---------- | ------------- | ------------ |
| **所有顧客**   | 不限制（預設）       | 節慶促銷、全場優惠    |
| **僅限新顧客**  | 從未有付費訂閱的顧客    | 獲客優惠、首購折扣    |
| **僅限現有顧客** | 曾經或目前有付費訂閱的顧客 | 升級優惠、留存/挽回優惠 |

**判斷邏輯：**

* **新顧客**：在您的組織內從未建立過 `ACTIVE`、`PAST_DUE`、`CANCELED`、`EXPIRED` 狀態的訂閱
* **現有顧客**：曾經或目前有上述任一狀態的訂閱
* 僅處於 `TRIAL` 狀態的顧客仍視為「新顧客」

**使用情境範例：**

| 優惠碼         | 顧客資格   | 用途        |
| ----------- | ------ | --------- |
| `WELCOME20` | 僅限新顧客  | 首次訂閱享 8 折 |
| `UPGRADE30` | 僅限現有顧客 | 升級方案享 7 折 |
| `XMAS2024`  | 所有顧客   | 聖誕節全場 9 折 |

**注意事項：**

* 設為「僅限新顧客」的優惠碼，無法在 Customer Portal 的方案切換中使用（因為切換方案代表已是現有顧客）
* 設為「僅限現有顧客」的優惠碼，無法在首次結帳時使用

***

使用統計 [#使用統計]

在優惠詳情頁面查看：

* **使用次數** - 已使用 / 總次數
* **使用率** - 使用次數 / 瀏覽次數
* **折扣總額** - 累計折扣金額
* **帶來營收** - 使用此優惠的訂單總額

***

技術整合 [#技術整合]

驗證優惠碼 [#驗證優惠碼]

使用 Publishable Key 在前端即時驗證，需帶上客戶身份：

```typescript
const response = await fetch('https://api.recur.tw/v1/promotion-codes/validate', {
  method: 'POST',
  headers: {
    'X-Recur-Publishable-Key': 'pk_test_xxx',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    code: 'SAVE100',
    external_id: 'user_123',   // 您系統的用戶 ID（必填）
    product_id: 'prod_xxx',    // 選填
    amount: 499,               // 選填：計算折後價
  }),
});

const { valid, discount, applicable_products } = await response.json();
```

驗證成功時會回傳折扣資訊（`discount.label`、`discount.amount`）和適用產品清單（含折後價）。

完整的請求參數、回應格式和安全機制請參考 [Promotion Codes API](/api/promotion-codes)。

套用優惠碼 [#套用優惠碼]

在建立 Checkout Session 時套用：

```typescript
const response = await fetch('https://api.recur.tw/v1/checkout/sessions', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer sk_test_xxx',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    productId: 'prod_xxx',
    mode: 'SUBSCRIPTION',
    promotionCode: 'SAVE100', // 套用優惠碼
    successUrl: 'https://your-site.com/success',
    cancelUrl: 'https://your-site.com/cancel',
  }),
});
```

用戶也可以在結帳頁面手動輸入優惠碼，不一定需要在建立 Session 時帶入。

相關 Webhook 事件 [#相關-webhook-事件]

訂閱相關事件的 payload 會包含折扣資訊：

| 欄位                        | 說明                                                         |
| ------------------------- | ---------------------------------------------------------- |
| `coupon`                  | 優惠資訊（id, name, discount\_type, discount\_amount, duration） |
| `coupon_remaining_cycles` | 週期性折扣剩餘期數（僅 REPEATING 類型）                                  |
| `discount_amount`         | 本期折扣金額                                                     |
| `promotion_code`          | 使用的推廣代碼                                                    |

**重要事件：**

* `subscription.created` - 訂閱建立，包含初始折扣設定
* `subscription.activated` - 訂閱啟用，首期折扣已套用
* `subscription.renewed` - 訂閱續訂，週期性折扣持續套用或恢復原價

**週期性折扣追蹤範例：**

```json
// 首期（3 期折扣）
{
  "coupon_remaining_cycles": 2,
  "discount_amount": 60
}

// 第 2 期
{
  "coupon_remaining_cycles": 1,
  "discount_amount": 60
}

// 第 3 期
{
  "coupon_remaining_cycles": 0,
  "discount_amount": 60
}

// 第 4 期（恢復原價）
{
  "coupon": null,
  "coupon_remaining_cycles": null,
  "discount_amount": 0
}
```

詳細 Webhook payload 格式請參考 [Webhook 事件類型](/guides/webhooks/events)。

***

最佳實踐 [#最佳實踐]

1. **簡單易記的代碼** - 如 `SAVE100`、`VIP20`
2. **設定合理期限** - 創造緊迫感
3. **限制使用次數** - 控制促銷成本
4. **清楚說明恢復價格** - 首期特價需明確告知後續價格
5. **追蹤成效** - 定期檢視使用統計與續約率
