Branch8

台灣電商品牌 HubSpot 會員分級自動化教學

Matt Li
October 17, 2026
13 mins read
台灣電商品牌 HubSpot 會員分級自動化教學

Key Takeaways

  • 對外等級用消費門檻制,對內 RFM 分群另存欄位,兩者勿混用
  • 滾動 12 個月金額需每日全量重算,不能只靠訂單 webhook
  • Custom code action 需 Operations Hub Professional,單次執行上限 20 秒
  • 務必開啟 Workflow Re-enrollment,否則會員只會被判定一次
  • 多市場擴張前先建好 market 與幣別欄位,事後重構成本高

台灣電商品牌要在 HubSpot 做會員分級自動化,核心是四件事:把訂單資料同步成 Contact 屬性、用計算屬性累加滾動年度消費、以 Workflow 搭配 Operations Hub 自訂程式碼判定級別,最後把級別回寫到電商前台與 LINE OA。以下是完整實作步驟。

開始前:你需要準備什麼

這份教學假設你要在正式環境上線,而不是只做 demo。動手前請先確認以下條件:

  1. HubSpot 訂閱方案:Marketing Hub Professional 以上(才有 Workflows)。若要在 Workflow 裡寫 JavaScript 或 Python,需要 Operations Hub Professional 的 Custom code action。根據 HubSpot 官方產品文件,Custom code 是 Operations Hub Professional 起跳的功能,Marketing Hub 單獨購買不包含。
  2. Private App Token:到 Settings → Integrations → Private Apps 建立,至少勾選 crm.objects.contacts.read/write、crm.objects.deals.read、crm.schemas.contacts.write。
  3. 電商平台的訂單來源:台灣常見的是 Shopify、SHOPLINE、Cyberbiz、91APP、或自建 Magento / WooCommerce。你需要能取得「會員識別碼 + 訂單金額 + 成立時間 + 訂單狀態」四個欄位。
  4. 一個明確的會員權益表:分級自動化是把商業規則程式化,規則沒談定就寫 workflow,最後一定重做。
  5. 測試用 Sandbox:HubSpot Enterprise 方案提供 Standard Sandbox;Professional 方案沒有的話,請用一組 test_ 前綴的測試聯絡人做驗證。

技術限制也要先記下來。HubSpot 開發者文件指出,Private App 在 Professional / Enterprise 方案的速率上限為每 10 秒 190 次請求,每日上限 250,000 次;Workflow 的 Custom code action 單次執行上限為 20 秒。這兩個數字會直接決定你的同步批次設計。

第一步:先把分級模型講清楚

大多數台灣電商的分級邏輯落在三種模式:

累計消費門檻制

最常見。例如:一般會員(0 元起)/銀卡(年度 10,000 元)/金卡(年度 30,000 元)/鑽石(年度 80,000 元)。優點是消費者好理解、客服好解釋;缺點是對高頻低客單的品類(美妝補充包、寵物食品)鑑別度低。

點數累積制

以點數取代金額,可針對特定品類加權(例如新品 2 倍點)。彈性高,但需要額外維護點數帳本,HubSpot 本身不是帳本系統,建議點數存在電商端、只把餘額同步進來。

RFM 行為分群

以 Recency(最近購買距今天數)、Frequency(年度訂單數)、Monetary(年度消費金額)三軸打分。適合做行銷分眾,但不適合當作對外公告的「會員等級」,因為消費者無法預期自己為什麼掉級。

實務建議:對外用「累計消費門檻制」當作會員等級,對內另外跑一組 RFM 分數做行銷分眾。兩者分開存在不同屬性,不要混在同一個欄位。這也是我們在協助一家東南亞與台灣雙市場的保健食品 DTC 品牌重建 HubSpot 架構時採取的做法——對外等級邏輯必須穩定,對內分群邏輯則要能每季調整。

Ready to Transform Your Ecommerce Operations?

Branch8 specializes in ecommerce platform implementation and AI-powered automation solutions. Contact us today to discuss your ecommerce automation strategy.

第二步:在 HubSpot 建立自訂屬性

到 Settings → Properties → Contact properties,建立以下欄位。命名用英文小寫加底線,之後 API 操作才不會出錯(HubSpot 會把中文屬性名稱轉成亂碼般的 internal name)。

  • membership_tier(下拉選單:bronze / silver / gold / diamond)
  • membership_tier_effective_date(日期)
  • membership_tier_expiry_date(日期)
  • ltv_total(數字,歷史累計消費)
  • rolling_12m_spend(數字,滾動 12 個月消費)
  • order_count_12m(數字)
  • last_order_date(日期)
  • rfm_score(單行文字,例如 445)
  • ecommerce_customer_id(單行文字,電商端主鍵,設為唯一值)

