FB / Push / Ads
แหล่ง click พร้อม UTM, gclid หรือ message context
raw campaign paramsแยก marketing context ออกจาก transaction identity เพื่อให้การเชื่อม Redirect → App/Web → Checkout → Payment → GA4/BigQuery ตรวจสอบย้อนกลับได้ แม้ข้าม session อุปกรณ์ และระบบชำระเงิน
Flow เดิมทำงานได้ในฐานะ tracking pipeline แต่ UTM เป็น input ที่ผู้ใช้แก้ได้และสูญหายได้ จึงไม่ควรทำหน้าที่เป็นกุญแจหลักในการยืนยันยอดเงินจริง
UTM, gclid, message_id และ creative metadata อธิบายว่า touchpoint มาจากไหน ภายใต้ policy และ attribution window ที่กำหนด
attribution_id, order_id และ transaction_id เชื่อมเหตุการณ์ข้ามระบบโดยมี Backend เป็นผู้ควบคุม lifecycle และ audit trail
ความเสี่ยงไม่ได้อยู่ที่การเก็บ UTM แต่อยู่ที่การให้ UTM รับผิดชอบงานที่ต้องการความน่าเชื่อถือ ความคงที่ และการตรวจสอบย้อนหลัง
| Failure mode | ผลกระทบ | Control ที่แนะนำ |
|---|---|---|
| UTM ถูกแก้หรือหายระหว่าง hop | Order ถูกผูกกับ campaign ผิด หรือกลายเป็น unattributed | รับ UTM จุดเดียว แล้วส่งต่อเฉพาะ server-issued attribution_id |
jid ไม่มี contract ชัด | เดาได้ ชนกัน ใช้ซ้ำผิดบริบท และ audit ยาก | กำหนด issuer, entropy, TTL, reuse rule และ binding กับ session/user |
| App storage เป็น source of truth | ข้อมูลหายเมื่อ reinstall, clear storage หรือเปลี่ยนอุปกรณ์ | ให้ client เป็น cache; ให้ server เก็บ touchpoint history และ resolved state |
| Client ยิง purchase อย่างเดียว | เกิด event loss, spoofing และยอดไม่ตรง provider | ยืนยันผ่าน webhook หรือ receipt verification พร้อม idempotency key |
| Checkout ข้าม domain / browser | Web session แยกจาก app session และ cross-domain แตก | เชื่อมด้วย token ฝั่ง backend; ใช้ cross-domain measurement เฉพาะ architecture เดียวกัน |
| UTM ถูกใช้ใน internal link | Campaign เดิมถูก overwrite ระหว่าง navigation | ห้าม UTM ภายในผลิตภัณฑ์; ใช้ promotion/event parameter แทน |
| ไม่มี naming governance | Facebook, facebook, fb แตกเป็นคนละ source | มี registry, lowercase normalization, enum และ immutable utm_id |
| UTM ปะปน PII | ข้อมูลส่วนบุคคลไหลเข้าสู่ analytics และ log หลายระบบ | Allowlist key/value, strip PII, จำกัดความยาว และควบคุม retention |
เลือกมุมมองเพื่อดูว่า field ใดมีหน้าที่อยู่ช่วงไหนของ flow โดยไม่ทำให้ campaign metadata กลายเป็น transaction proof
แหล่ง click พร้อม UTM, gclid หรือ message context
raw campaign paramsValidate, normalize, strip PII และสร้าง click record
→ attribution_idรับ opaque ID เป็น pending attribution และส่ง open events
attribution_idแนบ authenticated session และ checkout context
+ session / userResolve ID, snapshot attribution และ verify payment
order_id + transaction_idรับ authoritative events และวิเคราะห์ model ที่เลือก
verified revenue factsRaw UTM ถูก normalize ที่ redirect และเก็บเป็น immutable click context
ทุกระบบส่ง ID เดียว Backend จึงตัดสิน policy และ ownership ได้สม่ำเสมอ
Revenue event เกิดหลัง provider verification และผ่าน idempotency control
การออกแบบที่ตรวจสอบได้เริ่มจากการประกาศ ownership ชัดเจน ไม่ใช่พยายามทำให้ GA4, client และ payment provider มียอดตรงกันด้วย event ชุดเดียว
ค่าที่ผ่าน normalization, registry และ policy ณ click time
Redirect + Attribution DBCheckout session, authenticated user และ cart/order intent
Checkout + Order serviceModelled views ที่ join facts ด้วย order, transaction และ attribution identifiers
Warehouse / BIAttribution model เป็นนโยบายการวิเคราะห์ ไม่ควรถูกฝังจนแก้ย้อนหลังไม่ได้ เลือกแต่ละแบบเพื่อดูข้อแลกเปลี่ยน
ให้เครดิต token/click ที่พาเข้าสู่ checkout หรือ order นั้นโดยตรง เหมาะเป็น default เมื่อเป้าหมายคือ reconciliation ระดับธุรกรรม
Snapshot ทำให้กติกาที่ใช้ ณ เวลาตัดสินใจถูกเก็บไว้พร้อม order จึง audit, replay และ reconcile ได้ แม้ผู้ใช้จะมีหลาย touchpoint ก่อนซื้อ
{
"order_id": "ord_01…",
"attribution_id": "att_01…",
"attribution_model": "last_non_direct",
"utm_source": "facebook",
"utm_medium": "paid_social",
"utm_campaign": "10_10_sale",
"utm_id": "cmp_20261010_001",
"utm_content": "video_a",
"click_timestamp": "2026-10-01T09:15:00Z",
"attribution_captured_at": "2026-10-01T09:15:01Z"
}
เก็บค่า campaign ที่ resolve แล้วพร้อม model version ณ order time
ใช้ order_id, transaction_id และ attribution_id เป็น join keys
Payment, refund และ chargeback อัปเดต transaction state โดยไม่เปลี่ยน attribution snapshot
| Event | Producer | Required identity | Purpose |
|---|---|---|---|
campaign_click | Redirect server | attribution_id | บันทึก normalized acquisition context |
push_open | App | attribution_id + message_id | แยก push interaction จาก generic campaign open |
deep_link_open | App | attribution_id | บันทึก resolved route และ cold/warm start |
checkout_view | Web / App | attribution_id + checkout_session_id | วัด purchase intent โดยยังไม่ถือเป็นรายได้ |
order_created | Backend | order_id + snapshot | ตรึง attribution decision ของ order |
purchase_verified | Backend | order_id + transaction_id | สร้าง authoritative revenue fact |
refund_issued | Backend | order_id + transaction_id | ปรับ net revenue ด้วยสถานะหลังการซื้อ |
เริ่มจาก identity และ data quality ก่อน แล้วจึงเปลี่ยน revenue dashboard ไปใช้ authoritative facts เมื่อ reconciliation ผ่านเกณฑ์ของทีม
นิยาม UTM registry, event taxonomy, ID contract, TTL และ attribution policy
ออก attribution ID ที่ redirect และเก็บ touchpoint server-side โดยไม่เปลี่ยน dashboard
ผูก checkout/order กับ ID และบันทึก immutable attribution snapshot
ส่ง verified lifecycle events เข้า warehouse แล้วเทียบยอดกับ provider ก่อน cutover
Opaque ID ออกโดย server เท่านั้นมี entropy เพียงพอ, TTL และ audit fields
UTM ผ่าน allowlist และ normalizationห้าม PII, จำกัดความยาว, canonical casing
Order snapshot มี model versionรองรับ replay และ policy migration
Provider events idempotentรองรับ duplicate, delay, refund และ renewal
Client event ไม่ใช่ revenue truthใช้เพื่อ UX และ funnel diagnostics เท่านั้น
Dashboard ระบุ attribution modelทุก KPI บอก window และ model ที่ใช้
ใช้ UTM เพื่ออธิบายการตลาด ใช้ attribution_id เพื่อเชื่อม journey และใช้ verified order_id + transaction_id เพื่อยืนยันรายได้
แหล่งอ้างอิงประกอบ: Google Analytics — URL builders and campaign parameters · NordicClick — UTM tagging guidance for GA4