Atribuição de receitas de anúncios
Acompanhe as receitas de anúncios das plataformas de mediação e atribua-as a campanhas de marketing específicas que trouxeram utilizadores à sua aplicação, permitindo uma análise abrangente do ROI.
O Ad Revenue Attribution liga as receitas de anúncios de aplicações móveis às campanhas de marketing que geraram utilizadores, combinando o custo da campanha, as receitas in-app e as receitas de anúncios num relatório unificado. Esses dados também retornam às redes de anúncios para otimizar o desempenho da campanha.
Saiba mais: Consulte as FAQs da Singular Ad Revenue Attribution para obter informações detalhadas sobre a metodologia de atribuição e as plataformas de mediação suportadas.
Como funciona a atribuição de receita de anúncios
Fluxo de atribuição
A sua plataforma de mediação reporta dados de receita ao nível da impressão ou do utilizador através de callbacks, que valida e encaminha para a Singular para análise de atribuição.
- Atribuição de campanha: Vincula a receita de anúncios às campanhas específicas que adquiriram cada usuário, mostrando o verdadeiro ROI por campanha
- Fontes de dados: Os dados de receita são provenientes de sua plataforma de mediação, tanto em nível de usuário quanto em nível de impressão
- Otimização da rede: A Singular passa os dados de receita de volta para as redes de anúncios para melhorar as estratégias de segmentação e licitação
Requisitos de implementação
Assegurar a exatidão dos dados antes de implementar o rastreio de receitas de anúncios, uma vez que os dados de receitas incorrectos não podem ser corrigidos após a transmissão.
Requisitos críticos:
- Códigos de moeda: Utilizar códigos ISO 4217 de três letras (USD, EUR, INR). A maioria das plataformas de mediação utiliza USD por defeito
- Validação de dados: Sempre valide se os valores de receita são positivos e se os códigos de moeda não estão vazios antes de enviar para a Singular
- Conversão de unidades: Algumas plataformas informam a receita em micros (1.000.000 = US$ 1,00). Converta para dólares antes de enviar para a Singular
Etapas de configuração
Siga estas etapas para implementar a atribuição de receita de anúncios com sua plataforma de mediação.
- Atualizar SDK: Certifique-se de que está a executar a versão mais recente do Singular SDK do Flutter
- Configurar plataforma: Habilite o relatório de receita de anúncios no painel da sua plataforma de mediação (AdMob, AppLovin, etc.)
- Implementar retornos de chamada: Adicione ouvintes de eventos de receita do SDK de mediação para capturar dados de impressão
- Validar dados: Verificar se a receita é > 0 e se a moeda é válida antes de encaminhar para o Singular
- Testar integração: Verificar se os dados de receita aparecem nos relatórios do Singular em 24 horas
Integração com o AdMob
Pré-requisitos
Habilite o relatório de receita de anúncios na sua conta AdMob e implemente o SDK do Google Mobile Ads para Flutter antes de integrar com o Singular.
- Configuração do AdMob: Ative a receita de anúncios no nível da impressão no painel do AdMob. Consulte Suporte do AdMob
- Pacote Flutter: Instale o pacote google_mobile_ads. Consulte o Guia de introdução
Diferenças de plataforma: A AdMob reporta a receita de forma diferente por plataforma. O Android retorna a receita em micros (5000 = US$ 0,005), enquanto o iOS retorna valores decimais (0,005 = US$ 0,005). Converta os valores do Android dividindo-os por 1.000.000 antes de enviá-los para o Singular.
Etapas de implementação
Configure o retorno de chamada onPaidEvent ao carregar anúncios para capturar dados de receita de impressões de anúncios bem-sucedidas.
- Carregar anúncio: Criar e carregar um bloco de anúncios (Recompensado, Intersticial, Banner, etc.)
-
Definir retorno de chamada: Atribua a chamada de retorno
onPaidEventpara capturarAdValuequando o anúncio gerar receita -
Converter unidades: Dividir
valueMicrospor 1.000.000 para converter em dólares - Validar: Verificar se a receita é superior a 0 e se a moeda não está vazia
-
Enviar para Singular: Ligar para
Singular.adRevenue()com dados validados
Exemplo de anúncio recompensado
Capture a receita de anúncios em vídeo recompensados definindo a chamada de retorno onPaidEvent após a conclusão do carregamento do anúncio.
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');
}
}
}
Exemplo de anúncio intersticial
Monitorize as receitas dos anúncios intersticiais utilizando o mesmo padrão 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();
}
}
Exemplo de anúncio de banner
Acompanhe a receita de anúncios de banner exibidos na interface do usuário do 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();
}
}
Integração do AppLovin MAX
Pré-requisitos
Implemente o plug-in AppLovin MAX Flutter e configure o rastreamento de receita no nível de impressão antes de integrar com o Singular.
- Configuração MAX: Configure seu aplicativo no painel do AppLovin MAX
- Plugin Flutter: Instalar o pacote applovin_max. Consulte o Guia de Introdução
- API de receita: Ativar a API de receita do utilizador ao nível da impressão nas definições do painel MAX
Visão geral da implementação
Configure onAdRevenuePaidCallback listeners para cada formato de anúncio para capturar a receita quando as impressões geram ganhos.
- Inicializar o MAX: Configurar o AppLovin MAX SDK com a sua chave SDK
-
Definir ouvintes: Adicionar
onAdRevenuePaidCallbackpara cada formato de anúncio -
Extrair receita: Obter receita da propriedade
ad.revenue -
Tratamento de moeda: O AppLovin normalmente reporta em USD, mas verifique com
ad.currency -
Encaminhar para o Singular: Enviar dados validados para
Singular.adRevenue()
Implementação completa do MAX
Capture a receita de todos os formatos de anúncio MAX (Rewarded, Interstitial, Banner, MREC) usando um manipulador 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'),
),
);
}
}
Melhores práticas: Configurar ouvintes de receitas de anúncios durante a inicialização da aplicação, antes de carregar quaisquer anúncios, para garantir que não se perdem impressões.
Integração do IronSource (Unity LevelPlay)
Pré-requisitos
Ative o Impression Level Revenue (ILR) no painel do IronSource e implemente o plug-in IronSource Flutter antes de integrar com o Singular.
- Configuração do IronSource: Ativar o sinalizador ARM SDK Postbacks no painel do IronSource
- Plugin Flutter: Instalar o pacote ironsource_mediation. Consulte o Guia de Introdução
- API ILR: Configurar o rastreamento de receita no nível de impressão para seu aplicativo
Exemplo de implementação
Use o callback onImpressionDataSuccess para capturar dados de receita no nível de impressão da mediação 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');
}
Integração do TradPlus
Pré-requisitos
Configure o delegado de impressão do TradPlus para capturar dados eCPM quando os anúncios geram receita.
- Configuração do TradPlus: Configure seu aplicativo no painel do TradPlus
- Delegado de impressão: Ativar o rastreamento no nível de impressão nas configurações do TradPlus
Conversão de eCPM: O TradPlus normalmente reporta o eCPM em mili-unidades. Divida por 1000.0 para converter em dólares antes de enviar para a Singular.
Exemplo de implementação
Use o ouvinte de impressão global para capturar dados de receita de todos os formatos de anúncio do 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());
}
Integração genérica (outras plataformas)
Implementação personalizada
Para plataformas de mediação não explicitamente cobertas acima, implemente um gerenciador de receita personalizado usando o método de receita de anúncios da 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,
);
}
Melhores práticas e solução de problemas
Validação de dados
- Sempre validar: verifique se a receita é maior que 0 e se a moeda não está vazia antes de enviar para o Singular
- Conversão de unidades: Verifique se sua plataforma reporta em micros ou dólares e converta de acordo
- Códigos de moeda: Utilize códigos de três letras ISO 4217 (USD, EUR, JPY) de forma consistente
- Teste minucioso: Verificar se os dados de receita aparecem nos relatórios da Singular antes do lançamento em produção
Problemas comuns
- Falta de receita: Certifique-se de que a receita no nível de impressão esteja ativada no painel da plataforma de mediação
- Valores incorretos: Verifique a conversão de unidades (micros vs dólares) para sua plataforma específica
- Ausência de dados nos relatórios: Aguarde de 24 a 48 horas para que os dados apareçam nos relatórios do Singular após a implementação
- Receita nula: Verificar se os callbacks do anúncio estão corretamente definidos antes da conclusão do carregamento do anúncio
Importante: os dados de receita de anúncios não podem ser corrigidos após a transmissão. Valide sempre a exatidão dos dados antes de ligar para Singular.adRevenue().