Product Management
Đăng nhập
ESC

Nhập từ khóa để tìm kiếm

↑↓ Di chuyển
Enter Mở
ESC Đóng

Bài 47 — Deep-linking Attribution Testing

Đã đọc 0/13 mục · còn khoảng 12 phút
Cách chúng tôi ghi nhận

Một mục được tính là đã đọc khi nó nằm giữa màn hình đủ lâu so với độ dài của nó (bảng và sơ đồ tính một nửa), bạn vẫn đang cuộn hoặc bấm phím, và bạn đã thấy tới cuối mục. Lướt nhanh hoặc để tab mở không được tính. Chúng tôi chỉ lưu thời gian đọc từng mục — không lưu gì khác.

Mở đầu — vì sao bài này quan trọng

Hãy tưởng tượng bạn là QA cho một app thương mại điện tử ở Việt Nam. Marketing team vừa chi 300 triệu đồng cho một chiến dịch Facebook Ads trong tháng, kèm 150 triệu cho Google Ads và một loạt link affiliate qua các KOL trên TikTok. Cuối tháng, sếp marketing hỏi một câu tưởng chừng đơn giản: "Trong 12.000 lượt cài app tháng này, bao nhiêu đến từ Facebook, bao nhiêu từ Google, bao nhiêu là organic?" Nếu con số trả về sai — ví dụ Facebook được ghi nhận 8.000 install trong khi thực tế chỉ 3.000 — thì team sẽ đổ thêm tiền vào kênh không hiệu quả và cắt kênh đang hoạt động tốt. Cả một quyết định ngân sách hàng trăm triệu bị dẫn dắt bởi dữ liệu sai.

Đó chính là lý do attribution testing (kiểm thử quy kết nguồn) tồn tại. Ở bài 21 các bạn đã học về deep link và universal link — cách một cú click mở đúng màn hình trong app. Ở bài 46 các bạn học về event analytics — cách app ghi nhận hành vi. Bài 47 này ngồi ở giao điểm của cả hai: khi user click vào một link quảng cáo rồi cài app và mở lên, hệ thống phải quy đúng lượt cài đó về đúng chiến dịch, đúng kênh, đúng nguồn. Nếu link mở đúng nhưng attribution gán sai kênh, marketing vẫn ra quyết định sai. QA là người duy nhất trong team có thể chứng minh chuỗi dữ liệu này đúng từ đầu đến cuối trước khi tiền thật được đổ vào.

Trong bài này chúng ta sẽ tập trung hẹp vào một thứ: kiểm thử luồng attribution từ click quảng cáo → cài đặt → phiên đầu tiên → sự kiện chuyển đổi, và cách xác minh dữ liệu quy kết chính xác. Chúng ta không đi sâu vào cơ chế mở deep link (bài 21) hay cách định nghĩa event (bài 46) — mà kiểm tra rằng nguồn được gán đúng.

Khái niệm cốt lõi

Attribution là gì và tại sao mobile khó hơn web

Trên web, attribution khá đơn giản: click gắn UTM parameter, cookie theo dõi session, người dùng chuyển đổi ngay trong cùng trình duyệt. Trên mobile thì có một "khoảng trống" chết người: user click quảng cáo trong trình duyệt hoặc trong app Facebook, rồi bị đẩy sang App Store / Google Play, cài app (mất 30 giây đến vài phút), rồi mở app trong một ngữ cảnh hoàn toàn tách biệt — không cookie, không session nối tiếp. Làm sao nối được cú click ban đầu với lượt mở app đầu tiên?

Ngành mobile giải bài toán này bằng vài kỹ thuật, và QA cần hiểu để test đúng:

  • Deferred deep link: link "trì hoãn". User click link chứa thông tin chiến dịch, nếu chưa cài app thì được đưa sang store; sau khi cài và mở lần đầu, app đọc lại được thông tin chiến dịch đó và điều hướng đến đúng màn hình (ví dụ trang sản phẩm cụ thể). Đây là ca test quan trọng nhất và dễ hỏng nhất.
  • Fingerprinting theo xác suất: khi không có định danh chính xác, hệ thống dùng IP + user-agent + thời điểm click để "đoán" khớp click với install trong một cửa sổ thời gian. Độ chính xác không tuyệt đối.
  • Định danh chính xác trên iOS: Apple với SKAdNetwork (SKAN) và framework AdAttributionKit cho phép attribution mà không cần lộ danh tính người dùng — dữ liệu về theo dạng tổng hợp, có độ trễ, và bị giới hạn số "conversion value". Từ khi có ATT (App Tracking Transparency), nếu user bấm "Ask App Not to Track", IDFA không dùng được và attribution buộc phải dựa vào SKAN.

