🏛️ 嘉義高中校友會 兩層式 LINE 智慧官方網站
統一管理後台 · ECPay 集中金流 · 三方自動拆帳 · RBAC 四角色權限 · L0/L1/L2 三層架構
5
L1 區域校友會
4
角色類型 (RBAC)
統一
ECPay 鑫邦主帳號
10
核心資料表
4
Cron 自動排程
L0 / L1 / L2 三層組織架構
L0 入口門戶
🏛️ 鑫邦(統一金流主體)— 總會最高管理層
LINE 官方帳號入口導流 · 統一登入門戶
↓ L1 區域分流
L1 — 區域校友會(5 區)
🌈
北區
L1
NORTH
🏙️
中區
L1
MID
🌾
南區
L1
SOUTH
⛰️
東區
L1
EAST
🌏
海外
L1
INTL
↓ L2 子組織分流
L2 — 子組織 / 小組(可選 LINE 子官網或獨立 Web 應用)
💬
LINE 子官網
LINE OA
🔗
LIFF 網頁平台
Web App
👥
產業別小組
Sub-Group
🏢
獨立 Web 應用
SSO 串接
💡 L2 可選擇 LINE 子官網或獨立 Web 應用平台,雙向 SSO 串接會員資料。技術基礎:LINE 官方帳號 + LIFF 嵌入式網站
兩層式 LINE 智慧官方網站
- ✅ L0 總會入口 + L1 區域 Bot,共用後端
- ✅ 統一 Webhook 路由分流
/webhook/line/:orgId - ✅ Rich Menu 六宮格快捷功能
- ✅ Flex Message 卡片式互動訊息
- ✅ L2 支援 LINE 子官網或獨立 Web App
統一金流 + 自動拆帳
- ✅ ECPay 鑫邦主帳號統一收款
- ✅ 每筆交易綁定
org_id拆帳標記 - ✅ 三方拆帳:總會 / 所屬區域 / 母校
- ✅ Cron 每月自動產生各區拆帳報表
- ✅ 支援信用卡/ATM/超商/LINE Pay
RBAC 四角色權限
- 👑 超級管理者(鑫邦財務/幹事)
- 🏢 各區管理者(僅限本區資料)
- 👤 會員(個人後台 + 工商上架)
- 🏫 學校代表(跨區發布公告)
🏗️ 系統架構總覽
五層式 Cloudflare 全棧架構,L0/L1/L2 三層組織,Edge 原生部署
整體服務層級架構
📱 Layer 1 — 用戶互動層
LINE 官方帳號
各區 Bot
管理後台
Web Admin SPA
會員後台
Member Portal
學校代表
School Portal
↓ HTTPS / LINE Webhook ↓
⚡ Layer 2 — API 閘道層(Hono on Cloudflare Workers)
Hono Router
主要 API 路由
JWT Middleware
RBAC 驗證
LINE Webhook
路由分流器
ECPay Webhook
金流回呼處理
↓ Queues / Workers ↓
🧠 Layer 3 — 業務邏輯層
推播排程
Scheduler
拆帳引擎
Split Engine
訂購管理
Commerce
訊息佇列
Queues Worker
報表產生
Reporter
↓ Read / Write ↓
🗄️ Layer 4 — 資料儲存層
Cloudflare D1
SQLite 主資料庫
Cloudflare KV
Session / 快取
Cloudflare R2
圖片 / PDF
Cron Triggers
定時排程
↓ 外部服務 API ↓
🌐 Layer 5 — 外部服務整合
LINE Messaging API
Push / Reply
ECPay 綠界
信用卡/ATM/超商
Email / SMS
交易通知
資料流程說明
📨 LINE 訊息接收流程
使用者傳訊息至各區 LINE Bot
LINE Platform 送 Webhook
/webhook/line/:orgId依 orgId 找對應 Bot Token
HMAC-SHA256 簽章驗證
放入 Cloudflare Queue
異步處理,避免超時
Queue Worker 回覆訊息
推播 / 回覆 / 導向付款
💳 金流交易流程
用戶點選付款
活動報名 / 商品訂購
產生付款連結(帶 org_id)
DB 先建立 PENDING 交易
ECPay 完成收款
款項進入鑫邦帳戶
回呼 ECPay Webhook
驗簽 → 更新交易狀態
Cron 每月產生拆帳報表
依 org_id 自動計算撥款
🖥️ 統一管理後台 Unified Admin Dashboard
一個後台總覽全五區數據,即時掌握營收、會員、活動與拆帳狀況
$286,400
本月總營收 (NT$)
4,287
活躍會員數
12
進行中活動
0
待對帳訂單
各區營收佔比
🌈 北區45%
🏙️ 中區30%
🌾 南區15%
⛰️ 東區5%
🌏 海外5%
拆帳分潤分佈
母校基金(獎學金)
35%
區域發展
25%
活動專款
20%
會員回饋
15%
其他
5%
近期訂單列表
| 訂單編號 | 品項 | 金額 | 區域 | 狀態 |
|---|---|---|---|---|
ORD-20260612-001 | 春酒餐會 | NT$ 18,000 | 北區 | 已完成 |
ORD-20260612-002 | 地瓜預購 (23筆) | NT$ 6,900 | 中區 | 待出貨 |
ORD-20260613-001 | 畢業紀念冊 | NT$ 4,500 | 南區 | 處理中 |
ORD-20260613-002 | 運動服 | NT$ 2,200 | 東區 | 待付款 |
後台導覽選單設計
📊
儀表板
總覽數據
🗺️
區域管理
5 區管理
👥
會員
4,287 人
📅
活動
報名管理
🛍️
商城
農產/工商
💰
金流對帳
ECPay
📈
拆帳報表
三方分潤
📣
推播排程
Cron
🏫
母校公告
嘉中
最新通知
💰
春酒餐會入帳 NT$ 18,000
10 分鐘前
📦
地瓜預購 待出貨 23 筆
30 分鐘前
📢
母校公告 已發佈
1 小時前
🏢 資料庫 — 組織與使用者
多租戶核心結構,organizations 表以 parent_id 實現雙層架構
organizations(組織主表)
多租戶核心| 欄位名稱 | 型別 | 屬性 | 說明 |
|---|---|---|---|
id | TEXT | PK | UUID 主鍵 |
parent_id | TEXT | FK | 父組織 ID,NULL=L0/L1,有值=L2 子組織 |
org_level | INTEGER | 層級:0=總會入口(L0),1=區域校友會(L1),2=子組織(L2) | |
name | TEXT | NOT NULL | 組織名稱(如:北區校友會) |
short_code | TEXT | UNIQUE | 短碼,用於 Webhook URL(NORTH/MID/SOUTH/EAST/INTL) |
line_channel_id | TEXT | LINE Channel ID | |
line_channel_secret | TEXT | 🔐 加密 | LINE Channel Secret(AES-256 加密儲存) |
line_channel_token | TEXT | 🔐 加密 | Channel Access Token(AES-256 加密儲存) |
billing_ratio | REAL | DEFAULT 0.9 | 組織分潤比例(如 0.9 = 組織拿 90%,不含母校回饋) |
billing_bank_account | TEXT | 🔐 加密 | 拆帳目標銀行帳號 |
status | TEXT | DEFAULT 'active' | active / inactive / suspended |
users(系統使用者帳號)
後台登入帳號| 欄位名稱 | 型別 | 屬性 | 說明 |
|---|---|---|---|
id | TEXT | PK | UUID |
org_id | TEXT | FK | 所屬組織(NULL = 鑫邦總部) |
role | TEXT | NOT NULL | SUPER_ADMIN / ORG_ADMIN / MEMBER / SCHOOL_REP |
username | TEXT | UNIQUE | 登入帳號 |
password_hash | TEXT | 🔐 | bcrypt 雜湊密碼 |
is_active | INTEGER | DEFAULT 1 | 帳號啟用狀態 |
last_login_at | DATETIME | 最後登入時間 |
line_users(LINE 用戶綁定)
| 欄位名稱 | 型別 | 屬性 | 說明 |
|---|---|---|---|
id | TEXT | PK | UUID |
line_uid | TEXT | UNIQUE | LINE User ID(Uxxx...) |
member_id | TEXT | FK | 綁定的會員(已驗證後關聯) |
org_id | TEXT | FK | 由哪個 Bot 加入(區域識別) |
display_name | TEXT | LINE 顯示名稱 | |
follow_at | DATETIME | 加入 Bot 時間 | |
rich_menu_id | TEXT | 目前套用的 Rich Menu ID | |
is_active | INTEGER | DEFAULT 1 | 是否仍在追蹤中 |
👥 資料庫 — 會員模組
會員主表包含自我介紹輪播欄位,支援審核流程與公平輪播排隊
members(校友會員主表)
含輪播介紹欄位| 欄位名稱 | 型別 | 屬性 | 說明 |
|---|---|---|---|
id | TEXT | PK | UUID |
org_id | TEXT | FKIDX | 所屬第一層組織 |
sub_org_id | TEXT | FK | 所屬第二層子組織(可選) |
member_no | TEXT | UNIQUE | 會員編號(如 NORTH-2024-001) |
real_name | TEXT | NOT NULL | 真實姓名 |
graduation_year | INTEGER | 畢業年度(民國) | |
class_no | TEXT | 班級(如 303) | |
phone | TEXT | 🔐 遮罩 | 手機號碼 |
email | TEXT | 電子信箱 | |
avatar_url | TEXT | 頭貼 URL(Cloudflare R2) |
自我介紹模組需通過管理者審核後,才會加入輪播推播佇列。
| 欄位名稱 | 型別 | 說明 |
|---|---|---|
intro_title | TEXT | 介紹標題(如:王大明 | 建築師) |
intro_content | TEXT | 自我介紹內文(最多 500 字) |
intro_images | TEXT | JSON 陣列,圖片 URL 列表 |
intro_approved | INTEGER | 0=待審核,1=通過,2=拒絕 |
intro_approved_at | DATETIME | 審核通過時間 |
intro_priority | INTEGER | 輪播優先序(數值越高越優先) |
last_broadcast_at | DATETIME | ⭐ 最後一次被輪播推播時間(輪播公平排隊依據) |
| 欄位名稱 | 型別 | 說明 |
|---|---|---|
membership_type | TEXT | regular / lifetime / honorary |
membership_start | DATE | 會籍開始日 |
membership_expiry | DATE | 會籍到期日 |
status | TEXT | active / pending / suspended / expired |
💰 資料庫 — 金流與拆帳
transactions 表為核心,每筆交易帶 org_id 拆帳標記;split_reports 記錄月度拆帳結果
架構重點:所有款項均進入鑫邦 ECPay 帳戶,系統透過
org_id 欄位追蹤每筆交易的來源組織,作為後續自動計算拆帳金額的依據。transactions(金流交易主表)
⭐ 拆帳核心| 欄位名稱 | 型別 | 說明 |
|---|---|---|
id | TEXT | 系統 UUID 主鍵 |
merchant_trade_no | TEXT | ECPay 商店訂單號(送給綠界,唯一不重複) |
ecpay_trade_no | TEXT | ECPay 回傳的綠界交易序號 |
org_id | TEXT | ⭐⭐ 拆帳依據:款項歸屬的組織 |
sub_org_id | TEXT | 第二層子組織(若適用) |
source_type | TEXT | EVENT_FEE / PRODUCT_ORDER / MEMBERSHIP / AD |
source_id | TEXT | 關聯的活動 ID 或訂單 ID |
| 欄位名稱 | 說明 | 計算邏輯 |
|---|---|---|
amount | 交易金額(元) | 使用者實際付款金額 |
platform_fee | ECPay 手續費 | 信用卡約 1.5-2%,ATM 固定 15 元 |
net_amount | 實收金額 | amount - platform_fee |
xinbang_fee | 鑫邦服務費 | net_amount × (1 - org.billing_ratio) |
org_split_amount | 應撥給組織金額 | net_amount - xinbang_fee |
payment_method | 支付方式 | Credit / ATM / CVS / BARCODE |
| 欄位名稱 | 可能值 | 說明 |
|---|---|---|
status | PENDING / PAID / FAILED / REFUNDED / CANCELLED | ECPay 付款狀態 |
split_status | PENDING / INCLUDED / SETTLED | 拆帳流程狀態 |
split_report_id | FK → split_reports | 歸屬哪一期拆帳報表 |
paid_at | DATETIME | 實際付款時間(ECPay 回傳) |
settled_at | DATETIME | 鑫邦實際撥款給組織的時間 |
raw_ecpay_data | JSON TEXT | ECPay Webhook 原始資料(備查) |
split_reports(拆帳報表)
| 欄位名稱 | 型別 | 說明 |
|---|---|---|
id | TEXT | UUID 主鍵 |
report_no | TEXT | 報表編號(RPT-2024-M10-NORTH) |
org_id | TEXT | 拆帳對象組織 |
period_start / period_end | DATE | 統計區間(上月 1 日至月底) |
gross_amount | INTEGER | 本期總收款 |
platform_fee_total | INTEGER | ECPay 手續費合計 |
xinbang_fee_total | INTEGER | 鑫邦服務費合計 |
net_payable | INTEGER | ⭐ 應撥款給組織金額 |
status | TEXT | DRAFT → PENDING_APPROVAL → APPROVED → SETTLED |
settlement_ref | TEXT | 銀行匯款水單編號 |
report_pdf_url | TEXT | 產生的 PDF 下載 URL(R2) |
📅 資料庫 — 活動與訂單
活動、商品、訂單三表共同構成電商模組,orders 表帶 org_id 拆帳標記
events(活動主表)
| 欄位名稱 | 型別 | 說明 |
|---|---|---|
id | TEXT | UUID |
org_id | TEXT | 主辦組織(FK → organizations) |
title | TEXT | 活動名稱 |
event_type | TEXT | SOCIAL / SEMINAR / SPORTS / AGM |
start_at / end_at | DATETIME | 活動時間 |
registration_start / end | DATETIME | 報名開放期間 |
max_attendees | INTEGER | 名額上限(NULL=不限) |
fee | INTEGER | 報名費(0=免費) |
visibility | TEXT | ORG_ONLY / ALL_ORGS / PUBLIC |
status | TEXT | DRAFT / PUBLISHED / CANCELLED / COMPLETED |
products(工商 & 農作物商品)
| 欄位名稱 | 型別 | 說明 |
|---|---|---|
product_type | TEXT | COMMERCE / AGRICULTURAL / PROMOTION |
price | INTEGER | 單價(元) |
stock_total / remaining | INTEGER | 總庫存 / 剩餘庫存(原子更新,防超賣) |
sale_start_at / end_at | DATETIME | 開賣至截止時間 |
is_flash_sale | INTEGER | 是否為每週限時促銷 |
flash_discount_pct | REAL | 折扣比例(0.8 = 8折) |
flash_start_at / end_at | DATETIME | 限時促銷區間 |
preorder_deadline | DATETIME | 農作物預購截止日 |
delivery_date | TEXT | 農作物預計出貨日 |
approved | INTEGER | 管理者審核狀態 |
📢 資料庫 — 推播與訊息
broadcast_schedules 追蹤所有推播排程記錄,announcements 管理公告
broadcast_schedules(推播排程)
| 欄位名稱 | 型別 | 說明 |
|---|---|---|
schedule_type | TEXT | MEMBER_INTRO / EVENT / ANNOUNCEMENT / PRODUCT |
target_type | TEXT | ALL_FOLLOWERS / ORG_MEMBERS / SPECIFIC_USERS |
content_ref_id | TEXT | 關聯的 member_id / event_id / product_id |
content_type | TEXT | TEXT / FLEX_MESSAGE / CAROUSEL |
content_json | TEXT | LINE Flex Message JSON |
scheduled_at | DATETIME | 預計推播時間 |
status | TEXT | QUEUED / SENDING / SENT / FAILED |
sent_count / fail_count | INTEGER | 成功 / 失敗推播數量 |
🛡️ RBAC 四角色權限設計
四種角色透過 JWT Middleware 強制資料隔離,ORG_ADMIN 僅能存取自身組織
👑
SUPER_ADMIN
總會最高管理員
總幹事・副總幹事・秘書・鑫邦財務
擁有系統最高權限,全面管理校友會運作
全會務管理(完全開放)
各區金流檢視(完全開放)
拆帳報表審核並確認撥款
跨區活動發布與分潤設定
推播管理(全區)
母校公告(完全開放)
🏢
ORG_ADMIN
各區校友會管理員
各區校友會幹部・子組織負責人
聚焦所屬區域,管理分會活動與在地會員
各區金流檢視(本區)
拆帳報表(本區)
活動發布(本區)
會員資料管理(本區)
推播管理(本區)
❌ 無母校公告權限
👤
MEMBER
校友會員
一般校友會員
存取個人資料與活動,維護隱私與參與權
會員資料(本人)
建立與編輯個人自我介紹
上架農作物/商品預約訂購
透過 ECPay 直接收款
❌ 無金流/報表存取
❌ 無法查看他人資料
🏫
SCHOOL_REP
校友母校(嘉中行政端)
嘉義高中學校端代表
專屬發布官方公告,確保資訊準確傳達
母校公告(完全開放)
發布學校訊息至各區 Bot
發布校慶、招生公告
❌ 無金流存取權限
❌ 無法管理會員資料
功能存取控制矩陣(依 Slide 7 更新)
●=完全開放 ◑=本區/本人限定 ○=無權限
| 功能模組 | 👑 總會最高管理員 | 🏢 各區管理員 | 👤 校友會員 | 🏫 校友母校 |
|---|---|---|---|---|
| 全會務管理 | ✅完全開放 | ❌ | ❌ | ❌ |
| 各區金流檢視 | ✅全部 | 🟡本區 | ❌ | ❌ |
| 拆帳報表 | ✅審核 | 🟡本區 | ❌ | ❌ |
| 活動發布 | ✅全部 | 🟡本區 | ❌ | ❌ |
| 會員資料 | ✅全部 | 🟡本區 | 🟡本人 | ❌ |
| 推播管理 | ✅全區 | 🟡本區 | ❌ | ❌ |
| 母校公告 | ✅全部 | 👁唯讀 | 👁唯讀 | ✅發布 |
| 三方分潤設定 | ✅設定 | 👁唯讀 | ❌ | ❌ |
| 工商/農產上架 | ✅審核 | 👁本區 | ✅自身 | ❌ |
💬 LINE 智慧官方網站路由規劃
L0 入口總站 + L1 五區各有獨立 Bot,共用後端;Webhook URL 帶 orgId 參數識別來源
架構說明:L0 為鑫邦總會入口門戶(LINE 官方帳號),負責導流至各 L1 區域 Bot。L1 各區 Bot 各自獨立但共用統一後端 Hono Worker。
各層 LINE 帳號 Webhook 端點對應
| 層級 | 區域 | 短碼 | LINE Webhook URL | 狀態 |
|---|---|---|---|---|
| L0 | 🏛️ 嘉中校友會總站 | HQ | https://api.domain.com/webhook/line/HQ | active |
| L1 | 🌈 北區校友會 | NORTH | https://api.domain.com/webhook/line/NORTH | active |
| L1 | 🏙️ 中區校友會 | MID | https://api.domain.com/webhook/line/MID | active |
| L1 | 🌾 南區校友會 | SOUTH | https://api.domain.com/webhook/line/SOUTH | active |
| L1 | ⛰️ 東區校友會 | EAST | https://api.domain.com/webhook/line/EAST | active |
| L1 | 🌏 海外校友會 | INTL | https://api.domain.com/webhook/line/INTL | active |
Rich Menu 六宮格設計
📅
近期活動
postback
🛍️
校友工商
postback
🌾
農產訂購
postback
👤
校友介紹
postback
📢
最新公告
postback
🔗
會員後台
uri (外部連結)
💳 ECPay 金流架構
鑫邦統一 MerchantID,每筆交易帶 org_id 拆帳標記,ECPay 回呼驗簽防偽
統一金流原則(各區免申請):全系統僅使用鑫邦一組 ECPay 帳號(MerchantID / HashKey / HashIV),所有款項先進入鑫邦帳戶,後台依
org_id 自動計算三方拆帳。支援信用卡 / 超商代碼 / ATM 虛擬帳號 / LINE Pay,PCI-DSS 合規,24H 全天候,對帳自動化。付款建立 → 回呼流程
1
建立訂單
系統在 DB 建立 PENDING 交易,帶入
org_id(拆帳標記)2
產生付款連結
用鑫邦帳號組裝 ECPay 參數,計算 CheckMacValue
3
用戶完成付款
信用卡 / ATM 轉帳 / 超商繳費,款項進入鑫邦帳戶
4
ECPay 回呼 Webhook
POST /webhook/ecpay/result,驗證 CheckMacValue 簽章5
更新交易狀態
status → PAID,更新 net_amount、paid_at,推播 LINE 通知
6
Cron 月結拆帳
每月 1 日依 org_id 匯總計算,產生各區拆帳報表
支付方式與手續費
| 支付方式 | ECPay 手續費 | 到帳時間 | 適用場景 |
|---|---|---|---|
| 💳 信用卡 | 約 1.5%~2% | 月結撥款 | 活動報名、商品購買 |
| 🏦 ATM 虛擬帳號 | 固定 NT$15 | 付款後 T+1 | 大額訂購、農產預購 |
| 🏪 超商代碼繳費 | 約 NT$25 | 付款後 T+1 | 一般商品、活動費 |
| 📱 LINE Pay | 約 2%~3% | 即時 | 行動支付、快速結帳 |
🧮 智慧自動拆帳系統
後台智慧『自動拆帳』系統:三方分潤(總會 / 所屬區域 / 母校),Cron 每月自動執行
五階段自動拆帳流程
📱
Stage 1
校友 LINE 下單 / 報名
🛡️
Stage 2
綠界完成收款
🗄️
Stage 3
系統自動標記
區域屬性
區域屬性
🧮
Stage 4
拆帳分潤計算
即時算法
即時算法
📋
Stage 5
一鍵生成報表
跨區活動 · 三方分潤聯動機制
核心新功能總會發起跨區活動時,系統自動依「會員所屬區域」標記,三方分潤:總會 / 所屬區域 / 母校(嘉中)。區域會長有動機協助招募,凝聚向心力,帳目透明三方互信。
60%
→ 總會
活動主辦 · 行政與場地成本
30%
→ 所屬區域校友會
招募功勞 · 區域經營獎勵
10%
→ 校友母校(嘉中)
公益回饋 · 獎學金挹注
📝 備註:比例可依活動性質彈性調整(如純募款活動可調為 0/0/100)。由 SUPER_ADMIN 於後台設定各活動分潤模板。
📋 情境範例:2026 全國校友盃高爾夫(共 200 人,報名費 NT$3,800)
| 報名人 | 所屬區域 | 報名費 | 總會 (60%) | 所屬區 (30%) | 母校 (10%) | 到帳 |
|---|---|---|---|---|---|---|
| 陳○○ | 北區 | NT$ 3,800 | $2,280 | 北區 $1,140 | $380 | T+1 |
| 林○○ | 中區 | NT$ 3,800 | $2,280 | 中區 $1,140 | $380 | T+1 |
| 黃○○ | 南區 | NT$ 3,800 | $2,280 | 南區 $1,140 | $380 | T+1 |
| TOTAL | 全活動 200 人 | NT$ 760,000 | $456,000 | 各區合計 $228,000 | $76,000 | 自動 |
SAMPLE LEDGER — 範例總帳表格
| 訂單編號 | 品項 | 金額 | 區域歸屬 | 拆帳比例 | 入帳對象 |
|---|---|---|---|---|---|
20260612-001 | 春酒餐會 | NT$ 1,800 | 中區 | 100% | 中區校友會 |
20260612-002 | 地瓜預購 | NT$ 680 | 南區 | 90% : 10% | 南區 : 總會 |
20260613-001 | 捐款支持 | NT$ 5,000 | 北區 | 100% | 北區校友會 |
20260613-002 | 紀念品購買 | NT$ 1,200 | 海外 | 50% : 50% | 海外 : 總會 |
✅ 系統效益:帳目即時透明 · 免人工核算 · 總會/各區雙向稽核
拆帳計算公式(技術實作)
// 每月 Cron 自動執行(UTC+8 台灣時間)
gross_amount = SUM(transactions.amount) // 本期總收款
platform_fee = SUM(transactions.platform_fee) // ECPay 手續費合計
net_before_split = gross_amount - platform_fee
// 三方拆帳(以跨區活動為例):
hq_share = FLOOR(net_before_split × event.hq_ratio) // 總會份額
region_share = FLOOR(net_before_split × event.region_ratio) // 區域份額
school_share = FLOOR(net_before_split × event.school_ratio) // ✅ 母校份額
拆帳報表範例(北區 2026 年 6 月)
📊 RPT-2026-M06-NORTH
北區校友會 · 2026/06/01 ~ 06/30
交易筆數
48
總收款
$156,800
ECPay 手續費
-$3,136
鑫邦服務費(5%)
-$7,683
應撥款金額
$145,981
按來源分類
活動報名費:$68,000
工商訂購:$54,800
農作物預購:$34,000
按支付方式
信用卡:$112,000
ATM 轉帳:$32,800
超商繳費:$12,000
狀態流程
DRAFT → 系統產生
PENDING → 待審核
APPROVED → 確認
SETTLED → 已匯款
📣 輪播推播排程系統
依「最久未介紹」原則公平輪流,確保每位會員都有曝光機會
輪播排隊演算法
排序邏輯(SQL)
-- 取最久未推播的已審核會員
SELECT * FROM members
WHERE org_id = ?
AND intro_approved = 1
AND status = 'active'
ORDER BY
CASE WHEN last_broadcast_at
IS NULL THEN 0 ELSE 1
END ASC, -- 從未推播優先
last_broadcast_at ASC -- 最舊的排前面
LIMIT 1
推播完成後更新
-- 推播成功後更新時間
-- 讓該會員排到最後
UPDATE members
SET last_broadcast_at
= CURRENT_TIMESTAMP
WHERE id = ?
📅 Cron 執行時間
• 每週三 11:00(台灣時間)
• 每週六 11:00(台灣時間)
每次對每個組織各推播 1 位會員
Cron 排程總覽
| Cron 表達式 | 執行時間(台灣) | 任務 |
|---|---|---|
0 3 1 * * | 每月 1 日 11:00 | 🧮 產生上月各區拆帳報表,通知財務審核 |
0 3 * * 3,6 | 週三、週六 11:00 | 👤 會員自我介紹輪播推播 |
0 */6 * * * | 每 6 小時 | ⏰ 限時促銷到期檢查、訂單過期自動取消 |
0 1 * * * | 每日 09:00 | 🔄 LINE 追蹤者清單同步、過期 Session 清理 |
🛒 工商優惠與預約訂購模組
支援時間限制、數量限制、原子防超賣,串接 ECPay 直接收款
⏰ 限時促銷規則
🕒
設定
flash_start_at / end_at 時間區間,自動在區間內套用折扣價📉
flash_discount_pct = 0.8 表示 8 折,訂單建立時以折扣後計算📣
促銷開始前 1 小時自動推播 LINE 通知至該組織追蹤者
⛔
Cron 每 6 小時檢查,過期自動還原原價並更新 status
🌾 農作物預約訂購
📅
設定
preorder_deadline 截止日與 delivery_date 出貨日🔒
截止前下單付款,系統鎖定庫存並 LINE 通知賣家
🚚
出貨日前 3 天自動推播「出貨提醒」給買家
📊
截止後賣家可在後台查看總預購量與買家聯絡資訊
防超賣機制(原子操作)
-- 原子性扣減庫存,確保不超賣
-- SQLite RETURNING 語法防止競態條件
UPDATE products
SET stock_remaining = stock_remaining - ?quantity
WHERE id = ?productId
AND stock_remaining >= ?quantity -- 庫存足夠才扣
AND status = 'ACTIVE'
AND (sale_end_at IS NULL
OR sale_end_at > CURRENT_TIMESTAMP) -- 未過期
RETURNING * -- 若無匹配則回傳空(代表失敗)
若 UPDATE 沒有匹配任何資料列(庫存不足或已過期),系統回傳 400 錯誤「商品已售完或已過期」,不建立訂單。
📡 API 端點規劃
RESTful 設計,JWT 驗證,RBAC 中介層
| Method | 路徑 | 說明 | 權限 |
|---|---|---|---|
| POST | /api/auth/login | 管理後台登入(帳密) | Public |
| POST | /api/auth/refresh | 刷新 JWT Token | JWT |
| POST | /api/auth/logout | 登出(廢棄 Token) | JWT |
| POST | /api/auth/line/bind | LINE 帳號綁定會員 | LINE Token |
| GET | /api/auth/me | 取得目前登入使用者資訊 | JWT |
| Method | 路徑 | 說明 | 權限 |
|---|---|---|---|
| GET | /api/orgs | 取得所有組織列表 | SUPER_ADMIN |
| POST | /api/orgs | 建立新組織 | SUPER_ADMIN |
| GET | /api/orgs/:id | 組織詳情 | SUPER / ORG(自身) |
| PUT | /api/orgs/:id | 更新組織設定 | SUPER / ORG(自身) |
| GET | /api/orgs/:id/sub-orgs | 子組織列表 | SUPER / ORG |
| GET | /api/orgs/:id/stats | 組織統計(會員數、交易額) | SUPER / ORG |
| Method | 路徑 | 說明 | 權限 |
|---|---|---|---|
| GET | /api/members | 會員列表(含分頁過濾) | SUPER / ORG |
| POST | /api/members | 新增會員 | SUPER / ORG |
| GET | /api/members/:id | 會員詳情 | SUPER / ORG / MEMBER(自) |
| PUT | /api/members/:id/intro | 更新自我介紹 | MEMBER(自身) |
| POST | /api/members/:id/intro/submit | 提交介紹審核 | MEMBER(自身) |
| PUT | /api/members/:id/intro/approve | 審核通過/拒絕 | SUPER / ORG |
| Method | 路徑 | 說明 | 權限 |
|---|---|---|---|
| GET | /api/finance/transactions | 全域交易流水帳 | SUPER_ADMIN |
| GET | /api/finance/transactions?org_id= | 特定組織交易 | SUPER / ORG(自) |
| GET | /api/finance/split-reports | 拆帳報表列表 | SUPER_ADMIN |
| GET | /api/finance/split-reports/:id | 拆帳報表詳情 | SUPER / ORG(自) |
| POST | /api/finance/split-reports/generate | 手動觸發產生報表 | SUPER_ADMIN |
| PUT | /api/finance/split-reports/:id/approve | 審核批准 | SUPER_ADMIN |
| PUT | /api/finance/split-reports/:id/settle | 標記已撥款 | SUPER_ADMIN |
| GET | /api/finance/split-reports/:id/export | 匯出 PDF/Excel | SUPER / ORG(自) |
| Method | 路徑 | 說明 | 權限 |
|---|---|---|---|
| GET | /api/events | 活動列表(分頁/過濾) | All |
| POST | /api/events | 建立活動 | SUPER / ORG |
| GET | /api/events/:id | 活動詳情 | All |
| PUT | /api/events/:id | 更新活動 | SUPER / ORG(自) |
| POST | /api/events/:id/register | 活動報名(建立訂單+付款) | MEMBER |
| GET | /api/events/:id/attendees | 報名名單 | SUPER / ORG |
| Method | 路徑 | 說明 | 權限 |
|---|---|---|---|
| GET | /api/products | 商品列表(type/org 篩選) | All |
| POST | /api/products | 上架商品/農產 | MEMBER |
| PUT | /api/products/:id | 更新商品 | MEMBER(自身) |
| PUT | /api/products/:id/approve | 審核上架 | SUPER / ORG |
| POST | /api/orders | 建立訂單(含防超賣) | MEMBER |
| GET | /api/orders/:id | 訂單詳情 | SUPER / ORG / MEMBER(自) |
| Method | 路徑 | 說明 | 權限 |
|---|---|---|---|
| GET | /api/broadcasts | 推播記錄列表 | SUPER / ORG |
| POST | /api/broadcasts | 手動建立推播排程 | SUPER / ORG / SCHOOL |
| DELETE | /api/broadcasts/:id | 取消待推播排程 | SUPER / ORG(自) |
| POST | /api/announcements | 發布公告 | SUPER / SCHOOL_REP |
| GET | /api/announcements | 公告列表 | All |
| Method | 路徑 | 說明 | 認證 |
|---|---|---|---|
| POST | /webhook/line/:orgId | LINE 事件(各區 Bot) | LINE Signature |
| POST | /webhook/ecpay/result | ECPay 付款結果 | CheckMacValue |
| POST | /webhook/ecpay/period | 定期定額通知 | CheckMacValue |
⚙️ 技術棧與部署架構
Cloudflare 全棧方案,Edge 原生,零冷啟動,免運維
🔥 Cloudflare 全棧(建議)
後端框架Hono (TypeScript)
主資料庫Cloudflare D1 (SQLite)
快取/SessionCloudflare KV
檔案儲存Cloudflare R2
訊息佇列Cloudflare Queues
排程Cron Triggers
前端React + Pages
🔄 備選方案(規模擴大後)
後端:Node.js Fastify 或 Python FastAPI(VPS)
資料庫:PostgreSQL(Supabase / Neon)
佇列:Redis + Bull Queue(Upstash)
推播排程:進階 Job 重試、優先序控制
💡 建議初期使用 Cloudflare 全棧(免費方案充裕),待會員超過 5,000 人或業務需求增加時再評估遷移。
建置時程(M1~M4 甘特圖)
2026/07
M1 需求訪談 · 系統規劃
• 需求訪談
• 系統架構設計
• DB Schema 確認
• 系統架構設計
• DB Schema 確認
2026/08
M2 LINE 主站 + 金流串接
• L0/L1 Bot 建置
• ECPay 串接
• 里程碑:金流測試完成
• ECPay 串接
• 里程碑:金流測試完成
🏁 M2 末:金流測試完成
2026/09
M3 拆帳引擎 + 後台儀表板
• 三方拆帳引擎
• 管理後台 Dashboard
• 區域種子用戶上線
• 管理後台 Dashboard
• 區域種子用戶上線
🏁 M3 末:種子用戶上線
2026/10
M4 教育訓練 · 全區上線
• 各區管理員培訓
• 全區正式上線
• UAT 測試完成
• 全區正式上線
• UAT 測試完成
▼80%
行政對帳人力
▲3X
活動報名轉換
NT$1.5M
年度校友經濟產值
100%
帳目透明度
📅 投資回收期估計:8 個月
安全性設計要點
ECPay 金鑰安全
MerchantID / HashKey / HashIV 以 Cloudflare Secrets 儲存,不入版本控制,絕不明文儲存
LINE Secret 加密
DB 中的 line_channel_secret、token 以 AES-256 加密後儲存,讀取時即時解密
Webhook 簽章驗證
LINE:HMAC-SHA256 驗簽;ECPay:CheckMacValue 驗簽,防止偽造請求
Idempotency Key
ECPay 回呼可能重複,以 KV 儲存已處理的 MerchantTradeNo,防重複扣款
個資保護
身份證號、銀行帳號、電話加密儲存,介面僅顯示遮罩版本(如 09xx-xxxx-xx)
RBAC 資料隔離
ORG_ADMIN 所有 Query 自動套用 WHERE org_id = 自身,Middleware 強制執行無法繞過