> ## Documentation Index
> Fetch the complete documentation index at: https://sdk.qfapi.com/llms.txt
> Use this file to discover all available pages before exploring further.

# 訂閱支付 API 參考

> 本頁列出建立、更新與管理定期付款（訂閱支付）相關資源的 API 端點與參數說明。

本頁記錄定期付款可使用的 API 端點。開始前請先閱讀「定期付款概覽」，了解整體流程與必要條件（例如：Customer、Product、Token、Subscription 的關係，以及扣款失敗後的處理策略）。

***

## 何時使用

以下情境適合使用本頁 API：

* 建立顧客資料（Customer）與訂閱產品（Product）
* 以已綁定的支付令牌（Token）建立訂閱（Subscription）
* 更新 / 取消訂閱
* 查詢訂閱狀態、下次扣款時間、扣款訂單列表
* 對失敗扣款執行手動重試（Charge）

***

## 1. 建立 Customer

### Endpoint and Method

```http Create Customer theme={null}
POST /customer/v1/create
```

建立一筆新的顧客資料（Customer）。\
此 `customer_id` 會在後續建立 Subscription 時被引用，用於將訂閱關聯到指定顧客。

### Request Parameters

| 參數                | 類型            | 必填 | 說明                  |
| ----------------- | ------------- | -- | ------------------- |
| `customer_id`     | String        | 是  | 顧客 ID（由商戶系統生成並保持唯一） |
| `name`            | String        | 否  | 顧客姓名                |
| `phone`           | String        | 否  | 聯絡電話                |
| `email`           | String        | 否  | 電郵地址                |
| `billing_address` | String (JSON) | 否  | 帳單地址（JSON 字串）       |

### Response

回傳 `customer_id`。

***

## 2. 更新 Customer

### Endpoint and Method

```http Update Customer theme={null}
POST /customer/v1/update
```

更新既有顧客資料（以 `customer_id` 為主鍵）。

### Request Parameters

| 參數                | 類型     | 必填 | 說明           |
| ----------------- | ------ | -- | ------------ |
| `customer_id`     | String | 是  | 顧客 ID        |
| `name`            | String | 否  | 新的姓名         |
| `phone`           | String | 否  | 新的電話         |
| `email`           | String | 否  | 新的電郵地址       |
| `billing_address` | JSON   | 否  | 帳單地址 JSON 物件 |

### Response

回傳更新筆數。

***

## 3. 查詢 Customer

### Endpoint and Method

```http Query Customer theme={null}
POST /customer/v1/query
```

依條件查詢 Customer 列表（支援分頁）。

### Request Parameters

| 參數            | 類型     | 必填 | 說明                |
| ------------- | ------ | -- | ----------------- |
| `customer_id` | String | 否  | 顧客 ID             |
| `name`        | String | 否  | 姓名                |
| `phone`       | String | 否  | 聯絡電話              |
| `email`       | String | 否  | 電郵                |
| `page`        | Int    | 否  | 頁碼，預設 1           |
| `page_size`   | Int    | 否  | 每頁筆數，預設 10，最大 100 |

### Response

回傳符合條件的 Customer 列表。

***

## 4. 刪除 Customer

### Endpoint and Method

```http Delete Customer theme={null}
POST /customer/v1/delete
```

刪除指定 Customer。此操作無法還原。

### Request Parameters

| 參數            | 類型     | 必填 | 說明        |
| ------------- | ------ | -- | --------- |
| `customer_id` | String | 是  | 要刪除的顧客 ID |

### Response

回傳被刪除的 ID 與結果。

***

## 5. 建立 Product

### Endpoint and Method

```http Create Product theme={null}
POST /product/v1/create
```

建立可被訂閱引用的產品（Product）。通常代表一個固定計費方案（例如月費、年費）。

### Request Parameters

| 參數               | 類型     | 必填 | 說明                         |
| ---------------- | ------ | -- | -------------------------- |
| `name`           | String | 是  | 顯示給顧客的產品名稱                 |
| `type`           | String | 是  | 固定為 `recurring`            |
| `description`    | String | 否  | 產品描述                       |
| `txamt`          | Int    | 是  | 金額（最小幣值單位，例如 100 = 1 元）    |
| `txcurrcd`       | String | 是  | 幣別，例如 HKD                  |
| `interval`       | String | 是  | 計費週期，例如 `monthly`、`yearly` |
| `interval_count` | Int    | 是  | 週期間隔數，例如 1 = 每月；12 = 每年    |
| `usage_type`     | String | 是  | 固定為 `licensed`             |

<Note>
  在 Sandbox 環境中，`interval` 支援 `minutes`、`hours` 以方便測試。
</Note>

### Response

