會員可用點數是「算出來的」,不是存在某個欄位裡的。


九成的點數功能,是這樣做的:

$user->increment('points', 150);
$user->decrement('points', 600);

users 表加一個 points 欄位,加加減減。

這個設計撐不過三個月,因為它回答不出客服每天都會被問的問題:

  • 「我的點數為什麼少了?」
  • 「我上個月買東西的點數呢?」
  • 「我的點數什麼時候會過期?」

一個數字,什麼都答不出來。

帳本:兩張表

我的做法是把點數拆成「一張張點數卡」和「一筆筆使用紀錄」。

point_credits(點數從哪裡來)

user_id
points              這張卡原本有幾點
remaining_points    還剩幾點
type                order_reward / admin_adjustment / ...
order_id            來自哪張訂單
available_at        什麼時候可以開始用
expires_at          什麼時候過期
message             備註

point_usages(點數用到哪裡去)

user_id
point_credit_id     扣的是哪一張卡
points              扣了幾點
type                redemption / expiration / ...
order_id            用在哪張訂單

每一次發點、每一次折抵,都是 append 一列。沒有任何一個欄位會被覆蓋掉。

餘額是查出來的

public function availablePoints(): int
{
    return (int) PointCredit::where('user_id', $this->id)
        ->where('available_at', '<=', now())
        ->where(fn ($q) => $q->whereNull('expires_at')->orWhere('expires_at', '>', now()))
        ->sum('remaining_points');
}

已經生效、還沒過期的點數卡,剩餘點數加總。 這就是可用餘額。

不需要維護、不需要同步、不會跟明細對不起來——因為明細就是餘額的唯一來源。

為什麼值得多開一張表

客服可以自己查。 打開會員的點數明細,一列一列是什麼時候發的、哪張訂單發的、用在哪張訂單、什麼時候過期。不用工程師介入。

出錯可以追。 點數算錯的時候,你看得到是哪一筆發錯、哪一筆扣錯,而不是只看到一個「現在是 380 點」然後完全不知道怎麼來的。

點數效期才有辦法做。 這是關鍵——只要點數會過期,一個 balance 欄位就必然不夠用。因為你得知道「這 150 點是哪天發的、什麼時候過期」,而那需要一列資料,不是一個數字。


⭐️ Shopify 網站開發服務(給品牌)
https://job.turn.tw/shopify-services

⭐️ 川川電商事務所(全客製電商開發服務)
https://chuanchuan.tw

⭐️ 台灣 Shopify 商家交流 LINE 群(非官方)
https://line.me/ti/g2/PZ_1LILWVWWuzZQ50HNpYA-A3k6QXWF6znqoBQ

⭐️ 台灣 Shopify 開發者 LINE 群(非官方)
https://line.me/ti/g2/YUasX5K3CJ4QdIx76zppjHlh3-q8w-xkSyK1LA

共有 0 則留言


⭐️ Shopify 網站開發服務(給品牌)
https://job.turn.tw/shopify-services

⭐️ 川川電商事務所(全客製電商開發服務)
https://chuanchuan.tw

⭐️ 台灣 Shopify 商家交流 LINE 群(非官方)
https://line.me/ti/g2/PZ_1LILWVWWuzZQ50HNpYA-A3k6QXWF6znqoBQ

⭐️ 台灣 Shopify 開發者 LINE 群(非官方)
https://line.me/ti/g2/YUasX5K3CJ4QdIx76zppjHlh3-q8w-xkSyK1LA
🏆 本月排行榜
🥇
站長阿川
📝45   💬1  
643
評分標準:發文×10 + 留言×3 + 獲讚×5 + 點讚×1 + 瀏覽數÷10
本數據每小時更新一次