Rewarded ads are a great way to keep users engaged in your app while earning ad revenue. The reward generally comes in the form of in-game currency (gold, coins, power-ups, etc.) and is distributed to the user after a successful ad completion.
MoPub’s mediation solution officially supports rewarded ads from popular ad networks without any extra integration with network SDKs. We recommend placing rewarded ads where your users are already engaging with in-app purchases or in locations where users may be seeking an in-app rewards, such as at the end of a game level or at currency redemption points. Once your user has completed the rewarded experience, you can designate the reward they will receive.
Before integrating rewarded ads in your app, you must:
- In the MoPub UI, create an account, create an app, and create an ad unit using the format ‘Rewarded Ad’.
- Follow our steps to integrate the MoPub SDK into your project.
- If you use mediation, make sure you have added the ad network SDKs and the corresponding adapters you wish to use to your app.
- Be sure to initialize the MoPub SDK before loading an ad.
Important: Please do not use publisher-provided overlays (such as close buttons) that are located with the ad placement and that subsequently cover the ad creative. Doing so is against MoPub Policy. If you have questions, please visit the Support Center and file a ticket for additional assistance.
Step 1. Import the Required Headers
- Import the
- Import the
Step 2. Initialize the MoPub SDK
Initialize the MoPub SDK on app launches. Typically this is done in your AppDelegate.
It’s not necessary to explicitly initialize any mediated rewarded ad network SDKs via their APIs; the MoPub SDK handles that logic on your behalf.
Step 3. Request and Cache the Rewarded Ad
Cache a rewarded ad for a given ad unit ID (often a placement within the app; for example, a game-over screen or in-app store):
[MPRewardedAds loadRewardedAdWithAdUnitID:adUnitID withMediationSettings:nil];
Note: Ad requests must be made on the main thread.
Step 4. Set the Delegate to Receive Rewarded Ad Events
MPRewardedAds delegate for a given ad unit to allow your app to respond to events for the corresponding ad.
[MPRewardedAds setDelegate:self forAdUnitId:self.info.ID];
Step 5. Show the Rewarded Ad
Check if the rewarded ad has been fully cached by calling
hasAdAvailableForAdUnitID: before offering to play it to the user.
Show the rewarded ad when the user clicks to watch it.
MPRewardreward object, which can be extracted from the
NSStringcontaining any applicable data that is unique to the user and which you want to pass to the ad request.
[MPRewardedAds presentRewardedAdForAdUnitID:adUnitID fromViewController:viewController withReward:reward] customData:customData;
Step 6. Configure the Callback Server
Your callback server must return a 200 HTTP response status code when it successfully receives the reward callback. If your server returns a 500 HTTP response status code, MoPub will continually call the server at increasing intervals until your server returns a 200 HTTP code or the maximum retry limit of 14 is reached. The maximum retry limit is subjected to a two-hour time limit. MoPub stops the retries when your server returns a 200 HTTP response status code.
|HTTP Response Code||Description||When Used|
|200||Successful Request||Return this response code for a successful callback|
|500||Internal Server Error||Return this response code when a callback server error occurs|
If any other HTTP response status code is returned, MoPub logs the response and does not retry.
If the MoPub server detects a failure to connect, it may retry, to ensure that your server receives callbacks. Because of this, there is a slight possibility that your callback server may receive duplicate callbacks (from the same callback URL, for the same rewarded ad). We recommend that you store the hash ID (the value from the
%%VERIFIER%% macro) and only give a user one reward for each unique ID.
To secure the callback sent from MoPub to your callback server, the
%%VERIFIER%% macro must be present in the callback URL. The
%%VERIFIER%% is a SHA256 hash generated from the callback’s parameter values and uses a Secret Key. You can find the Callback Secret Key in the MoPub UI Account Settings page.
Your server should use the Callback Secret Key to regenerate the SHA256 hash from the callback’s parameter values. If the hash generated on your server matches the one in the callback sent by MoPub, this signals that the callback is valid and the user should be rewarded.
To generate the hash on the reward server:
|1. Parse the callback URL and retrieve the query parameters.||Callback URL:
|2. Drop the verifier key and value from the array of parameters.||Verifier Hash:
|3. Sort the query parameters alphabetically.||Alphabetical array of query parameters (excluding the verifier)
|4. Concatenate the values in that alphabetical order.||Concatenated String:
|5. Hash the concatenated string using a HMAC SHA256 hash algorithm and the Callback Secret Key.||HMAC SHA256 the concatenated string and the Secret Key: 7dbcfd2a42134f47bfb72daa02f85ec9
* The result:
* The result matches the hash passed in the request
After generating the hash, compare the received hash with your generated hash. They should be identical. Once the hash is verified, your server must return a 200 response code to MoPub and can reward the user.
Refer to our list of available server-side callback macros.
Step 7. Optionally Implement Lifecycle Callbacks
MPRewardedAdsDelegate includes a variety of optional callbacks that you can use to be notified of events; for example, when a rewarded ad has successfully loaded, or when a rewarded ad is about to appear. Refer to
MPRewardedAdsDelegate for the following methods:
- (void)rewardedAdDidLoadForAdUnitID:(NSString *)adUnitID // Called when the ad for the given adUnitId has loaded. At this point you should be able to call presentRewardedAdForAdUnitID to show the ad. - (void)rewardedAdDidFailToLoadForAdUnitID:(NSString *)adUnitID error:(NSError *)error // Called when an ad fails to load for the given adUnitId. The provided error code will provide more insight into the reason for the failure to load. - (void)rewardedAdDidFailToShowForAdUnitID:(NSString *)adUnitID error:(NSError *)error // Called when there is an error while attempting to show the ad. - (void)rewardedAdWillPresentForAdUnitID:(NSString *)adUnitID // Called when a rewarded ad starts playing. - (void)rewardedAdDidPresentForAdUnitID:(NSString *)adUnitID - (void)rewardedAdWillDismissForAdUnitID:(NSString *)adUnitID - (void)rewardedAdDidDismissForAdUnitID:(NSString *)adUnitID // Called when a rewarded ad is closed. At this point your application should resume. - (void)rewardedAdShouldRewardForAdUnitID:(NSString *)adUnitID reward:(MPReward *)reward // Called when a rewarded ad is completed and the user should be rewarded. - (void)rewardedAdDidExpireForAdUnitID:(NSString *)adUnitID // Called when a rewarded ad is expired. - (void)rewardedAdDidReceiveTapEventForAdUnitID:(NSString *)adUnitID - (void)rewardedAdWillLeaveApplicationForAdUnitID:(NSString *)adUnitID /** Called when an impression is fired on a Rewarded Ad. Includes information about the impression if applicable. @param adUnitID The ad unit ID of the rewarded ad that fired the impression. @param impressionData Information about the impression, or @c nil if the server didn't return any information. */ - (void)didTrackImpressionWithAdUnitID:(NSString *)adUnitID impressionData:(MPImpressionData *)impressionData;
Here are a few examples of how callacks can be useful:
To be notified that a rewarded ad was fetched successfully, implement
To pause the game whenever you present a rewarded ad, and resume it when the rewarded ad is dismissed, use the
Advanced Use Cases
Advanced use cases include:
Mediation settings enable you to pass in third-party network specific settings and can be provided as additional parameters during the rewarded ad initialization call. For example, during Unity and Chartboost mediation, this is the only mechanism by which a user ID or customer ID can be specified in networks’ server-side callbacks.
You can pass in an array of configured global mediation objects. These objects are used to configure the underlying ad networks, which, in turn, affect all ads for the specific network. Any ad network may or may not have global mediation settings classes. Using a global mediation settings class involves:
- Creating an instance of the global settings class for any ad networks that may supply ads to your application.
- Configuring the properties on the objects.
- Passing them inside an array when initializing rewarded ad.
Furthermore, you can pass in instance mediation settings when calling
+loadRewardedAdWithAdUnitID:adUnitID withMediationSettings:mediationSettings:. These settings apply to the ad network for the ad unit ID you are using to load an ad. Any ad network may or may not have instance mediation settings classes. Using a instance mediation settings class involves:
- Creating an instance of the mediation settings class for ad networks that may be loaded for your ad unit ID.
- Configuring the properties on the objects.
- Passing them inside an array when loading a rewarded ad.
Passing Custom Data
There may be cases where your reward server needs additional information to determine an appropriate reward for the user. When the rewarded ad is presented, the app can call
+presentRewardedAdForAdUnitID:adUnitID fromViewController:viewController withReward:reward customData:customData, and include an optional string containing custom data. The optional custom data is sent as part of the URL in the server-to-server callback.
We recommended that the custom data String not exceed 8kb in size because this will significantly degrade performance. Try to keep the custom data payload as small as possible.
Custom data is only passed if the ad unit has been set up for server-side callbacks.
In addition to specifying the custom data at presentation time, the server-side callback URL in the MoPub UI must also include a query parameter that uses the
%%CUSTOM_DATA%%macro. For example:
Reward type must be in English only. We do not currently support localized characters.
At this time, we do not support concurrent ad requests using the same ad unit ID.
Due to a known issue with
WKWebViewnot respecting the ringer/mute switch settings to control volume, some creatives may have audio on even when the device is on mute and the volume is non-zero.
How can we make this article better for you?
Last updated March 18, 2021
TWITTER, MOPUB, and the Bird logo are trademarks of Twitter, Inc. or its affiliates. All third party logos and trademarks included are the property of their respective owners.
© 2021 MoPub (a division of Twitter, Inc.)