AppsFlyer
Adapty は AppsFlyer と双方向でデータをやり取りします。AppsFlyer は各ユーザーをどのキャンペーンが獲得したかを Adapty に通知します。Adapty は AppsFlyer に対して、そのユーザーの支払い情報(購入、更新、トライアル、返金)を収益やプロダクトの詳細とともに送信します。
- サブスクリプションの初回購入だけでなく、ライフサイクル全体を把握できます。 更新やトライアルのコンバージョンはストアイベントであり、AppsFlyerのクライアントサイドSDKがレポートするアプリセッションは発生しません。Adaptyはサブスクリプションイベントをサーバーサイドで受信し、AppsFlyerに転送するため、初回インストール後もキャンペーンの数値が更新され続けます。返金も同じ経路で処理され、AppsFlyerはキャンペーン収益から自動的に差し引きます。
- サブスクリプションイベントデータで広告キャンペーンを最適化できます。 AppsFlyerはAdaptyからのアプリ内イベントをポストバックとして広告ネットワークに転送します。広告予算を管理するサービスは、ユーザーが実際に支払った金額をもとに最適化を行えます。
- キャンペーンでAdaptyアナリティクスをフィルタリングできます。 Adaptyは各プロファイルにAppsFlyerのアトリビューション(広告セットやクリエイティブレベルまで)を保存し、サブスクリプションのチャートでフィルタリングに使用できます。
- キャンペーンごとに異なるペイウォールを表示できます。 Adaptyのセグメントでは、キャンペーン・広告セット・クリエイティブなど同じアトリビューションフィールドでフィルタリングできます。セグメントをオーディエンスとして使用することで、ユーザーを獲得した広告に合わせたペイウォールを表示できます。
Adapty アカウントには、有料キャンペーン向けのツールが2つ含まれています。Adapty Ads Manager は Apple Ads キャンペーンを管理し、Adapty Attribution は Meta Ads と TikTok をカバーします。どちらも Adapty の購入データから ROAS と LTV を直接レポートし、無料で始められます — 詳しくは料金ページをご覧ください。
インテグレーションの仕組み
Adapty は AppsFlyer からアトリビューションデータを受け取り、サブスクリプションイベントを AppsFlyer に送り返します。どちらも AppsFlyer ID という 1 つの値に依存しています。これは、アプリが初回起動したときに AppsFlyer が生成する文字列です。
- ユーザーがアプリをインストールすると、AppsFlyer SDK がそのユーザーに一意のIDを割り当てます。
- アプリはそのIDを Adapty に渡し、Adapty はそれをユーザーのプロファイルに
appsflyer_idとして保存します。 - アプリは AppsFlyer のアトリビューションデータも Adapty に渡し、Adapty は同じプロファイルに保存します。
- その後、ユーザーがサブスクリプションイベント(例:トライアルの開始やプロダクトの購入)をトリガーすると、Adapty のサーバーが同じ
appsflyer_idを使って AppsFlyer の S2S API にそのイベントを送信します。 - AppsFlyer はそのIDをすでにアトリビュートされたインストールと照合し、購入がそのインストールのキャンペーンおよびメディアソースを引き継ぎます。
セットアップ手順
始める前に:
- AppsFlyer のプランが S2S アプリ内イベントを受け付けることを確認してください。 AppsFlyer のエントリーレベルプラン Zero はこれに対応しておらず、Adapty が送信するすべてのイベントに対して
403 Forbiddenが返されます。 - アプリに AppsFlyer SDK を組み込んでください。 この統合が依存する AppsFlyer ID は、その SDK が初期化されて初めて生成されます。サーバーサイド統合だけでは ID は生成されません。
- 他のアトリビューション統合をすべて無効にしてください。 Adapty はプロファイルごとに 1 つのアトリビューションソースしか受け付けず、既存の値を上書きすることはできません。iOS では、オーガニック以外の Apple 広告のアトリビューション が常に優先されます。詳細は 単一のアトリビューションソースを選択する を参照してください。
AppsFlyer で S2S トークンを作成する
Adapty は、あなたが作成したトークンを使って AppsFlyer の S2S API に対して認証を行います。Tokens ページを開けるのは AppsFlyer の管理者のみです。アカウントが管理者でない場合は、管理者にトークンの作成を依頼してください。すでにトークンをお持ちの場合は、Adapty を設定する までスキップしてください。
-
AppsFlyer にサインインします。
-
右上のアカウント名をクリックし、Security center を開きます。
-
Manage your account security ページで AppsFlyer API and S2S tokens カードを見つけ、Manage your AppsFlyer tokens をクリックします。Tokens ページが開きます。
-
New token をクリックします。
-
トークンの Name を入力します。この名前は自分用のメモとして使うもので、後から変更できます。
-
S2S トークンタイプを選択します。他のタイプを選択すると連携が機能しません。
-
Create new token をクリックします。
AppsFlyer では、タイプごとに2つのトークンを使用できます。すでに2つのS2Sトークンがある場合は、そのいずれかを再利用してください。
-
リストで新しいトークンを見つけます。AppsFlyer は値をマスクするため、Token 列のコピーアイコンをクリックして取得してください。
Adaptlyを設定する
- Adapty ダッシュボードで Integrations > AppsFlyer を開きます。
- AppsFlyer トグルを有効にします。
- アプリをすでに App Store に接続している場合、iOS App ID フィールドにはアプリの Apple ID(数値)が自動入力されます。空の場合は、先に App Store アカウントを接続してください。Android には同等のフィールドはありません。
- S2S トークンを S2S key for iOS、S2S key for Android、またはその両方の Production フィールドに貼り付けます。
- テスト購入が本番データに混入しないよう Sandbox フィールドを入力します。詳しくは Keep sandbox data out of production を参照してください。
- How the revenue data should be send の下で、Adapty が
af_revenueとして送信する売上数値を選択します。3つのオプションは Adapty Analytics の売上ビュー に対応しているため、選択した内容は AppsFlyer の数値と一致させるべきビューも示しています。
| オプション | Adapty が送信する内容 |
|---|---|
| Gross revenue | 手数料と税金を差し引く前の購入者が支払った全額。デフォルト。 |
| Proceeds after store commission | ストアの手数料を差し引いた金額(税金は含む)。 |
| Proceeds after store commission and taxes | 手数料と税金の両方を差し引いた金額。 |
- 残りのオプションを設定します:
| トグル | オンの場合 | デフォルト |
|---|---|---|
| Report user’s currency | 購入者が支払った通貨で各売上をレポートします(USDではなく)。 | オフ |
| Send trial price | 試用開始はデフォルトでは収益として計上されません。これをオンにすると各試用にプレースホルダー価格が設定され、Trial price percentage フィールドが表示されます — サブスクリプション価格に対する割合を設定してください。60% の場合、$10 のサブスクリプションは $6 として送信されます。 | オフ |
| Exclude historical events | Adapty SDK を含むビルドをインストールする前に発生したイベントをスキップします。 | オン |
| Delay events with a future datetime | Apple はリニューアルや試用コンバージョンを事前にレポートするため、これらのイベントには将来の日付が付きます。AppsFlyer は通常その日付をイベント到着日に置き換えます。これをオンにすると、各イベントをその日付まで保留します — リニューアルが誤った日に記録されるを参照してください。 | オフ |
-
Events names セクションで個々のイベントの名前を変更または無効化します — イベント名を参照してください。
-
Save をクリックします。
サンドボックスデータを本番環境から分離する
テスト購入が実際の数値に混入しないよう、テスト購入は別のAppsFlyerアプリに送信してください。開発ビルド用に2つ目のアプリを登録し、そのトークンを各プラットフォームセクションの Sandbox フィールドに貼り付けます。
Adaptyはすべてのトランザクションを環境ごとに振り分けます。本番の購入は Production にトークンが設定されたアプリへ、テスト購入は Sandbox のアプリへルーティングされます。すべてを1つのアプリにまとめて計測したい場合は、同じトークンを両方のフィールドに貼り付けてください。
App Store のレビューや TestFlight での購入はサンドボックストランザクションです。本番ビルド上で実行されても同様です。Adapty はこれらの購入を Sandbox キーとともに送信します。
サンドボックスのトランザクションはすべてのアナリティクスチャートから除外されます。 個々のプロファイルページやイベントフィードには引き続き表示されます。
アプリのコードを設定する
- AppsFlyer SDK にコンバージョンコールバックを登録します。iOS では
AppsFlyerLibDelegateプロトコルを実装し、Android ではAppsFlyerConversionListenerインターフェース、Unity ではIAppsFlyerConversionDataインターフェースを実装してください。React Native と Flutter では、onInstallConversionDataメソッドにハンドラーを渡します。 - AppsFlyer がそのコールバックを呼び出すまで待ちます。AppsFlyer は自社のサーバー側でインストールのアトリビューションを行うため、結果はアプリ起動時ではなく非同期で届きます。SDK はその後のセッションごとにコールバックを再度呼び出します。
- コールバック内で
getAppsFlyerUIDを使ってユーザーの AppsFlyer ID を取得し、setIntegrationIdentifier()で Adapty に渡します。Adapty のイベントが正しい AppsFlyer ユーザーに届くのは、この値が設定されている場合に限られます。 - 同じコールバック内で、
updateAttribution()を使って AppsFlyer のアトリビューションデータを Adapty に渡します。これにより、どのキャンペーンがそのインストールをもたらしたかを Adapty に伝えられます。iOS および Android SDK 4.1 以降では、このメソッドはupdateExternalAttribution()という名前になっています。 - ステップ 3・4 と並行して実行するのではなく、
Adapty.identify()を await してください。Adapty はアクティベーション時に匿名プロファイルを作成し、identify()が解決すると識別済みプロファイルに切り替わります。この切り替え中に設定したappsflyer_idは、切り替え後に引き継がれないことがあります。
完全なシーケンスについては、iOS、Android、React Native、Flutter、Unity、Capacitor、Kotlin Multiplatform の各 SDK における呼び出し順序をご参照ください。
サードパーティSDKはユーザーIDを非同期で生成します。Adapty.activate() の実行時にIDがまだ準備できていない場合があります。Customer User ID がこれらのSDKのいずれかから取得される場合は、IDなしで Adapty.activate() を呼び出してください。IDが取得できたら、setIntegrationIdentifier() を呼び出し、次にCUIDで identify() を呼び出してください。
インテグレーションを確認する
- サンドボックス購入をトリガーし、アプリのEvent Feedを開きます。すべての配信試行がそこに表示されます。失敗した試行に対するAppsFlyerのレスポンスを確認するには、その行にカーソルを合わせてください。
- AppsFlyerで Settings > SDK Integration Tests > Live Events を開き、テストデバイスを選択します。Live Eventsには、AppsFlyerの Activity ダッシュボードに届くよりずっと前に、S2Sイベントがリアルタイムで表示されます。
- アプリの Activity ダッシュボードを開き、イベント、収益、メディアソースを確認します。S2Sイベントがこのダッシュボードに反映されるまで約1時間かかる場合があります。
AdaptyのイベントはアプリのAppsFlyer SDKデバッグログには表示されません。AdaptyはAdapty自身のサーバーからイベントを送信するため、アプリを経由することがありません。ローカルログが空であっても、インテグレーションの状態については何も示しません。
AppsFlyer イベント構造
Adapty は、イベントごとに https://api3.appsflyer.com/inappevent/{app_id} へ POST リクエストを1件送信し、authentication ヘッダーに S2S トークンを含めます。API 2 の場合は https://api2.appsflyer.com/inappevent/{app_id} を使用します。
{
"appsflyer_id": "1699887556000-6192770",
"eventName": "af_subscribe",
"eventTime": "2026-03-01 12:00:00",
"eventValue": "{\"af_content_id\":\"yearly.premium.6999\",\"af_order_id\":\"GPA.3383-4699-1373-07113\",\"store_country\":\"US\",\"profile_country\":\"US\",\"af_content_type\":\"in_app\",\"af_revenue\":\"9.9900\",\"af_currency\":\"USD\",\"af_quantity\":\"1\"}",
"os": "17.0.1",
"bundleIdentifier": "com.example.app",
"customer_user_id": "user_12345",
"eventCurrency": "USD",
"ip": "192.168.100.1",
"advertising_id": "00000000-0000-0000-0000-000000000000",
"idfa": "00000000-0000-0000-0000-000000000000",
"idfv": "00000000-0000-0000-0000-000000000000",
"att": "3"
}
| パラメータ | 型 | 説明 |
|---|---|---|
appsflyer_id | String | アプリが setIntegrationIdentifier に渡した AppsFlyer ID。AppsFlyer はこの値を使ってイベントをインストールに紐付けます。 |
eventName | String | Events names セクションに記載されている名前 — イベント名を参照。 |
eventTime | String | イベントの発生日時(UTC、YYYY-MM-DD HH:MM:SS)。26時間より古いイベントの場合、Adapty は現在時刻に置き換えます — 古いイベントが今日の日付で届くを参照。 |
eventValue | String | 以下のテーブルに記載されたフィールドを JSON エンコードした文字列。 |
os | String | ユーザーのデバイスの OS バージョン。 |
bundleIdentifier | String | iOS のアプリのバンドル ID、または Android のパッケージ名。 |
customer_user_id | String | ユーザーの Customer User ID。 |
eventCurrency | String | ISO 4217 通貨コード(例:USD)。 |
ip | String | ユーザーの IP アドレス。 |
advertising_id | String | Android のみ。 Google Advertising ID。 |
idfa | String | iOS のみ。 広告主向け ID(IDFA)。 |
idfv | String | iOS のみ。 ベンダー向け ID(IDFV)。 |
att | String | iOS のみ。 App Tracking Transparency のステータス(0 ~ 3)。値がない場合、Adapty は 0 を送信します。 |
eventValue には購入情報が格納されています。最後の4つのパラメーターは、収益を伴うイベントにのみ表示されます:
| パラメーター | タイプ | 説明 |
|---|---|---|
af_content_id | String | ストアのプロダクトID。 |
af_order_id | String | オリジナルのトランザクションID。 |
store_country | String | ユーザーのストアアカウントの国。 |
profile_country | String | AdaptyがユーザーのIPアドレスから導出した国。 |
af_content_type | String | 常に in_app。 |
af_revenue | String | 収益金額(小数点以下4桁)。返金時はマイナス値。 |
af_currency | String | af_revenue の通貨。 |
af_quantity | String | 常に 1。 |
イベント名
Adapty はデフォルトで、収益に関連するイベントを独自のイベント名でカスタムイベントとして送信するのではなく、AppsFlyer の標準イベント名にマッピングします。広告ネットワークにイベントを転送する場合、ネットワークはすでに認識している標準名に基づいて処理を行うため、各イベントのマッピングを独自に定義する手間が省けます。
| Adapty イベント | デフォルトの AppsFlyer 名 |
|---|---|
| Subscription started | af_subscribe |
| Subscription renewed | af_subscribe |
| Trial converted | af_subscribe |
| Trial started | af_start_trial |
| Non-subscription purchase | af_purchase |
その他の Adapty イベントはそれぞれ固有の名前を保持します(例:subscription_refunded)。AppsFlyer インテグレーションページの Events names セクションで、イベント名を変更したり、不要なイベントをオフにしたりできます。Adapty が送信できるイベントの全一覧については、イベントを参照してください。
制限事項
appsflyer_idのないプロファイルはイベントを生成しません。 AppsFlyer はイベントをそのIDを生成したインストールに紐付け、そのインストールからキャンペーン情報を読み取ります。IDがない場合、Adapty は何も送信せず、Event Feed ではそのようなプロファイルにフラグが立ちます。詳細は AppsFlyerにイベントが届かない を参照してください。- 過去データのバックフィルはありません。 Adapty はインテグレーションを有効にした時点からイベントを転送します。それ以前の購入は AppsFlyer に送信されません。
- AppsFlyer のローデータではデバイス情報が空になります。 S2S イベントにはリクエストに含まれる情報しか含まれません。Device Model、Device Category、Language、Operator、WIFI、App Version、App Name には S2S パラメーターが存在しないため、これらの項目は入力できません。
トラブルシューティング
- イベントが AppsFlyer に届かない
- 購入がオーガニックとして表示される
- 古いイベントが今日の日付で届く
- リニューアルが間違った日に記録される
- AppsFlyer の収益が Adapty Analytics と一致しない
- イベントフィードに
Failed to authenticateが表示される access_level_updatedがイベントフィードで失敗として表示される
AppsFlyer にイベントが届かない
まず Event Feed を開いてください。配信に失敗した場合は、AppsFlyer が返したエラーが表示されます。多くの場合、以下の原因が該当します:
- プロファイルに
appsflyer_idがありません。 アプリがgetAppsFlyerUIDを呼び出し、その結果をすべてのプラットフォームでsetIntegrationIdentifierに渡していることを確認してください — アプリコードを設定するをご覧ください。 - そのプラットフォームのアプリ ID が未設定です。 AppsFlyer は各アプリを ID で識別するため、ID がない場合 Adapty は何も送信しません。iOS のイベントにはインテグレーションページの iOS App ID が必要で、Android のイベントには App settings > Android SDK のパッケージ名が必要です — Adapty を設定するをご覧ください。
- 購入がサンドボックストランザクションで、Sandbox キーが空です。 サンドボックスデータを本番環境から分離するをご覧ください。
- イベントが無効になっています — Events names セクションで確認してください。
配信が成功しても、AppsFlyer がそのイベントを保持するとは限りません。AppsFlyer は正しい形式のリクエストに対しては 200 OK を返しますが、appsflyer_id が実際のインストールと一致しないイベントは破棄されます。
購入がオーガニックとして表示される
各 appsflyer_id は 1 つのインストールを識別し、その ID を持つすべてのイベントはそのインストールのアトリビューション(インストールを生み出したキャンペーン、またはオーガニックインストールの場合はなし)を継承します。AppsFlyer が新しいインストールをアトリビュートするには 20〜30 秒以上かかります。それ以前に届いたイベントは継承すべきアトリビューションが存在しないため、AppsFlyer はそれを未アトリビュートのオーガニックとしてマークします。
アプリ起動直後の購入がオーガニックとして報告されるのは想定内です。アプリ起動から数秒以内に開始されるトライアルがこれに該当します。これを回避するには、AppsFlyer がインストールの処理を完了するのに十分な時間だけ、ペイウォールの表示を遅らせてください。
すべてのイベントが(初回起動時の購入だけでなく)オーガニックと表示される場合、原因はタイミングではなくアトリビューションにあります。別のソースが先にそのプロファイルを取得している可能性があります。詳しくは単一のアトリビューションソースを選択するを参照してください。
古いイベントが今日の日付で届く
イベントが遅れて Adapty に届く原因は2つあります:
- App Store Connect で App Store Server Notifications が Delayed と表示されている場合、Apple は通知をキューに入れます。更新の通知が実際の発生からかなり後に Adapty へ届くことがあります — App Store Server Notifications が「Delayed」と表示されるを参照してください。
- Exclude historical events がオフの場合、過去日付のイベントがそのまま通過します。
AppsFlyer は古いタイムスタンプを受け付けません。イベント処理の一貫性を確保するため、Adapty は26時間以上前のイベントの eventTime を現在時刻に置き換えます。この書き換えを無効にすることはできません。
更新が誤った日付に記録される
Apple はサブスクリプションの更新やトライアルの変換を実際に発生する前に Adapty へ通知し、Adapty はそれを受け取り次第、未来の eventTime をそのまま転送します。AppsFlyer が未来のタイムスタンプを保持するのは、それが受信日と同じ日付の場合のみです。明日の日付が付いた更新イベントは、受信した今日の時刻に書き換えられます。
integration settingsのDelay events with a future datetimeをオンにしてください。これにより、Adaptyは各イベントをその時刻まで保留するため、AppsFlyer にはAppleが通知した日付が記録されます。詳しくは将来の日付のイベントタイムスタンプを参照してください。
AppsFlyer の収益が Adapty Analytics と一致しない場合
Adapty と AppsFlyer では、同じ購入でも集計方法が異なります。この違いが、ほぼすべての不一致の原因となっています。
- AppsFlyerの概要ダッシュボードは収益をインストール日でグループ化しますが、Adaptyのチャートはイベント日でグループ化します。 AppsFlyerでは、1月のインストールによる7月の更新は1月に計上されます。そのダッシュボードとAdaptyのコホート分析を比較してください。こちらもインストール月で収益をグループ化します。AppsFlyerのローデータレポートはイベント日でグループ化されるため、こちらをAdaptyのチャートと比較してください。
appsflyer_idを持たないプロファイルからの購入はAppsFlyerに届きません。 それらはAdapty Analyticsに残ります。イベントがAppsFlyerに届かないを参照してください。- AppsFlyerにはAdaptyで選択した収益データのみが表示されます。 How the revenue data should be sendの設定により、Adaptyが総収益、手取り額、または純収益のどれを送信するかが決まります。それを別のAdapty Analyticsのビューと比較すると、手数料、税金、またはその両方に相当する差異が生じます。
- Adaptyはアプリのレポートタイムゾーンを使用しますが、AppsFlyerはUTCで受信します。 App Settingsで何を設定していても、インテグレーションには常にUTCのタイムスタンプが送信されます。UTCで7月1日23:30の購入は、レポートタイムゾーンが+02:00の場合、Adaptyでは7月2日として記録されます。
- AppsFlyerに過去のイベントが存在しません。 原因として2つ考えられます。Exclude historical eventsがオンの場合、ユーザーのAppsFlyerの履歴はAdaptyビルドの初回起動時から始まります。また、インテグレーションを有効にする前にAdaptyが処理したイベントは、バックフィルされることはありません。
- サンドボックスの購入は、Sandboxキーで指定されたAppsFlyerアプリに届きます。 それが本番アプリの場合、テスト購入がその収益を水増しします。サンドボックスデータを本番環境に混入させないを参照してください。
- インテグレーションでオフにしたイベントはAppsFlyerに届きません。 Adapty Analyticsでは引き続きカウントされます。Events namesセクションを確認してください。
subscription_renewedをオフにすると、定着したアプリの収益のほとんどが失われます。
Event Feed での Failed to authenticate
AppsFlyer は、APIバージョンに合わない認証情報を拒否します。API 2 は Dev キーを必要とし、API 3 は S2S トークンを必要とします。キーを変更せずにバージョンを切り替えると、すべてのイベントでこのエラーが発生します。
AppsFlyer Security Center で新しいトークンを作成し、S2S key フィールドに貼り付けるか、AppsFlyer S2S API 2 から 3 への切り替えの手順に従ってください。
Event Feed で access_level_updated が失敗と表示される
access_level_updated は webhook 専用イベントです。Adapty はこのインテグレーションにこのイベントを送信しません。ただし、Adapty は有効なすべてのインテグレーションに対して結果を記録するため、サポートされていないイベントは失敗として表示されます。