Các thành phần của một bản ghi attribution

Một install được quy kết đúng sẽ mang theo các trường mà QA phải xác minh:

  • Media source / channel: nguồn (facebook, googleadwords, tiktok, organic...).
  • Campaign / Adset / Ad: tên chiến dịch, nhóm quảng cáo, mẫu quảng cáo.
  • Attribution type: click-through (user click rồi cài) hay view-through (chỉ xem quảng cáo rồi cài).
  • Attribution window: cửa sổ thời gian hợp lệ, thường 7 ngày cho click, 1 ngày cho view. Cài ngoài cửa sổ → tính là organic.
  • Là install mới hay re-attribution / re-engagement: user mới hay user cũ quay lại qua một chiến dịch.

Tools mà team Việt Nam hay dùng

Ở Việt Nam và Đông Nam Á, ba nền tảng MMP (Mobile Measurement Partner) phổ biến nhất là AppsFlyer (thị phần lớn nhất khu vực), Adjust, và Branch (mạnh về deep link). Nhiều startup nhỏ dùng thẳng Firebase / Google Analytics for Firebase kết hợp Google Ads. QA cần biết mình đang test trên nền tảng nào, vì mỗi nền tảng có test console riêng để tra cứu bản ghi attribution thô — đây là "nguồn chân lý" để đối chiếu.

Tình huống thực tế

Ví dụ 1 — Deferred deep link ghi nhận sai kênh (sàn TMĐT giả định "ChợViệt")

Team QA của một sàn TMĐT giả định tên ChợViệt chạy chiến dịch Tết: KOL trên TikTok chia sẻ link dẫn thẳng đến trang deal "Giỏ quà Tết". Link được tạo qua AppsFlyer OneLink với media_source=tiktok và deep_link_value=tet_gift_basket. Kỳ vọng: user chưa cài app click link → cài từ store → mở app lần đầu → nhảy thẳng vào trang Giỏ quà Tết → bản ghi attribution ghi nguồn tiktok.

QA test và phát hiện: trên thiết bị đã đăng nhập sẵn Facebook, khi click link từ TikTok, ứng dụng lại bị gán media_source=Facebook Ads. Điều tra ra nguyên nhân: Facebook SDK trong app tự động "claim" install nếu phát hiện Facebook app có mặt trên máy, và do thứ tự khởi tạo SDK sai, Facebook SDK báo cáo trước khi AppsFlyer kịp gửi. Kết quả: TikTok bị "cướp công". Nếu không phát hiện, marketing sẽ thấy TikTok "không ra install" và cắt ngân sách KOL — trong khi kênh đó thực chất đang chạy tốt.

Bài học: attribution không chỉ là "link có mở đúng không" mà là "ai được ghi công". Phải test với ma trận thiết bị có/không cài sẵn app mạng xã hội, và kiểm tra thứ tự khởi tạo các SDK.

Ví dụ 2 — Cửa sổ attribution và re-install (app gọi xe giả định "XeNhanh")

App gọi xe giả định XeNhanh chạy chiến dịch re-engagement: gửi SMS chứa deep link kèm mã khuyến mãi cho user cũ đã xóa app. QA cần xác minh: user gỡ app từ 10 ngày trước, click link SMS, cài lại → được ghi nhận là re-attribution về đúng chiến dịch SMS, không phải "install mới organic".

QA dựng kịch bản: dùng test device, gỡ app, xóa advertising ID (reset), chờ, rồi click link. Phát hiện một lỗi tinh vi: attribution window cho re-engagement bị cấu hình 7 ngày trong khi chiến dịch chạy 14 ngày. User click ở ngày thứ 9 bị tính là organic → mã khuyến mãi vẫn áp nhưng doanh thu không được quy về chiến dịch SMS. Sếp marketing thấy chiến dịch "lỗ" và định dừng. QA chỉ ra sai lệch giữa window kỹ thuật (7 ngày) và window kinh doanh (14 ngày).

Bài học: QA phải test ở rìa của attribution window — ngay trước, ngay tại, và ngay sau mốc thời gian — chứ không chỉ test "happy path" click-rồi-cài-ngay.

