Chuyển đến nội dung chính

Đo Lường Chuyển Đổi Cho Deep Link

Bạn sẽ học: Sau khi deep link được phân giải, cách gắn các sự kiện kinh doanh thật — đăng ký (lead), mua hàng (sale) — về đúng cú click đã dẫn dắt chúng. iOS dùng Li2 SDK (gói sẵn cầu nối click id). Android tự gọi HTTP POST /track/leadPOST /track/sale.
Yêu cầu gói dịch vụ. Conversion tracking là tính năng trả phí (Premium+). Nếu org hoặc link cụ thể chưa bật, mọi lời gọi trả về 403 kèm lý do trong message lỗi.

Mô hình tinh thần: cầu nối click id

Một deep link khớp (.matched) để lại một click id. Mọi lead/sale sau đó gắn về đúng touch-point bằng cách đọc lại click id này — bạn không phải tự truyền nó qua code.
 deep link khớp            lưu lại                       gắn về touch-point
 (resolver .matched)  ──▶  click id  ──────────────▶  trackAttributedLead / Sale
                           iOS: Li2.lastClickId          (iOS tự đọc; Android
                           (TTL 30 ngày)                  bạn tự giữ & truyền)
Nền tảngCách lấy click idCách gắn vào conversion
iOS (SDK)SDK tự lưu Li2.lastClickId khi .matched (TTL 30 ngày)Các biến attributed/anonymous tự đọc Li2.lastClickId — bạn không truyền tay
Android (HTTP)Đọc outcome.clickId từ Li2DeepLinkOutcome.Matchedtự lưuTruyền chính chuỗi đó vào click_id của request
Hệ thống hiện chỉ hỗ trợ 2 loại tiền: USDVND. Loại tiền khác không có cấu hình chính thức (server mặc định coi như không có số thập phân). Nếu org bạn cần loại tiền khác, hãy liên hệ trước khi gửi sale.
Từ 0.2.0, SDK gói sẵn conversion: trackLead (3 biến), trackSale (2 biến) và identify. API được định kiểu theo ý định — chọn đúng phương thức, quy tắc click id được xử lý sẵn (không còn bẫy nil vs "" như web SDK).

Gọi phương thức nào?

Có clickId?Có user id?LeadSale
Không (hoặc không cần attribution)trackDirectLeadtrackDirectSale
Có (từ deep-link match)Chưa (ẩn danh)trackAnonymousLead
trackAttributedLeadtrackAttributedSale
  • Biến Direct không bao giờ attribute — gửi click_id = ""bắt buộc externalId. Dùng khi không có deep link nào (vd: người dùng mở app trực tiếp, mua trong app).
  • Biến attributed / anonymous mặc định clickId = Li2.lastClickId. Nếu nil (chưa có match nào) chúng ném .noClickIdAvailable ngay phía client, trước khi gọi mạng — hãy chạy deep-link match trước, hoặc dùng biến Direct.

Lead

import Li2SDK

// Direct: user đã biết, không attribution.
let r = try await Li2.trackDirectLead(externalId: "user_42", eventName: "signup",
                                      email: "[email protected]")

// Anonymous: gắn về một click, chưa biết danh tính user.
// clickId mặc định = Li2.lastClickId.
try await Li2.trackAnonymousLead(eventName: "viewed_pricing")

// Attributed: user đã biết VÀ có click deep link.
try await Li2.trackAttributedLead(externalId: "user_42", eventName: "signup")

Sale

amount tính bằng đơn vị nhỏ nhất của loại tiền và phải > 0 — server từ chối 0. currency tùy chọn; bỏ trống để dùng mặc định của org.
Đơn vị nhỏ nhất phụ thuộc loại tiền. Tiền có 2 chữ số thập phân (USD, EUR…) tính bằng cent/xu: 4999 = $49.99. Tiền không có số thập phân (VND, JPY…) thì amount chính là số đơn vị tiền — với VND, amountsố đồng trực tiếp (không nhân /100): 10000 = 10.000đ.
// Sale trực tiếp — USD có 2 số thập phân nên amount tính bằng cent.
let s = try await Li2.trackDirectSale(externalId: "user_42", amount: 4999)  // $49.99

// Sale attributed — tự đọc Li2.lastClickId, link visit / touch-point.
// VND không có số thập phân → amount là số đồng trực tiếp.
try await Li2.trackAttributedSale(externalId: "user_42", amount: 10000, currency: "vnd")  // 10.000đ

identify — ẩn danh ➜ định danh

