← → 翻页 · ESC 索引
Vol.05 · Module Five
01 / 20
NTUB · GTM × Ad-Tech · Week 5

電商追蹤的三件大事

三小時,把 GA4 items array、WooCommerce dataLayer、purchase 去重與退款一次串起來——
讓 ROAS 報表可信,讓老闆對得起對帳單。

Keyword·items array ·GTM4WP ·transaction_id
Duration·3 小時授課 ·3 單元
National Taipei University of Business 數位行銷實務 II|GTM × 廣告科技 · 30hr 2026 Fall
Opening · Manifesto
02 / 20 講義 · M5
Why this module matters
電商追蹤不是把事件送出去就好——
是讓 GA4、Meta、Ads 三方對得起來
讓財務系統 vs 報表 不再差一個位數
—— Module 5 · 電商追蹤的三件大事

事件、外掛、去重——
少一塊都會變成「報表很漂亮,老闆很生氣」

Module 5 · Opening NTUB GTM × Ad-Tech
This Module · Outcomes
03 / 20 講義 · M5
Learning Outcomes · 三件事做到

三小時,三個能交付

不只「看得懂」,要能產出 schema、跑通漏斗、寫出 QA 報告

Outcome 01
01
列出自家漏斗的核心電商事件清單與 items array 七大欄位 schema。
Outcome 02
02
在 LocalWP + WooCommerce 跑通 view_item / add_to_cart / begin_checkout / purchase 四漏斗。
Outcome 03
03
寫出一份「上線前 8 項 QA Checklist」報告,含 transaction_id 唯一性、refund、內部 IP 排除。
NTUB · Week 5 3hr · 3 Units · Build the Data Loop
Act I · Unit 5-1
04 / 20
Section 5.1 · GA4 Ecommerce Events

十大事件與items 陣列

從 view_item_list 到 purchase——
十個事件、七大必填欄位、一條漏斗骨架

4 Slides·Concept + Code + Case ·~55 min
Act I · Items Array Unit 5-1
5-1 · Event Map
05 / 20 講義 · M5-1
Step 01 · 十個事件,三個層次

不是全追——按漏斗選四個核心

曝光、購物、結帳三層各取一個,加上 purchase——
四件事就能算出完整漏斗轉換率

The minimum viable funnel · 按 → 逐步點亮
01
view_item
商品頁瀏覽——興趣的最小單位,分母用這個。
02
add_to_cart
加入購物車——意願轉強,AJAX 也要追。
03
begin_checkout
進入結帳流程——掉單高峰區,必看。
04
purchase
訂單成立——transaction_id 必唯一,雙算最痛。
其餘六事件(select_item、view_cart、remove_from_cart、view_promotion / select_promotion、refund)按需求加,不要貪多。
Unit 5-1 · Funnel Skeleton view_item → add_to_cart → begin_checkout → purchase
5-1 · Items Schema
06 / 20 講義 · M5-1
Step 02 · 每個 item 物件最少要帶這幾個

items 陣列七大必填欄位

缺一個 GA4 不會報錯,但報表會錯得很隱性——
只有靠 BigQuery 驗 schema 才抓得到。

01
item_id
商品 SKU——必唯一且穩定。建議直接用 ERP 的主鍵;換編碼系統 = 歷史資料斷鏈。
02
item_name
商品名稱——人類讀的,報表 group by 用。
03
price · quantity
單價與件數——缺 price 那筆訂單算 $0,月營收會少報 30%。
04
currency
建議 item 層級也帶(不要只 push 在 ecommerce 層)——跨幣別一定要
05
item_category · item_brand
分類與品牌——後續分析的維度,category 最多 5 層但 2 層通常夠用。
Unit 5-1 · Required Fields Missing one = silently wrong
5-1 · Purchase Snippet
07 / 20 講義 · M5-1
Step 03 · 課堂照抄這段

一個 完整 purchase 長這樣

注意是 ecommerce 包 items 的雙層結構——GTM4WP 預設就是這個格式,手寫時不要把 items 平鋪到外層。

dataLayer.push({
  event: 'purchase',
  ecommerce: {
    transaction_id: 'T_12345',   // 必填且必唯一
    value: 1290,
    currency: 'TWD',
    tax: 0,
    shipping: 80,
    items: [
      { item_id: 'SKU001', item_name: '中焙咖啡豆 200g',
        price: 590, quantity: 2,
        item_category: '咖啡豆', item_brand: 'small美' }
    ]
  }
});

// 送下一個 ecommerce 事件前先清乾淨,避免跨事件汙染:
dataLayer.push({ ecommerce: null });
用 GA4 GTM Tag template 的「Send Ecommerce data」開關會自動處理 ecommerce:null——能用 template 就別手刻。
Unit 5-1 · Code Two-layer structure · ecommerce → items[]
5-1 · Real Case
08 / 20 講義 · M5-1
Step 04 · 一個 3C 電商的真實事故

少一欄 price,月營收蒸發 30%