用 API 一次建立會比手動快。以下是用 Properties API 建立 membership_tier 的範例:

1curl -X POST \
2 'https://api.hubapi.com/crm/v3/properties/contacts' \
3 -H "Authorization: Bearer $HUBSPOT_PRIVATE_APP_TOKEN" \
4 -H 'Content-Type: application/json' \
5 -d '{
6 "name": "membership_tier",
7 "label": "會員等級",
8 "groupName": "contactinformation",
9 "type": "enumeration",
10 "fieldType": "select",
11 "options": [
12 {"label": "一般會員", "value": "bronze", "displayOrder": 0},
13 {"label": "銀卡", "value": "silver", "displayOrder": 1},
14 {"label": "金卡", "value": "gold", "displayOrder": 2},
15 {"label": "鑽石卡", "value": "diamond", "displayOrder": 3}
16 ]
17 }'

預期回應為 HTTP 201,body 內含 "name": "membership_tier"。若回傳 409,代表屬性已存在,改用 PATCH 更新 options 即可。

重點提醒:ecommerce_customer_id 請在建立後到屬性設定勾選「Require unique values」。這一步能避免後續 upsert 產生重複聯絡人——台灣電商最常見的髒資料來源,就是同一個人用 Gmail 註冊、用 Yahoo 信箱結帳。

第三步:把訂單資料同步進 HubSpot

方案 A:使用原生整合

Shopify 有 HubSpot 官方整合,可自動同步訂單為 Deal 並關聯 Contact。SHOPLINE、Cyberbiz、91APP 在台灣多半需要透過 API 或中介平台(Make、Zapier、n8n)串接。原生整合的優點是免維護,缺點是欄位對應固定,退貨/取消訂單的處理邏輯往往不符合台灣品牌的實際需求(例如超商取貨未取的訂單仍計入金額)。

方案 B:自建同步腳本

若要精準控制「哪些訂單才算數」,建議自建。以下是 Node.js 的批次 upsert 範例,重點在於用 Batch Upsert API 以 ecommerce_customer_id 作為 idProperty,一次最多 100 筆:

1import fetch from 'node-fetch';
2
3const TOKEN = process.env.HUBSPOT_PRIVATE_APP_TOKEN;
4
5/**
6 * customers: [{ customerId, email, rolling12mSpend, orderCount12m, lastOrderDate, ltvTotal }]
7 */
8async function upsertBatch(customers) {
9 const inputs = customers.map((c) => ({
10 idProperty: 'ecommerce_customer_id',
11 id: c.customerId,
12 properties: {
13 email: c.email,
14 ecommerce_customer_id: c.customerId,
15 rolling_12m_spend: String(c.rolling12mSpend),
16 order_count_12m: String(c.orderCount12m),
17 ltv_total: String(c.ltvTotal),
18 // HubSpot 日期屬性需為 UTC 午夜的毫秒時間戳
19 last_order_date: Date.parse(c.lastOrderDate + 'T00:00:00Z')
20 }
21 }));
22
23 const res = await fetch(
24 'https://api.hubapi.com/crm/v3/objects/contacts/batch/upsert',
25 {
26 method: 'POST',
27 headers: {
28 Authorization: `Bearer ${TOKEN}`,
29 'Content-Type': 'application/json'
30 },
31 body: JSON.stringify({ inputs })
32 }
33 );
34
35 if (res.status === 429) {
36 // 命中速率上限,退避後重試
37 await new Promise((r) => setTimeout(r, 11000));
38 return upsertBatch(customers);
39 }
40
41 const data = await res.json();
42 console.log(`status=${res.status} updated=${data.results?.length ?? 0}`);
43 return data;
44}

預期輸出類似 status=200 updated=100。若看到 status=400 且 message 提到 Property values were not valid,通常是日期欄位送了 ISO 字串而非毫秒時間戳,或數字欄位夾帶了千分位逗號。

排程建議:每日凌晨跑一次全量重算(滾動 12 個月的金額本來就會因時間推移而下降),再搭配訂單 webhook 做即時增量。只靠 webhook 會導致「客人沒下單所以金額永遠不會下降」的邏輯漏洞。

Ready to Transform Your Ecommerce Operations?

Branch8 specializes in ecommerce platform implementation and AI-powered automation solutions. Contact us today to discuss your ecommerce automation strategy.

第四步:決定用計算屬性還是程式碼

