---
name: private-order-page
description: 快閃私人訂購頁產生器。收集品牌素材（名稱、LOGO、配色、商品、價格、寄送方式、法律條款、身份角色、專業折扣、付款階段、匯款資料、LINE）後，產出一套完整的快閃私人訂購頁：動態密碼閘門（可關閉）、商品多圖輪播與分色選購、課程日曆預約、身份折扣、運費試算、名片上傳、強制閱讀條款、多階段付款、HTML 排版訂單通知信＋Google 試算表訂單總表，並指導部署到 Cloudflare Workers 與自訂網域。凡使用者提到「展場預購網站」「快閃訂購頁」「幫某品牌做預購/訂購表單網站」「限定販售頁」「展會收單」「私人邀請預購」「私人訂購頁」「快閃私人訂購頁」「快閃私人頁」，或想為品牌建立含動態密碼、名片上傳、訂金分期的活動網站時，都應使用本技能——即使對方沒有明說要「網站」，只要情境是限量／限期／受邀才能買，就適用。
author: Clou（入雲視覺設計工作室・clouluo.com）
license: MIT
---

# 快閃私人訂購頁產生器

為任何品牌複製一套經實戰驗證的預購系統。
架構固定、內容全配置：Cloudflare Worker 承載「動態密碼閘門＋訂購頁＋名片與圖示 KV 儲存」，
Google Apps Script 負責「寫入訂單總表＋寄 HTML 通知信」。每月成本 $0。

實戰來源：曾實際用於精品品牌展場活動與工作室的「私人邀請・限量預購」場景。

## 這套系統能做什麼

決定要不要用這個技能時，先看功能對不對得上：

- **動態密碼閘門**——每 30 秒更新的 6 位數，現場人員報給客人才進得去。
  未通過閘門連 HTML 原始碼都拿不到，網址單獨外流沒有用
- **商品卡**：一項多張圖左右滑動輪播、分色選購（每色可獨立定價）、固定顏色、數量加減
- **課程／體驗**：日曆選場次，可設每場名額；`makeSessions(n)` 能自動排未來 n 個月的週末場次
- **身份折扣**：專業身份（設計師、企業採購等）上傳名片，全站價格自動切換成折扣價
- **寄送**：宅配／超商兩種運費，材積超限的商品自動鎖住超商選項；不需寄送的品項不問地址
- **多階段付款**：百分比自動試算，最後一段吃四捨五入尾差
- **強制閱讀條款**：捲到底才能勾同意
- **收單雙保險**：HTML 排版通知信（公司收件＋客人副本）＋ Google 試算表總表

## 工作流程總覽

1. **素材訪談** → 讀 `references/intake.md`，逐項收集（缺必要項不要硬做，先問）
2. **產出網站檔案包** → 本文件〈產出步驟〉
3. **部署與驗收** → 讀 `references/deployment.md`（含歷史教訓，部署前必讀）
4. **交接** → 產出品牌專屬交接說明

第 2 步可完全離線完成；若使用者只要檔案包（自行部署），做完第 2 步即可交付。

## 產出步驟

工作目錄建議：`<品牌代號>-preorder/`。

### 1. 客製訂購頁：assets/template.html → site.html

模板所有 `{{…}}` 都是待替換欄位，全部換掉才算完成。主要區塊：

| 位置 | 改什麼 |
|---|---|
| `:root` CSS 變數 | 品牌配色（--bg 背景、--ink 文字、--accent 輔色、--sale 強調價色等）|
| `<link rel="icon">` | 指向 `/fav/light`、`/fav/dark`、`/fav/touch`，圖檔另外上傳 KV（見部署文件）|
| hero 區 | LOGO 圖片網址、英文標語、主標題、副標兩行、三個賣點 |
| `const SHIPPING` | 宅配／超商的名稱、運費、說明 |
| `const PAY_STAGES` | 付款階段：`{name, pct, note, short, highlight, remainder}`，pct 總和 100，最後一段設 remainder:true 吃尾差 |
| `const ROLES` | 身份角色：`{name, pro}`，pro=true 須填公司＋名片 |
| `HINT_PRO / HINT_BASIC / HINT_NONE` | 身份提示文案 |
| `const PRO_RATE` | 專業身份折數（0.9＝9 折；不打折就設 1，並把 HINT 文案改掉）|
| `makeSessions()` | 課程場次自動排程規則（時段組合、每月開幾天）|
| `const PRODUCTS` | 商品陣列，模板內有三種型態的示範，照著填 |
| terms-box | 法律條款全文（分節 `<p>`，粗體小標）|
| 匯款資料（成功頁 `dl.bank`）＋ `hidden("匯款資訊")` | 戶名、銀行代碼、帳號 |
| LINE 按鈕與線上刷卡連結 | 官方帳號 ID＋加好友連結、金流收款連結 |
| 訂單編號前綴 | 預設兩碼英文，例如 `RY-260802-1234` |
| footer | 公司名、統編、信箱、LINE |

**有專業折扣時，條款要加一條**：名片查核不符者改以一般價計算並通知補差額，
買方不同意可於三日內取消全額退款。頁面承諾了折扣，條款就要接得住。