Before · 開發者覺得
「item_id 跟 quantity 就夠了吧
items 陣列只 push item_id + quantity,沒帶 price。GA4 預設用 item 層級算營收——沒 price 就當 $0
Result·月營收 −30%
After · 補欄位 + 回補資料
補齊 price + currency,靠 BigQuery 回算半年
補欄位後恢復正常,但歷史半年只能靠 BigQuery Export 手動重算。對帳會議連開三場——學員聽到這裡都會點頭
Lesson·schema 缺欄位 = 隱性錯
對策:上線前用 BigQuery Export 跑一次 schema 驗證,確認每個 item 都有 price + currency。事後對帳的成本永遠比事前驗 schema 高十倍。
Unit 5-1 · Case Study Silent error · 30% missing
Act II · Unit 5-2
09 / 20
Section 5.2 · GTM4WP + WooCommerce

把 schema 真的跑出來

WooCommerce 是台灣最常見的自建站方案——
用 GTM4WP 省下 80% 手刻工作,剩下 20% 是 hook 客製。

5 Slides·Setup + Verify + Hook + Case ·~55 min
Act II · WooCommerce Unit 5-2
5-2 · GTM4WP Setup
10 / 20 講義 · M5-2
Step 05 · 三個分頁,五個勾選

GTM4WP 後台該勾哪些

WordPress 後台 → GTM4WP → 三個分頁設定到位,dataLayer 當天就會自動 push

A
Basic data
GTM-XXX 容器 ID。沒填整個外掛形同不存在。
B
Integration → WooCommerce
Track enhanced e-commerce(重點)+ 勾 Track classic(舊 UA 相容)。
C
Events
view_item / add_to_cart / remove_from_cart / begin_checkout / purchase。儲存即生效。
!
商品 SKU 必填
商品編輯頁 → Inventory → SKU——空的話 item_id 會 fallback 到 post_id,後續歸因會錯亂。
Unit 5-2 · Plugin Setup WordPress → GTM4WP → 3 tabs
5-2 · Verify Funnel
11 / 20 講義 · M5-2
Step 06 · 一條龍跑一次給自己看

四個事件逐一驗 dataLayer

打開 Console 看 dataLayer,按順序走一次——
每一站都要看到 push,缺一站就回頭查設定。

Verification path · 按 → 逐步點亮
01
商品頁
看到 view_item + items[0].item_id = SKU。
02
點加車
AJAX 不跳頁,但 Preview 應冒出 add_to_cart
03
進結帳
看到 begin_checkout + items + value。
04
order-received
PHP hook 自動 push purchase,含 transaction_id = order_id。
自訂佈景若覆蓋 AJAX 按鈕行為,add_to_cart 監聽會失效——這是最常見的「沒看到 push」原因。
Unit 5-2 · End-to-End Test Console · dataLayer · Preview Mode
5-2 · Custom Filter Hook
12 / 20 講義 · M5-2
Step 07 · 要 push 自訂欄位(會員等級、是否首購)

filter hook,不要硬改外掛本體

放在 theme functions.php 或自訂外掛裡。直接改 GTM4WP 原始檔下次更新會被覆蓋——三個月後找不到問題就是這樣來的。

// theme/functions.php
add_filter( 'gtm4wp_datalayer_purchase', function( $data ) {
    $user = wp_get_current_user();
    $data['customer_tier']    = get_user_meta( $user->ID, 'tier', true );
    $data['is_first_order']   = is_user_first_order( $user->ID ) ? 'yes' : 'no';
    return $data;
});
i
PHP 層 hook,擋不到
purchase 在 server 端 render——ad blocker 擋不到,比純 JS 穩定。
!
redirect 失敗 = 訂單丟
客戶被金流 redirect 沒回站 = purchase 不會 fire——備援要等到 6.2 CAPI
Unit 5-2 · Extend Safely filter hook over plugin patch
5-2 · Real Case
13 / 20 講義 · M5-2
Step 08 · 一個常見的接手坑

裝了 GTM4WP,又留著舊的 gtag

Before · 接手前
thank-you 頁同時兩段送 purchase
前任放了一段手寫 gtag purchase,新任裝了 GTM4WP——同一筆訂單被算兩次,月營收虛膨 100%。
Detect·GA4 DebugView 看到雙送
After · 拔 + 去重
移除手動 code + 啟用 GTM4WP de-dup
拔掉手動 gtag、打開 Thank you page de-dup(基於 transaction_id)。WooCommerce 訂單狀態變化也只選一個穩定點(processing 或 completed)送。
Lesson·接手先盤埋碼
對策:接手任何站第一件事——盤一次現有埋碼。同一個 purchase 不應該有兩個來源。
Unit 5-2 · Case Study Inherited site · audit before extend
Act III · Unit 5-3
14 / 20
Section 5.3 · Dedup × Refund × Internal IP

讓資料變成可信

有事件不等於有乾淨資料——
這節決定你的 ROAS 報表 可不可以拿去開會

5 Slides·Dedup + Refund + Filter + Checklist ·~50 min
Act III · Clean Data Unit 5-3
5-3 · Dedup Strategy
15 / 20 講義 · M5-3
Step 09 · 同一筆訂單只送一次 purchase