HubSpot 的 Calculation property 可以直接做欄位加總、相減、條件判斷,不需寫程式。但它有限制:無法跨時間窗加總(例如「過去 365 天的訂單」),也無法回溯歷史事件。

判斷原則:

  • 金額加總、幣別換算、簡單四則運算 → 用 Calculation property。
  • 時間窗口(滾動 12 個月)、多條件分級、跨物件統計 → 在電商端或同步腳本算好再寫進來。

台灣品牌若同時經營蝦皮、momo 與官網,建議在資料倉儲(BigQuery、Snowflake)或 CDP 層先做好 identity resolution 與金額彙總,HubSpot 只負責「接收已算好的數字 + 執行行銷動作」。把 HubSpot 當成計算引擎,是我們看過最常見的架構失誤。

第五步:建立分級 Workflow 與自訂程式碼

到 Automation → Workflows → Create workflow → Contact-based,選擇 Blank workflow。

Enrollment trigger(觸發條件):

  • rolling_12m_spend is known
  • AND rolling_12m_spend has been updated(勾選 Re-enrollment)

務必開啟 Re-enrollment,否則聯絡人只會被判定一次,之後再怎麼消費都不會升級。這是初次設定最常見的疏漏。

接著加入 Custom code action,Runtime 選 Node.js 20.x,並定義 Property to include:

  • rolling_12m_spend → spend
  • membership_tier → currentTier
  • membership_tier_expiry_date → expiry
1exports.main = async (event, callback) => {
2 const spend = Number(event.inputFields['spend'] || 0);
3 const currentTier = event.inputFields['currentTier'] || 'bronze';
4
5 const THRESHOLDS = [
6 { tier: 'diamond', min: 80000 },
7 { tier: 'gold', min: 30000 },
8 { tier: 'silver', min: 10000 },
9 { tier: 'bronze', min: 0 }
10 ];
11
12 const RANK = { bronze: 0, silver: 1, gold: 2, diamond: 3 };
13
14 const earned = THRESHOLDS.find((t) => spend >= t.min).tier;
15
16 // 只升不降:降級交給每年期滿的獨立 workflow 處理
17 const nextTier =
18 RANK[earned] > RANK[currentTier] ? earned : currentTier;
19
20 const isUpgrade = RANK[nextTier] > RANK[currentTier];
21
22 // 升級則重新計算一年效期
23 const now = new Date();
24 const expiry = new Date(
25 Date.UTC(now.getUTCFullYear() + 1, now.getUTCMonth(), now.getUTCDate())
26 );
27
28 callback({
29 outputFields: {
30 nextTier,
31 isUpgrade: String(isUpgrade),
32 newExpiry: isUpgrade ? expiry.getTime() : null,
33 tierGap: String(
34 (THRESHOLDS.find((t) => RANK[t.tier] === RANK[nextTier] + 1)?.min ??
35 0) - spend
36 )
37 }
38 });
39};

tierGap 是個實用的小技巧:它直接算出「距離下一級還差多少元」,可以在 EDM 或 LINE 訊息裡用 personalization token 呈現,例如「再消費 3,200 元即可升級金卡」。

Workflow 後續步驟:

  1. Copy property value → 把 nextTier 寫入 membership_tier。
  2. If / then branch → 當 isUpgrade = true 時,寫入 newExpiry 到 membership_tier_expiry_date,並寄送升級通知。
  3. Webhook action(Operations Hub Professional 可用)→ 把等級推回電商平台。

在 Custom code action 裡記得測試:HubSpot 的測試面板可輸入任一聯絡人 ID,執行後會顯示 outputFields 的實際值與執行時間。若執行時間接近 20 秒上限,代表你在裡面做了過多外部 API 呼叫,應該拆成獨立的非同步服務。

Ready to Transform Your Ecommerce Operations?

Branch8 specializes in ecommerce platform implementation and AI-powered automation solutions. Contact us today to discuss your ecommerce automation strategy.

降級與效期該怎麼設計?

升級邏輯好寫,降級邏輯才是爭議來源。三種常見做法:

固定年度結算

每年 1 月 1 日依前一年消費重新核定等級。邏輯乾淨、客服好解釋,但一月會湧入大量降級客訴。

滾動效期(建議)

升級當下起算 12 個月效期,到期前依滾動 12 個月消費重新核定。體感最公平,但需要額外一支 workflow:

  • Enrollment trigger:membership_tier_expiry_date is less than today
  • 動作:Custom code 依 rolling_12m_spend 重新計算等級(這次允許降級),並延展效期。

只升不降

