Understanding Ad Revenue Attribution
Ad Revenue Attribution helps you connect your ad revenue to the specific campaigns that brought users to your app. This gives you a clear picture of how well your ads are performing by showing the campaign cost, in-app revenue, and ad revenue all in one place. This feature also lets you send ad revenue data back to your ad networks to improve your ad performance.
Key Points:
- What It Does: Ad Revenue Attribution ties mobile app ad revenue to the marketing campaigns that generated users for your app. This way, you can see how much you earned from each campaign and how it affects your overall ad ROI.
- Data Source: This data usually comes from your mediation platform and can be at the user level or impression level. Singular supports different ways to get this attribution data.
- Read More: For more details, check out the FAQ and Troubleshooting article on Singular Ad Revenue Attribution.
Important Notes:
- Currency Codes: Use three-letter ISO 4217 currency codes (e.g., "USD" for US Dollars, "EUR" for Euros, "INR" for Indian Rupees). Many mediation platforms use "USD", so make sure your code matches this if you're using it. If you use a different currency, update the validation code accordingly.
- Data Accuracy: Always check that your revenue and currency data are correct before sending it to Singular. Incorrect data can't be fixed later, so it’s crucial to ensure it’s accurate.
Implementing Ad Revenue Attribution
- Update the SDK: Make sure you have the latest version of the Singular SDK.
- Add Code Snippets: Depending on your mediation platform, add the right code snippets to your Singular SDK setup.
Following these steps will help you set up Ad Revenue Attribution correctly and get the most out of your ad data.
Partner Notes
- This feature needs to be enabled in your AdMob account.
See AdMob Support.
-
When you load an ad format (such as "App Open," "Banner," "Interstitial," "Native," or "Rewarded"), set up a paidEventHandler as a callback function that is triggered whenever an ad generates revenue. The Google Mobile Ads SDK tracks impression events and calls this handler with the Ad generated revenue.
To do this, modify the "load" function of the ad format to include the paidEventHandler. Inside this callback, you manage the ad revenue data, validate it, and send it to Singular using the Singular.adRevenue function.
For example, when a "Rewarded ad" loads successfully, the paidEventHandler will receive the ad's revenue information (adValue). In this function, handle the revenue data and send it to Singular.
For more details, check the AdMob documentation.
IMPORTANT: The AdMob SDK reports revenue differently depending on the platform. For instance, ad revenue of $0.005 will be returned as 5000 on Unity and Android platforms but as 0.005 on iOS. For iOS, send 0.005 directly to the Singular SDK. On other platforms, convert adValue from micros to dollars before sending it to Singular.
Select the code base for your SDK implementation:
How it works:
- Implement the Google AdMob Mobile Ads SDK (iOS): See the Getting Started Guide.
- AdMob Integration: Load the ad from AdMob and set a setOnPaidEventListener to handle ad revenue events.
- Revenue Validation: Add a check to ensure that revenue is greater than 0. This prevents sending zero or negative revenue values.
- Currency Validation: Ensure that the currency is not nil or empty before sending data to Singular.
- Logging Invalid Data: If the data fails validation, print a log message for debugging, and do not send the data to Singular.
import Singular
private let adUnitID = "AD_UNIT_ID"
var rewardedAd: GADRewardedAd?
func loadRewardedAd() {
let request = GADRequest()
GADRewardedAd.load(withAdUnitID: adUnitID, request: request) { [weak self] ad, error in
guard let self = self else { return }
if let error = error {
print("Rewarded ad failed to load with error: \(error.localizedDescription)")
return
}
self.rewardedAd = ad
self.rewardedAd?.paidEventHandler = { adValue in
// Ensure valid revenue data
let revenue = adValue.value
let currency = adValue.currencyCode
// Validate the revenue and currency before sending to Singular
guard revenue > 0, let currency = currency, !currency.isEmpty else {
print("Invalid ad revenue data: revenue = \(revenue), currency = \(String(describing: currency))")
return
}
let data = SingularAdData(
adPlatform: "Admob",
currency: currency,
revenue: revenue
)
// Send Ad Revenue data to Singular
Singular.adRevenue(data: data)
// Log the data for debugging
print("Ad Revenue reported to Singular: \(data)")
}
}
}
How it works:
- Implement the Google AdMob Mobile Ads SDK (iOS): See the Getting Started Guide.
- AdMob Integration: Load the ad from AdMob and set a paidEventHandler to handle ad revenue events.
- Revenue Validation: Add a check to ensure that revenue is greater than 0. This prevents sending zero or negative revenue values.
- Currency Validation: Ensure that the currency is not nil or empty before sending data to Singular.
- Logging Invalid Data: If the data fails validation, print a log message for debugging, and do not send the data to Singular.
#import <Singular/Singular.h>
static NSString *const adUnitID = @"AD_UNIT_ID";
// Initialize and load the rewarded ad
@interface YourClassName () <GADRewardedAdDelegate>
@property(nonatomic, strong) GADRewardedAd *rewardedAd;
@end
@implementation YourClassName
- (void)loadRewardedAd {
GADRequest *request = [[GADRequest alloc] init];
[GADRewardedAd loadWithAdUnitID:adUnitID
request:request
completionHandler:^(GADRewardedAd *ad, NSError *error) {
if (error) {
NSLog(@"Rewarded ad failed to load with error: %@", [error localizedDescription]);
return;
}
self.rewardedAd = ad;
self.rewardedAd.fullScreenContentDelegate = self;
self.rewardedAd.paidEventHandler = ^(GADAdValue *adValue) {
// Ensure valid revenue data
NSDecimalNumber *revenue = adValue.value;
NSString *currency = adValue.currencyCode;
if (revenue.doubleValue > 0 && currency.length > 0) {
SingularAdData *data = [[SingularAdData alloc] initWithAdPlatfrom:@"Admob"
currency:currency
revenue:revenue.doubleValue];
// Send Ad Revenue data to Singular
[Singular adRevenue:data];
// Log the data for debugging
NSLog(@"Ad Revenue reported to Singular: %@", data);
} else {
NSLog(@"Invalid ad revenue data: revenue = %@, currency = %@", revenue, currency);
}
};
}];
}
@end
How it works:
- Implement the Google AdMob Mobile Ads SDK (Android): See the Getting Started Guide.
- AdMob Integration: Load the ad from AdMob and set a setOnPaidEventListener to handle ad revenue events.
- Revenue Validation: Add a check to ensure that revenue is greater than 0. This prevents sending zero or negative revenue values.
- Currency Validation: Ensure that the currency is not nil or empty before sending data to Singular.
- Logging Invalid Data: If the data fails validation, print a log message for debugging, and do not send the data to Singular.
import com.singular.sdk.Singular
import com.singular.sdk.SingularAdData
private const val AD_UNIT_ID = "AD_UNIT_ID"
class AdManager(private val context: Context) {
private var rewardedAd: RewardedAd? = null
fun loadRewardedAd() {
val adRequest = AdRequest.Builder().build()
RewardedAd.load(context, AD_UNIT_ID, adRequest, object : RewardedAdLoadCallback() {
override fun onAdLoaded(ad: RewardedAd) {
rewardedAd = ad
rewardedAd?.fullScreenContentCallback = object : FullScreenContentCallback() {
override fun onAdShowedFullScreenContent() {
Log.d("AdManager", "Rewarded ad displayed.")
}
override fun onAdFailedToShowFullScreenContent(adError: AdError) {
Log.d("AdManager", "Rewarded ad failed to show with error: ${adError.message}")
}
override fun onAdDismissedFullScreenContent() {
Log.d("AdManager", "Rewarded ad dismissed.")
}
}
rewardedAd?.setOnPaidEventListener { adValue: AdValue ->
// Ensure valid revenue data
val revenue = adValue.valueMicros / 1_000_000.0
val currency = adValue.currencyCode
if (revenue > 0 && !currency.isNullOrEmpty()) {
val data = SingularAdData(
"Admob",
currency,
revenue
)
// Send Ad Revenue data to Singular
Singular.adRevenue(data)
// Log the data for debugging
Log.d("AdManager", "Ad Revenue reported to Singular: $data")
} else {
Log.d("AdManager", "Invalid ad revenue data: revenue = $revenue, currency = $currency")
}
}
}
override fun onAdFailedToLoad(loadAdError: LoadAdError) {
Log.d("AdManager", "Rewarded ad failed to load with error: ${loadAdError.message}")
}
})
}
}
How it works:
- Implement the Google AdMob Mobile Ads SDK (Android): See the Getting Started Guide.
- AdMob Integration: Load the ad from AdMob and set a setOnPaidEventListener to handle ad revenue events.
- Revenue Validation: Add a check to ensure that revenue is greater than 0. This prevents sending zero or negative revenue values.
- Currency Validation: Ensure that the currency is not nil or empty before sending data to Singular.
- Logging Invalid Data: If the data fails validation, print a log message for debugging, and do not send the data to Singular.
import com.singular.sdk.Singular;
import com.singular.sdk.SingularAdData;
// Define constants for better maintainability
private static final String AD_UNIT_ID = "AD_UNIT_ID";
public class AdManager {
private RewardedAd rewardedAd;
private Context context;
public AdManager(Context context) {
this.context = context;
}
public void loadRewardedAd() {
AdRequest adRequest = new AdRequest.Builder().build();
RewardedAd.load(context, AD_UNIT_ID, adRequest, new RewardedAdLoadCallback() {
@Override
public void onAdLoaded(RewardedAd ad) {
rewardedAd = ad;
rewardedAd.setFullScreenContentCallback(new FullScreenContentCallback() {
@Override
public void onAdShowedFullScreenContent() {
Log.d("AdManager", "Rewarded ad displayed.");
}
@Override
public void onAdFailedToShowFullScreenContent(AdError adError) {
Log.d("AdManager", "Rewarded ad failed to show with error: " + adError.getMessage());
}
@Override
public void onAdDismissedFullScreenContent() {
Log.d("AdManager", "Rewarded ad dismissed.");
}
});
rewardedAd.setOnPaidEventListener(new OnPaidEventListener() {
@Override
public void onPaidEvent(AdValue adValue) {
double revenue = adValue.getValueMicros() / 1_000_000.0;
String currency = adValue.getCurrencyCode();
// Validate the revenue value
if (revenue <= 0 || currency == null || currency.isEmpty()) {
Log.d("AdManager", "Invalid ad revenue data: revenue = " + revenue + ", currency = " + currency);
return;
}
SingularAdData data = new SingularAdData(
"Admob",
currency,
revenue
);
// Send Ad Revenue data to Singular
Singular.adRevenue(data);
// Log the data for debugging
Log.d("AdManager", "Ad Revenue reported to Singular: " + data);
}
});
}
@Override
public void onAdFailedToLoad(LoadAdError loadAdError) {
Log.d("AdManager", "Rewarded ad failed to load with error: " + loadAdError.getMessage());
}
});
}
}
How it works:
- Implement the Google AdMob Mobile Ads SDK (Flutter): See the Getting Started Guide.
- AdMob Integration: Load the ad from AdMob and set a onPaidEvent callback to handle ad revenue events.
- Revenue Validation: Add a check to ensure that revenue is greater than 0. This prevents sending zero or negative revenue values.
- Currency Validation: Ensure that the currency is not nil or empty before sending data to Singular.
- Logging Invalid Data: If the data fails validation, print a log message for debugging, and do not send the data to Singular.
import 'package:singular_flutter_sdk/singular_flutter_sdk.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;
_rewardedAd?.fullScreenContentCallback = FullScreenContentCallback(
onAdShowedFullScreenContent: () {
print('Rewarded ad displayed.');
},
onAdFailedToShowFullScreenContent: (AdError adError) {
print('Rewarded ad failed to show with error: ${adError.message}');
},
onAdDismissedFullScreenContent: () {
print('Rewarded ad dismissed.');
_rewardedAd = null; // Clear the ad when it is dismissed
},
);
_rewardedAd?.onPaidEvent = (AdValue adValue) {
double revenue = adValue.valueMicros / 1_000_000.0; // Convert from micros to dollars
String? currency = adValue.currencyCode;
// Validate the revenue and currency before sending to Singular
if (revenue > 0 && currency != null && currency.isNotEmpty) {
final data = {
'adPlatform': 'Admob',
'currency': currency,
'revenue': revenue,
};
// Send Ad Revenue data to Singular
Singular.adRevenue(data);
// Log the data for debugging
print('Ad Revenue reported to Singular: $data');
} else {
print('Invalid ad revenue data: revenue = $revenue, currency = $currency');
}
};
},
onAdFailedToLoad: (LoadAdError loadAdError) {
print('Rewarded ad failed to load with error: ${loadAdError.message}');
},
),
);
}
}
How it works:
- Cordova is not officially supported by Google, and requires the use of a third party Cordova plugin. AdMob Plus Cordova is the successor of cordova-plugin-admob-free, which provides a cleaner API and build with modern tools. This plugin is not supported by Singular. See the Getting Started Guide.
- AdMob Initialization: Create an instance for the ad format with the ad unit ID. Make sure to replace 'ca-app-pub-xxx/yyy' with the actual ad unit ID.
- Event Handling: Trigger the on paid Event callback: This event provides the revenue and currency code. Validate these values and convert the revenue from micros to dollars. Send this data to Singular. Handle the "load", "show", "dismiss", and "error" lifecycle events with logging if needed.
- Data Validation: Ensure that the revenue is greater than zero and the currency code is present before sending the data to Singular.
- Singular Integration: Use the SingularAdData object to prepare the data and call adRevenue to send the data to Singular.
document.addEventListener('deviceready', async () => {
const admob = window.cordova.plugins.AdMobPlus;
// Initialize RewardedAd
const rewarded = admob.RewardedAd.create({
adUnitId: 'ca-app-pub-xxx/yyy', // Replace with your ad unit ID
// Optional configurations
isTesting: true, // Set to false when going live
});
// Handle the 'paid' event to get revenue details
rewarded.on('paid', (event) => {
const { value, currencyCode } = event;
// Validate the revenue and currency data
if (value > 0 && currencyCode) {
const revenueAmount = value / 1_000_000.0; // Convert from micros to dollars
// Prepare data for Singular
const adData = new cordova.plugins.SingularCordovaSdk.SingularAdData(
'Admob', // Mediation platform
currencyCode, // Currency code
revenueAmount // Revenue amount
);
// Send Ad Revenue data to Singular
cordova.plugins.SingularCordovaSdk.adRevenue(adData);
// Log the data for debugging
console.log('Ad Revenue reported to Singular:', {
adPlatform: 'Admob',
currency: currencyCode,
revenue: revenueAmount
});
} else {
console.error('Invalid ad revenue data:', { value, currencyCode });
}
});
// Handle ad load and show events
rewarded.on('load', async () => {
console.log('Rewarded ad loaded.');
// Load the next ad as soon as the current one is dismissed
await rewarded.load();
});
rewarded.on('show', () => {
console.log('Rewarded ad shown.');
});
rewarded.on('dismiss', async () => {
console.log('Rewarded ad dismissed.');
// Load a new ad for future use
await rewarded.load();
});
rewarded.on('error', (error) => {
console.error('Error with rewarded ad:', error);
});
// Load and show the rewarded ad
await rewarded.load();
await rewarded.show();
}, false);
How it works:
- Implement the React Native Google Mobile Ads package: See the Getting Started Guide.
- AdMob Integration: Load the ad from AdMob and set a onAdEvent to handle ad revenue events.
- Revenue Validation: Add a check to ensure that revenue is greater than 0. This prevents sending zero or negative revenue values.
- Currency Validation: Ensure that the currency is not nil or empty before sending data to Singular.
- Logging Invalid Data: If the data fails validation, print a log message for debugging, and do not send the data to Singular.
import { Singular } from 'singular-react-native';
const adUnitID = 'AD_UNIT_ID';
const loadRewardedAd = () => {
// Create a RewardedAd instance with the provided adUnitID
const rewardedAd = RewardedAd.createForAdRequest(adUnitID);
// Set up event listener for ad events
rewardedAd.onAdEvent((type, error, data) => {
if (type === AdEventType.LOADED) {
console.log('Rewarded ad loaded');
} else if (type === AdEventType.ERROR) {
console.error('Rewarded ad failed to load', error);
} else if (type === AdEventType.PAID_EVENT) {
// Extract value and currencyCode from event data
const { value, currencyCode } = data;
// Validate the revenue and currency before sending to Singular
if (value > 0 && currencyCode) {
const revenue = value / 1_000_000.0; // Convert from micros to dollars
const adRevenueData = {
'Admob',
currency: currencyCode,
revenue,
};
// Send Ad Revenue data to Singular
Singular.adRevenue(adRevenueData);
// Log the data for debugging
console.log('Ad Revenue reported to Singular:', adRevenueData);
} else {
console.error('Invalid ad revenue data:', { value, currencyCode });
}
}
});
// Load the rewarded ad
rewardedAd.load();
};
useEffect(() => {
// Load the rewarded ad when the component mounts
loadRewardedAd();
}, []);
How it works:
- Implement the Google AdMob Mobile Ads SDK (Unity): See the Getting Started Guide.
- Listen to rewarded ad events as documented in the Google AdMob documentation HERE
- AdMob Integration: Load the ad from AdMob and set a OnAdPaid callback for when the ad has generated money.
- Revenue Validation: Add a check to ensure that revenue is greater than 0. This prevents sending zero or negative revenue values.
- Currency Validation: Ensure that the currency is not nil or empty before sending data to Singular.
- Logging Invalid Data: If the data fails validation, print a log message for debugging, and do not send the data to Singular.
using Singular;
private void RegisterEventHandlers(RewardedAd ad)
{
// Raised when the ad is estimated to have earned money.
ad.OnAdPaid += (AdValue adValue) =>
{
// Validate and ensure revenue data is within an expected range
float revenue = adValue.Value / 1_000_000f; // Convert micros to dollars
string currency = adValue.CurrencyCode;
// Check if revenue is positive and currency is valid
if (revenue > 0 && !string.IsNullOrEmpty(currency))
{
// Construct and send the Singular AdMon Event
SingularAdData data = new SingularAdData(
"Admob",
currency,
revenue
);
SingularSDK.AdRevenue(data);
// Log the revenue data for debugging purposes
Debug.Log($"Ad Revenue reported to Singular: {data}");
}
else
{
Debug.LogError($"Invalid ad revenue data: revenue = {revenue}, currency = {currency}");
}
};
}
Partner Notes
- Share impression-level ad revenue data using the Applovin Impression-Level User Revenue API.
Select the code base for your SDK implementation:
How it works:
- Uses the AppLovin Impression-Level User Revenue API (iOS): See the Getting Started Guide.
- AppLovin Integration: Load a rewarded ad from AppLovin MAX and use the didReceive function to handle ad revenue events.
- Revenue Validation: Add a check to ensure that revenue is greater than 0. This prevents sending zero or negative revenue values.
- Currency Validation: In the sample below, the currency is hard coded to "USD". Ensure that the currency is accurate and not nil or empty before sending data to Singular.
- Logging Invalid Data: If the data fails validation, print a log message for debugging, and do not send the data to Singular.
import Singular
func didReceive(_ message: ALCMessage) {
if "max_revenue_events" == message.topic {
// Safely unwrap values from the message data
guard
let revenueValue = message.data["revenue"] as? Double,
revenueValue > 0
else {
print("Failed to parse valid revenue value from message data or revenue is not greater than 0")
return
}
let data = SingularAdData(
adPlatform: "AppLovin",
currency: "USD", // Update this if a different currency is needed
revenue: revenueValue
)
// Send the revenue data to Singular
Singular.adRevenue(data)
}
}
How it works:
- Uses the AppLovin Impression-Level User Revenue API (iOS): See the Getting Started Guide.
- AppLovin Integration: Load a rewarded ad from AppLovin MAX and use the didReceive function to handle ad revenue events.
- Revenue Validation: Add a check to ensure that revenue is greater than 0. This prevents sending zero or negative revenue values.
- Currency Validation: In the sample below, the currency is hard coded to "USD". Ensure that the currency is accurate and not nil or empty before sending data to Singular.
- Logging Invalid Data: If the data fails validation, print a log message for debugging, and do not send the data to Singular.
#import <Singular/Singular.h>
- (void)didReceive:(ALCMessage *)message {
if ([@"max_revenue_events" isEqualToString:message.topic]) {
NSDictionary *data = message.data;
NSNumber *revenueNumber = data[@"revenue"];
double revenueValue = [revenueNumber doubleValue];
if (revenueValue > 0) {
SingularAdData *adData = [[SingularAdData alloc] initWithAdPlatfrom:@"AppLovin"
currency:@"USD"
revenue:revenueValue];
// Send the revenue data to Singular
[Singular adRevenue:adData];
} else {
NSLog(@"Failed to parse valid revenue value from message data or revenue is not greater than 0");
}
}
}
How it works:
- Uses the AppLovin Impression-Level User Revenue API (Android): See the Getting Started Guide.
- AppLovin Integration: Load a rewarded ad from AppLovin MAX and use the onMessageReceived function to handle ad revenue events.
- Revenue Validation: Add a check to ensure that revenue is greater than 0. This prevents sending zero or negative revenue values.
- Currency Validation: In the sample below, the currency is hard coded to "USD". Ensure that the currency is accurate and not nil or empty before sending data to Singular.
- Logging Invalid Data: If the data fails validation, print a log message for debugging, and do not send the data to Singular.
import com.singular.sdk.*
override fun onMessageReceived(message: AppLovinCommunicatorMessage) {
// In the case that you are subscribed to multiple topics, check for the desired one
if ("max_revenue_events" == message.topic) {
val adData: Bundle? = message.messageData
// Safely access and validate revenue value
val revenueValue = adData?.getDouble("revenue", 0.0) ?: 0.0
if (revenueValue > 0) {
val data = SingularAdData(
adPlatform = "AppLovin",
currency = "USD",
revenue = revenueValue
)
Singular.adRevenue(data)
} else {
Log.e("AppLovinRevenue", "Failed to parse valid revenue value from message data or revenue is not greater than 0")
}
}
}
How it works:
- Uses the AppLovin Impression-Level User Revenue API (Android): See the Getting Started Guide.
- AppLovin Integration: Load a rewarded ad from AppLovin MAX and use the onMessageReceived function to handle ad revenue events.
- Revenue Validation: Add a check to ensure that revenue is greater than 0. This prevents sending zero or negative revenue values.
- Currency Validation: In the sample below, the currency is hard coded to "USD". Ensure that the currency is accurate and not nil or empty before sending data to Singular.
- Logging Invalid Data: If the data fails validation, print a log message for debugging, and do not send the data to Singular.
import com.singular.sdk.*;
@Override
public void onMessageReceived(AppLovinCommunicatorMessage message) {
// In the case that you are subscribed to multiple topics, check for the desired one
if ("max_revenue_events".equals(message.getTopic())) {
Bundle adData = message.getMessageData();
// Safely access and validate revenue value
double revenueValue = (adData != null) ? adData.getDouble("revenue", 0.0) : 0.0;
if (revenueValue > 0) {
SingularAdData data = new SingularAdData(
"AppLovin",
"USD",
revenueValue
);
Singular.adRevenue(data);
} else {
Log.e("AppLovinRevenue", "Failed to parse valid revenue value from message data or revenue is not greater than 0");
}
}
}
How it works:
- Uses the AppLovin Impression-Level User Revenue API (Flutter): See the Getting Started Guide.
- AppLovin Integration: Set up ad listeners for the onAdRevenuePaidCallback and pass the ad data to a handleAdRevenuePaid function to handle ad revenue events.
- Revenue Validation: Add a check to ensure that revenue is greater than 0. This prevents sending zero or negative revenue values.
- Currency Validation: In the sample below, the currency is hard coded to "USD". Ensure that the currency is accurate and not nil or empty before sending data to Singular.
- Logging Invalid Data: If the data fails validation, print a log message for debugging, and do not send the data to Singular.
import 'package:singular_flutter_sdk/singular.Flutter';
@override
void initState() {
super.initState();
// Set up ad listeners
AppLovinMAX.setInterstitialListener(InterstitialListener(
onAdRevenuePaidCallback: (ad) {
_handleAdRevenuePaid(ad);
},
));
AppLovinMAX.setRewardedAdListener(RewardedAdListener(
onAdRevenuePaidCallback: (ad) {
_handleAdRevenuePaid(ad);
},
));
AppLovinMAX.setBannerListener(AdViewAdListener(
onAdRevenuePaidCallback: (ad) {
_handleAdRevenuePaid(ad);
},
));
AppLovinMAX.setMRecListener(AdViewAdListener(
onAdRevenuePaidCallback: (ad) {
_handleAdRevenuePaid(ad);
},
));
}
void _handleAdRevenuePaid(Ad ad) {
final double revenueValue = ad.revenue ?? 0.0;
final String currency = ad.currency ?? 'USD'; // Default to 'USD' if currency is not available
if (revenue > 0) {
final SingularAdData adData = SingularAdData(
adPlatform: "AppLovin",
currency: currency,
revenue: revenueValue,
);
Singular.adRevenue(adData);
_logger.i('Sent ad revenue to Singular: $revenueValue $currency');
} else {
_logger.e('Failed to parse valid revenue value from ad revenue data or revenue is not greater than 0');
}
}
Not Supported:
AppLovin's Cordova SDK does not natively support capturing ad revenue information through the adInfo object. The Cordova SDK is typically more limited in terms of advanced features compared to the native SDKs for Android and iOS.
For advanced ad revenue tracking, you might need to integrate with the native AppLovin SDKs directly or use a custom plugin to bridge the functionality between Cordova and the native SDKs. If you require ad revenue data, consider reaching out to AppLovin support for the most current information or looking into alternative methods to capture this data.
How it works:
- Uses the AppLovin Impression-Level User Revenue API (React Native): See the Getting Started Guide.
- AppLovin Integration: Load a rewarded ad from AppLovin MAX and retrieve the revenue amount in all ad lifecycle callbacks.
- Revenue Validation: Add a check to ensure that revenue is greater than 0. This prevents sending zero or negative revenue values.
- Currency Validation: In the sample below, the currency is hard coded to "USD". Ensure that the currency is accurate and not nil or empty before sending data to Singular.
- Logging Invalid Data: If the data fails validation, print a log message for debugging, and do not send the data to Singular.
import Singular from 'singular-react-native';
// Function to handle ad revenue
const handleAdRevenue = (adInfo) => {
const revenue = adInfo.revenue;
if (revenue > 0) {
const adData = {
adPlatform: "AppLovin",
currency: "USD", // AppLovin typically reports revenue in USD
revenue: revenue,
};
// Send ad revenue data to Singular
Singular.adRevenue(adData);
} else {
console.error("Failed to parse valid revenue value from ad info or revenue is not greater than 0");
}
};
// Set up listeners for various ad types
InterstitialAd.addAdRevenuePaidListener(handleAdRevenue);
RewardedAd.addAdRevenuePaidListener(handleAdRevenue);
BannerAd.addAdRevenuePaidListener(handleAdRevenue);
MRecAd.addAdRevenuePaidListener(handleAdRevenue);
AppOpenAd.addAdRevenuePaidListener(handleAdRevenue);
How it works:
- Uses the AppLovin Impression-Level User Revenue API (Unity): See the Getting Started Guide.
- AppLovin Integration: Load a rewarded ad from AppLovin MAX and retrieve the revenue amount in all ad lifecycle callbacks.
- Revenue Validation: Add a check to ensure that revenue is greater than 0. This prevents sending zero or negative revenue values.
- Currency Validation: In the sample below, the currency is hard coded to "USD". Ensure that the currency is accurate and not nil or empty before sending data to Singular.
- Logging Invalid Data: If the data fails validation, print a log message for debugging, and do not send the data to Singular.
using Singular;
public class AdRevenueHandler : MonoBehaviour
{
void Start()
{
// Attach callbacks based on the ad format(s) you are using
MaxSdkCallbacks.Interstitial.OnAdRevenuePaidEvent += OnAdRevenuePaidEvent;
MaxSdkCallbacks.Rewarded.OnAdRevenuePaidEvent += OnAdRevenuePaidEvent;
MaxSdkCallbacks.Banner.OnAdRevenuePaidEvent += OnAdRevenuePaidEvent;
MaxSdkCallbacks.MRec.OnAdRevenuePaidEvent += OnAdRevenuePaidEvent;
}
private void OnAdRevenuePaidEvent(string adUnitId, MaxSdkBase.AdInfo adInfo)
{
double revenue = adInfo.Revenue;
if (revenue > 0)
{
// Create a SingularAdData object with relevant information
SingularAdData adData = new SingularAdData(
"Applovin",
"USD",
revenue);
// Send ad revenue data to Singular
SingularSDK.AdRevenue(adData);
}
else
{
Debug.LogError("Failed to parse valid revenue value from ad info or revenue is not greater than 0");
}
}
void OnDestroy()
{
// Detach callbacks to prevent memory leaks
MaxSdkCallbacks.Interstitial.OnAdRevenuePaidEvent -= OnAdRevenuePaidEvent;
MaxSdkCallbacks.Rewarded.OnAdRevenuePaidEvent -= OnAdRevenuePaidEvent;
MaxSdkCallbacks.Banner.OnAdRevenuePaidEvent -= OnAdRevenuePaidEvent;
MaxSdkCallbacks.MRec.OnAdRevenuePaidEvent -= OnAdRevenuePaidEvent;
}
}
Partner Notes
- The Impression Level Revenue (ILR) SDK API provides impression level data for ironSource Ads and other mediated networks, using the ironSource SDK. Read more on [developers.is.com]
- Ensure that the ARM SDK Postbacks Flag in IronSource is turned on
Select the code base for your SDK implementation:
How it works:
- Uses the ironSource SDK to get Impression-Level User Revenue (iOS): See the Getting Started Guide.
- Ironsource Integration: Load a rewarded ad from Ironsource and use the impressionDataDidSucceed function to handle Ad Revenue events.
- Revenue Validation: Add a check to ensure that revenue is greater than 0. This prevents sending zero or negative revenue values.
- Currency Validation: In the sample below, the currency is hard coded to "USD". Ensure that the currency is accurate and not nil or empty before sending data to Singular.
- Logging Invalid Data: If the data fails validation, print a log message for debugging, and do not send the data to Singular.
import Singular
class IronSourceRewardedAdViewController: UIViewController {
func impressionDataDidSucceed(impressionData: ISImpressionData?) {
logCallback(#function)
// Ensure impressionData is not nil
guard let impressionData = impressionData else {
print("No impression data available.")
return
}
// Ensure revenue value is valid
let revenue = impressionData.revenue
guard revenue > 0 else {
print("Invalid revenue value: \(revenue)")
return
}
// Create SingularAdData object with appropriate values
let data = SingularAdData(
adPlatform: "IronSource",
currency: "USD",
revenue: revenue
)
// Send the Ad Revenue data to Singular
Singular.adRevenue(data)
// Log the data for debugging
print("Ad Revenue reported to Singular: AdPlatform: \(data.adPlatform), Currency: \(data.currency), Revenue: \(data.revenue)")
}
private func logCallback(_ functionName: String) {
// Implement logging if needed
print("Function called: \(functionName)")
}
}
How it works:
- Uses the ironSource SDK to get Impression-Level User Revenue (iOS): See the Getting Started Guide.
- Ironsource Integration: Load a rewarded ad from Ironsource and use the impressionDataDidSucceed function to handle Ad Revenue events.
- Revenue Validation: Add a check to ensure that revenue is greater than 0. This prevents sending zero or negative revenue values.
- Currency Validation: In the sample below, the currency is hard coded to "USD". Ensure that the currency is accurate and not nil or empty before sending data to Singular.
- Logging Invalid Data: If the data fails validation, print a log message for debugging, and do not send the data to Singular.
#import <Singular/Singular.h>
@implementation IronSourceRewardedAdViewController
- (void)impressionDataDidSucceed:(ISImpressionData *)impressionData {
[self logCallback:NSStringFromSelector(_cmd)];
// Ensure impressionData is not nil
if (!impressionData) {
NSLog(@"No impression data available.");
return;
}
// Ensure revenue value is valid
double revenue = impressionData.revenue;
if (revenue <= 0) {
NSLog(@"Invalid revenue value: %f", revenue);
return;
}
// Create SingularAdData object with appropriate values
SingularAdData *data = [[SingularAdData alloc] initWithAdPlatfrom:@"IronSource"
currency:@"USD"
revenue:revenue];
// Send the Ad Revenue data to Singular
[Singular adRevenue:data];
// Log the data for debugging
NSLog(@"Ad Revenue reported to Singular: AdPlatform: %@, Currency: %@, Revenue: %f",
data.adPlatform, data.currency, data.revenue);
}
- (void)logCallback:(NSString *)functionName {
// Implement logging if needed
NSLog(@"Function called: %@", functionName);
}
@end
How it works:
- Uses the ironSource SDK to get Impression-Level User Revenue (Android): See the Getting Started Guide.
- Ironsource Integration: Load a rewarded ad from Ironsource and use the onImpressionDataSuccess function to handle Ad Revenue events.
- Revenue Validation: Add a check to ensure that revenue is greater than 0. This prevents sending zero or negative revenue values.
- Currency Validation: In the sample below, the currency is hard coded to "USD". Ensure that the currency is accurate and not nil or empty before sending data to Singular.
- Logging Invalid Data: If the data fails validation, print a log message for debugging, and do not send the data to Singular.
import com.singular.sdk.Singular
// Method called when impression data is successfully received
fun onImpressionDataSuccess(impressionData: ISImpressionData?) {
// Ensure impressionData is not null
if (impressionData == null) {
Log.d("IronSource", "No impression data available.")
return
}
// Ensure revenue value is valid
val revenue = impressionData.revenue.toDouble()
if (revenue <= 0) {
Log.w("IronSource", "Invalid revenue value: $revenue")
return
}
// Create SingularAdData object with required fields
val data = SingularAdData(
adPlatform = "IronSource",
currency = "USD",
revenue = revenue
)
// Send the Ad Revenue data to Singular
Singular.adRevenue(data)
// Log the data for debugging
Log.i("IronSource", "Ad Revenue reported to Singular: AdPlatform: ${data.adPlatform}, Currency: ${data.currency}, Revenue: ${data.revenue}")
}
How it works:
- Uses the ironSource SDK to get Impression-Level User Revenue (Android): See the Getting Started Guide.
- Ironsource Integration: Load a rewarded ad from Ironsource and use the onImpressionDataSuccess function to handle Ad Revenue events.
- Revenue Validation: Add a check to ensure that revenue is greater than 0. This prevents sending zero or negative revenue values.
- Currency Validation: In the sample below, the currency is hard coded to "USD". Ensure that the currency is accurate and not nil or empty before sending data to Singular.
- Logging Invalid Data: If the data fails validation, print a log message for debugging, and do not send the data to Singular.
import com.singular.sdk.Singular;
import com.singular.sdk.SingularAdData;
public class IronSourceAdManager {
// Method called when impression data is successfully received
public void onImpressionDataSuccess(ISImpressionData impressionData) {
// Ensure impressionData is not null
if (impressionData == null) {
Log.d("IronSource", "No impression data available.");
return;
}
// Ensure revenue value is valid
double revenue = impressionData.getRevenue().doubleValue();
if (revenue <= 0) {
Log.w("IronSource", "Invalid revenue value: " + revenue);
return;
}
// Create SingularAdData object with required fields
SingularAdData data = new SingularAdData(
"IronSource", // adPlatform
"USD", // currency
revenue // revenue
);
// Send the Ad Revenue data to Singular
Singular.adRevenue(data);
// Log the data for debugging
Log.i("IronSource", "Ad Revenue reported to Singular: AdPlatform: " + data.getAdPlatform() +
", Currency: " + data.getCurrency() +
", Revenue: " + data.getRevenue());
}
}
How it works:
- Uses the ironSource Flutter Plugin to get Impression-Level User Revenue: See the Getting Started Guide.
- Ironsource Integration: Load a rewarded ad from Ironsource and use the onImpressionDataSuccess function to handle Ad Revenue events.
- Revenue Validation: Add a check to ensure that revenue is greater than 0. This prevents sending zero or negative revenue values.
- Currency Validation: In the sample below, the currency is hard coded to "USD". Ensure that the currency is accurate and not nil or empty before sending data to Singular.
- Logging Invalid Data: If the data fails validation, print a log message for debugging, and do not send the data to Singular.
import 'package:singular_flutter_sdk/singular.Flutter';
// Method called when impression data is successfully received
void onImpressionDataSuccess(ISImpressionData? impressionData) {
// Ensure impressionData is not null
if (impressionData == null) {
print("No impression data available.");
return;
}
// Ensure revenue value is valid
final revenue = impressionData.revenue.toDouble();
if (revenue <= 0) {
print("Invalid revenue value: $revenue");
return;
}
// Create SingularAdData object with required fields
final data = SingularAdData(
adPlatform: "IronSource",
currency: "USD",
revenue: revenue,
);
// Send the Ad Revenue data to Singular
Singular.adRevenue(data);
// Log the data for debugging
if (kDebugMode) {
print("Ad Revenue reported to Singular: AdPlatform: ${data.adPlatform}, Currency: ${data.currency}, Revenue: ${data.revenue}");
}
}
Not Supported:
ironSource does not natively support capturing ad revenue on the Cordova framework.
For advanced ad revenue tracking, you might need to integrate with the native ironSource's SDKs directly or use a custom plugin to bridge the functionality between Cordova and the native SDKs. If you require ad revenue data, consider reaching out to ironSource support for the most current information or looking into alternative methods to capture this data.
How it works:
- Uses the ironSource React Native Plugin to get Impression-Level User Revenue: See the Getting Started Guide.
- Ironsource Integration: Load a rewarded ad from Ironsource and use the onImpressionDataSuccess listener to handle Ad Revenue events.
- Revenue Validation: Add a check to ensure that revenue is greater than 0. This prevents sending zero or negative revenue values.
- Currency Validation: In the sample below, the currency is hard coded to "USD". Ensure that the currency is accurate and not nil or empty before sending data to Singular.
- Logging Invalid Data: If the data fails validation, print a log message for debugging, and do not send the data to Singular.
import { Singular } from 'singular-react-native';
const { IronSourceModule } = NativeModules;
const ironSourceEventEmitter = new NativeEventEmitter(IronSourceModule);
const AD_PLATFORM = 'IronSource';
const CURRENCY = 'USD'; // Assuming USD, adjust if necessary
ironSourceEventEmitter.addListener('onImpressionDataSuccess', (impressionData) => {
if (!impressionData) {
console.log('No impression data available.');
return;
}
const revenue = impressionData.revenue;
// Validate the revenue to ensure it is within the expected range
if (revenue <= 0) {
console.warn(`Invalid revenue value: ${revenue}`);
return;
}
// Create SingularAdData object with valid values
const data = {
adPlatform: AD_PLATFORM,
currency: CURRENCY,
revenue: revenue,
};
// Send the revenue data to Singular
Singular.adRevenue(data);
// Log the data for debugging purposes
console.log(`Ad Revenue reported to Singular: AdPlatform: ${data.adPlatform}, Currency: ${data.currency}, Revenue: ${data.revenue}`);
});
How it works:
- Uses the ironSource Unity Plugin to get Impression-Level User Revenue: See the Getting Started Guide.
- Ironsource Integration: Load a rewarded ad from Ironsource and use the ImpressionDataReadyEvent function to handle Ad Revenue events.
- Revenue Validation: Add a check to ensure that revenue is greater than 0. This prevents sending zero or negative revenue values.
- Currency Validation: In the sample below, the currency is hard coded to "USD". Ensure that the currency is accurate and not nil or empty before sending data to Singular.
- Logging Invalid Data: If the data fails validation, print a log message for debugging, and do not send the data to Singular.
using Singular;
public class IronSourceRewardedAdViewController : MonoBehaviour
{
void Start()
{
// Ensure the listener is added before initializing the SDK
IronSourceEvents.onImpressionDataReadyEvent += ImpressionDataReadyEvent;
// Initialize the IronSource SDK here if not already done
// IronSource.Agent.init("YOUR_IRONSOURCE_APP_KEY");
}
private void ImpressionDataReadyEvent(IronSourceImpressionData impressionData)
{
if (impressionData != null)
{
// Ensure revenue value is valid
double? revenue = impressionData.revenue;
if (revenue.HasValue && revenue.Value > 0)
{
// Create SingularAdData object with appropriate values
SingularAdData adData = new SingularAdData(
"IronSource",
"USD",
revenue.Value
);
// Send the Ad Revenue data to Singular
SingularSDK.AdRevenue(adData);
// Log the data for debugging
Debug.Log($"Ad Revenue reported to Singular: AdPlatform: {adData.AdPlatform}, Currency: {adData.Currency}, Revenue: {adData.Revenue}");
}
else
{
Debug.LogError($"Invalid revenue value: {revenue}");
}
}
else
{
Debug.LogError("Impression data is null.");
}
}
void OnDestroy()
{
// Detach the callback to prevent memory leaks
IronSourceEvents.onImpressionDataReadyEvent -= ImpressionDataReadyEvent;
}
}
Partner Notes
- Set the impressionDelegate
- Add Singular to the TradPlusAdImpression Callback
Select the code base for your SDK implementation:
How it works:
- TradPlus Integration: Load a rewarded ad from TradPlus and use the tradPlusAdImpression function to handle Ad Revenue events.
- Revenue Validation: Add a check to ensure that revenue is greater than 0. This prevents sending zero or negative revenue values. The adInfo dictionary contains an "ecpm" key with a valid NSNumber value. It converts this value to a Double and scales it (typically ecpm is given in milli-units, so dividing by 1000.0 converts it to dollars).
- Currency Validation: In the sample below, the currency is hard coded to "USD". Ensure that the currency is accurate and not nil or empty before sending data to Singular.
- Logging Invalid Data: If the data fails validation, print a log message for debugging, and do not send the data to Singular.
import Singular
// Set up the delegate
TradPlus.sharedInstance().impressionDelegate = self
// Delegate method for handling ad impressions
func tradPlusAdImpression(_ adInfo: [String: Any]) {
let currency = "USD" // Assuming USD, adjust if necessary
// Ensure adInfo contains the necessary key and its value is valid
if let ecpmValue = adInfo["ecpm"] as? NSNumber {
let revenue = ecpmValue.doubleValue / 1000.0
// Validate the revenue value
guard revenue > 0 else {
print("Ad Revenue value out of expected range: \(revenue)")
return
}
// Create SingularAdData object with required fields
let data = SingularAdData(
adPlatform: "TradPlus",
currency: currency,
revenue: revenue
)
// Send the Ad Revenue data to Singular
Singular.adRevenue(data)
print("Ad Revenue reported to Singular: \(data)")
} else {
// Log the issue for debugging
print("No eCPM data available in adInfo")
}
}
How it works:
- TradPlus Integration: Load a rewarded ad from TradPlus and use the tradPlusAdImpression function to handle Ad Revenue events.
- Revenue Validation: Add a check to ensure that revenue is greater than 0. This prevents sending zero or negative revenue values. The adInfo dictionary contains an "ecpm" key with a valid NSNumber value. It converts this value to a Double and scales it (typically ecpm is given in milli-units, so dividing by 1000.0 converts it to dollars).
- Currency Validation: In the sample below, the currency is hard coded to "USD". Ensure that the currency is accurate and not nil or empty before sending data to Singular.
- Logging Invalid Data: If the data fails validation, print a log message for debugging, and do not send the data to Singular.
#import <Singular/Singular.h>
// Set up the delegate
TradPlus.sharedInstance.impressionDelegate = self;
// Delegate method for handling ad impressions
- (void)tradPlusAdImpression:(NSDictionary<NSString *, id> *)adInfo {
NSString *currency = @"USD"; // Assuming USD, adjust if necessary
// Ensure adInfo contains the necessary key and its value is valid
NSNumber *ecpmValue = adInfo[@"ecpm"];
if (ecpmValue) {
double revenue = [ecpmValue doubleValue] / 1000.0;
// Validate the revenue value
if (revenue <= 0) {
NSLog(@"Ad Revenue value out of expected range: %f", revenue);
return;
}
// Create SingularAdData object with required fields
SingularAdData *data = [[SingularAdData alloc] initWithAdPlatfrom:@"TradPlus"
currency:currency
revenue:revenue];
// Send the Ad Revenue data to Singular
[Singular adRevenue:data];
NSLog(@"Ad Revenue reported to Singular: AdPlatform: %@, Currency: %@, Revenue: %f", data.adPlatform, data.currency, data.revenue);
} else {
// Log the issue for debugging
NSLog(@"No eCPM data available in adInfo");
}
}
How it works:
- TradPlus Integration: Load a rewarded ad from TradPlus and use the onImpressionSuccess function to handle Ad Revenue events.
- Revenue Validation: Add a check to ensure that revenue is greater than 0. This prevents sending zero or negative revenue values. The adInfo dictionary contains an "ecpm" key with a valid NSNumber value. It converts this value to a Double and scales it (typically ecpm is given in milli-units, so dividing by 1000.0 converts it to dollars).
- Currency Validation: In the sample below, the currency is hard coded to "USD". Ensure that the currency is accurate and not nil or empty before sending data to Singular.
- Logging Invalid Data: If the data fails validation, print a log message for debugging, and do not send the data to Singular.
import com.singular.sdk.Singular
import com.singular.sdk.SingularAdData
// Set the global impression listener for TradPlus
TradPlusSdk.setGlobalImpressionListener(
object : GlobalImpressionManager.GlobalImpressionListener {
override fun onImpressionSuccess(tpAdInfo: TPAdInfo?) {
// Ensure tpAdInfo is not null
if (tpAdInfo == null) {
println("AdInfo is null")
return
}
// Calculate revenue (assuming ecpm is a valid field)
val revenue = tpAdInfo.ecpm.toDouble() / 1000
// Validate the revenue value
if (revenue <= 0) {
println("Ad Revenue value out of expected range: $revenue")
return
}
// Create SingularAdData object with required fields
val data = SingularAdData(
adPlatform = "TradPlus",
currency = "USD", // Assuming USD, adjust if necessary
revenue = revenue
)
// Send the Ad Revenue data to Singular
Singular.adRevenue(data)
// Log for debugging
println("Ad Revenue reported to Singular: AdPlatform: ${data.adPlatform}, Currency: ${data.currency}, Revenue: ${data.revenue}")
}
}
)
How it works:
- TradPlus Integration: Load a rewarded ad from TradPlus and use the onImpressionSuccess function to handle Ad Revenue events.
- Revenue Validation: Add a check to ensure that revenue is greater than 0. This prevents sending zero or negative revenue values. The adInfo dictionary contains an "ecpm" key with a valid NSNumber value. It converts this value to a Double and scales it (typically ecpm is given in milli-units, so dividing by 1000.0 converts it to dollars).
- Currency Validation: In the sample below, the currency is hard coded to "USD". Ensure that the currency is accurate and not nil or empty before sending data to Singular.
- Logging Invalid Data: If the data fails validation, print a log message for debugging, and do not send the data to Singular.
import com.singular.sdk.Singular;
import com.singular.sdk.SingularAdData;
public class AdImpressionListener implements GlobalImpressionManager.GlobalImpressionListener {
private static final String TAG = "AdImpressionListener";
@Override
public void onImpressionSuccess(TPAdInfo tpAdInfo) {
// Ensure tpAdInfo is not null
if (tpAdInfo == null) {
Log.e(TAG, "AdInfo is null");
return;
}
// Ensure eCPM is valid and not null
if (tpAdInfo.getEcpm() == null) {
Log.e(TAG, "eCPM value is null");
return;
}
// Calculate revenue (assuming ecpm is in micros)
double revenue = tpAdInfo.getEcpm().doubleValue() / 1000;
// Validate the revenue value
if (revenue <= 0) {
Log.e(TAG, "Ad Revenue value out of expected range: " + revenue);
return;
}
// Create SingularAdData object with required fields
SingularAdData data = new SingularAdData(
"TradPlus",
"USD",
revenue
);
// Send the Ad Revenue data to Singular
Singular.adRevenue(data);
// Log for debugging
Log.d(TAG, "Ad Revenue reported to Singular: AdPlatform: " + data.getAdPlatform() +
", Currency: " + data.getCurrency() + ", Revenue: " + data.getRevenue());
}
}
How it works:
- TradPlus Integration: Load a rewarded ad from TradPlus and use the setGlobalImpressionListener to handle Ad Revenue events.
- Revenue Validation: Add a check to ensure that revenue is greater than 0. This prevents sending zero or negative revenue values. The adInfo dictionary contains an "ecpm" key with a valid NSNumber value. It converts this value to a Double and scales it (typically ecpm is given in milli-units, so dividing by 1000.0 converts it to dollars).
- Currency Validation: In the sample below, the currency is hard coded to "USD". Ensure that the currency is accurate and not nil or empty before sending data to Singular.
- Logging Invalid Data: If the data fails validation, print a log message for debugging, and do not send the data to Singular.
import 'package:singular_flutter_sdk/singular.dart';
void setupTradPlusImpressionListener() {
// Set up the global impression listener
TradPlusSdk.setGlobalImpressionListener((tpAdInfo) {
if (tpAdInfo == null) {
print("AdInfo is null");
return;
}
// Ensure eCPM is not null
if (tpAdInfo.ecpm == null) {
print("eCPM value is null");
return;
}
// Calculate revenue (assuming ecpm is in micros)
double revenue = tpAdInfo.ecpm / 1000.0;
// Validate the revenue value
if (revenue <= 0) {
print("Ad Revenue value out of expected range: $revenue");
return;
}
// Create SingularAdData object
final data = SingularAdData(
adPlatform: "TradPlus", // Ad platform name
currency: "USD", // Currency
revenue: revenue // Revenue
);
// Send the Ad Revenue data to Singular
Singular.adRevenue(data);
// Print log for debugging
print("Ad Revenue reported to Singular: AdPlatform: ${data.adPlatform}, Currency: ${data.currency}, Revenue: ${data.revenue}");
});
}
void main() {
// Initialize TradPlus SDK and other setup
setupTradPlusImpressionListener();
// Run your app
runApp(MyApp());
}
Not Supported:
TradPlus does not natively support capturing ad revenue information through the adInfo object. The Cordova SDK is typically more limited in terms of advanced features compared to the native SDKs for Android and iOS.
For advanced ad revenue tracking, you might need to integrate with the native TradPlus SDKs directly or use a custom plugin to bridge the functionality between Cordova and the native SDKs. If you require ad revenue data, consider reaching out to AppLovin support for the most current information or looking into alternative methods to capture this data.
How it works:
- TradPlus Integration: Load a rewarded ad from TradPlus and set an onImpressionSuccess listener to handle Ad Revenue events.
- Revenue Validation: Add a check to ensure that revenue is greater than 0. This prevents sending zero or negative revenue values. The adInfo dictionary contains an "ecpm" key with a valid NSNumber value. It converts this value to a Double and scales it (typically ecpm is given in milli-units, so dividing by 1000.0 converts it to dollars).
- Currency Validation: In the sample below, the currency is hard coded to "USD". Ensure that the currency is accurate and not nil or empty before sending data to Singular.
- Logging Invalid Data: If the data fails validation, print a log message for debugging, and do not send the data to Singular.
import { NativeModules, NativeEventEmitter } from 'react-native';
import { Singular } from 'singular-react-native';
const { TradPlusModule } = NativeModules;
const tradPlusEventEmitter = new NativeEventEmitter(TradPlusModule);
const AD_PLATFORM = 'TradPlus';
const CURRENCY = 'USD'; // Assuming USD, adjust if necessary
tradPlusEventEmitter.addListener('onImpressionSuccess', (tpAdInfo) => {
if (!tpAdInfo) {
console.log('AdInfo is null');
return;
}
const revenue = tpAdInfo.ecpm / 1000;
// Validate the revenue to ensure it is within the expected range
if (revenue <= 0) {
console.warn(`Ad Revenue value out of expected range: ${revenue}`);
return;
}
// Create the ad revenue data object
const data = {
adPlatform: AD_PLATFORM,
currency: CURRENCY,
revenue: revenue,
};
// Send the revenue data to Singular
Singular.adRevenue(data);
// Log the data for debugging purposes
console.log(`Ad Revenue reported to Singular: AdPlatform: ${data.adPlatform}, Currency: ${data.currency}, Revenue: ${data.revenue}`);
});
How it works:
- TradPlus Integration: Load a rewarded ad from TradPlus and use the onImpressionSuccess function to handle Ad Revenue events.
- Revenue Validation: Add a check to ensure that revenue is greater than 0. This prevents sending zero or negative revenue values. The adInfo dictionary contains an "ecpm" key with a valid NSNumber value. It converts this value to a Double and scales it (typically ecpm is given in milli-units, so dividing by 1000.0 converts it to dollars).
- Currency Validation: In the sample below, the currency is hard coded to "USD". Ensure that the currency is accurate and not nil or empty before sending data to Singular.
- Logging Invalid Data: If the data fails validation, print a log message for debugging, and do not send the data to Singular.
using Singular;
public class AdImpressionListener : MonoBehaviour
{
private const string TAG = "AdImpressionListener";
void Start()
{
// Add Global Ad Impression Listener
TradplusAds.Instance().AddGlobalAdImpression(OnGlobalAdImpression);
}
void OnGlobalAdImpression(Dictionary<string, object> adInfo)
{
// Ensure adInfo is not null
if (adInfo == null)
{
Debug.LogError($"{TAG}: AdInfo is null");
return;
}
// Ensure eCPM is present and valid
if (!adInfo.ContainsKey("ecpm") || adInfo["ecpm"] == null)
{
Debug.LogError($"{TAG}: eCPM value is null or missing");
return;
}
// Parse the eCPM value
if (!double.TryParse(adInfo["ecpm"].ToString(), NumberStyles.Float | NumberStyles.AllowThousands, CultureInfo.InvariantCulture, out double revenue))
{
Debug.LogError($"{TAG}: Failed to parse eCPM value");
return;
}
// Convert eCPM to revenue (assuming eCPM is in micros)
revenue = revenue / 1000;
// Validate the revenue value
if (revenue <= 0)
{
Debug.LogError($"{TAG}: Ad Revenue value out of expected range: " + revenue);
return;
}
// Create SingularAdData object with the necessary fields
SingularAdData data = new SingularAdData(
"TradPlus", // Ad platform name
"USD", // Currency
revenue // Revenue value
);
// Send the Ad Revenue data to Singular
SingularSDK.AdRevenue(data);
// Log the data for debugging purposes
Debug.Log($"{TAG}: Ad Revenue reported to Singular: AdPlatform: {data.AdPlatform}, Currency: {data.Currency}, Revenue: {data.Revenue}");
}
}
Partner Notes
- Generic Integration: Initialize a SingularAdData object and pass the required data. Data should include the adPlatform as a String, currency as a String, and revenue as a Double.
- Revenue Reporting: Check that your revenue and currency data are correct before sending it to Singular. Incorrect data can NOT be fixed later, so it’s crucial to ensure it’s accurate.
- Tip: Log information for debugging purposes.
Select the code base for your SDK implementation:
import Singular
// Function to send Ad Revenue data to Singular
func reportAdRevenue(adPlatform: String, currency: String, revenue: Double) {
// Validate the revenue value
guard revenue > 0 else {
print("Invalid revenue value: \(revenue)")
return
}
// Create a SingularAdData object with the provided fields
let data = SingularAdData(
adPlatform: adPlatform,
currency: currency,
revenue: revenue
)
// Send the Ad Revenue data to Singular
Singular.adRevenue(data)
// Log the data for debugging
print("Ad Revenue reported to Singular: AdPlatform: \(data.adPlatform), Currency: \(data.currency), Revenue: \(data.revenue)")
}
#import <Singular/Singular.h>
// Function to send Ad Revenue data to Singular
- (void)reportAdRevenueWithPlatform:(NSString *)adPlatform currency:(NSString *)currency revenue:(double)revenue {
// Validate the revenue value
if (revenue <= 0) {
NSLog(@"Invalid revenue value: %f", revenue);
return;
}
// Create a SingularAdData object with the provided fields
SingularAdData *data = [[SingularAdData alloc] initWithAdPlatfrom:adPlatform currency:currency revenue:revenue];
// Send the Ad Revenue data to Singular
[Singular adRevenue:data];
// Log the data for debugging
NSLog(@"Ad Revenue reported to Singular: AdPlatform: %@, Currency: %@, Revenue: %f", data.adPlatform, data.currency, data.revenue);
}
import com.singular.sdk.Singular
import com.singular.sdk.SingularAdData
// Function to send Ad Revenue data to Singular
fun reportAdRevenue(adPlatform: String, currency: String, revenue: Double) {
// Validate the revenue value
if (revenue <= 0) {
println("Invalid revenue value: $revenue")
return
}
// Create a SingularAdData object with the provided fields
val data = SingularAdData(
adPlatform = adPlatform,
currency = currency,
revenue = revenue
)
// Send the Ad Revenue data to Singular
Singular.adRevenue(data)
// Log the data for debugging
println("Ad Revenue reported to Singular: AdPlatform: ${data.adPlatform}, Currency: ${data.currency}, Revenue: ${data.revenue}")
}
import com.singular.sdk.Singular;
import com.singular.sdk.SingularAdData;
// Function to send Ad Revenue data to Singular
public void reportAdRevenue(String adPlatform, String currency, double revenue) {
// Validate the revenue value
if (revenue <= 0) {
Log.w("AdRevenue", "Invalid revenue value: " + revenue);
return;
}
// Create a SingularAdData object with the provided fields
SingularAdData data = new SingularAdData(
adPlatform, // adPlatform
currency, // currency
revenue // revenue
);
// Send the Ad Revenue data to Singular
Singular.adRevenue(data);
// Log the data for debugging
Log.d("AdRevenue", "Ad Revenue reported to Singular: AdPlatform: " + data.getAdPlatform() + ", Currency: " + data.getCurrency() + ", Revenue: " + data.getRevenue());
}
import 'package:singular_flutter_sdk/singular.Flutter';
// Function to send Ad Revenue data to Singular
void reportAdRevenue({
required String adPlatform,
required String currency,
required double revenue,
}) {
// Validate the revenue value
if (revenue <= 0) {
print('Invalid revenue value: $revenue');
return;
}
// Create a SingularAdData object with the provided fields
final data = SingularAdData(
adPlatform: adPlatform,
currency: currency,
revenue: revenue,
);
// Send the Ad Revenue data to Singular
Singular.adRevenue(data);
// Log the data for debugging
print('Ad Revenue reported to Singular: AdPlatform: ${data.adPlatform}, Currency: ${data.currency}, Revenue: ${data.revenue}');
}
// Function to report Ad Revenue to Singular
function reportAdRevenue(mediationPlatform, currencyCode, revenueAmount) {
// Validate input values
if (!mediationPlatform || !currencyCode || typeof revenueAmount !== 'number' || revenueAmount <= 0) {
console.error("Invalid input for Ad Revenue reporting: ", {
mediationPlatform,
currencyCode,
revenueAmount
});
return;
}
try {
// Create a SingularAdData object
const adData = new cordova.plugins.SingularCordovaSdk.SingularAdData(
mediationPlatform,
currencyCode, // e.g., "USD"
revenueAmount
);
// Report Ad Revenue to Singular
cordova.plugins.SingularCordovaSdk.adRevenue(adData);
// Log success
console.log("Ad Revenue reported successfully: ", {
mediationPlatform: adData.mediationPlatform,
currencyCode: adData.currencyCode,
revenueAmount: adData.revenueAmount
});
} catch (error) {
// Log any errors that occur during the process
console.error("Failed to report Ad Revenue: ", error);
}
}
import { Singular } from 'singular-react-native';
const reportAdRevenue = (adPlatform, currency, revenue) => {
// Validate the revenue value
if (revenue <= 0) {
console.warn(`Invalid revenue value: ${revenue}`);
return;
}
// Create a SingularAdData object with the provided fields
const data = {
adPlatform: adPlatform,
currency: currency,
revenue: revenue,
};
// Send the Ad Revenue data to Singular
Singular.adRevenue(data);
// Log the data for debugging
console.log(`Ad Revenue reported to Singular: AdPlatform: ${data.adPlatform}, Currency: ${data.currency}, Revenue: ${data.revenue}`);
};
using Singular;
public class AdRevenueReporter : MonoBehaviour
{
// Function to report ad revenue to Singular
public void ReportAdRevenue(string adPlatform, float revenueInMicros, string currency)
{
// Convert revenue from micros to the standard unit (e.g., dollars)
float revenue = revenueInMicros / 1_000_000f;
// Validate the input: ensure revenue is positive and currency is not null or empty
if (revenue > 0 && !string.IsNullOrEmpty(currency))
{
// Create a SingularAdData object with the validated data
SingularAdData data = new SingularAdData(
adPlatform,
currency,
revenue
);
// Send the ad revenue data to Singular
SingularSDK.AdRevenue(data);
// Log the reported data for debugging
Debug.Log($"Ad Revenue reported to Singular: Platform = {adPlatform}, Currency = {currency}, Revenue = {revenue}");
}
else
{
// Log a warning if validation fails
Debug.LogWarning("Invalid ad revenue data: " +
$"Platform = {adPlatform}, Revenue = {revenue}, Currency = {currency}");
}
}
}