Tích hợp AppsFlyer + RevenueCat + TikTok Ads + Meta Ads cho app subscription

14-08-2026

Nếu bạn đang xây một mobile subscription app và muốn trả lời được câu hỏi: Quảng cáo TikTok/Meta nào mang về install, trial và cuối cùng là paid subscriber?

Tích hợp AppsFlyer + RevenueCat + TikTok Ads + Meta Ads cho app subscription

Nếu bạn đang xây một mobile subscription app và muốn trả lời được câu hỏi:

Quảng cáo TikTok/Meta nào mang về install, trial và cuối cùng là paid subscriber?

Một architecture tương đối sạch là:

                    ┌── TikTok Advanced SRN
                    │
Mobile App → AppsFlyer ─── Meta SRN
     │              │
     │              └── SKAN / AdAttributionKit (iOS)
     │
     └── RevenueCat
             │
             ├── Trial Started
             ├── Initial Purchase
             ├── Trial Converted
             └── Renewal
                    │
                    └────→ AppsFlyer

Trong setup này:


1. Hiểu vai trò của từng thành phần

AppsFlyer

AppsFlyer là MMP — Mobile Measurement Partner.

Nó đứng giữa app và các advertising network:

TikTok ──┐
Meta ────┼──→ AppsFlyer ←── App
Google ──┘

Mục đích là xác định:

Install X
↓
đến từ TikTok
↓
Campaign A
↓
Ad Group B
↓
Creative C

Sau đó gắn các event:

install
trial
purchase
revenue

vào acquisition source đó.


2. RevenueCat đóng vai trò gì?

AppsFlyer có thể nhận purchase event trực tiếp từ app, nhưng đối với subscription thì RevenueCat là nguồn đáng tin cậy hơn.

Ví dụ:

Day 0
Start 7-day trial

Day 7
Trial → Paid

Day 37
Renewal

Day 67
Renewal

User không cần mở app vào Day 37 hoặc Day 67.

RevenueCat vẫn biết transaction xảy ra và có thể gửi server-to-server sang AppsFlyer.

RevenueCat chính thức hỗ trợ gửi trial conversion, purchase và renewal sang AppsFlyer, kể cả khi app không mở. (RevenueCat)

Architecture:

App Store / Play Store
        ↓
    RevenueCat
        ↓
     AppsFlyer
        ↓
 TikTok / Meta / ...

Đừng track purchase hai lần

Nếu đã dùng:

RevenueCat → AppsFlyer

thì không nên đồng thời làm:

await Purchases.purchasePackage(pkg);

// DON'T do this as a duplicate revenue event
appsFlyer.logEvent("af_purchase", {
  af_revenue: 29.99,
  af_currency: "USD"
});

Nếu không:

Purchase
  ├── App → AppsFlyer
  └── RevenueCat → AppsFlyer

              ↓

        2 purchases ❌

RevenueCat cũng yêu cầu remove client-side revenue tracking khi sử dụng AppsFlyer integration. (RevenueCat)


3. Cài AppsFlyer vào Expo React Native

Ví dụ:

npx expo install react-native-appsflyer

Với Expo development build/EAS, AppsFlyer là native module nên sau khi thêm plugin cần build native app lại.

Ví dụ:

eas build --platform ios

preferAppsFlyerBackupRules đôi khi xuất hiện trong Expo config:

[
  "react-native-appsflyer",
  {
    "preferAppsFlyerBackupRules": true
  }
]

Option này liên quan đến Android backup/data extraction rules, không phải:

Nếu chỉ quan tâm iOS thì nó không phải phần quan trọng của integration.


4. Khởi tạo AppsFlyer

Conceptually:

import appsFlyer from "react-native-appsflyer";