適合高客單、低頻次的品類(珠寶、家具、精品家電)。管理成本最低,但長期會讓高階會員池失去意義。

不論選哪一種,降級前 30 天一定要發提醒。做法是另設一支 workflow,觸發條件為 membership_tier_expiry_date is 30 days from now,寄送「保級提醒」並附上 tierGap 的個人化數字。

把等級推回 LINE 與電商前台

台灣市場的特殊性在於 LINE 的滲透率。根據 LINE 官方對台灣市場公布的資料,LINE 在台灣的月活躍使用者超過 2,100 萬,是品牌與會員溝通的主要通道,EDM 在台灣的實際開信表現通常低於歐美基準。因此分級結果若只停在 HubSpot 的 email,等於做了一半。

Webhook action 設定:在 Workflow 加入 Webhook,Method 選 POST,Request body 帶入 contact 屬性。接收端(你的中介服務)再轉呼叫 LINE Messaging API 或 MAAC / Super 8 這類台灣常用的 LINE 行銷平台:

1// 中介服務:接收 HubSpot webhook → 打 LINE Messaging API 加標籤 / 發訊息
2app.post('/hubspot/tier-updated', async (req, res) => {
3 const { ecommerce_customer_id, membership_tier, line_user_id } = req.body;
4
5 await fetch('https://api.line.me/v2/bot/message/push', {
6 method: 'POST',
7 headers: {
8 Authorization: `Bearer ${process.env.LINE_CHANNEL_ACCESS_TOKEN}`,
9 'Content-Type': 'application/json'
10 },
11 body: JSON.stringify({
12 to: line_user_id,
13 messages: [
14 {
15 type: 'text',
16 text: `恭喜升級為${TIER_LABEL[membership_tier]}!專屬權益已開通。`
17 }
18 ]
19 })
20 });
21
22 // 同步回寫電商平台會員標籤
23 await updateEcommerceTier(ecommerce_customer_id, membership_tier);
24 res.sendStatus(200);
25});

要串 LINE,前提是你已完成 LINE 帳號綁定(LINE Login 取得 userId 並存入 HubSpot 的自訂屬性)。沒有綁定率,再好的分級邏輯也推不出去——這通常才是真正的瓶頸。

Ready to Transform Your Ecommerce Operations?

Branch8 specializes in ecommerce platform implementation and AI-powered automation solutions. Contact us today to discuss your ecommerce automation strategy.

上線前的測試清單

逐項驗證,不要跳過:

  1. 建立 5 個測試聯絡人,分別設定 rolling_12m_spend 為 0 / 9,999 / 10,000 / 29,999 / 80,000,確認等級判定落在正確區間(邊界值最容易出錯)。
  2. 把一位銀卡會員的金額改成 0,確認不會立即降級(降級應由效期 workflow 處理)。
  3. 確認 Re-enrollment 開啟:把同一人金額從 10,000 改成 30,000,看是否再次觸發。
  4. 在 Workflow 的 Action logs 檢查 Custom code 的執行紀錄與 output。
  5. 用 Webhook 測試端點(如 webhook.site)驗證 payload 欄位完整。
  6. 關掉 workflow 的 "Allow contacts to re-enroll" 之外的所有實驗設定,正式上線前把測試聯絡人從清單排除。

常見問題排查

Workflow 有觸發但等級沒變 — 九成是 Custom code 的 outputFields 名稱與後續 Copy property value 的對應不符。output 名稱有大小寫區別。

聯絡人完全沒被 enroll — 檢查 enrollment trigger 是否用了 "is known" 卻在屬性為空字串時失效;空字串在 HubSpot 不等於 unknown。改用 is greater than or equal to 0。

Custom code 回傳 timeout — 20 秒上限(依 HubSpot 開發者文件)。把外部 API 呼叫移出,改用 Webhook action 非同步處理。

同一人出現多筆聯絡人 — ecommerce_customer_id 未設唯一值,或 upsert 時用 email 當 idProperty 而客人改了信箱。補一支去重腳本,用 Merge API 合併。

金額對不上 — 檢查三件事:退貨訂單是否扣除、超商未取訂單是否排除、運費與折價券是否計入。這三項定義不一致,會造成客服與行銷各說各話。

429 Too Many Requests — 依 HubSpot 開發者文件,Professional / Enterprise 方案的 Private App 上限為每 10 秒 190 次。加入指數退避,並把同步改成 batch 100 筆一次。

Ready to Transform Your Ecommerce Operations?

Branch8 specializes in ecommerce platform implementation and AI-powered automation solutions. Contact us today to discuss your ecommerce automation strategy.