Ví dụ 3 — iOS ATT làm sập số liệu (fintech giả định "ViPay")

App fintech giả định ViPay cập nhật lên iOS build mới, hiện popup ATT hỏi quyền tracking. Sau release, marketing hoảng vì attribution trên iOS "biến mất" 60% — tưởng có bug. QA vào cuộc và làm rõ đây không phải bug mà là hành vi đúng: khi user chọn "Ask App Not to Track", IDFA bị chặn, attribution rơi về SKAdNetwork với dữ liệu tổng hợp và trễ 24–48 giờ, không có breakdown chi tiết theo từng install. QA xác minh rằng SKAN postback vẫn về đúng, conversion value được map đúng với các mốc hành vi (đăng ký → liên kết ngân hàng → giao dịch đầu). Việc QA làm ở đây là phân biệt "số liệu giảm do thiết kế" với "số liệu sai do lỗi", tránh cả team lao vào fix một thứ không hỏng.

Bài học: trên iOS, hiểu ATT/SKAN là bắt buộc. Kỳ vọng test phải điều chỉnh theo trạng thái quyền tracking của user.

Hướng dẫn từng bước

Dưới đây là quy trình kiểm thử một luồng attribution hoàn chỉnh mà bạn có thể áp dụng ngay.

Bước 1 — Lấy đúng test link và ghi rõ kỳ vọng. Yêu cầu marketing/growth cung cấp link tracking thật (OneLink của AppsFlyer, link Adjust/Branch...). Với mỗi link, viết ra bảng kỳ vọng: media_source, campaign, deep_link_value, màn hình đích, attribution type. Đây là "oracle" để đối chiếu.

Bước 2 — Chuẩn bị thiết bị sạch. Attribution rất nhạy với trạng thái máy. Gỡ app hoàn toàn. Reset advertising ID (Android: Settings → Google → Ads → Reset; iOS: qua trạng thái ATT). Nếu test deferred deep link, đảm bảo app chưa từng cài (install mới) hoặc đã ở đúng trạng thái tái attribution. Ghi lại IDFA/GAID nếu cần khớp trong console.

Bước 3 — Thực hiện cú click đúng ngữ cảnh. Click link từ đúng nơi kịch bản mô tả: trong app TikTok, trong Facebook, trong trình duyệt Safari/Chrome, trong SMS. Ngữ cảnh khác nhau cho kết quả attribution khác nhau (in-app browser vs system browser).

Bước 4 — Cài và mở lần đầu, quan sát điều hướng. Sau khi cài từ store, mở app và xác minh deferred deep link đưa đúng màn hình. Đồng thời bắt log network để thấy request attribution gửi đi (dùng proxy như Charles/Proxyman — liên hệ bài 40 về network mocking để dựng môi trường bắt gói).

Bước 5 — Đối chiếu trong test console của MMP. Vào AppsFlyer/Adjust/Branch, tra bản ghi raw của install vừa tạo (thường có mục "Test" hoặc filter theo device ID). Kiểm tra từng trường khớp với bảng kỳ vọng ở Bước 1. Đây là điểm xác minh quan trọng nhất — đừng chỉ tin UI app.

Bước 6 — Xác minh chuỗi post-install event. Attribution không dừng ở install. Thực hiện các hành vi chuyển đổi (đăng ký, thêm giỏ hàng, mua) và kiểm tra chúng được gán về đúng nguồn trong cửa sổ attribution. Một install đúng nguồn nhưng purchase bị mất attribution vẫn là lỗi.

Bước 7 — Test các biên và các nhánh âm. Cài ngoài attribution window (phải ra organic). Click nhiều link liên tiếp (kiểm tra quy tắc last-click). Test trường hợp không có mạng lúc mở lần đầu. Test trên iOS với cả hai lựa chọn ATT.