appsFlyer.initSdk(
  {
    devKey: "YOUR_APPSFLYER_DEV_KEY",
    appId: "YOUR_APPLE_APP_ID",

    isDebug: __DEV__,

    onInstallConversionDataListener: true,
    onDeepLinkListener: true,

    timeToWaitForATTUserAuthorization: 0
  },
  result => {
    console.log("AppsFlyer initialized", result);
  },
  error => {
    console.error(error);
  }
);

Nếu không request ATT thì không cần AppsFlyer chờ ATT response.


5. Kết nối AppsFlyer với RevenueCat

Đây là bước rất quan trọng.

RevenueCat cần biết:

RevenueCat customer X
        =
AppsFlyer installation Y

RevenueCat yêu cầu:

$appsflyerId

cho AppsFlyer integration.

Các identifier khác như:

$idfa
$gpsAdId
$idfv
$ip

giúp cải thiện attribution matching nhưng $appsflyerId mới là required identifier. (RevenueCat)

Flow:

AppsFlyer
   ↓
getAppsFlyerUID()
   ↓
RevenueCat
   ↓
$appsflyerId

Ví dụ React Native:

appsFlyer.getAppsFlyerUID((error, uid) => {
  if (error || !uid) return;

  Purchases.setAttributes({
    $appsflyerId: uid
  });
});

Phải thực hiện:

Configure RevenueCat
        ↓
Set AppsFlyer ID
        ↓
User purchase

chứ không nên đợi tới sau purchase mới set ID.

RevenueCat yêu cầu attribution attributes được set sau khi Purchases SDK configure và trước purchase đầu tiên. (RevenueCat)


6. RevenueCat → AppsFlyer

Trong RevenueCat:

Project
→ Integrations
→ AppsFlyer

Điền AppsFlyer developer key.

RevenueCat cho phép sử dụng default event names.

Ví dụ:

Initial purchase
→ rc_initial_purchase_event

Trial started
→ rc_trial_started_event

Trial converted
→ rc_trial_converted_event

Trial cancelled
→ rc_trial_cancelled_event

Renewal
→ rc_renewal_event

Cancellation
→ rc_cancellation_event

RevenueCat cũng hỗ trợ sandbox events nếu cấu hình sandbox API/developer key tương ứng. (RevenueCat)


7. App có cả Trial và Direct Purchase thì map thế nào?

Giả sử app hỗ trợ cả:

A. 7-day trial → paid

B. Buy subscription immediately

Ba event acquisition quan trọng nhất là:

rc_trial_started_event

rc_trial_converted_event

rc_initial_purchase_event

Flow Trial:

Start Trial
    ↓
rc_trial_started_event
    ↓
StartTrial


7 days later
    ↓
Trial converts
    ↓
rc_trial_converted_event
    ↓
Subscribe

Flow direct purchase:

Buy Now
   ↓
rc_initial_purchase_event
   ↓
Subscribe

Do đó khi gửi sang ad network:

AppsFlyer event Advertising event
rc_trial_started_event StartTrial
rc_trial_converted_event Subscribe
rc_initial_purchase_event Subscribe

Không nên map:

rc_renewal_event → Subscribe

nếu mục đích của Subscribe là acquisition conversion.

Nếu làm vậy:

User subscribes
→ Subscribe #1

Month 2 renew
→ Subscribe #2

Month 3 renew
→ Subscribe #3

sẽ khiến acquisition conversion bị phình lên.

Renewal vẫn rất hữu ích cho:

Revenue
LTV
ROAS
Cohort analysis

nhưng nó không phải một new subscriber.


8. Tại sao AppsFlyer dropdown ban đầu chỉ có vài events?

Ví dụ AppsFlyer chỉ hiện:

af_complete_registration
af_skad_revenue
af_app_opened

Điều này không có nghĩa AppsFlyer chỉ hỗ trợ ba event.

Thông thường AppsFlyer UI ưu tiên những event mà nó đã nhận.

Nếu RevenueCat chưa gửi:

rc_trial_started_event

thì event có thể chưa xuất hiện trong dropdown.

Ở những UI cho phép Add item, có thể manually add exact event name:

rc_trial_started_event
rc_trial_converted_event
rc_initial_purchase_event

Tên phải match chính xác với RevenueCat.


9. TikTok SAN là gì?

TikTok hiện dùng Advanced SRN/SAN integration với AppsFlyer. AppsFlyer liệt kê TikTok for Business Advanced SRN cùng các self-reporting network như Meta, Google Ads, Apple Ads và Snapchat. (AppsFlyer Support)

SAN có thể hiểu đơn giản là:

TikTok có first-party advertising interaction data của chính TikTok và tham gia trực tiếp vào attribution flow với AppsFlyer.

Ví dụ:

User sees TikTok Ad #123
        ↓
User clicks
        ↓
App Store
        ↓
Install
        ↓
AppsFlyer
        ↕
TikTok Advanced SRN

TikTok biết:

Campaign
Ad Group
Creative
click/view
...

vì những interactions này xảy ra trên TikTok.

AppsFlyer sau đó đóng vai trò MMP để tổng hợp attribution/reporting giữa nhiều media sources.


10. Kết nối AppsFlyer với TikTok Ads

Trong TikTok Ads Manager:

Tools
→ Events
→ Connect data source
→ App

Chọn:

Mobile Measurement Partner
→ AppsFlyer
→ TikTok for Business

Sau đó trong AppsFlyer:

Collaborate
→ Partner Marketplace / Active Integrations
→ TikTok for Business

Enable integration.

Map subscription events

Map:

rc_trial_started_event
→ StartTrial

rc_trial_converted_event
→ Subscribe

rc_initial_purchase_event
→ Subscribe

Flow cuối cùng:

TikTok Ad
   ↓
Install
   ↓
AppsFlyer
   ↑
RevenueCat
   ↓
Trial / Purchase
   ↓
AppsFlyer
   ↓
TikTok

TikTok có thể sử dụng conversion signal để optimize campaign cho deeper events thay vì chỉ install.


11. Meta có SAN/SRN tương tự không?

Có.

AppsFlyer classify Meta Ads là SRN — Self-Reporting Network. (AppsFlyer Support)

Concept:

Facebook / Instagram Ad
           ↓
        App Store
           ↓
         Install
           ↓
       AppsFlyer
           ↕
        Meta SRN

Vì vậy Meta không hoạt động giống một ad network thông thường chỉ dựa trên attribution tracking link.


12. Tạo Meta App

Trong Meta for Developers:

My Apps
→ Create App

Khi Meta hỏi use case, nếu mục tiêu là chạy mobile app ads, chọn:

Create & manage app ads with Meta Ads Manager

Không cần chọn:

Marketing API

trừ khi muốn tự viết software để programmatically quản lý campaign.

Cũng không cần:

Facebook Login

chỉ để làm attribution.

AppsFlyer xác nhận Facebook Login và Facebook SDK không bắt buộc để thực hiện Meta mobile attribution qua AppsFlyer. (AppsFlyer Support)


13. Kết nối Meta với AppsFlyer

Sau khi tạo Meta App, lấy:

Facebook / Meta App ID

Trong AppsFlyer:

Collaborate
→ Active Integrations
→ Meta ads

Bật integration và nhập Meta App ID.

Sau đó bật:

In-app event postbacks

Map:

rc_trial_started_event
→ StartTrial

rc_trial_converted_event
→ Subscribe

rc_initial_purchase_event
→ Subscribe

AppsFlyer yêu cầu SKAN conversion events phải được map sang Meta event tương ứng nếu muốn Meta sử dụng chúng để optimize; nếu không, Meta có thể chỉ nhận install measurement. (AppsFlyer Support)


14. Events Manager: phải chọn đúng app

Meta Events Manager có thể chứa nhiều loại data source:

Website → Meta Pixel
App → Facebook SDK / MMP
Dataset

Nếu đang setup một app mới, đừng chọn dataset của app khác chỉ vì nó đã có sẵn.

