AppsFlyer
Adapty échange des données avec AppsFlyer dans les deux sens. AppsFlyer indique à Adapty quelle campagne a amené chaque utilisateur. Adapty indique à AppsFlyer ce que cet utilisateur a payé — achats, renouvellements, essais et remboursements, avec les détails de revenus et de produits associés.
- Visualisez l’ensemble du cycle de vie de l’abonnement, pas seulement le premier achat. Les renouvellements et les conversions d’essai sont des événements store, sans session d’application pour que le SDK côté client d’AppsFlyer puisse les signaler. Adapty reçoit les événements d’abonnement côté serveur et les transmet à AppsFlyer, de sorte que les chiffres de campagne continuent de se mettre à jour bien après l’installation initiale. Les remboursements suivent le même chemin, et AppsFlyer les déduit des revenus de campagne.
- Optimisez vos campagnes publicitaires avec les données d’événements d’abonnement. AppsFlyer relaie les événements d’achats intégrés depuis Adapty vers vos réseaux publicitaires sous forme de postbacks. Les services qui gèrent votre budget publicitaire peuvent ainsi optimiser sur ce que les utilisateurs ont réellement payé.
- Filtrez les analyses Adapty par campagne. Adapty enregistre l’attribution AppsFlyer sur chaque profil, jusqu’au niveau du groupe d’annonces et de la création, et les graphiques d’abonnement peuvent être filtrés par ces données.
- Affichez un paywall différent par campagne. Les segments Adapty filtrent sur les mêmes champs d’attribution — campagne, groupe d’annonces et création. Utilisez un segment comme audience pour faire correspondre le paywall à l’annonce qui a amené l’utilisateur.
Votre compte Adapty inclut déjà deux outils pour les campagnes payantes. Adapty Ads Manager gère vos campagnes Apple Ads ; Adapty Attribution couvre Meta Ads et TikTok. Les deux reportent le ROAS et la LTV directement depuis vos données d’achat Adapty, et tous deux sont gratuits au démarrage — consultez les tarifs.
Fonctionnement de l’intégration
Adapty reçoit les données d’attribution d’AppsFlyer et lui renvoie les événements d’abonnement. Les deux dépendent d’une seule valeur : l’AppsFlyer ID, une chaîne générée par AppsFlyer au premier lancement de votre application.
- Quand l’utilisateur installe votre app, le SDK AppsFlyer lui attribue un identifiant unique.
- Votre app transmet cet identifiant à Adapty, qui le stocke dans le profil de l’utilisateur sous la clé
appsflyer_id. - Votre app transmet également les données d’attribution AppsFlyer à Adapty, qui les enregistre sur le même profil.
- Plus tard, quand l’utilisateur déclenche un événement d’abonnement — par exemple, il démarre un essai ou achète un produit — les serveurs d’Adapty envoient l’événement à l’API S2S d’AppsFlyer avec le même
appsflyer_id. - AppsFlyer associe cet identifiant à l’installation qu’il a déjà attribuée, de sorte que l’achat hérite de la campagne et de la source média de cette installation.
Instructions de configuration
Avant de commencer :
- Confirmez que votre offre AppsFlyer accepte les événements S2S in-app. Le forfait d’entrée de gamme Zero d’AppsFlyer ne le prend pas en charge : son API rejette chaque événement envoyé par Adapty avec un
403 Forbidden. - Intégrez le SDK AppsFlyer dans votre application. L’identifiant AppsFlyer dont dépend l’intégration n’existe qu’après l’initialisation de ce SDK. Une intégration côté serveur seule ne génère pas cet identifiant.
- Désactivez toutes les autres intégrations d’attribution. Adapty n’accepte qu’une seule source d’attribution par profil et ne peut pas écraser une valeur existante. Sur iOS, l’attribution Apple Ads non organique est toujours prioritaire — consultez Sélectionner une source d’attribution unique.
Créer un token S2S dans AppsFlyer
Adapty s’authentifie auprès de l’API S2S d’AppsFlyer avec un token que vous créez. Seuls les admins AppsFlyer peuvent accéder à la page Tokens, demandez donc à l’un d’entre eux de créer le token si votre compte n’est pas admin. Passez directement à Configurer Adapty si vous en avez déjà un.
-
Connectez-vous à AppsFlyer.
-
Cliquez sur votre nom de compte en haut à droite et ouvrez le Security center.
-
Sur la page Manage your account security, trouvez la carte AppsFlyer API and S2S tokens et cliquez sur Manage your AppsFlyer tokens. La page Tokens s’ouvre.
-
Cliquez sur New token.
-
Saisissez un Name pour le token. Ce nom est uniquement pour votre référence et peut être modifié ultérieurement.
-
Sélectionnez le type de token S2S. Tout autre type rompra l’intégration.
-
Cliquez sur Create new token.
AppsFlyer autorise deux tokens par type. Si votre compte en possède déjà deux, réutilisez l’un d’eux.
-
Retrouvez votre nouveau token dans la liste. AppsFlyer masque la valeur, alors cliquez sur l’icône de copie dans la colonne Token pour la récupérer.
Configurer Adapty
- Ouvrez Integrations > AppsFlyer dans l’Adapty Dashboard.
- Activez le bouton AppsFlyer.
- Si vous avez déjà connecté votre app à l’App Store, le champ iOS App ID est automatiquement renseigné avec l’identifiant Apple numérique de votre app. S’il est vide, connectez d’abord votre compte App Store. Android ne nécessite pas de champ équivalent.
- Collez le token S2S dans le champ Production de S2S key for iOS, S2S key for Android, ou des deux.
- Renseignez les champs Sandbox pour que les achats de test ne viennent pas polluer vos données de production — voir Garder les données sandbox hors de la production.
- Sous How the revenue data should be send, choisissez quelle valeur de revenus Adapty envoie en tant que
af_revenue. Les trois options correspondent aux vues de revenus d’Adapty Analytics, votre choix détermine donc la vue avec laquelle vos chiffres AppsFlyer doivent correspondre.
| Option | What Adapty sends |
|---|---|
| Gross revenue | Le montant total payé par l’acheteur, avant commission et taxes. Par défaut. |
| Proceeds after store commission | Le montant moins la commission du store, taxes comprises. |
| Proceeds after store commission and taxes | Le montant moins les deux. |
- Configurez les options restantes :
| Bascule | Quand activé | Par défaut |
|---|---|---|
| Report user’s currency | Adapty rapporte chaque vente dans la devise utilisée par l’acheteur, plutôt qu’en USD. | Off |
| Send trial price | Les démarrages d’essai ne génèrent aucun revenu autrement. Activez cette option pour attribuer un prix fictif à chacun ; un champ Trial price percentage apparaît alors — définissez-le à la part du prix d’abonnement que doit rapporter un essai. À 60%, un abonnement à 10 $ envoie 6 $. | Off |
| Exclude historical events | Adapty ignore les événements survenus avant que l’utilisateur ait installé une version de l’application contenant le SDK Adapty. | On |
| Delay events with a future datetime | Apple signale les renouvellements et les conversions d’essai à l’avance, ce qui donne à ces événements une date future. AppsFlyer remplace généralement cette date par celle d’arrivée de l’événement. Activez cette option pour retenir chaque événement jusqu’à sa date — voir Les renouvellements arrivent au mauvais jour. | Off |
-
Renommez ou désactivez des événements individuels dans la section Events names — voir Noms des événements.
-
Cliquez sur Save.
Exclure les données sandbox de la production
Pour éviter que les achats de test ne se retrouvent dans vos chiffres réels, envoyez-les vers une application AppsFlyer distincte. Enregistrez une deuxième application pour vos builds de développement, puis collez son token dans le champ Sandbox de chaque section de plateforme.
Adapty achemine chaque transaction selon son environnement — les achats réels vers l’application dont le token est dans Production, et les achats de test vers celle dans Sandbox. Pour tout regrouper dans une seule application, collez simplement le même token dans les deux champs.
Les achats effectués lors des revues App Store et via TestFlight sont des transactions sandbox, même si elles s’exécutent sur une version de production. Adapty envoie ces achats avec la clé Sandbox.
Les transactions sandbox sont exclues de tous les graphiques analytiques. Elles apparaissent tout de même sur les pages de profil individuelles et dans le flux d’événements.
Configurer le code de votre application
- Enregistrez un callback de conversion auprès du SDK AppsFlyer. Sur iOS, implémentez le protocole
AppsFlyerLibDelegate; sur Android, l’interfaceAppsFlyerConversionListener; sur Unity, l’interfaceIAppsFlyerConversionData. Sur React Native et Flutter, passez un handler à la méthodeonInstallConversionDataà la place. - Attendez qu’AppsFlyer appelle ce callback. AppsFlyer attribue chaque installation sur ses propres serveurs, donc le résultat parvient à votre application de manière asynchrone plutôt qu’au lancement. Le SDK rappelle le callback à chaque session ultérieure.
- Dans le callback, récupérez l’identifiant AppsFlyer de l’utilisateur avec
getAppsFlyerUIDet transmettez-le à Adapty avecsetIntegrationIdentifier(). Les événements d’Adapty n’atteignent le bon utilisateur AppsFlyer qu’avec cette valeur. - Dans le même callback, transmettez les données d’attribution d’AppsFlyer à Adapty avec
updateAttribution(). Cela indique à Adapty quelle campagne a généré l’installation. Sur iOS et Android SDK 4.1 et versions ultérieures, la méthode s’appelleupdateExternalAttribution(). - Attendez la résolution de
Adapty.identify()plutôt que de l’exécuter en parallèle des étapes 3 et 4. Adapty crée un profil anonyme à l’activation, puis bascule vers le profil identifié une fois queidentify()est résolu. Unappsflyer_iddéfini pendant ce basculement ne survit pas toujours à celui-ci.
Pour la séquence complète, voir l’ordre des appels dans les SDK iOS, Android, React Native, Flutter, Unity, Capacitor et Kotlin Multiplatform.
Les SDK tiers génèrent des identifiants utilisateur de manière asynchrone. L’identifiant peut ne pas être disponible au moment où Adapty.activate() s’exécute. Si votre Customer User ID provient de l’un de ces SDK, appelez Adapty.activate() sans lui. Dès que l’identifiant est disponible, appelez setIntegrationIdentifier(), puis identify() avec le CUID.
Vérifier l’intégration
- Déclenchez un achat sandbox et ouvrez le Event Feed de votre application. Chaque tentative de livraison y apparaît. Pour lire la réponse d’AppsFlyer à une tentative échouée, survolez la ligne correspondante.
- Dans AppsFlyer, ouvrez Settings > SDK Integration Tests > Live Events et sélectionnez votre appareil de test. Live Events liste les événements S2S dès leur arrivée, bien avant qu’ils n’atteignent le tableau de bord Activity d’AppsFlyer.
- Ouvrez le tableau de bord Activity de votre application et confirmez l’événement, ses revenus et sa source média. Comptez environ une heure — les événements S2S n’atteignent pas ce tableau de bord immédiatement.
Les événements d’Adapty n’apparaissent jamais dans le journal de débogage du SDK AppsFlyer de votre application. Adapty les envoie depuis ses propres serveurs, ils ne transitent donc jamais par votre application. Un journal local vide ne dit rien sur l’intégration.
Structure des événements AppsFlyer
Adapty envoie une requête POST par événement vers https://api3.appsflyer.com/inappevent/{app_id}, avec le token S2S dans l’en-tête authentication. L’API 2 utilise 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"
}
| Paramètre | Type | Description |
|---|---|---|
appsflyer_id | String | L’identifiant AppsFlyer que votre application a transmis à setIntegrationIdentifier. AppsFlyer associe l’événement à une installation grâce à cette valeur. |
eventName | String | Le nom provenant de la section Events names — voir Noms d’événements. |
eventTime | String | Horodatage de l’événement (UTC, YYYY-MM-DD HH:MM:SS). Adapty le remplace par l’heure actuelle pour les événements datant de plus de 26 heures — voir Les anciens événements arrivent avec la date du jour. |
eventValue | String | Une chaîne JSON encodée contenant les champs du tableau ci-dessous. |
os | String | La version du système d’exploitation de l’appareil de l’utilisateur. |
bundleIdentifier | String | L’identifiant de bundle de l’application sur iOS, ou le nom de package sur Android. |
customer_user_id | String | L’identifiant utilisateur client (Customer User ID) de l’utilisateur. |
eventCurrency | String | Le code de devise ISO 4217, par exemple USD. |
ip | String | L’adresse IP de l’utilisateur. |
advertising_id | String | Android uniquement. L’identifiant publicitaire Google (Google Advertising ID). |
idfa | String | iOS uniquement. L’identifiant pour les annonceurs (ID for Advertisers). |
idfv | String | iOS uniquement. L’identifiant pour les vendeurs (ID for Vendors). |
att | String | iOS uniquement. Le statut App Tracking Transparency, de 0 à 3. Adapty envoie 0 lorsqu’il ne dispose d’aucune valeur. |
eventValue contient l’achat lui-même. Les quatre derniers paramètres n’apparaissent que sur les événements qui génèrent des revenus :
| Paramètre | Type | Description |
|---|---|---|
af_content_id | String | L’identifiant du produit dans le store. |
af_order_id | String | L’identifiant de transaction d’origine. |
store_country | String | Le pays du compte store de l’utilisateur. |
profile_country | String | Le pays déterminé par Adapty à partir de l’adresse IP de l’utilisateur. |
af_content_type | String | Toujours in_app. |
af_revenue | String | Le montant des revenus, à 4 décimales. Négatif en cas de remboursement. |
af_currency | String | La devise de af_revenue. |
af_quantity | String | Toujours 1. |
Noms des événements
Par défaut, Adapty associe ses événements générateurs de revenus aux noms d’événements standard d’AppsFlyer, plutôt que de les envoyer sous ses propres noms en tant qu’événements personnalisés. C’est important si vous transmettez des événements aux réseaux publicitaires : un réseau réagit aux noms standard qu’il reconnaît déjà, ce qui vous évite d’avoir à créer un mappage pour chacun d’eux.
| Événement Adapty | Nom AppsFlyer par défaut |
|---|---|
| Subscription started | af_subscribe |
| Subscription renewed | af_subscribe |
| Trial converted | af_subscribe |
| Trial started | af_start_trial |
| Non-subscription purchase | af_purchase |
Tous les autres événements Adapty conservent leur propre nom, par exemple subscription_refunded. Dans la section Events names de la page d’intégration AppsFlyer, renommez les événements ou désactivez ceux dont vous n’avez pas besoin. Pour la liste complète de ce qu’Adapty peut envoyer, consultez Événements.
Limitations
- Un profil sans
appsflyer_idne génère aucun événement. AppsFlyer associe un événement à l’installation qui a généré l’ID, et lit la campagne depuis cette installation. Adapty n’envoie rien sans cet identifiant, et l’Event Feed signale ces profils — voir Les événements n’atteignent pas AppsFlyer. - Pas de renvoi des données historiques. Adapty transmet les événements à partir du moment où vous activez l’intégration. Les achats passés n’atteignent jamais AppsFlyer.
- Les détails de l’appareil restent vides dans les données brutes AppsFlyer. Un événement S2S ne contient que ce que la requête transporte. Device Model, Device Category, Language, Operator, WIFI, App Version et App Name n’ont pas de paramètre S2S, donc rien de ce qui est envoyé de cette façon ne peut les renseigner.
Résolution des problèmes
- Les événements n’arrivent pas dans AppsFlyer
- Les achats apparaissent comme organiques
- Les anciens événements arrivent avec la date d’aujourd’hui
- Les renouvellements tombent au mauvais jour
- Les revenus dans AppsFlyer ne correspondent pas à Adapty Analytics
Failed to authenticatedans l’Event Feedaccess_level_updatedapparaît comme échoué dans l’Event Feed
Les événements n’arrivent pas dans AppsFlyer
Ouvrez d’abord l’Event Feed. Une livraison échouée affiche l’erreur renvoyée par AppsFlyer. Ces causes en expliquent la plupart :
- Le profil n’a pas d’
appsflyer_id. Vérifiez que votre application appellegetAppsFlyerUIDet passe le résultat àsetIntegrationIdentifiersur chaque plateforme — voir Configurer le code de votre application. - L’identifiant de l’application pour cette plateforme est manquant. AppsFlyer identifie chaque application par son ID, donc Adapty n’envoie rien sans lui. Les événements iOS nécessitent un iOS App ID sur la page d’intégration ; les événements Android nécessitent le nom de package dans App settings > Android SDK — voir Configurer Adapty.
- L’achat est une transaction sandbox et la clé Sandbox est vide. Voir Garder les données sandbox hors de la production.
- L’événement est désactivé dans la section Events names.
Une livraison réussie ne garantit pas qu’AppsFlyer conserve l’événement. AppsFlyer renvoie 200 OK pour toute requête bien formée, puis supprime les événements dont l’appsflyer_id ne correspond à aucune installation réelle.
Les achats apparaissent comme organiques
Chaque appsflyer_id identifie une installation, et chaque événement portant cet identifiant hérite de l’attribution de cette installation — la campagne qui l’a générée, ou aucune si l’installation était organique. AppsFlyer a besoin de 20 à 30 secondes ou plus pour attribuer une nouvelle installation. Un événement qui arrive avant ce délai n’a aucune attribution à hériter, et AppsFlyer le marque comme organique non attribué.
Attendez-vous à ce que les achats effectués au premier lancement soient signalés comme organiques — des essais qui démarrent dans les secondes suivant le lancement de l’application. Pour l’éviter, retardez suffisamment votre paywall pour qu’AppsFlyer ait le temps de terminer le traitement de l’installation.
Si chaque événement apparaît comme organique, et pas seulement l’achat occasionnel au premier lancement, la cause est l’attribution plutôt que le timing : une autre source a revendiqué le profil en premier. Voir Sélectionner une source d’attribution unique.
Les anciens événements arrivent avec la date d’aujourd’hui
Les événements peuvent parvenir à Adapty en retard pour deux raisons :
- Lorsque App Store Server Notifications affiche Delayed dans App Store Connect, Apple met ses notifications en file d’attente. Un renouvellement parvient alors à Adapty bien après qu’il se soit produit — voir App Store Server Notifications affiche « Delayed ».
- Les événements antidatés sont transmis dès que l’option Exclude historical events est désactivée.
AppsFlyer n’accepte pas les horodatages anciens de ce type. Pour garantir un traitement cohérent des événements, Adapty remplace eventTime par l’heure actuelle pour tout événement datant de plus de 26 heures. Cette réécriture ne peut pas être désactivée.
Les renouvellements sont enregistrés au mauvais jour
Apple notifie Adapty des renouvellements et des conversions d’essai avant qu’ils ne se produisent, et Adapty les transmet immédiatement avec l’eventTime futur inchangé. AppsFlyer conserve un horodatage futur uniquement s’il tombe le jour de réception — un renouvellement daté de demain se voit attribuer l’heure d’arrivée d’aujourd’hui à la place.
Activez Delay events with a future datetime dans les paramètres d’intégration. Adapty retient alors chaque événement jusqu’à sa date d’échéance, afin qu’AppsFlyer enregistre la date annoncée par Apple. Voir Horodatages d’événements avec des dates futures.
Les revenus dans AppsFlyer ne correspondent pas à Adapty Analytics
Adapty et AppsFlyer comptabilisent les mêmes achats de manière différente. Ces différences expliquent la quasi-totalité des écarts constatés.
- Le tableau de bord Overview d’AppsFlyer regroupe les revenus par date d’installation ; les graphiques d’Adapty les regroupent par date d’événement. Dans AppsFlyer, un renouvellement de juillet issu d’une installation de janvier est comptabilisé en janvier. Comparez ce tableau de bord avec l’analyse de cohortes d’Adapty, qui regroupe également les revenus par mois d’installation. Les rapports de données brutes d’AppsFlyer regroupent par date d’événement — comparez-les plutôt avec les graphiques d’Adapty.
- Les achats issus de profils sans
appsflyer_idn’atteignent jamais AppsFlyer. Ils restent dans Adapty Analytics. Voir Les événements n’arrivent pas dans AppsFlyer. - AppsFlyer n’affiche que la donnée de revenu sélectionnée dans Adapty. Le paramètre How the revenue data should be send détermine si Adapty envoie le revenu brut, les revenus nets de commission ou le revenu net. Comparer cela avec une autre vue d’Adapty Analytics génère un écart égal à la commission, la taxe, ou les deux.
- Adapty utilise le fuseau horaire de reporting de votre application ; AppsFlyer reçoit l’heure UTC. Les intégrations reçoivent toujours des horodatages UTC, quelle que soit la valeur définie dans App Settings. Un achat à 23h30 UTC le 1er juillet apparaît le 2 juillet dans Adapty si votre fuseau horaire de reporting est +02:00.
- AppsFlyer ne dispose pas des événements historiques. Il y a deux causes probables. Avec Exclude historical events activé, l’historique AppsFlyer d’un utilisateur commence à son premier lancement d’une version intégrant Adapty. De plus, Adapty ne renseigne jamais rétroactivement les événements traités avant l’activation de l’intégration.
- Les achats sandbox sont envoyés à l’application AppsFlyer identifiée par la clé Sandbox. Si c’est l’application de production, les achats de test gonflent ses revenus. Voir Garder les données sandbox hors de la production.
- Les événements désactivés dans l’intégration n’atteignent jamais AppsFlyer. Adapty Analytics les comptabilise quand même. Vérifiez la section Events names — désactiver
subscription_renewedsupprime l’essentiel des revenus pour toute application établie.
Failed to authenticate dans le flux d’événements
AppsFlyer rejette les identifiants lorsqu’ils ne correspondent pas à la version de l’API. L’API 2 attend une Dev key ; l’API 3 attend un token S2S. Changer de version sans remplacer la clé génère cette erreur à chaque événement.
Créez un nouveau token dans l’AppsFlyer Security Center et collez-le dans les champs S2S key, ou suivez Passer de l’API AppsFlyer S2S 2 à 3.
access_level_updated s’affiche comme échoué dans le flux d’événements
access_level_updated est un événement réservé aux webhooks. Adapty ne l’envoie jamais à cette intégration. Mais Adapty enregistre un résultat pour chaque intégration activée, et un événement non pris en charge est affiché comme un échec.