Atribución de ingresos publicitarios
Realice un seguimiento de los ingresos publicitarios de las plataformas de mediación y atribúyalos a las campañas de marketing específicas que llevaron a los usuarios a su aplicación, lo que permite un análisis exhaustivo del ROI.
Ad Revenue Attribution conecta los ingresos publicitarios de las aplicaciones móviles con las campañas de marketing que generaron usuarios, combinando el coste de la campaña, los ingresos dentro de la aplicación y los ingresos publicitarios en un informe unificado. Estos datos también se transmiten a las redes publicitarias para optimizar el rendimiento de las campañas.
Más información: Consulte Singular Ad Revenue Attribution FAQ para obtener información detallada sobre la metodología de atribución y las plataformas de mediación compatibles.
Cómo funciona la atribución de ingresos publicitarios
Flujo de atribución
Su plataforma de mediación comunica los datos de ingresos a nivel de impresión o a nivel de usuario a través de callbacks, que usted valida y envía a Singular para el análisis de atribución.
- Atribución de campaña: Vincula los ingresos publicitarios a las campañas específicas que adquirieron cada usuario, mostrando el verdadero ROI por campaña.
- Fuentes de datos: Los datos de ingresos proceden de su plataforma de mediación, ya sea a nivel de usuario o de impresión.
- Optimización de la red: Singular transmite los datos de ingresos a las redes publicitarias para mejorar las estrategias de segmentación y pujas.
Requisitos de implementación
Asegúrese de la exactitud de los datos antes de implementar el seguimiento de ingresos publicitarios, ya que los datos de ingresos incorrectos no se pueden corregir después de la transmisión.
Requisitos críticos:
- Códigos de moneda: Utilice códigos ISO 4217 de tres letras (USD, EUR, INR). La mayoría de las plataformas de mediación utilizan USD por defecto.
- Validación de datos: Valide siempre que los valores de los ingresos sean positivos y que los códigos de moneda no estén vacíos antes de enviarlos a Singular.
- Conversión de unidades: Algunas plataformas informan de los ingresos en micros (1.000.000 = 1,00 $). Convertir a dólares antes de enviar a Singular
Pasos de configuración
Siga estos pasos para implementar la atribución de ingresos publicitarios con su plataforma de mediación.
- Actualice el SDK: Asegúrese de que está ejecutando la última versión del SDK de Singular Flutter.
- Configure la plataforma: Habilite los informes de ingresos publicitarios en el panel de su plataforma de mediación (AdMob, AppLovin, etc.)
- Implemente retrollamadas: Añada escuchadores de eventos de ingresos desde su SDK de mediación para capturar los datos de impresión.
- Valide los datos: Compruebe que los ingresos sean superiores a 0 y que la divisa sea válida antes de reenviarlos a Singular.
- Pruebe la integración: Compruebe que los datos de ingresos aparecen en los informes de Singular en 24 horas
Integración con AdMob
Requisitos previos
Habilite los informes de ingresos publicitarios en su cuenta de AdMob e implemente el SDK de Google Mobile Ads para Flutter antes de la integración con Singular.
- Configuración de AdMob: Habilite los ingresos publicitarios a nivel de impresión en su panel de AdMob. Consulte Soporte de AdMob
- Paquete Flutter: instale el paquete google_mobile_ads. Consulte la Guía de introducción
Diferencias entre plataformas: AdMob informa de los ingresos de forma diferente según la plataforma. Android devuelve los ingresos en micros (5000 = 0,005 $), mientras que iOS devuelve valores decimales (0,005 = 0,005 $). Convierta los valores de Android dividiéndolos por 1.000.000 antes de enviarlos a Singular.
Pasos de implementación
Configure la devolución de llamada onPaidEvent al cargar anuncios para capturar los datos de ingresos de las impresiones de anuncios correctas.
- Cargar anuncio: Cree y cargue un bloque de anuncios (recompensado, intersticial, banner, etc.).
-
Establecer devolución de llamada: Asigne
onPaidEventcallback para capturarAdValuecuando el anuncio genere ingresos -
Convertir unidades: Divida
valueMicrosentre 1.000.000 para convertir a dólares. - Validar: Compruebe que los ingresos sean > 0 y que la divisa no esté vacía
-
Enviar a Singular: Llamar a
Singular.adRevenue()con los datos validados
Ejemplo de anuncio con recompensa
Capture ingresos publicitarios de anuncios de vídeo con recompensa configurando la devolución de llamada onPaidEvent una vez finalizada la carga del anuncio.
import 'package:google_mobile_ads/google_mobile_ads.dart';
import 'package:singular_flutter_sdk/singular.dart';
const String adUnitId = 'YOUR_AD_UNIT_ID';
class AdManager {
RewardedAd? _rewardedAd;
void loadRewardedAd() {
RewardedAd.load(
adUnitId: adUnitId,
request: AdRequest(),
rewardedAdLoadCallback: RewardedAdLoadCallback(
onAdLoaded: (RewardedAd ad) {
_rewardedAd = ad;
print('Rewarded ad loaded successfully');
// Set up full screen content callback
_rewardedAd?.fullScreenContentCallback = FullScreenContentCallback(
onAdShowedFullScreenContent: () {
print('Rewarded ad displayed');
},
onAdFailedToShowFullScreenContent: (AdError adError) {
print('Rewarded ad failed to show: ${adError.message}');
},
onAdDismissedFullScreenContent: () {
print('Rewarded ad dismissed');
_rewardedAd = null;
},
);
// Set up paid event callback for revenue tracking
_rewardedAd?.onPaidEvent = (AdValue adValue) {
// Convert revenue from micros to dollars
double revenue = adValue.valueMicros / 1_000_000.0;
String? currency = adValue.currencyCode;
// Validate revenue and currency before sending
if (revenue > 0 && currency != null && currency.isNotEmpty) {
final adData = {
'adPlatform': 'AdMob',
'currency': currency,
'revenue': revenue,
};
// Send ad revenue data to Singular
Singular.adRevenue(adData);
// Log for debugging
print('Ad Revenue reported: $revenue $currency');
} else {
print('Invalid ad revenue: revenue=$revenue, currency=$currency');
}
};
},
onAdFailedToLoad: (LoadAdError loadAdError) {
print('Rewarded ad failed to load: ${loadAdError.message}');
},
),
);
}
void showRewardedAd() {
if (_rewardedAd != null) {
_rewardedAd!.show(
onUserEarnedReward: (AdWithoutView ad, RewardItem reward) {
print('User earned reward: ${reward.amount} ${reward.type}');
},
);
} else {
print('Rewarded ad not ready');
}
}
}
Ejemplo de anuncio intersticial
Realice un seguimiento de los ingresos de los anuncios intersticiales utilizando el mismo patrón onPaidEvent.
import 'package:google_mobile_ads/google_mobile_ads.dart';
import 'package:singular_flutter_sdk/singular.dart';
const String interstitialAdUnitId = 'YOUR_INTERSTITIAL_AD_UNIT_ID';
class InterstitialAdManager {
InterstitialAd? _interstitialAd;
void loadInterstitialAd() {
InterstitialAd.load(
adUnitId: interstitialAdUnitId,
request: AdRequest(),
adLoadCallback: InterstitialAdLoadCallback(
onAdLoaded: (InterstitialAd ad) {
_interstitialAd = ad;
print('Interstitial ad loaded');
// Set paid event callback
_interstitialAd?.onPaidEvent = (AdValue adValue) {
double revenue = adValue.valueMicros / 1_000_000.0;
String? currency = adValue.currencyCode;
if (revenue > 0 && currency != null && currency.isNotEmpty) {
Singular.adRevenue({
'adPlatform': 'AdMob',
'currency': currency,
'revenue': revenue,
});
print('Interstitial revenue: $revenue $currency');
}
};
// Set full screen callback
_interstitialAd?.fullScreenContentCallback = FullScreenContentCallback(
onAdDismissedFullScreenContent: () {
_interstitialAd = null;
loadInterstitialAd(); // Load next ad
},
);
},
onAdFailedToLoad: (LoadAdError error) {
print('Interstitial ad failed to load: ${error.message}');
},
),
);
}
void showInterstitialAd() {
_interstitialAd?.show();
}
}
Ejemplo de anuncio de banner
Realice un seguimiento de los ingresos procedentes de los banners publicitarios mostrados en su interfaz de usuario de Flutter.
import 'package:flutter/material.dart';
import 'package:google_mobile_ads/google_mobile_ads.dart';
import 'package:singular_flutter_sdk/singular.dart';
const String bannerAdUnitId = 'YOUR_BANNER_AD_UNIT_ID';
class BannerAdWidget extends StatefulWidget {
@override
_BannerAdWidgetState createState() => _BannerAdWidgetState();
}
class _BannerAdWidgetState extends State<BannerAdWidget> {
BannerAd? _bannerAd;
bool _isBannerAdReady = false;
@override
void initState() {
super.initState();
_loadBannerAd();
}
void _loadBannerAd() {
_bannerAd = BannerAd(
adUnitId: bannerAdUnitId,
size: AdSize.banner,
request: AdRequest(),
listener: BannerAdListener(
onAdLoaded: (Ad ad) {
setState(() {
_isBannerAdReady = true;
});
print('Banner ad loaded');
// Set paid event callback
(ad as BannerAd).onPaidEvent = (AdValue adValue) {
double revenue = adValue.valueMicros / 1_000_000.0;
String? currency = adValue.currencyCode;
if (revenue > 0 && currency != null && currency.isNotEmpty) {
Singular.adRevenue({
'adPlatform': 'AdMob',
'currency': currency,
'revenue': revenue,
});
print('Banner revenue: $revenue $currency');
}
};
},
onAdFailedToLoad: (Ad ad, LoadAdError error) {
ad.dispose();
print('Banner ad failed to load: ${error.message}');
},
),
);
_bannerAd?.load();
}
@override
void dispose() {
_bannerAd?.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
if (_isBannerAdReady && _bannerAd != null) {
return Container(
alignment: Alignment.center,
width: _bannerAd!.size.width.toDouble(),
height: _bannerAd!.size.height.toDouble(),
child: AdWidget(ad: _bannerAd!),
);
}
return SizedBox.shrink();
}
}
Integración de AppLovin MAX
Requisitos previos
Implemente el complemento AppLovin MAX Flutter y configure el seguimiento de ingresos a nivel de impresión antes de integrarlo con Singular.
- Configuración MAX: Configure su aplicación en el panel de AppLovin MAX.
- Plugin Flutter: Instala el paquete applovin_max. Consulte la Guía de introducción
- API de ingresos: Habilita Impression-Level User Revenue API en la configuración del panel MAX.
Descripción general de la implementación
Configure onAdRevenuePaidCallback listeners para cada formato de anuncio para capturar ingresos cuando las impresiones generen ganancias.
- Inicializar MAX: Configure AppLovin MAX SDK con su clave SDK.
-
Configurar escuchas: Añadir
onAdRevenuePaidCallbackpara cada formato de anuncio -
Extraer ingresos: Obtenga ingresos de la propiedad
ad.revenue -
Manejo de divisas: AppLovin normalmente informa en USD, pero verifíquelo con
ad.currency -
Enviar a Singular: Envía los datos validados a
Singular.adRevenue()
Implementación completa de MAX
Capture los ingresos de todos los formatos publicitarios MAX (Rewarded, Interstitial, Banner, MREC) utilizando un gestor unificado.
import 'package:flutter/material.dart';
import 'package:applovin_max/applovin_max.dart';
import 'package:singular_flutter_sdk/singular.dart';
class AppLovinMaxManager extends StatefulWidget {
@override
_AppLovinMaxManagerState createState() => _AppLovinMaxManagerState();
}
class _AppLovinMaxManagerState extends State<AppLovinMaxManager> {
@override
void initState() {
super.initState();
_initializeAppLovinMax();
}
Future<void> _initializeAppLovinMax() async {
// Initialize AppLovin MAX SDK
await AppLovinMAX.initialize('YOUR_SDK_KEY');
// Set up revenue listeners for all ad formats
_setupRewardedAdListeners();
_setupInterstitialAdListeners();
_setupBannerAdListeners();
_setupMRecAdListeners();
print('AppLovin MAX initialized with revenue tracking');
}
void _setupRewardedAdListeners() {
AppLovinMAX.setRewardedAdListener(RewardedAdListener(
onAdRevenuePaidCallback: (ad) {
_handleAdRevenuePaid(ad, 'Rewarded');
},
onAdLoadedCallback: (ad) {
print('Rewarded ad loaded');
},
onAdLoadFailedCallback: (adUnitId, error) {
print('Rewarded ad failed to load: $error');
},
));
}
void _setupInterstitialAdListeners() {
AppLovinMAX.setInterstitialListener(InterstitialListener(
onAdRevenuePaidCallback: (ad) {
_handleAdRevenuePaid(ad, 'Interstitial');
},
onAdLoadedCallback: (ad) {
print('Interstitial ad loaded');
},
onAdLoadFailedCallback: (adUnitId, error) {
print('Interstitial ad failed to load: $error');
},
));
}
void _setupBannerAdListeners() {
AppLovinMAX.setBannerListener(AdViewAdListener(
onAdRevenuePaidCallback: (ad) {
_handleAdRevenuePaid(ad, 'Banner');
},
onAdLoadedCallback: (ad) {
print('Banner ad loaded');
},
onAdLoadFailedCallback: (adUnitId, error) {
print('Banner ad failed to load: $error');
},
));
}
void _setupMRecAdListeners() {
AppLovinMAX.setMRecListener(AdViewAdListener(
onAdRevenuePaidCallback: (ad) {
_handleAdRevenuePaid(ad, 'MREC');
},
onAdLoadedCallback: (ad) {
print('MREC ad loaded');
},
onAdLoadFailedCallback: (adUnitId, error) {
print('MREC ad failed to load: $error');
},
));
}
void _handleAdRevenuePaid(Ad ad, String adType) {
// Extract revenue and currency from ad object
final double revenueValue = ad.revenue ?? 0.0;
final String currency = ad.revenueCurrency ?? 'USD';
// Validate revenue before sending
if (revenueValue > 0) {
final adData = {
'adPlatform': 'AppLovin',
'currency': currency,
'revenue': revenueValue,
};
// Send ad revenue to Singular
Singular.adRevenue(adData);
// Log for debugging
print('[$adType] Revenue: $revenueValue $currency');
} else {
print('[$adType] Invalid revenue: $revenueValue');
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('AppLovin MAX Revenue Tracking'),
),
body: Center(
child: Text('MAX revenue tracking active'),
),
);
}
}
Práctica recomendada: Configure los receptores de ingresos publicitarios durante la inicialización de la aplicación antes de cargar los anuncios para garantizar que no se pierda ninguna impresión.
Integración con IronSource (Unity LevelPlay)
Requisitos previos
Habilite Impression Level Revenue (ILR) en su panel de IronSource e implemente el plugin IronSource Flutter antes de integrar con Singular.
- Configuración de IronSource: Habilite ARM SDK Postbacks Flag en el cuadro de mandos de IronSource
- Plugin Flutter: Instale el paquete ironsource_mediation. Consulte la Guía de introducción
- API ILR: Configure el seguimiento de ingresos a nivel de impresión para su aplicación
Ejemplo de implementación
Utilice la devolución de llamada onImpressionDataSuccess para capturar datos de ingresos a nivel de impresión de la mediación IronSource.
import 'package:ironsource_mediation/ironsource_mediation.dart';
import 'package:singular_flutter_sdk/singular.dart';
void setupIronSourceRevenueTracking() {
// Set up impression data listener
IronSource.setImpressionDataListener((ISImpressionData? impressionData) {
onImpressionDataSuccess(impressionData);
});
}
void onImpressionDataSuccess(ISImpressionData? impressionData) {
// Ensure impression data is not null
if (impressionData == null) {
print('No impression data available');
return;
}
// Extract and validate revenue
final revenue = impressionData.revenue?.toDouble() ?? 0.0;
if (revenue <= 0) {
print('Invalid revenue value: $revenue');
return;
}
// Create ad revenue data for Singular
final adData = {
'adPlatform': 'IronSource',
'currency': 'USD',
'revenue': revenue,
};
// Send to Singular
Singular.adRevenue(adData);
// Log for debugging
print('IronSource Revenue: $revenue USD');
}
Integración de TradPlus
Requisitos previos
Configure el delegado de impresiones de TradPlus para capturar datos de eCPM cuando los anuncios generen ingresos.
- Configuración de TradPlus: Configure su aplicación en el panel de TradPlus.
- Delegado de impresión: Habilite el seguimiento a nivel de impresión en los ajustes de TradPlus
Conversión eCPM: TradPlus suele informar del eCPM en mili-unidades. Divídalo por 1000,0 para convertirlo a dólares antes de enviarlo a Singular.
Ejemplo de implementación
Utilice la escucha de impresiones global para capturar los datos de ingresos de todos los formatos de anuncios de TradPlus.
import 'package:singular_flutter_sdk/singular.dart';
void setupTradPlusImpressionListener() {
// Set up global impression listener
TradPlusSdk.setGlobalImpressionListener((tpAdInfo) {
if (tpAdInfo == null) {
print('AdInfo is null');
return;
}
// Ensure eCPM is available
if (tpAdInfo.ecpm == null) {
print('eCPM value is null');
return;
}
// Convert eCPM from milli-units to dollars
double revenue = tpAdInfo.ecpm! / 1000.0;
// Validate revenue
if (revenue <= 0) {
print('Invalid revenue: $revenue');
return;
}
// Create ad revenue data
final adData = {
'adPlatform': 'TradPlus',
'currency': 'USD',
'revenue': revenue,
};
// Send to Singular
Singular.adRevenue(adData);
// Log for debugging
print('TradPlus Revenue: $revenue USD');
});
}
void main() {
// Initialize TradPlus SDK
setupTradPlusImpressionListener();
runApp(MyApp());
}
Integración genérica (otras plataformas)
Implementación personalizada
Para plataformas de mediación no cubiertas explícitamente anteriormente, implemente un gestor de ingresos personalizado utilizando el método de ingresos de anuncios de Singular.
import 'package:singular_flutter_sdk/singular.dart';
/// Generic function to report ad revenue to Singular
/// Use this for any mediation platform not explicitly supported above
void reportAdRevenue({
required String adPlatform,
required String currency,
required double revenue,
}) {
// Validate revenue value
if (revenue <= 0) {
print('Invalid revenue value: $revenue');
return;
}
// Validate currency code
if (currency.isEmpty) {
print('Currency code is empty');
return;
}
// Create ad revenue data
final adData = {
'adPlatform': adPlatform,
'currency': currency,
'revenue': revenue,
};
// Send to Singular
Singular.adRevenue(adData);
// Log for debugging
print('Ad Revenue reported: $revenue $currency from $adPlatform');
}
// Example usage with a custom mediation platform
void onCustomAdImpression(Map<String, dynamic> impressionData) {
reportAdRevenue(
adPlatform: 'CustomNetwork',
currency: impressionData['currency'] ?? 'USD',
revenue: impressionData['revenue'] ?? 0.0,
);
}
Mejores prácticas y resolución de problemas
Validación de datos
- Validar siempre: compruebe que los ingresos sean superiores a 0 y que la divisa no esté vacía antes de enviar los datos a Singular.
- Conversión de unidades: Verifique si su plataforma informa en micros o en dólares y convierta en consecuencia
- Códigos de moneda: Utilice códigos ISO 4217 de tres letras (USD, EUR, JPY) de forma coherente
- Pruebe a fondo: Verifique que los datos de ingresos aparecen en los informes de Singular antes del lanzamiento de producción
Problemas comunes
- Falta de ingresos: Asegúrese de que los ingresos a nivel de impresión están habilitados en el panel de su plataforma de mediación.
- Valores incorrectos: Compruebe la conversión de unidades (micros vs dólares) para su plataforma específica
- No hay datos en los informes: Espere de 24 a 48 horas para que los datos aparezcan en los informes de Singular después de la implementación
- Ingresos nulos: Compruebe que las devoluciones de llamada de los anuncios están correctamente configuradas antes de que se complete la carga del anuncio.
Importante: Los datos de ingresos por anuncios no se pueden corregir después de la transmisión. Valide siempre la exactitud de los datos antes de llamar a Singular.adRevenue().