Branch8

台灣個資法下電商重新同意機制設計:舊名單合規補件實作

Matt Li
August 22, 2026
13 mins read
台灣個資法下電商重新同意機制設計:舊名單合規補件實作

Key Takeaways

  • 舊名單先分四層盤點,別急著群發重新同意信
  • 同意要記成 append-only 事件,不是布林欄位
  • 使用法務部特定目的代號,稽核時才對得上
  • 來源不可驗證的名單,連 re-consent 邀請都不該發
  • 台港星三地可共用一套同意資料模型,差異放對照層

台灣《個人資料保護法》要求電商在蒐集個資時明確告知法定告知事項並取得當事人同意。若舊有名單缺乏可稽核的同意紀錄,正確做法不是刪光重來,而是分層盤點:以合約履行等法定事由保留必要資料,對行銷用途發送重新同意(re-consent)通知,並保留完整同意軌跡。

為什麼舊有名單在 PIPA 下會踩雷?

台灣《個人資料保護法》(以下簡稱個資法)第 8 條規定,非公務機關向當事人蒐集個資時,應明確告知蒐集機關名稱、蒐集目的、個資類別、利用期間/地區/對象/方式,以及當事人權利與不提供的影響。第 19 條則要求非公務機關蒐集或處理個資必須具備特定目的與法定事由,第 20 條進一步規定「特定目的外之利用」原則上需另行取得書面同意。條文全文可在全國法規資料庫查得。

實務上,電商團隊十年前建的 MySQL 會員表,通常只有一個 subscribe_newsletter tinyint(1)。這個欄位無法回答稽核員三個問題:

  1. 當事人是在什麼版本的隱私權政策下勾選的?
  2. 勾選時間、來源 IP、頁面 URL 為何?
  3. 同意涵蓋的「特定目的」有哪些(例:行銷、會員管理、跨境傳輸給新加坡 CRM)?

這三個問題也正是 GDPR Article 7(1) 對「controller shall be able to demonstrate that the data subject has consented」的核心要求。對同時經營台灣、香港、新加坡、澳洲市場的品牌來說,把同意紀錄設計成可稽核的資料結構,等於一次滿足多個轄區。

值得注意的是,個資法 2023 年修正已明定將設立個人資料保護委員會(個資會)作為獨立監管機關,籌備處已於 2023 年掛牌。根據國家發展委員會與行政院公開資訊,未來裁罰與檢查密度預期高於過去分散於各目的事業主管機關的狀態。台灣品牌若打算延用 2015 年的同意設計,風險曲線是往上走的。

開始前需要準備什麼?

資料面前置條件

  • 可寫入的會員資料庫(MySQL 8.0 / PostgreSQL 14 以上皆可),且有 DDL 權限
  • 歷史行為日誌:註冊來源、訂單紀錄、EDM 開信與點擊紀錄(至少 24 個月)
  • 現行隱私權政策的版本控管:如果政策只有一份沒有版本號,先補上 v1.0 並固定 URL

工具面前置條件

  • CDP 或行銷自動化平台(Klaviyo、Braze、HubSpot、Ortto 皆可),需支援 custom properties 與 event API
  • 交易型郵件通道(SendGrid、Amazon SES、電子豹),與行銷通道分流
  • 一套同意管理介面:可自建,也可用 OneTrust、Cookiebot 等 CMP,但注意多數 CMP 專注 cookie,會員層級的 purpose consent 通常仍需自建

組織面前置條件

  • 個資檔案的特定目的代號清單。法務部公告的「個人資料保護法之特定目的及個人資料之類別」共 182 項特定目的代號,電商常用的包括 040(行銷)、069(契約、類似契約或其他法律關係事務)、090(消費者、客戶管理與服務)、148(網路購物及其他電子商務服務)。
  • 一位能拍板的法遵窗口。技術團隊不該自行決定「哪些舊資料可以留」。

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.

步驟一:先做同意基線盤點,不要急著發信

把名單切成四層,處理方式完全不同。

第一層:有明確同意紀錄

有時間戳、政策版本、勾選來源。這層不需要 re-consent,但要確認當年告知的「特定目的」是否涵蓋你今天要做的事。若當年只寫「電子報」,今天要做跨境 lookalike 廣告,就屬於目的外利用。

