香港 SMS 計費怎麼算 — 字數、Unicode 與分段的完整解析
「我明明只發了 1,000 個號碼,為什麼帳單顯示 3,000 則?」
這是我們最常被問到的計費問題,答案幾乎都在同一個地方:一則訊息不等於一則計費單位。中文尤其容易踩到。
這篇把規則講清楚,你可以自己算得出來。
兩種編碼,兩套上限
SMS 這個標準訂得很早,當年沒有考慮中文。它有兩種文字編碼:
GSM-7 — 每個字元 7 bit,涵蓋英文字母、數字和常用標點。 UCS-2 — 每個字元 16 bit,能表達中文、日文、韓文、emoji 等。
單則訊息的容量是固定的 140 bytes(1,120 bit)。除下去就是:
| 編碼 | 單則上限 | 需要分段時,每段 |
|---|---|---|
| GSM-7(純英數) | 160 字元 | 153 字元 |
| UCS-2(含中文) | 70 字元 | 67 字元 |
為什麼分段後上限會變小?因為每一段要留 6 bytes 放「這是第幾段、總共幾段」的表頭(UDH),讓收件裝置能重新組裝。
關鍵在於:只要訊息裡出現任何一個 UCS-2 字元,整則訊息都會用 UCS-2 編碼。 一個中文字、一個 emoji、一個全形標點,就會把上限從 160 直接砍到 70。
中文訊息的實際長度
拿一則典型的推廣訊息來算:
【XX 百貨】會員專享 8 折優惠,即日起至 8 月 31 日,
憑此訊息到門市即可使用。詳情:https://xxx.co/a1b2c3
退訂請致電 2XXX XXXX
這則大約 70 個字元出頭 — 剛好卡在第一段的邊緣。多寫兩個字就變成兩段,計費翻倍。
而如果只是 70 個中文字,很多人的直覺是「這也太短了」。實際上這正是為什麼中文推廣訊息要寫得很緊 — 每一個字都在花錢。
幾個省字的實務技巧
- 短連結。 一條完整的 UTM 追蹤網址可能佔掉 60 個字元,用短連結能壓到 20 左右。我們的可追蹤連結本身就是短的。
- 日期用數字。 「8/31 前」比「即日起至八月三十一日」省一半。
- 退訂資訊必須留。 這是《非應邀電子訊息條例》的要求,不能為了省字砍掉 — 詳見合規清單。
- 不要為了美觀加 emoji。 純英文訊息加一個 emoji,上限就從 160 掉到 70。
GSM-7 裡的「隱藏雙倍字元」
即使是純英文訊息,也有幾個字元會算兩個位置:
^ { } [ ] ~ | \ €
這些在 GSM-7 裡屬於擴充字元集,需要跳脫字元。一則訊息裡放了幾個 [ ],就可能讓原本 158 字的內容突破 160,變成兩段。
寫模板時要注意這點,特別是用方括號當佔位符的做法。
怎麼核對實際計費筆數
不要用猜的。我們的 API 有一個用量報表端點:
GET /v1/sms/get-usage-report?date_from=2026-07-01&date_to=2026-07-31
回應會給你:
{
"rc": 100,
"rm": "OK",
"date_from": "2026-07-01",
"date_to": "2026-07-31",
"sms_count": "30000",
"points_used": "5000"
}
sms_count 是實際計費的訊息筆數,points_used 是消耗的點數。拿這兩個數字對回你自己的發送紀錄,就能算出「平均每個收件人耗掉幾則」。
如果這個比值明顯高於 1,代表你的訊息模板在分段 — 值得回頭把文案壓短。
計費是以哪一段為準
這一點常被誤解。在我們的機制下,計費發生在第一段 callback 回 SMD 的時候 — 也就是訊息成功提交給電信商的那一刻。
反過來說,第一段回 -100 系列失敗碼(IM 號碼錯誤、OFCA 拒收登記、IP 點數不足、IS 發送人未登記)的,不計費。
至於第二段 DLR 回 UNDELIV 或 EXPIRED 的,訊息已經送出到電信商了,這部分是已發生的成本。這也是為什麼號碼清洗值得做 — 髒名單的成本不在被拒的那些,而在送出去卻送不到的那些。
各狀態碼的意義在 DLR 狀態碼完全解讀有完整整理。
三個實務建議
1. 在發送前先算長度。 大部分語言都有現成的 SMS 分段計算函式庫。在後台或 CMS 存模板時就顯示「這則會分成幾段」,比事後看帳單有用得多。
2. 監控點數餘額。 用 /v1/acct/get-points-balance 在大批量發送前檢查一次。點數中途用完的話,剩下的訊息會回 IP 全部失敗。
3. 名單品質比壓字數重要。 把訊息從兩段壓成一段能省一半,但把 20% 的無效號碼清掉,省的是實實在在的錯發成本,而且不用犧牲訊息品質。
端點細節與參數說明在 SMS API 整合指南;想知道實際費率,聯絡我們按你的量給報價。