WordPress 預約系統開發實例 | 空間租借的動態時段與計價設計
AI 文章延伸
選擇平台後可直接帶入閱讀脈絡,快速整理重點、補齊盲點,並延伸到同站相關文章。
當計價邏輯複雜到現成外掛裝不下時,自建一套 WordPress 預約系統,反而比繼續改外掛更省。這是我們幫 HOWSHOW Space 開發空間租借預約系統時最先確認的一件事。
HOWSHOW Space 經營多間會議室和活動空間,原本的預約流程全靠客服私訊往返:客人問哪個時段還空著、報價多少、怎麼付款,客服一則一則回。業主想把這整套搬到線上,讓客人自己選日期、選時段、線上付款完成預約。聽起來就是裝一個預約外掛的事,我們評估到第二天卻決定不裝外掛,自己寫。
會議室預約系統的需求為什麼裝不進現成外掛
我們先試著把需求套進市面上的方案,FluentBooking、LatePoint 都測過。這些外掛的資料模型都建立在同一個假設上:一項服務有固定的時長和固定的價格,客人挑一個服務、挑一個時段就結束。剪髮 60 分鐘、諮詢 30 分鐘,都是這個模型。
HOWSHOW 的租借邏輯完全不是這樣:
- 動態時段:客人自己框選一段連續時間,不是選一個預設好的服務長度
- 四種費率:平日和假日不同價,下午 1 點為時段分界,界線前後又不同價,一個空間就有四種費率交錯
- 長租折扣:租超過一定時數,套用多組級距折扣
- 各空間獨立開放規則:每間空間的開放時段、假日是否營業,都各自設定
單一個「平日/假日 × 分界前/後」的計價,就已經超出這些外掛的欄位能表達的範圍。我們試著用外掛的自訂欄位硬湊,發現每加一條規則就要繞過一次它的資料結構。判斷標準其實很清楚:當核心計價邏輯塞不進外掛的資料模型時,繼續改外掛只會比重寫更貴。
決策一:放棄現成外掛,自建專屬系統
這個決策背後是一個常被誤解的原則——適切技術不等於「選最簡單的方案」,而是選恰好能裝下需求的方案。形象官網不需要動態功能,用 Astro 靜態生成就夠,那是往簡單走;但當現成外掛簡單到裝不下計價邏輯,適切的選擇反而是自建。方向相反,判斷準則一樣:需要的功能有沒有超過方案能提供的一半?未來擴展的機率撐不撐得起現在的複雜度?
決定自建之後,我們用資料結構優先的方式開發,先設計資料再寫邏輯:
- 建一個自訂文章類型(Custom Post Type)叫「空間」,每間會議室是一筆
- 用 WordPress 內建的 Meta Box API 存圖片、介紹、地址、費率、折扣級距,不依賴第三方欄位外掛
- 業主在後台維護每間空間的所有設定,新增一間空間只是後台建一筆資料,不用改程式
先把資料結構釘死,計價邏輯、時段驗證、前端顯示才有一致的地基可以長。這一步偷懶,後面每個功能都會為了遷就零散的欄位而變形。
決策二:迴避 WooCommerce,直接從表單結帳
第二個容易踩的坑是把金流交給 WooCommerce。WooCommerce 的設計假設是「賣一件商品」,而租時段不是賣商品——它有保留、有時效、有動態算出來的價格。硬把時段包成商品,等於再繞一層不屬於這個場景的資料結構。
我們讓流程走一條直線:填表 → 付款 → 回寫狀態 → 寄通知信,預約表單直接觸發藍新金流的加密參數結帳,中間不經過購物車。另一個值得記下來的實務細節是重新付款,客人第一次沒付成功要重新付款時,我們會在同一筆預約底下生成新的訂單編號,而不是沿用舊的,因為金流商會拒絕重複的訂單編號,沿用舊編號的話第二次付款會直接被擋掉。
三個真正難的技術點
計價和金流是邏輯問題,寫清楚就好。真正花時間的是下面三個。
併發預約:兩個人同時搶同一個時段
熱門時段會有兩個人幾乎同時按下預約。如果沒有處理,兩筆請求都會讀到「時段空著」,然後都寫入成功,變成超賣。我們用 MySQL 的具名鎖 GET_LOCK 處理併發衝突:先送出請求的人拿到鎖、贏得時段,後到的人被擋下。
搶到時段的人有一小時的保留期。超過 30 分鐘沒付款,系統寄一封提醒信;滿一小時還沒付,自動釋出時段讓別人能訂。這段邏輯讓熱門時段不會被沒付款的預約卡住。
通知信:涵蓋預約的完整生命週期
一筆預約從成立到結束會經過好幾個狀態,每個狀態都要有對應的信:
- 預約成功確認
- 30 分鐘未付款提醒
- 超時自動取消通知
- 付款成功確認(含進場資訊和空間門鎖密碼)
- 活動前一天提醒
信件系統看起來瑣碎,卻是最容易在上線後出包的地方。狀態一多,很容易發生同一封信重複寄、或某個狀態轉換漏寄的狀況,這也是我們上線前特別驗證的項目之一。
Google Calendar 同步:不透過官方 SDK
業主希望預約確認後自動寫進 Google Calendar,取消時自動刪掉。我們的做法是自簽 JWT 直接打 Google Calendar API,沒有引入官方 SDK。官方 SDK 會帶進一整包相依套件,對這個只需要「新增」和「刪除」兩個動作的場景來說太重了。自簽 JWT 換 access token 的程式碼不到幾十行,維護面積小很多。
客戶自助操作:把客服從信箱裡放出來
系統上線的重點不只是讓客人能訂,還要讓客人能自己改。我們用綁定預約的安全 token 做驗證,客人憑連結就能取消、改期、退款,不用再找客服。
退款規則直接寫進系統:三天前取消全額退、一天前退 50%、當天不退。系統依規則算出金額,直接呼叫金流商的退款 API 執行,客服完全不用經手。
開發方法論:TDD 加多模型交叉審查
這種計價和併發邏輯,錯一個判斷就是真金白銀的損失,所以關鍵邏輯我們都用測試驅動開發(TDD)覆蓋——同時預約、金流加解密、退款金額計算,先寫測試再寫實作。
程式碼審查則用了多個模型交叉看,Codex、Grok、Claude 各審一輪,背後是一個我們反覆驗證過的觀察:AI 產出的 PHP 常常超過一千行、架構不合理、不符合 WordPress 的程式碼規範,單一模型的盲點需要另一個模型來補。上線前我們特別針對兩件事做確認:資安風險,以及前面提過的重複寄信問題。
值得一提的是這次的協作模式:客戶端用 AI 自己做好前端介面設計,我們專注在後端邏輯。介面歸介面、邏輯歸邏輯,兩邊平行推進,這也是透明時薪制下常見的分工——業主把能自己掌控的部分留在手上,把需要專業判斷的後端交給我們。
最終成果
系統上線後,原本綁在客服私訊上的排程流程被整個拿掉,客人自己線上選時段、付款、確認,業主回收了那段被問答佔掉的時間,專心經營空間本身。架構也是可擴展的,之後業主要新增空間,後台配置一筆就好,不用再找我們改程式。
回到最根本的判斷:現成外掛不是不好,是它替你做掉的假設剛好跟你的生意不合。當那些假設一條條變成你要繞過的障礙時,自建就從「比較貴」變成「比較省」。
常見問題
空間租借或會議室預約系統,一定要自建嗎?
不一定。如果你的計價是固定時長、固定價格,市面上的 FluentBooking、Amelia 這類外掛就夠用,不需要自建。只有當計價邏輯(多段費率、動態時段、級距折扣)複雜到外掛的資料模型裝不下時,自建才會比一直改外掛划算。
為什麼預約系統不用 WooCommerce?
WooCommerce 的資料模型是為「賣商品」設計的,租時段有保留、時效、動態計價這些商品沒有的特性。硬把時段包成商品會多繞一層不屬於這個場景的結構,直接從預約表單觸發金流結帳反而更單純、更好維護。
併發預約造成的超賣怎麼處理?
我們用 MySQL 的具名鎖 GET_LOCK,讓先送出請求的人贏得時段、後到的人被擋下,避免兩筆請求同時讀到「空著」而雙雙寫入。搶到的時段保留一小時,逾時未付款自動釋出。
自建預約系統的金流串接難不難?
台灣的藍新、綠界金流串接本身有成熟的文件和流程,難的是細節,例如重新付款要換新的訂單編號、退款要依規則算金額再呼叫 API。這些我們在多個金流專案裡累積成可複製的做法。
有類似的會議室或空間租借預約需求,或想討論現成外掛裝不下的客製化開發?歡迎聯絡我們,或加入我們的 LINE 官方帳號聊聊你的專案。
Google 偏好來源
喜歡我們的內容嗎?一鍵將我們設為偏好來源,未來在 Google 焦點新聞與 AI 概覽中就能優先看到我們的文章。