回傳新建立的 `product_id`。

***

## 6. 更新 Product

### Endpoint and Method

```http Update Product theme={null}
POST /product/v1/update
```

更新產品資料（不影響既有已建立的扣款紀錄，但可能影響後續新扣款計算方式，實際行為以系統設定為準）。

### Request Parameters

| 參數            | 類型     | 必填 | 說明     |
| ------------- | ------ | -- | ------ |
| `product_id`  | String | 是  | 產品 ID  |
| `name`        | String | 否  | 新的產品名稱 |
| `description` | String | 否  | 新的產品描述 |

### Response

回傳更新筆數。

***

## 7. 查詢 Product

### Endpoint and Method

```http Query Product theme={null}
POST /product/v1/query
```

依條件查詢 Product 列表（支援分頁）。

### Request Parameters

| 參數            | 類型     | 必填 | 說明                            |
| ------------- | ------ | -- | ----------------------------- |
| `product_id`  | String | 否  | 產品 ID                         |
| `name`        | String | 否  | 產品名稱                          |
| `description` | String | 否  | 產品描述                          |
| `txcurrcd`    | String | 否  | 交易幣別                          |
| `interval`    | String | 否  | 計費週期（例如 `monthly` / `yearly`） |
| `page`        | Int    | 否  | 頁碼，預設 1                       |
| `page_size`   | Int    | 否  | 每頁筆數，預設 10，最大 100             |

### Response

回傳符合條件的 Product 列表。

***

## 8. 刪除 Product

### Endpoint and Method

```http Delete Product theme={null}
POST /product/v1/delete
```

刪除指定 Product（需確保該產品未被任何 Subscription 使用中）。

### Request Parameters

| 參數           | 類型     | 必填 | 說明                 |
| ------------ | ------ | -- | ------------------ |
| `product_id` | String | 是  | 要刪除的產品 ID（不可被訂閱關聯） |

### Response

回傳被刪除的 ID 與結果。

***

## 9. 建立 Subscription

<Note>
  建立 Subscription 前，請先確保已完成以下資源：

  * `customer_id`
  * `product_id`
  * `token_id`
</Note>

### Endpoint and Method

```http Create Subscription theme={null}
POST /subscription/v1/create
```

建立新的訂閱計劃。Subscription 建立後，系統會依 `start_time`（若提供）及產品週期自動排程扣款。

### Request Parameters

| 參數                     | 類型     | 必填 | 說明                              |
| ---------------------- | ------ | -- | ------------------------------- |
| `customer_id`          | String | 是  | 顧客 ID                           |
| `token_id`             | String | 是  | 支付令牌 ID                         |
| `products`             | List   | 是  | 產品清單（`product_id` + `quantity`） |
| `total_billing_cycles` | Int    | 否  | 總扣款次數；為 null 代表無限期              |
| `start_time`           | String | 否  | 訂閱開始時間（亦可作為首次扣款時間）              |

#### products 內部參數

| 欄位           | 類型     | 必填 | 說明      |
| ------------ | ------ | -- | ------- |
| `product_id` | String | 是  | 產品 ID   |
| `quantity`   | Int    | 否  | 數量，預設 1 |

### Example Request

```json Create Subscription Request theme={null}
{
  "products": [
    {
      "product_id": "prod_54c3772d******9a54b236e09ec74f",
      "quantity": 1
    }
  ],
  "customer_id": "cust_aaf6aae94******982c54c9cae5ba32",
  "token_id": "tk_a99892fd*********d3417d168a18bb",
  "total_billing_cycles": 2,
  "start_time": "2020-05-14 12:32:56"
}
```

### Response Parameters（data）

| 欄位                | 類型     | 說明                                             |
| ----------------- | ------ | ---------------------------------------------- |
| `subscription_id` | String | 訂閱 ID（例如 `sub_xxxxxxxx`）                       |
| `state`           | String | 初始狀態（例如 `ACTIVE` / `INCOMPLETE` / `COMPLETED`） |

***

## 10. 更新 Subscription

### Endpoint and Method

```http Update Subscription theme={null}
POST /subscription/v1/update
```

更新訂閱配置（例如：扣款次數、產品、token、開始時間）。

### Request Parameters

| 參數                     | 類型     | 必填 | 說明                              |
| ---------------------- | ------ | -- | ------------------------------- |
| `subscription_id`      | String | 是  | 訂閱 ID                           |
| `total_billing_cycles` | Int    | 否  | 總扣款次數（null = 無限）                |
| `start_time`           | String | 否  | 訂閱開始時間（影響首次扣款）                  |
| `token_id`             | String | 否  | 新的支付令牌 ID                       |
| `products`             | Object | 否  | 產品清單（`product_id` + `quantity`） |