個資法與跨境資料流要注意什麼?

台灣《個人資料保護法》要求蒐集個資時應明確告知蒐集目的、類別、利用期間與地區。把會員資料寫進 HubSpot(資料實際儲存於美國或歐盟區域)屬於跨境傳輸,隱私權政策應載明。HubSpot 在 Settings → Account Defaults 可查看你的資料存放區域(Data hosting location)。

若你同時經營新加坡(PDPA)、澳洲(Privacy Act)或歐盟(GDPR)市場,建議在 HubSpot 啟用 GDPR 功能並以 Legal basis for processing 屬性統一管理同意狀態。多市場品牌最好用單一 Portal 搭配 market 自訂屬性做分區,而非每個國家開一個 Portal——後者會讓跨市場的會員識別幾乎不可能。

用 LLM 加速分級維運

分級自動化上線後,真正耗時的是持續調整。幾個已被團隊驗證可行的用法:

  • 用 LLM 產生 HubSpot 自訂程式碼草稿:把門檻表與屬性清單貼進去,產出 exports.main 骨架,再由工程師校對邊界條件。省的是打字時間,不是審查時間。
  • 分級說明文案多語生成:台灣繁中、香港繁中、新加坡英文、馬來西亞英文的權益說明,用同一份 source of truth 生成後人工校稿。香港與台灣的繁中用語差異(「積分」vs「點數」、「結帳」vs「付款」)必須有在地人複核。
  • 異常偵測:每日把等級分布拉出來,用腳本比對前一日,若某一級人數變動超過閾值就告警。這比等客服收到客訴才發現 workflow 壞掉快得多。

Ready to Transform Your Ecommerce Operations?

Branch8 specializes in ecommerce platform implementation and AI-powered automation solutions. Contact us today to discuss your ecommerce automation strategy.

從台灣延伸到 APAC 多市場

台灣品牌往東南亞、香港、澳洲擴張時,分級架構通常會遇到三個問題:

  1. 幣別:門檻要用本地幣別還是統一換算?建議在 HubSpot 存 rolling_12m_spend_twd(統一換算後)與 rolling_12m_spend_local 兩個欄位,判級用前者、對客溝通用後者。
  2. 通路差異:台灣靠 LINE、香港與新加坡靠 WhatsApp、澳洲靠 Email 與 SMS。Workflow 的最後一哩路必須依 market 分支。
  3. 營運時區:台灣、香港、新加坡同在 UTC+8,澳洲東岸 UTC+10/+11。排程重算務必統一在 UTC 定義,否則澳洲會員的「昨日訂單」會被算進錯的一天。

把資料模型設計成多市場可擴充,比事後重構便宜很多。這也是為什麼我們建議品牌在第一次導入時就把 market、幣別欄位、通道偏好欄位一併建好,即使當下只有台灣一個市場。


Branch8 在香港設立總部,並於台灣、新加坡、越南、馬來西亞、印尼、菲律賓與澳洲設有交付團隊,協助品牌規劃與落地 HubSpot、Salesforce 與 CDP 架構,涵蓋跨市場會員模型、電商系統串接與 LINE/WhatsApp 通道整合。若你正在評估會員分級自動化,或現有 HubSpot Portal 需要重整,歡迎與我們聯繫討論可行架構。

Sources

FAQ

不一定。若分級邏輯單純(例如三級門檻、只升不降),可以用 Marketing Hub Professional 的 Workflow if/then 分支加上 Set property value 完成。但只要涉及滾動時間窗計算、動態效期、或需要呼叫外部 API 回寫電商平台,就需要 Operations Hub Professional 的 Custom code 與 Webhook action。

About the Author

Matt Li

Co-Founder & CEO, Branch8 & Second Talent

Matt Li is Co-Founder and CEO of Branch8, a Y Combinator-backed (S15) Adobe Solution Partner and e-commerce consultancy headquartered in Hong Kong, and Co-Founder of Second Talent, a global tech hiring platform ranked #1 in Global Hiring on G2. With 12 years of experience in e-commerce strategy, platform implementation, and digital operations, he has led delivery of Adobe Commerce Cloud projects for enterprise clients including Chow Sang Sang, HomePlus (HKBN), Maxim's, Hong Kong International Airport, Hotai/Toyota, and Evisu. Prior to founding Branch8, Matt served as Vice President of Mid-Market Enterprises at HSBC. He serves as Vice Chairman of the Hong Kong E-Commerce Business Association (HKEBA). A self-taught software engineer, Matt graduated from the University of Toronto with a Bachelor of Commerce in Finance and Economics.