前端 + 後端,雙重保險

使用者 F5 / 返回 / 分享 URL 都可能二次觸發——
單靠前端會漏,單靠後端慢,兩邊一起做最穩。

前端 · sessionStorage
A
到 thank-you 頁先檢查 order_id 是否已送過,送過就跳過 push。最便宜的第一道擋。
後端 · DB status
B
Server-Side 發送時以 DB 的 order status 判斷——只有 status=completed 時送,重複呼叫只算一次。
id 規則 · 永久唯一
C
直接用訂單 DB 的 primary key。不要用 timestamp、不要用 session_id、不要用 user_id+date——下一頁示範一個翻車案。
Unit 5-3 · Dedup Front + Back · two layers
5-3 · Refund Event
16 / 20 講義 · M5-3
Step 10 · 沒送 refund = ROAS 虛增

退款也要 push 一個事件

GA4 看到 refund 才會從原本 purchase 扣回——不送就是讓報表騙自己。WooCommerce 有 woocommerce_order_refunded hook 可以自動 push。

// 全額退款
dataLayer.push({
  event: 'refund',
  ecommerce: {
    transaction_id: 'T_12345',  // 同原本 purchase 的 ID
    value: 1290,
    items: [ /* 同原 items */ ]
  }
});

// 部分退款 → 對應比例的 value 與 items 數量
//(不是整筆撤銷)
規則:refund 是否含 shipping 看商業邏輯——大多店家退款不退運費。Meta / Ads 的歸因要與 GA4 保持一致
Unit 5-3 · Refund woocommerce_order_refunded hook
5-3 · Internal Traffic
17 / 20 講義 · M5-3
Step 11 · 不要被自己污染 ROAS

內部流量三層排除

LocalWP 測試流量、員工瀏覽、staging 環境——
都會把 ROAS 灌水。三層一起做才乾淨。

Filter pipeline · 按 → 逐步點亮
01
GA4 IP 排除
Admin → Data streams → Define internal traffic 加公司/居家 IP,再去 Data filters 啟用 Exclude internal traffic
02
GTM 容器變數
staging / LocalWP 容器設 traffic_type = 'internal',所有事件都帶。生產容器不帶。
03
GA4 Property 分家
有預算的團隊:測試走獨立 GA4 Property,正式跟測試完全隔離——最乾淨。
發現法:ROAS 異常高、轉換突然變多——先檢查是不是自己的測試流量。九成是這個。
Unit 5-3 · Internal Filter IP · GTM var · Property split
5-3 · Go-Live Checklist
18 / 20 講義 · M5-3
Step 12 · 每個新站上線都要跑一次

上線前 8 項 QA Checklist

八項都打勾——你的電商追蹤穩了。少一項就回頭補。

01
transaction_id 唯一
下兩單同 ID 是大忌——用訂單 DB 主鍵最穩。
02
value = items 加總 + tax + shipping
前端就算好;不對齊 Meta / Ads 歸因會跑歪。
03
currency 一致 TWD
item 層級也帶——跨幣別才不亂。
04
refund 實測一次
退一筆假訂單,看 GA4 確實扣回
05
內部 IP 已排除
公司 / 居家 / VPN 都加進 Data filters。
06
桌機 + 手機都能 fire
手機 Safari 常爆 cookie / storage——實機開來看
07
redirect 回站 purchase 能 fire
綠界 / 藍新 / Stripe 各跑一次,跑完 thank-you 才算 OK
08
三方都看到
GA4 DebugView · Meta Test Events · Ads Debug——三個視窗一起看,數字對得起來才上。
Unit 5-3 · QA 8 boxes · all green = ship it
5-3 · Real Case
19 / 20 講義 · M5-3
Step 13 · 一個秒殺活動的真實事故

用 timestamp 當 ID,秒殺丟 7 單

Before · 開發者覺得
用 timestamp 當 order_id 比較簡單」
秒殺活動同一秒湧進 8 張訂單——都用同一個 timestamp。GA4 以為是同一筆,去重後只留 1 筆,丟失 7 筆營收資料
Result·對帳差 7 單
After · 改用 uuid-v4
換成 uuid-v4(或訂單 DB 主鍵)
立即恢復——但歷史那 7 單只能靠金流後台手動補回。事後對帳的時間成本,比一開始選對 ID 高十倍。
Lesson·id = 永久唯一
規則:transaction_id 必須全站唯一且永久唯一(不是會話唯一)、跟訂單系統 ID 一致方便對帳。直接用 DB primary key 就好——不要自作聰明
Unit 5-3 · Case Study Timestamp ≠ Unique
End · To Be Continued
20 / 20
Next Week · Module 6

下週把資料送出去

電商 dataLayer 跑通了,下一步——
Meta Pixel + Conversion API,iOS 14.5 之後的必修。

Module 6·Pixel ·CAPI ·event_id 去重
Today's homework·跑完一份 LocalWP 上線前 8 項 QA 報告