### Response Parameters（data）

| 欄位                | 類型     | 說明     |
| ----------------- | ------ | ------ |
| `subscription_id` | String | 訂閱 ID  |
| `rowAffected`     | Int    | 被更新的筆數 |

***

## 11. 查詢 Subscription

### Endpoint and Method

```http Query Subscription theme={null}
POST /subscription/v1/query
```

查詢訂閱列表（支援分頁）。

### Request Parameters

| 參數                | 類型     | 必填 | 說明                                 |
| ----------------- | ------ | -- | ---------------------------------- |
| `page`            | Int    | 否  | 頁碼，預設 1                            |
| `page_size`       | Int    | 否  | 每頁筆數，預設 10，最大 100                  |
| `subscription_id` | String | 否  | 訂閱 ID                              |
| `customer_id`     | String | 否  | 顧客 ID                              |
| `state`           | String | 否  | 訂閱狀態（例如 `ACTIVE` / `INCOMPLETE` 等） |

### Response Parameters（data）

| 欄位                            | 類型     | 說明               |
| ----------------------------- | ------ | ---------------- |
| `subscription_id`             | String | 訂閱 ID            |
| `customer_id`                 | String | 顧客 ID            |
| `token_id`                    | String | 支付令牌 ID          |
| `products`                    | Object | 產品清單             |
| `total_billing_cycles`        | Int    | 總扣款次數（null = 無限） |
| `state`                       | String | 訂閱狀態             |
| `next_billing_time`           | String | 下次扣款時間           |
| `last_billing_time`           | String | 上次扣款時間           |
| `completed_billing_iteration` | Int    | 已完成扣款次數          |
| `start_time`                  | String | 訂閱開始時間           |

***

## 12. 取消 Subscription

### Endpoint and Method

```http Cancel Subscription theme={null}
POST /subscription/v1/cancel
```

立即取消訂閱。取消後是否仍會完成當期扣款，依實際訂閱設定與渠道規則為準。

### Request Parameters

| 參數                | 類型     | 必填 | 說明        |
| ----------------- | ------ | -- | --------- |
| `subscription_id` | String | 是  | 要取消的訂閱 ID |

***

## 13. 查詢訂閱扣款訂單列表

### Endpoint and Method

```http List Billing Orders theme={null}
POST /subscription/billing_order/v1/list
```

查詢指定訂閱下的扣款訂單（每次扣款會對應一筆訂單紀錄）。

### Request Parameters

| 參數                | 類型     | 必填 | 說明                |
| ----------------- | ------ | -- | ----------------- |
| `subscription_id` | String | 是  | 所屬訂閱 ID           |
| `page`            | Int    | 否  | 頁碼，預設 1           |
| `page_size`       | Int    | 否  | 每頁筆數，預設 10，最大 100 |

### Response Parameters（data）

| 欄位                      | 類型     | 說明                                            |
| ----------------------- | ------ | --------------------------------------------- |
| `subscription_order_id` | String | 扣款訂單 ID（例如 `sub_ord_{訂閱ID}_{0001}` 代表第 1 次扣款） |
| `subscription_id`       | String | 訂閱 ID                                         |
| `trigger_by`            | String | 觸發類型：`auto`（系統自動）或 `manual`（手動）               |
| `sequence_no`           | Int    | 該訂閱的第幾次扣款                                     |

***

## 14. 手動重試扣款（Charge）

### Endpoint and Method

```http Retry Charge theme={null}
POST /subscription/v1/charge
```

對失敗的訂閱扣款訂單執行手動扣款重試。

### Request Parameters

| 參數                      | 類型     | 必填 | 說明              |
| ----------------------- | ------ | -- | --------------- |
| `subscription_id`       | String | 是  | 訂閱 ID           |
| `subscription_order_id` | String | 否  | （可選）指定要重試的訂單 ID |

<Note>
  本 API 只適用於狀態為 `UNPAID`、`INCOMPLETE`、`PAST_DUE` 的訂閱扣款事件。

  * 若重試日期在下一次扣款日前，訂閱會繼續按計劃進行
  * 若重試日期在下一次扣款日之後，訂閱可能被取消（依平台規則為準）
  * 若重試失敗，狀態保持不變
</Note>

***

## 整合注意事項與最佳實務

* 建議商戶在後台儲存並關聯：`customer_id`、`product_id`、`subscription_id`、`subscription_order_id`
* 請以 Webhook（定期付款通知）作為扣款成功/失敗的主要事件來源，並搭配查詢 API 做補單
* Sandbox 可使用更短週期（minutes / hours）驗證重試與狀態流轉，再切換至正式週期（monthly / yearly）