第二層:有交易關係、無行銷同意

這是最大宗。依個資法第 19 條第 1 項第 2 款「與當事人有契約或類似契約之關係」,你可以為履行契約、售後服務、保固等目的保留資料,但不能推送促銷 EDM。這層是 re-consent 的主要對象。

第三層:來源不明

第三方名單、展會抄寫、線下活動紙本。沒有可證明的合法蒐集來源,建議直接進入停用(suppress)流程,不要發送任何行銷訊息——包括 re-consent 邀請本身。發一封「請重新同意」的行銷信給來源不明名單,本身就可能是一次未經同意的利用。

第四層:長期無互動

24 個月以上未開信、未下單。即使有同意紀錄,個資法第 5 條的比例原則與第 11 條第 3 項(特定目的消失或期限屆滿應刪除)都指向應主動清理。

分層 SQL 範例(MySQL 8.0):

1CREATE OR REPLACE VIEW v_consent_tiers AS
2SELECT
3 c.customer_id,
4 c.email,
5 CASE
6 WHEN cr.consent_id IS NOT NULL
7 AND cr.status = 'granted'
8 AND cr.policy_version IS NOT NULL
9 THEN 'T1_documented'
10 WHEN o.order_count > 0
11 THEN 'T2_contractual_no_marketing'
12 WHEN c.source_channel IN ('third_party_list','offline_paper','unknown')
13 THEN 'T3_unverifiable'
14 ELSE 'T4_dormant'
15 END AS tier,
16 o.last_order_at,
17 e.last_engaged_at
18FROM customers c
19LEFT JOIN consent_records cr
20 ON cr.customer_id = c.customer_id
21 AND cr.purpose_code = '040'
22 AND cr.status = 'granted'
23LEFT JOIN (
24 SELECT customer_id, COUNT(*) AS order_count, MAX(created_at) AS last_order_at
25 FROM orders WHERE status NOT IN ('cancelled','fraud') GROUP BY customer_id
26) o ON o.customer_id = c.customer_id
27LEFT JOIN (
28 SELECT customer_id, MAX(event_at) AS last_engaged_at
29 FROM email_events WHERE event_type IN ('open','click') GROUP BY customer_id
30) e ON e.customer_id = c.customer_id;

預期輸出:一張可直接 GROUP BY tier 的視圖。實務上第二層通常佔 50–70%,第三層若超過 15%,代表過去的名單取得流程需要一併檢討。

步驟二:建立可稽核的同意資料模型

同意不是布林值,是一連串事件。用 append-only 的事件表,不要 UPDATE 覆蓋。

1CREATE TABLE consent_records (
2 consent_id BIGINT AUTO_INCREMENT PRIMARY KEY,
3 customer_id BIGINT NOT NULL,
4 subject_email VARCHAR(320) NOT NULL,
5 purpose_code VARCHAR(8) NOT NULL COMMENT '法務部特定目的代號,如 040/090/148',
6 purpose_label VARCHAR(120) NOT NULL,
7 channel ENUM('email','sms','line','push','postal') NOT NULL,
8 status ENUM('granted','withdrawn','expired','pending') NOT NULL,
9 policy_version VARCHAR(16) NOT NULL,
10 policy_url VARCHAR(512) NOT NULL,
11 capture_method ENUM('web_form','checkout','reconsent_email','csr_phone','offline') NOT NULL,
12 capture_url VARCHAR(512),
13 source_ip VARBINARY(16),
14 user_agent VARCHAR(512),
15 cross_border JSON COMMENT '跨境傳輸對象與地區,如 ["SG:CRM","US:ESP"]',
16 evidence_hash CHAR(64) COMMENT '同意當下頁面快照的 SHA-256',
17 created_at TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
18 expires_at TIMESTAMP NULL,
19 INDEX idx_lookup (customer_id, purpose_code, channel, created_at DESC)
20) ENGINE=InnoDB;