Lỗi thường gặp & mẹo

  • Test trên máy đã cài sẵn app — sai kinh điển. Attribution "first install" chỉ xảy ra một lần; máy đã có dữ liệu sẽ cho kết quả rác. Luôn bắt đầu từ máy sạch, ID đã reset.
  • Chỉ kiểm tra UI app, bỏ qua raw data trong console. App có thể điều hướng đúng màn hình nhưng bản ghi attribution phía server vẫn gán sai nguồn. Nguồn chân lý là dashboard MMP, không phải màn hình app.
  • Bỏ qua độ trễ. SKAN có thể trễ 24–48 giờ; một số postback về sau. Đừng kết luận "mất attribution" ngay sau vài phút — chờ đúng SLA của nền tảng.
  • Nhầm attribution window kỹ thuật với window kinh doanh. Như ví dụ XeNhanh: luôn đối chiếu con số window trong cấu hình MMP với thời lượng chiến dịch thực tế.
  • Không xét self-attributing networks (SAN). Facebook, Google, TikTok, Apple Search Ads tự báo cáo attribution của riêng họ và có quyền "claim" cao. Xung đột giữa SAN và MMP là nguồn lỗi phổ biến — luôn test ma trận có/không cài sẵn app SAN.
  • Mẹo — dùng "test mode" của MMP. AppsFlyer có chức năng đăng ký device làm test device để bản ghi hiện gần như realtime và không làm bẩn dữ liệu production. Adjust/Branch có cơ chế tương tự. Bật nó trước khi test.
  • Mẹo — lập ma trận kịch bản. Trục 1: nguồn (FB/Google/TikTok/organic/SMS). Trục 2: trạng thái (chưa cài / đã gỡ trong window / đã gỡ ngoài window / user hiện hữu). Trục 3: nền tảng (Android / iOS-ATT-cho-phép / iOS-ATT-từ-chối). Mỗi ô là một ca test.
  • Mẹo — dùng deep link đã biết để phân biệt lỗi mở link vs lỗi attribution. Nếu màn hình mở sai → lỗi thuộc bài 21. Nếu màn hình đúng mà nguồn sai → lỗi attribution. Tách bạch giúp báo cáo bug đúng team.

Bài tập thực hành

  • Dựng bảng kỳ vọng: Chọn một app bạn đang test (hoặc app demo có AppsFlyer/Branch). Lấy một tracking link và viết ra bảng gồm: media_source, campaign, deep_link_value, màn hình đích, attribution type, attribution window. Đây là oracle của bạn.
  • Chạy full luồng deferred deep link: Trên một thiết bị/emulator sạch chưa cài app, click link, cài, mở lần đầu. Ghi lại: (a) màn hình có đúng không, (b) request attribution trong network log, (c) bản ghi trong console MMP. So khớp cả ba với bảng kỳ vọng.
  • Test biên attribution window: Thiết kế 3 ca — click trong window, click đúng mốc cuối window, click sau window — và dự đoán kết quả (đúng nguồn / organic) cho từng ca trước khi chạy. Đối chiếu dự đoán với thực tế.
  • Ma trận SAN: Test cùng một link trên hai máy — một máy có cài Facebook app, một máy không — và ghi nhận sự khác biệt về media_source được gán. Viết một bug report giả định nếu phát hiện Facebook "cướp" attribution từ nguồn khác.
  • Kịch bản iOS ATT: Viết ra kỳ vọng attribution khác nhau cho hai trường hợp user chọn "Allow" và "Ask App Not to Track", giải thích vì sao dữ liệu ở trường hợp thứ hai bị hạn chế và cách xác minh SKAN postback thay thế.

Tóm tắt

Attribution testing là mắt xích quyết định giữa "link mở đúng" (bài 21) và "event ghi đúng" (bài 46): nó đảm bảo mỗi lượt cài và mỗi chuyển đổi được quy về đúng nguồn, để marketing tiêu tiền dựa trên dữ liệu thật. Cốt lõi cần nhớ: mobile có "khoảng trống" giữa click và mở app, được vá bằng deferred deep link, fingerprinting và SKAdNetwork trên iOS. QA phải test trên thiết bị sạch, đối chiếu raw data trong console MMP chứ không chỉ UI app, chú ý attribution window, phân biệt self-attributing networks, và điều chỉnh kỳ vọng theo trạng thái ATT trên iOS. Ba tình huống — TikTok bị Facebook cướp công, re-engagement rơi ngoài window, và iOS ATT làm số liệu tụt — cho thấy một sự thật: khi attribution sai, cả một quyết định ngân sách hàng trăm triệu có thể đi sai hướng, và QA thường là người duy nhất phát hiện được điều đó trước khi quá muộn.

Học xong bài này rồi? Tạo tài khoản miễn phí để lưu lại — lần sau vào là biết ngay đang dở ở đâu, và học hết khóa thì có chứng chỉ. Lưu tiến độ của tôi