identify bắt buộc cho hành trình anonymous lead ➜ attributed sale. Một sale chỉ phân giải khách hàng theo externalId — nó không có đường merge ẩn danh — nên nếu thiếu identify, lead ẩn danh và sale rơi vào hai hồ sơ khách hàng tách biệt. Gọi identify trước sẽ “thăng cấp” hồ sơ anon_<clickId> thành user id thật, để sale tìm đúng hồ sơ:
// 1. Lead ẩn danh từ một click deep link → hồ sơ anon_<clickId>.
try await Li2.trackAnonymousLead(eventName: "viewed_pricing")

// 2. User đăng nhập / đăng ký — thăng cấp hồ sơ ẩn danh.
try await Li2.identify(externalId: "user_42", email: "[email protected]")

// 3. Sale giờ rơi vào CÙNG một hồ sơ.
try await Li2.trackAttributedSale(externalId: "user_42", amount: 4999)
externalId phải khác rỗng — một id rỗng không thăng cấp được gì, nên identify ném .missingExternalId trước khi gọi mạng. clickId mặc định Li2.lastClickId và ném .noClickIdAvailable nếu vắng.
Hành trình anonymous lead ➜ attributed lead không cần identifytrackAttributedLead tự merge hồ sơ ẩn danh. identify sinh ra chỉ để bắc cầu cho hành trình sale. Lưu ý: identify ghi một lead __identify__ thật và tăng lead_count (giống JS SDK, không có filter phía backend) — chấp nhận theo thiết kế.
Tham chiếu đầy đủ tham số từng phương thức + bảng lỗi: xem README của Li2 Swift SDK.

Khi nào dùng — use case thực tế

1

Acquisition tới mua hàng (deferred, ẩn danh)

User chạm short link khi chưa cài app → cài → mở lần đầu → deep-link match lưu click id. Trước khi đăng nhập, ghi lead ẩn danh (viewed_pricing). Khi user đăng ký, identify (iOS) / lead __identify__ (HTTP). Khi họ mua, ghi sale attributed. → Một hồ sơ mang cả lead lẫn sale, doanh thu quy về đúng chiến dịch.
2

Re-engagement (immediate, đã định danh)

User đã cài + đã đăng nhập, chạm short link mở thẳng app (Universal Link / App Link). Sau hành động, ghi lead/sale attributed với external_id của họ — click id từ match tự gắn về.
3

Sự kiện không từ deep link

Mua trong app, không có click nào (mở app trực tiếp). Dùng biến Direct: click_id = "", không attribution, vẫn ghi nhận doanh thu cho khách hàng.

Best practices

  • Gọi identify (hoặc lead __identify__) ngay khi biết danh tính, trước sale đầu tiên — đó là lằn ranh giữa “một khách hàng” và “hai hồ sơ tách rời”.
  • Dùng external_id ổn định (user id nội bộ của bạn), giống hệt nhau ở lead, identify và sale. Lệch một ký tự = tách hồ sơ.
  • amount luôn là số nguyên đơn vị nhỏ nhất — tiền 2 thập phân tính bằng xu (4999 = $49.99), tiền không thập phân như VND là số đồng trực tiếp (10000 = 10.000đ). Đừng gửi số thực; 0 bị từ chối.
  • Bỏ trống currency để server dùng mặc định của org — chỉ set khi thật sự cần khác (vd "vnd").
  • Đừng tự truyền click id cũ trừ khi có lý do đặc biệt. iOS: để mặc định Li2.lastClickId. Android: truyền đúng click id vừa lưu từ Matched, đừng tái dùng click id của một phiên cũ.
  • Conversion là best-effort, không hàng đợi/offline buffer: một POST duy nhất, lỗi thì báo lỗi. Bắt lỗi và quyết định retry theo nghiệp vụ của bạn (đừng retry mù vô hạn).

Bảng lỗi conversion

Tình huốngiOS (lỗi ném ra)HTTP statusCách xử lý
Chưa có click id để attribute.noClickIdAvailable (ném trước khi gọi mạng)Chạy deep-link match trước, hoặc dùng biến Direct
identify thiếu external_id.missingExternalId (ném trước khi gọi mạng)Cấp user id ổn định
Gói/feature chưa bật.httpError(403, msg)403Bật conversion tracking cho org/link
Không thấy khách hàng / thiếu trường.httpError(400, msg)400Cấp email/name/phone để tự tạo, hoặc ghi lead trước
Sai loại key.httpError(401, msg)401Dùng publishable key (li2_pk_…), không phải server API key

Bước tiếp theo

Tích Hợp iOS & Android

Quay lại phần phân giải deep link — tiền đề để có click id.

Khắc phục sự cố

Tra theo triệu chứng khi conversion hoặc deep link không như mong đợi.