幾個設計決策值得說明:

  • purpose_code 用法務部代號而非自訂字串。稽核時你要能對照公告清單,自訂的 "marketing" 對不上。
  • cross_border 欄位。個資法第 21 條允許主管機關在特定情形限制國際傳輸。若你的 CRM 在新加坡、ESP 在美國、資料倉儲在澳洲,這些都應在告知事項中列明。GDPR 對 EU 客戶另有 Chapter V 的傳輸機制要求,欄位設計相同可共用。
  • evidence_hash。把同意當下的隱私政策 HTML 與勾選畫面存成不可變快照,只在資料庫存雜湊值。日後爭議時能證明「當事人看到的是這一版」。
  • append-only。撤回同意是插入一筆 status='withdrawn',不是把舊列改掉。

查詢「當前有效同意」的寫法:

1SELECT cr.*
2FROM consent_records cr
3JOIN (
4 SELECT customer_id, purpose_code, channel, MAX(created_at) AS latest
5 FROM consent_records
6 GROUP BY customer_id, purpose_code, channel
7) m
8 ON m.customer_id = cr.customer_id
9 AND m.purpose_code = cr.purpose_code
10 AND m.channel = cr.channel
11 AND m.latest = cr.created_at
12WHERE cr.status = 'granted'
13 AND (cr.expires_at IS NULL OR cr.expires_at > NOW());

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.

用什麼通道發?

對第二層(有交易關係)名單,re-consent 通知應該走交易型/服務型通道,內容以「政策更新與偏好確認」為主軸,不夾帶商品促銷。夾帶折扣碼會讓這封信在性質上變成行銷訊息,反而削弱你原本依契約關係發送的正當性。

SendGrid 的分流設定範例(避免 re-consent 信被行銷退訂清單攔截):

1curl -X POST "https://api.sendgrid.com/v3/mail/send" \
2 -H "Authorization: Bearer $SENDGRID_API_KEY" \
3 -H "Content-Type: application/json" \
4 -d '{
5 "personalizations": [{
6 "to": [{"email": "[email protected]"}],
7 "custom_args": {"campaign_type": "reconsent", "policy_version": "v3.0"}
8 }],
9 "from": {"email": "[email protected]", "name": "品牌隱私權中心"},
10 "subject": "請確認您的個人資料使用偏好",
11 "content": [{"type": "text/html", "value": "..."}],
12 "mail_settings": {"bypass_list_management": {"enable": false}},
13 "asm": {"group_id": 12345}
14 }'

注意 asm.group_id 指向一個獨立的「帳戶通知」訂閱群組,與行銷群組分開;bypass_list_management 保持 false,已明確表示拒絕聯繫的人不應再被打擾。

頁面要放哪些告知事項?

落地頁必須完整涵蓋個資法第 8 條的告知項目。可勾選項目建議拆成用途 × 通道的矩陣,而不是一個「我同意接收行銷訊息」大勾勾:

  • 電子郵件 — 新品與促銷資訊(目的代號 040)
  • 簡訊/LINE — 訂單狀態以外的活動通知(040)
  • 會員分析與個人化推薦(090)
  • 將個資傳輸至境外服務供應商以提供上述服務(列明地區)

預設值一律 unchecked。台灣個資法未如 GDPR 明文禁止預先勾選,但 GDPR Recital 32 與歐盟法院 Planet49 判決已確立預勾選不構成有效同意;跨境經營的品牌採高標比較省事。

前端最小實作

1<form id="reconsent" method="post" action="/api/consent">
2 <input type="hidden" name="token" value="{{signed_token}}">
3 <input type="hidden" name="policy_version" value="v3.0">
4
5 <label><input type="checkbox" name="purposes[]" value="040:email"> 電子郵件行銷</label>
6 <label><input type="checkbox" name="purposes[]" value="040:sms"> 簡訊/LINE 行銷</label>
7 <label><input type="checkbox" name="purposes[]" value="090:profiling"> 個人化推薦</label>
8
9 <button type="submit">儲存偏好</button>
10 <a href="/api/consent/withdraw-all?token={{signed_token}}">全部拒絕並停止聯繫</a>
11</form>

signed_token 建議用 JWT,內含 customer_idexp(7–14 天)、jti(防重放)。不要在 URL 明文帶 email——那本身就是一次不必要的個資外洩風險。