改完必做（自動驗收）：
```
node scripts/check_site.js site.html
```
會檢查：JS 語法、`{{…}}` 佔位是否清空、舊品牌字樣殘留、角色／階段／商品設定完整性、
付款百分比總和＝100、各種總額下的金額加總一致性、條款鎖定與送單驗證機制是否完好。
未通過就修到通過再繼續——這些都是實際踩過的坑。

### 2. 建置 Worker：assets/build_worker.py

複製到工作目錄，改頂部 CONFIG（SITE_HTML_PATH、GATE_ENABLED、品牌名、
閘門文案、LOGO 網址、閘門配色、`SESSION_HOURS`），執行後產出 worker.js。
`SESSION_HOURS` 是訪談時問到的放行時效，不要沿用範例預設值。
`GATE_ENABLED: False` 時網站直接公開、名片上傳不驗 session，其餘功能不變。
產出後跑 `node --input-type=module --check < worker.js`。

Worker 內建 `/fav/<key>` 路由，從 KV 讀網站圖示。圖示不要 base64 內嵌進 HTML——
會讓 worker.js 肥好幾十 KB，改版重傳很慢。

### 3. 收單程式：assets/apps-script-template.gs

改頂部 CONFIG：試算表 ID、收件信箱、品牌名、寄件顯示名、HEADERS、預設狀態。
HEADERS 的付款欄位命名必須是「階段名＋pct＋%」（與網頁 hidden 欄位一致），
例如 PAY_STAGES 有「訂金50%」就要有欄位 `訂金50%`。

**HEADERS 與網頁送出的欄位名要逐一對齊**。交付前用這個檢查：
把 site.html 裡所有 `name="…"` 與 `hidden("…")` 收集起來，比對 HEADERS，
兩邊都不該有對方沒有的欄位（`時間`、`處理狀態` 除外，那兩欄由程式自己填）。

`sendOrderMail_()` 產生 HTML 排版的通知信，分區塊呈現，不是一長串純文字。
要調整分區就改 `MAIL_SECTIONS`。
`formatSheet()` 設定試算表版面（欄寬、自動換行、狀態下拉、隔行底色），
建表時自動執行，也可手動跑一次套用到既有的表。

### 4. 交付前最終驗收

```
node scripts/check_site.js site.html          # 頁面 34 項檢查
node --input-type=module --check < worker.js  # Worker 語法
python3 -c "import ast;ast.parse(open('build_worker.py',encoding='utf8').read())"
```
全部通過才交付。剩下的 ⚠️ 警告（條款待補、圖片未接圖床）要明確告知使用者哪些還沒補齊。

### 5. 金鑰與 QR：scripts/gen_keys.py

`python3 gen_keys.py <品牌> <網址> <輸出目錄> <QR色碼>`（無閘門版跳過驗證器 QR，仍要入口 QR）。
**網址之後若有變更，記得重產入口 QR。**

### 6. 品牌交接說明

寫 `專案交接說明.md`：網址與帳號表、架構圖、現場怎麼用、改東西的三步驟、
常用設定對照表、上線前待補項目、緊急操作（換金鑰＝全場踢人、刪 Worker＝下架）、歷史教訓。
若使用者打算長期接案，再加一節「未來要幫新客戶開一個站」的步驟。

## 設計原則（為什麼這樣做）

- **內容伺服器端保護**：訂購頁 HTML 內嵌在 Worker，未通過閘門連原始碼都拿不到——
  這是「防外流」的實質保證，不只是擋 UI。
- **確認成功才顯示成功**：送單讀到後端 `ok` 才給成功頁。第三方出事時客人看到的是明確錯誤
  而非假成功，訂單不會無聲消失。
- **只依賴 Cloudflare＋Google**：寄信一律 Apps Script MailApp。不要用 FormSubmit 等免費表單
  轉信服務（曾發生過三次事故，詳見 deployment.md 歷史教訓）。
- **雙保險收單**：信箱（單筆通知＋名片連結）＋試算表（總覽對帳），一邊漏了另一邊還在。
- **金額只算一次**：總額＝商品＋運費，付款階段從總額拆。置底總計列、成功頁、訂單信、
  試算表必須是同一個數字——分開算過一次，結果少收運費。
- **狀態要誠實反映**：沒選商品時，置底總計列不寫「已選 0 項，合計 NT$ 0」——那是一排沒有意義的零。
  改成「尚未選擇商品」，金額淡化、送出鍵降對比，選了東西才亮起來。使用者一眼知道現在能不能送。
- **主要按鈕用描邊而非實心**：深色底上一整塊白會像促銷 banner。細框透明底、hover 才填滿，
  同樣醒目但不吵，和限量、受邀的調性比較合。
- **失敗要留退路**：送單失敗先自動重試一次；仍失敗就給訂單編號、請對方別重送。
  「叫客人再試一次」在後端其實已寫入的情況下會製造重複訂單。
- **承諾與實作要對齊**：頁面上寫的（折扣、時限、運費）就是系統實際會做的事。
  不確定就先問使用者，不要先寫個好聽的文案再說。

## 交付物清單

`site.html`（原始碼）、`worker.js`（部署產物）、`apps-script.gs`（已填品牌 CONFIG）、
`build_worker.py`（已填 CONFIG，供日後改版重建）、`TOTP_SECRET.txt`＋兩張 QR、
`專案交接說明.md`。全部打包成 zip 用 present_files 交給使用者保存。