Ví dụ:

Lịch Ta
📱 Facebook SDK

FitFo
📱 MMP

Nếu đang setup FitFo thì phải sử dụng data source/app của FitFo.

Không reuse App ID/dataset của Lịch Ta.


15. SKAN là gì?

SKAdNetwork — SKAN — là privacy-preserving attribution framework của Apple.

Nó hoạt động mà không cần IDFA và không cần ATT consent. (AppsFlyer Support)

Concept:

Ad
 ↓
Install
 ↓
Apple SKAN
 ↓
privacy-safe postback
 ↓
Ad network / AppsFlyer

Điểm quan trọng:

SKAN ≠ SAN

SAN/SRN

TikTok/Meta ↔ AppsFlyer

Network sử dụng first-party advertising data và integration với MMP.

SKAN

Apple
 ↓
privacy-preserving attribution

Hai hệ thống có thể cùng tồn tại:

                 ┌── TikTok Advanced SRN
TikTok campaign ─┤
                 └── Apple SKAN
                          ↓
                      AppsFlyer

16. Có phải tự code SKAN không?

Nếu dùng AppsFlyer SKAN solution thì phần lớn là không.

AppsFlyer nói rõ với SKAN solution:

Do đó không cần tự làm kiểu:

SKAdNetwork.updatePostbackConversionValue(...)

nếu AppsFlyer đang là SDK quản lý conversion value.


17. SKAN Conversion Studio

Trong AppsFlyer:

Settings
→ SKAN Conversion Studio

SKAN 4+ có ba measurement windows:

Window 1
1–2 days

Window 2
3–7 days

Window 3
8–35 days

AppsFlyer xác nhận ba measurement periods này trong SKAN solution. (AppsFlyer Support)

Điều này rất quan trọng với subscription app.

Ví dụ app có:

7-day trial

thì:

Window 1

Install
↓
Trial Started

trong khi:

Window 2 / later

Trial
↓
Paid subscription

có thể xảy ra nhiều ngày sau.

Do đó không nên thiết kế SKAN schema chỉ quanh immediate revenue.


18. Revenue measurement trong SKAN

Nếu Conversion Studio hỏi:

Revenue source

○ Overall revenue
○ In-app event

đừng chọn rc_trial_started_event làm revenue source.

Trial started không phải revenue.

Nếu muốn đo tổng purchase revenue thì:

Overall revenue

thường hợp lý hơn.

Còn:

Trial Started
Subscription

là conversion behavior/event measurement.

Đây là hai khái niệm khác nhau.


19. Meta + SKAN interoperability

Meta có thêm một integration quan trọng.

AppsFlyer ↔ Meta có thể chia sẻ SKAN conversion-value schema:

AppsFlyer
   │
   │ CV schema
   ▼
Meta

Meta
   │
   │ decoded SKAN data
   ▼
AppsFlyer

AppsFlyer cho biết khi interoperability được enable:

Trong AppsFlyer:

Collaborate
→ Active Integrations
→ Meta ads
→ SKAN

Login Meta account có quyền phù hợp.

Sau đó AppsFlyer có thể hiện:

Waiting for sync

và sau khi sync:

Data was pulled successfully

AppsFlyer cho biết dữ liệu SKAN Meta được đồng bộ theo chu kỳ, không nhất thiết xuất hiện ngay lập tức. (AppsFlyer Support)


20. MMP Connection URL cho Meta

AppsFlyer cung cấp MMP Connection URL cho Meta SKAN integration.

Trong Meta Events Manager:

App
→ Settings
→ Configure events
→ Import from Partner App

Paste AppsFlyer MMP Connection URL.

Mục đích:

AppsFlyer CV schema
       ↓
      Meta

Sau lần connection đầu tiên, khi thay đổi measurement settings trong AppsFlyer, không cần paste URL lại. AppsFlyer cho biết Meta có thể mất tới khoảng 24 giờ để nhận measurement configuration mới. (AppsFlyer Support)