後端寫入(Node.js / Express 範例):

1app.post('/api/consent', async (req, res) => {
2 const claims = verifyJwt(req.body.token); // 失敗即 401
3 const selected = new Set(req.body['purposes[]'] || []);
4 const allOptions = ['040:email', '040:sms', '090:profiling'];
5
6 const rows = allOptions.map(opt => {
7 const [purpose, channel] = opt.split(':');
8 return {
9 customer_id: claims.sub,
10 purpose_code: purpose,
11 channel,
12 status: selected.has(opt) ? 'granted' : 'withdrawn',
13 policy_version: req.body.policy_version,
14 policy_url: `https://yourstore.tw/privacy/${req.body.policy_version}`,
15 capture_method: 'reconsent_email',
16 capture_url: req.get('referer'),
17 source_ip: ipToBinary(req.ip),
18 user_agent: req.get('user-agent'),
19 cross_border: JSON.stringify(['SG:crm', 'US:esp']),
20 evidence_hash: await snapshotHash(req.body.policy_version)
21 };
22 });
23
24 await db('consent_records').insert(rows); // 未勾選的也寫入 withdrawn
25 await syncToCdp(claims.sub, rows);
26 res.redirect('/privacy/preferences-saved');
27});

關鍵在最後兩行:未勾選的項目也要寫入 withdrawn。沉默不是同意,但沉默要留下紀錄,否則下次稽核你無法區分「他拒絕了」和「他沒點開」。

步驟四:把同意狀態同步回行銷平台

資料庫是事實來源(source of truth),行銷平台是消費端。單向同步,永遠不要讓行銷平台的 opt-in 狀態回寫資料庫。

Klaviyo API 範例:

1curl -X POST "https://a.klaviyo.com/api/profile-import/" \
2 -H "Authorization: Klaviyo-API-Key $KLAVIYO_KEY" \
3 -H "revision: 2024-10-15" \
4 -H "Content-Type: application/json" \
5 -d '{
6 "data": {
7 "type": "profile",
8 "attributes": {
9 "email": "[email protected]",
10 "properties": {
11 "pipa_consent_040_email": "granted",
12 "pipa_consent_040_sms": "withdrawn",
13 "pipa_policy_version": "v3.0",
14 "pipa_consent_at": "2026-01-15T09:22:41Z"
15 }
16 }
17 }
18 }'

所有行銷 segment 都應加上硬性條件 pipa_consent_040_email equals granted。不要靠行銷同事記得篩選——把它做成 segment 層級的強制條件。

AI 輔助的一個實用切點:re-consent 專案最耗人力的其實是第三層名單的來源判讀——大量自由文字備註欄(「2019 秋季展會」「客服電話留單」「經銷商轉介」)需要歸類。用 LLM 做初步分類、人工複核邊界案例,比純人工逐筆看快得多。但分類結果一律偏保守:模型不確定的,歸到不可驗證層。合規判斷不外包給機率模型。

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. 第 0 天:政策新版上線並固定 URL,舊版保留可存取(/privacy/v2.1)。
  2. 第 1 天:對第一層名單發送「政策更新通知」,不要求動作,但提供偏好中心連結。
  3. 第 3 天:對第二層發送第一封 re-consent 邀請。
  4. 第 14 天:對未回應者發送第二封,主旨改寫,內容不變。
  5. 第 30 天:第三封,明確說明「未回應將停止行銷聯繫」。
  6. 第 45 天:未回應者一律轉入 suppression list,保留契約履行所需資料,停止所有行銷用途。

業界對 re-consent 回應率的普遍觀察是偏低的。Litmus 與各家 ESP 的公開報告顯示零售業 EDM 平均開信率約在 20–30% 區間,而需要點擊並完成表單的 re-consent 流程,完成率必然低於開信率。請在專案啟動前就讓行銷主管理解:名單會縮小,這是設計上的預期結果,不是執行失敗。縮小後的名單投遞率與互動指標通常會改善,因為分母裡的殭屍地址被清掉了。

常見問題排除

