---
title: "AppsFlyer"
description: "Intégrez AppsFlyer avec Adapty pour un suivi avancé de l'attribution mobile."
---

[AppsFlyer](https://www.appsflyer.com/) est une plateforme de référence pour l'attribution mobile et l'analyse marketing. C'est un service tiers qui collecte et organise les données issues des campagnes marketing, permettant aux entreprises de suivre leurs performances au même endroit.

Adapty fournit un ensemble complet de données vous permettant de suivre les [événements d'abonnement](events) depuis les stores en un seul endroit. Avec Adapty, vous pouvez facilement observer le comportement de vos abonnés, comprendre leurs préférences et utiliser ces informations pour communiquer avec eux de manière ciblée et efficace. Cette intégration vous permet donc de suivre les événements d'abonnement dans AppsFlyer et d'analyser précisément les revenus générés par vos campagnes.

L'intégration entre Adapty et AppsFlyer fonctionne de deux façons principales.

1. **Réception des données d'attribution depuis AppsFlyer**
   Une fois que vous avez [configuré l'envoi de l'attribution AppsFlyer à Adapty dans le code de votre application](appsflyer#connect-your-app-to-appsflyer), Adapty commencera à recevoir les données d'attribution d'AppsFlyer. Vous pouvez facilement consulter ces données sur la page du profil de l'utilisateur.

  <img src="/assets/shared/img/c2991f6-CleanShot_2023-08-04_at_16.29.202x.webp"
  style={{
    border: '1px solid #727272', /* border width and color */
    width: '700px', /* image width */
    display: 'block', /* for alignment */
    margin: '0 auto' /* center alignment */
  }}
/>

2. **Envoi des événements d'abonnement à AppsFlyer**
   Adapty peut envoyer tous les événements d'abonnement configurés dans votre intégration à AppsFlyer. Vous pourrez ainsi suivre ces événements depuis le tableau de bord AppsFlyer. Cette intégration est utile pour évaluer l'efficacité de vos campagnes publicitaires.

## Configurer la configuration \{#set-up-configuration\}

### Connecter Adapty à AppsFlyer \{#connect-adapty-to-appsflyer\}

Pour configurer l'intégration avec AppsFlyer :

1. Ouvrez [**Integrations** -> **AppsFlyer**](https://app.adapty.io/integrations/appsflyer) dans l'Adapty Dashboard.

2. Activez le bouton pour activer l'intégration.

3. L'étape suivante consiste à renseigner les identifiants.
   Pour iOS, trouvez l'App ID en copiant l'**Apple ID** dans App Store Connect (pour ce faire, ouvrez la page de votre application dans [App Store Connect](https://appstoreconnect.apple.com/), accédez à la page **App Information** dans la section **General**, et repérez l'**Apple ID** en bas à gauche de l'écran).
   

  <img src="/assets/shared/img/43a5cc6-apple_id.webp"
  style={{
    border: '1px solid #727272', /* border width and color */
    width: '700px', /* image width */
    display: 'block', /* for alignment */
    margin: '0 auto' /* center alignment */
  }}
/>

3.2. Collez l'**Apple ID** copié dans le champ **iOS App ID** de l'Adapty Dashboard.

  <img src="/assets/shared/img/61bff5a-appsflyer_iOS_app_id.webp"
  style={{
    border: '1px solid #727272', /* border width and color */
    width: '700px', /* image width */
    display: 'block', /* for alignment */
    margin: '0 auto' /* center alignment */
  }}
/>

:::warning

Si vous utilisez AppsFlyer API 2, vous devez passer à l'API 3, car l'ancienne version sera bientôt dépréciée par AppsFlyer. Pour ce faire, dans la liste **AppsFlyer S2S API**, sélectionnez **API 3**.

:::

5. Pour iOS et Android, ouvrez le [site AppsFlyer](https://www.appsflyer.com/home) et connectez-vous.

6. Cliquez sur **Your account name** -> **Security Center** dans le coin supérieur droit du tableau de bord.

  <img src="/assets/shared/img/1c18c50-appsflyer_security_center.webp"
  style={{
    border: '1px solid #727272', /* border width and color */
    width: '700px', /* image width */
    display: 'block', /* for alignment */
    margin: '0 auto' /* center alignment */
  }}
/>

7. Dans la fenêtre **Manage your account security**, cliquez sur le bouton **Manage your AppsFlyer API and S2S tokens**.

8. Si vous disposez déjà d'un token S2S, passez directement à l'étape 12. Sinon, cliquez sur le bouton **New token**.

  <img src="/assets/shared/img/7934920-appsflyer_new_token.webp"
  style={{
    border: '1px solid #727272', /* border width and color */
    width: '700px', /* image width */
    display: 'block', /* for alignment */
    margin: '0 auto' /* center alignment */
  }}
/>

9. Dans la fenêtre **New token**, saisissez le nom du token. Ce nom est uniquement destiné à votre usage personnel.

10. Sélectionnez **S2S** dans la liste **Choose type**.

11. Cliquez sur le bouton **Create new token** pour enregistrer le nouveau token.

12. Dans la fenêtre **Tokens**, copiez le token S2S.

13. Dans l'Adapty Dashboard, collez la clé S2S copiée dans les champs **Dev key for iOS** et **Dev key for Android**.

  <img src="/assets/shared/img/a7d1c31-appsflyer_dev_keys.webp"
  style={{
    border: '1px solid #727272', /* border width and color */
    width: '700px', /* image width */
    display: 'block', /* for alignment */
    margin: '0 auto' /* center alignment */
  }}
/>

14. Cliquez sur le bouton **Save** pour enregistrer les modifications.
    
    :::info
    
AppsFlyer ne dispose pas de mode Sandbox pour l'intégration server2server. Vous avez donc besoin d'une application/d'un compte différent dans AppsFlyer pour la Sandbox Dev Key. Si vous souhaitez envoyer des événements sandbox vers la même application, utilisez simplement la même clé pour la production et le sandbox.
    :::

Par défaut, Adapty associe certains événements aux [événements standard](https://support.appsflyer.com/hc/en-us/articles/115005544169-Rich-in-app-events-for-Android-and-iOS#event-types) d'AppsFlyer. Avec cette configuration, AppsFlyer peut ensuite transmettre les événements à chaque réseau publicitaire que vous utilisez sans configuration supplémentaire.

Une autre chose importante à noter : AppsFlyer ne prend pas en charge les événements datant de plus de 26 heures. Ainsi, si un événement a plus de 26 heures, Adapty l'enverra quand même à AppsFlyer, mais la date et l'heure de l'événement seront remplacées par l'horodatage actuel.

### Configurer les événements et les tags \{#configure-events-and-tags\}

En dessous des identifiants, vous trouverez trois groupes d'événements que vous pouvez envoyer à AppsFlyer depuis Adapty. Activez simplement ceux dont vous avez besoin. Consultez la liste complète des événements proposés par Adapty [ici](events).

  <img src="/assets/shared/img/1b0c777-CleanShot_2023-08-11_at_14.56.362x.webp"
  style={{
    border: '1px solid #727272', /* border width and color */
    width: '700px', /* image width */
    display: 'block', /* for alignment */
    margin: '0 auto' /* center alignment */
  }}
/>

Nous vous recommandons d'utiliser les noms d'événements par défaut fournis par Adapty. Vous pouvez toutefois les modifier selon vos besoins.

Adapty enverra les événements d'abonnement à AppsFlyer via une intégration serveur à serveur, vous permettant de consulter tous les événements d'abonnement dans votre tableau de bord AppsFlyer et de les associer à vos campagnes d'acquisition.

### Connectez votre application à AppsFlyer

Une fois les étapes décrites ci-dessus terminées, appelez la méthode `updateAttribution` pour enregistrer les données d'attribution, et utilisez `Adapty.setIntegrationIdentifier()` pour définir l'identifiant d'intégration.

Initialisez le SDK AppsFlyer et attendez son callback UID avant d'identifier les utilisateurs dans Adapty. Sinon, `appsflyer_id` sera associé à un profil Adapty anonyme temporaire créé lors de l'activation, et ne sera pas toujours transféré vers le profil identifié. Dans ce cas, le transfert des revenus AppsFlyer échoue silencieusement.

<Tabs groupId="current-os" queryString>
<TabItem value="swift" label="iOS (Swift)" default>

```swift showLineNumbers
class YourAppsFlyerLibDelegateImplementation {
    // Find your implementation of AppsFlyerLibDelegate 
    // and update onConversionDataSuccess method:
    func onConversionDataSuccess(_ conversionInfo: [AnyHashable : Any]) {
        let uid = AppsFlyerLib.shared().getAppsFlyerUID()
        // Adapty SDK 4.x
        Adapty.setIntegrationIdentifier(.appsflyerId(uid))
        Adapty.updateAttribution(conversionInfo, source: .appsflyer)
        // Adapty SDK 3.x
        Adapty.setIntegrationIdentifier(key: "appsflyer_id", value: uid)
        Adapty.updateAttribution(conversionInfo, source: "appsflyer")
    }
}
```
</TabItem>

<TabItem value="kotlin" label="Android (Kotlin)" default>

```kotlin showLineNumbers
val conversionListener: AppsFlyerConversionListener = object : AppsFlyerConversionListener {
    override fun onConversionDataSuccess(conversionData: Map<String, Any>) {
        val uid = AppsFlyerLib.getInstance().getAppsFlyerUID(context)
        Adapty.setIntegrationIdentifier("appsflyer_id", uid) { error ->
            if (error != null) {
                // handle the error
            }
        }
        Adapty.updateAttribution(conversionData, "appsflyer") { error ->
            if (error != null) {
                //handle the error
            }
        }
    }
}
```
</TabItem>
<TabItem value="rn" label="React Native (TS)" default>

```typescript showLineNumbers

appsFlyer.onInstallConversionData(installData => {
    appsFlyer.getAppsFlyerUID((error, networkUserId) => {
        if (error) {
            // handle the error
        }
        try {
            adapty.updateAttribution(installData, AttributionSource.AppsFlyer, networkUserId);
        } catch (error) {
            // handle the error
        }
    });
});

// ...
appsFlyer.initSdk(/*...*/);
```
</TabItem>
<TabItem value="flutter" label="Flutter (Dart)" default>

```javascript showLineNumbers

AppsflyerSdk appsflyerSdk = AppsflyerSdk(<YOUR_OPTIONS>);

appsflyerSdk.onInstallConversionData((data) async {
    try {
        final appsFlyerUID = await appsFlyerSdk.getAppsFlyerUID();
        
        await Adapty().setIntegrationIdentifier(
          key: "appsflyer_id", 
          value: appsFlyerUID,
        );
        
        await Adapty().updateAttribution(data, source: "appsflyer");
    } on AdaptyError catch (adaptyError) {
        // handle the error
    } catch (e) {
        // handle the error
    }
});

appsflyerSdk.initSdk(
    registerConversionDataCallback: true,
    registerOnAppOpenAttributionCallback: true,
    registerOnDeepLinkingCallback: true,
);
```
</TabItem>
<TabItem value="unity" label="Unity (C#)" default>

```csharp showLineNumbers
using AdaptySDK;
using AppsFlyerSDK;

// before SDK initialization
AppsFlyer.getConversionData(this.name);

// in your IAppsFlyerConversionData
void onConversionDataSuccess(string conversionData) {
    string appsFlyerId = AppsFlyer.getAppsFlyerId();
    
    Adapty.SetIntegrationIdentifier(
      "appsflyer_id", 
      appsFlyerId, 
      (error) => {
        // handle the error
    });
    
    Adapty.UpdateAttribution(
      conversionData, 
      "appsflyer",
      (error) => {
        // handle the error
    });
}
```
</TabItem>
</Tabs>

## Structure des événements \{#event-structure\}

Adapty envoie les événements sélectionnés à AppsFlyer via une requête POST avec un corps JSON vers :
- API v2 : `https://api2.appsflyer.com/inappevent/{app_id}`
- API v3 : `https://api3.appsflyer.com/inappevent/{app_id}` (recommandé)

Chaque événement est structuré comme suit :

```json
{
  "appsflyer_id": "1699887556000-6192770",
  "eventName": "subscription_renewed",
  "eventTime": "2024-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"
}
```

Where:

| Paramètre          | Type   | Description                                                                              |
|:-------------------|:-------|:-----------------------------------------------------------------------------------------|
| `appsflyer_id`     | String | L'identifiant AppsFlyer (collecté via le SDK).                                           |
| `eventName`        | String | Le nom de l'événement AppsFlyer (mappé depuis l'événement Adapty).                       |
| `eventTime`        | String | Date et heure de l'événement (UTC, au format `YYYY-MM-DD HH:MM:SS`).                     |
| `eventValue`       | String | Chaîne JSON contenant les détails de l'événement (voir ci-dessous).                      |
| `os`               | String | Version du système d'exploitation.                                                       |
| `bundleIdentifier` | String | Bundle ID / nom de package de l'application.                                             |
| `customer_user_id` | String | L'identifiant utilisateur (Customer User ID).                                            |
| `eventCurrency`    | String | Code de devise (p. ex. "USD").                                                           |
| `ip`               | String | Adresse IP de l'utilisateur.                                                             |
| `advertising_id`   | String | **Android uniquement**. Google Advertising ID.                                           |
| `idfa`             | String | **iOS uniquement**. Identifiant publicitaire (ID for Advertisers).                       |
| `idfv`             | String | **iOS uniquement**. Identifiant fournisseur (ID for Vendors).                            |
| `att`              | String | **iOS uniquement**. Statut App Tracking Transparency (p. ex. "3" pour autorisé).         |

Le paramètre `eventValue` est une chaîne encodée en JSON contenant les champs suivants :

| Paramètre         | Type   | Description                                                  |
|:------------------|:-------|:-------------------------------------------------------------|
| `af_content_id`   | String | L'ID du produit dans le store.                               |
| `af_order_id`     | String | L'ID de transaction d'origine.                               |
| `store_country`   | String | Code pays de l'utilisateur dans le store.                    |
| `profile_country` | String | Code pays basé sur l'IP de l'utilisateur.                    |
| `af_content_type` | String | Toujours `in_app` si un revenu est présent.                  |
| `af_revenue`      | String | Montant du revenu formaté à 4 décimales.                     |
| `af_currency`     | String | Code devise.                                                 |
| `af_quantity`     | String | Toujours `1` si un revenu est présent.                       |

## Dépannage \{#troubleshooting\}

### Écart de revenus \{#revenue-discrepancy\}

Si vous constatez un écart de revenus entre Adapty et AppsFlyer, cela peut être dû au fait que tous vos utilisateurs n'utilisent pas la version de l'application intégrant le SDK Adapty. Pour garantir la cohérence des données, vous pouvez forcer vos utilisateurs à mettre à jour l'application vers une version incluant le SDK Adapty.

### Données d'intégration manquantes \{#missing-integration-data\}

Si l'envoi d'événements échoue, c'est généralement dû à des données d'intégration manquantes. Pour résoudre ce problème, vérifiez les points suivants :
- Votre application a le SDK AppsFlyer installé.
- Vous appelez la méthode `getAppsFlyerUID`.

### Échec d'authentification \{#authentication-failure\}

Si vous obtenez l'erreur `Failed to authenticate` dans la console, cela peut être dû à une incompatibilité entre la version d'AppsFlyer et la version des identifiants.

Consultez le [guide de migration](switch-from-appsflyer-s2s-api-2-to-3) ou remplacez les identifiants par des identifiants valides disponibles [ici](https://hq1.appsflyer.com/security-center/api-tokens).

### `access_level_updated` apparaît comme échoué dans le flux d'événements \{#access_level_updated-shows-as-failed-in-the-event-feed\}

`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.