21. Có cần ATT không?

Không phải chỉ vì cài AppsFlyer.

SKAN hoạt động:

without IDFA
without ATT consent

theo AppsFlyer. (AppsFlyer Support)

Nếu không request ATT:

ATT permission       ❌
IDFA                 ❌
AppsFlyer ID         ✅
SKAN                 ✅
RevenueCat           ✅
TikTok/Meta MMP      ✅

Nếu user cho ATT:

ATT Allow
   ↓
IDFA available
   ↓
deterministic/device-level matching tốt hơn

RevenueCat cũng coi $idfa là recommended chứ không phải required cho AppsFlyer integration. (RevenueCat)

Do đó với một indie app mới, có thể bắt đầu mà không show ATT prompt, rồi chỉ thêm ATT nếu có use case rõ ràng cho IDFA-based tracking.


22. TestFlight và sandbox

Nếu test bằng TestFlight + RevenueCat sandbox, một check rất hữu ích là RevenueCat customer attributes phải có:

$appsflyerId = ...

Nếu thấy giá trị này, connection:

AppsFlyer SDK
     ↓
AppsFlyer UID
     ↓
RevenueCat

đã hoạt động.

Nhưng:

RevenueCat has AppsFlyer ID

không đồng nghĩa:

RevenueCat has already sent a subscription event to AppsFlyer

Muốn event xuất hiện phải thực sự xảy ra lifecycle event:

Trial Started
Purchase
Trial Converted
Renewal
...

RevenueCat cũng hỗ trợ sandbox event delivery khi sandbox credentials được cấu hình. (RevenueCat)

TestFlight/sandbox chủ yếu hữu ích để verify:

RevenueCat
   ↓
AppsFlyer S2S

Nó không phải full production SKAN campaign attribution test.


23. Android: Google Play Data Safety

Đây là phần rất dễ bỏ sót.

Sau khi thêm AppsFlyer SDK vào Android, Google Play Data Safety declaration có thể cần thay đổi.

Google yêu cầu developer khai báo cả dữ liệu được third-party SDK collect/share, không chỉ code do developer tự viết.

AppsFlyer Android SDK mặc định collect Google Advertising ID — GAID đối với app trên Google Play. (AppsFlyer Support)

GAID thuộc nhóm:

Device or other IDs

Do đó nếu Data Safety trước đây khai:

Device or other IDs
Collected: No

thì sau khi thêm AppsFlyer cần review lại.

AppsFlyer Data Safety guidance nói Android SDK mặc định collect GAID và nếu app gửi in-app events thì App activity cũng có thể cần được khai báo tùy configuration. (AppsFlyer Support)


24. Collected và Shared không giống nhau

Google Play phân biệt:

Collected

và:

Shared

AppsFlyer có thể hoạt động như service provider xử lý dữ liệu thay developer.

Nhưng nếu AppsFlyer được cấu hình gửi data tới advertising partners thông qua:

postbacks
SRNs
audiences

AppsFlyer cảnh báo việc đó có thể được Google xem là sharing, và developer phải đánh giá declaration dựa trên configuration thực tế. (AppsFlyer Support)

Ví dụ architecture:

App
 ↓
AppsFlyer
 ↓
├── TikTok
└── Meta

khác về Data Safety implications so với:

App
 ↓
AppsFlyer only

Do đó không nên copy một Data Safety template chung cho mọi app.


25. Device or other IDs trên Android

Với AppsFlyer Android mặc định:

GAID
↓
Device or other IDs

AppsFlyer xác nhận GAID được tự động collect trên Google Play apps từ SDK v4.8.0 trở đi. (AppsFlyer Support)

Nếu muốn disable advertising identifiers, AppsFlyer cung cấp privacy-preserving configuration để làm điều đó.

Nhưng nếu mục tiêu của việc cài AppsFlyer là:

TikTok Ads attribution
+
Meta Ads attribution