檢查是否從行銷子網域(mail.brand.tw)發送。改用交易型子網域(notify.brand.tw),並確認 SPF、DKIM、DMARC 對齊。Google 自 2024 年起對大量寄件者要求 DMARC 政策與一鍵退訂(List-Unsubscribe),Google Workspace 的寄件者指引有完整說明。

同一使用者多筆衝突紀錄

這是 append-only 設計的正常現象。永遠用 MAX(created_at) 取最新一筆,並在應用層加 SELECT ... FOR UPDATE 或用 jti 去重,避免使用者連點兩次產生同秒兩筆。

客服電話收到的同意怎麼記?

capture_method='csr_phone',並在 evidence_hash 存通話錄音檔的雜湊值(錄音本身依保存政策另存)。CSR 必須完整宣讀告知事項——把逐字稿做成 CRM 內的 script 模板,不要讓客服自由發揮。

香港、新加坡名單要不要一起做?

通常值得。香港《個人資料(私隱)條例》PDPO 的 DPP1 有告知要求,第 35C–35M 條對直接促銷有獨立且嚴格的規定,包括必須以易於理解的方式告知並取得同意。新加坡 PDPA 則有 Do Not Call Registry 的額外義務。三地的同意資料模型可以共用一張表,差異放在 purpose_code 的對照層與各地必要的告知文案。跨境電商用一次工程投入涵蓋多轄區,比每個市場各做一套省。

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.

一個匿名化的實作觀察

Branch8 曾協助一家在台灣與香港同時經營自營站與電商平台的美妝零售集團重整會員同意架構。當時的狀況很典型:Shopify 前台、自建 ERP、Klaviyo 行銷,三邊各有一份「訂閱狀態」,彼此不一致。

處理方式是把 ERP 的會員表定為唯一事實來源,新增上述的 append-only 同意事件表,Shopify 端透過 webhook 寫入、Klaviyo 端只讀不寫。最花時間的不是寫程式,而是跟法務逐項確認每個 checkbox 對應哪個特定目的代號,以及哪些歷史來源可以被視為有效。技術實作大約兩週,目的對照與名單分層的討論遠比這久。這個比例在多數專案裡都成立——工程不是瓶頸,決策才是。

把同意當成長期資產,而不是一次性專案

完成 re-consent 之後,維持機制才是重點:

  • 政策改版即觸發評估:任何涉及新的利用目的或新的境外接收者,都需要重新評估是否需要新同意。
  • 同意效期:對長期不互動者設 expires_at,到期自動轉 expired 並停止行銷利用。
  • 當事人權利自助化:個資法第 3 條賦予查詢、閱覽、複製、補正、停止利用、刪除等權利,且不得預先拋棄。做成偏好中心的自助功能,比每次走客服工單快也便宜。
  • 季度稽核查詢:跑一次「有行銷發送紀錄但無有效同意」的交叉比對,這是最容易抓出流程破口的一條 SQL。
1SELECT s.customer_id, s.sent_at, s.campaign_id
2FROM marketing_sends s
3LEFT JOIN v_active_consent c
4 ON c.customer_id = s.customer_id
5 AND c.purpose_code = '040'
6 AND c.channel = s.channel
7WHERE c.customer_id IS NULL
8 AND s.sent_at >= DATE_SUB(NOW(), INTERVAL 90 DAY);

這條查詢的預期輸出應該是零列。任何非零結果都是需要當週處理的事件。

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.

需要跨市場的落地協助?

Branch8 的團隊分布在香港、台灣、新加坡、越南、馬來西亞、澳洲等地,熟悉台灣個資法、香港 PDPO 與新加坡 PDPA 在電商同意流程上的差異,也實際處理過 Shopify、Klaviyo、HubSpot 與自建 ERP 之間的同意資料同步。如果你正在盤點舊有名單、或準備一次涵蓋多個市場的 re-consent 專案,歡迎與我們談談你目前的資料結構與時程。

Sources

FAQ

不一定。依個資法第 19 條,與當事人有契約或類似契約關係者,可為履行契約、售後服務等特定目的繼續保留必要資料,但不得用於行銷。真正需要處理的是行銷用途的同意缺口,以及來源完全無法驗證的名單。

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.