thì việc tắt GAID cần được cân nhắc kỹ vì nó làm mất một deterministic attribution signal hữu ích trên Android.


26. Architecture cuối cùng

Một setup gọn cho subscription app chạy cả TikTok và Meta:

                         ┌─────────────────────┐
                         │      TikTok Ads     │
                         │    Advanced SRN     │
                         └─────────▲───────────┘
                                   │
                                   │ postbacks
                                   │
┌──────────────┐          ┌────────┴─────────┐
│              │          │                  │
│  Mobile App  ├─────────►│    AppsFlyer     │
│              │          │                  │
└──────┬───────┘          └────────▲─────────┘
       │                            │
       │                            │ S2S
       ▼                            │
┌──────────────┐                   │
│  RevenueCat  ├───────────────────┘
└──────────────┘
       │
       │
       │ subscription truth
       ▼
┌────────────────────┐
│ App Store / Google │
│       Play         │
└────────────────────┘


AppsFlyer
    │
    ├──────────────► Meta SRN
    │
    └──────────────► SKAN / Apple attribution

RevenueCat events:

rc_trial_started_event
        ↓
StartTrial


rc_trial_converted_event
        ↓
Subscribe


rc_initial_purchase_event
        ↓
Subscribe


rc_renewal_event
        ↓
Revenue/LTV
        ↓
NOT a new Subscribe conversion

27. Recommended implementation order

Đừng setup mọi dashboard cùng lúc. Làm theo thứ tự này sẽ dễ debug hơn:

1. Install AppsFlyer SDK
          ↓
2. Verify app opens/install in AppsFlyer
          ↓
3. Install/configure RevenueCat
          ↓
4. Pass $appsflyerId → RevenueCat
          ↓
5. Configure RevenueCat → AppsFlyer
          ↓
6. Test trial/purchase
          ↓
7. Verify rc_* events reach AppsFlyer
          ↓
8. Connect TikTok Advanced SRN
          ↓
9. Map Trial/Subscribe events
          ↓
10. Connect Meta SRN
          ↓
11. Map Trial/Subscribe events
          ↓
12. Configure SKAN Conversion Studio
          ↓
13. Configure Meta SKAN interoperability
          ↓
14. Update Google Play Data Safety
          ↓
15. Launch campaigns

Đây cũng là thứ tự dễ troubleshoot nhất: mỗi layer được verify trước khi thêm layer tiếp theo.


28. Checklist trước khi chạy ads

App

RevenueCat

TikTok

Meta

iOS

Android


Kết luận

Điểm quan trọng nhất là đừng coi AppsFlyer, RevenueCat, TikTok/Meta và SKAN là bốn hệ thống làm cùng một việc.

Mỗi cái giải quyết một layer:

RevenueCat
= chuyện gì xảy ra với subscription?


AppsFlyer
= subscriber đó đến từ đâu?


TikTok / Meta SRN
= quảng cáo/campaign/creative nào tạo ra user đó?


SKAN
= Apple cho phép đo attribution thế nào khi không có IDFA?


ATT
= app có được quyền truy cập IDFA/tracking hay không?

Khi tách đúng trách nhiệm, architecture trở nên khá đơn giản:

Ad
 ↓
Install
 ↓
AppsFlyer attribution
 ↓
RevenueCat subscription lifecycle
 ↓
AppsFlyer
 ↓
Ad network conversion postback
 ↓
Campaign optimization

Đối với subscription app có cả free trial và direct purchase, ba acquisition signals quan trọng nhất thường là:

Trial Started
Direct Subscription
Trial → Paid Conversion

RevenueCat giữ subscription truth, AppsFlyer giữ attribution truth, còn TikTok/Meta sử dụng những signal đó để tìm thêm user có khả năng trở thành subscriber.

Tích hợp AppsFlyer + RevenueCat + TikTok Ads + Meta Ads cho app subscription | Duy Nguyen