Server-to-server callbacks
You can manage your application data in Unity Mediation by implementing server-to-server (S2S) redeem callbacks to an external server. This notifies you when a user of your app successfully completes a rewarded video ad and qualifies to receive a reward. Use these callbacks to add a layer of protection in your app against users who try to abuse your game economy and cheat the rewarding system without actually viewing a rewarded ad.
Note: When an ad served is from a third-party Ad Source, we also send a server-to-server redeem callback. This is sent for all rewarded videos, regardless of ad network. We recommend that publishers turn off redeem callbacks on the ad network side to avoid getting sent the callback twice.
How it works
Publishers need to provide a callback URL so it can receive notifications from the Unity Mediation backend, and generate a Secret Key that is used to create a hash-based message authentication code (HMAC). Both the callback URL and Secret Key are stored in a database.
To grant an in-app reward, publishers need to set the User ID before they show the rewarded ad in the SDK. Publishers also need to add an optional parameter (for example, RewardedAdShowOptions
) when showing a rewarded ad, where the optional parameter contains an S2SRedeemData
object that specifies a User ID to know which player to reward. In addition, you can add custom data parameters (for example, the type of reward, amount of the reward, and so on.)
When a rewarded video close event occurs, the SDK makes calls to the backend, including the Mediation S2S service to start the redeem callback flow. This means that in your app, when a user views a rewarded video ad to its full completion, an event fires to acknowledge that the user meets the requirements to receive a reward.
The Mediation S2S service listens to project updates, and when it receives requests from the SDK, it appends USER_ID, EVENT_ID, TIMESTAMP, SIGNATURE, and CUSTOMIZED_DATA as parameters to the callback URL. This URL is forwarded to the redeem-callbacks service, where the dispatcher will send GET requests by using the Callback URL format.
If the Unity Mediation SDK receives a non-200 response HTTP failed request code from the Mediation S2S redeem callback service, the Unity Mediation SDK retries the callback up to three times after the first attempt. For more information, see the Callback response section.
To ensure a smooth gameplay experience, minimize delays when issuing a reward and simplify the process for publishers to account for cheaters. Also, when a user completes a rewarded video ad and meets the requirements to receive the reward, reward them immediately, because callbacks can take some time to be performed.
We recommend that you use S2S callbacks to retroactively review the validation of a rewarded video ad reward.
Prerequisites
To implement S2S callbacks in your app:
Set up and use rewarded video ads in your app:
Modify the
Show
call of your rewarded ad to include S2S data (see code examples for Unity, Android, and iOS)Use the Unity Mediation SDK version 0.4.0 or later
Callback information
Callback URL format
The request is an HTTP/1.1 GET
request to a URL of the following format:
[CALLBACK_URL]?customized_data=[CUSTOMIZED_DATA]&eventId=[EVENT_ID]×tamp=[TIMESTAMP]&userId=[USER_ID]&signature=[SIGNATURE]
The following table describes each of the query parameters:
Parameter | Content |
---|---|
CALLBACK_URL | The server URL that is provided by publishers to receive redeem callbacks. For example:
Note: Ensure that you use a valid URL for the Callback URL. You cannot use an IP address. |
CUSTOMIZED_DATA | Customized data (optional). |
USER_ID | The User ID provided by the publisher of any custom data you want to send to your endpoint. |
EVENT_ID | The unique ID generated by Unity Mediation. |
TIMESTAMP | The timestamp in Unix format. |
SIGNATURE | A HMAC-MD5 hash of a parameter string consisting of:
|
Formatted callback URL example
https://developer.example.com/award.php?CUSTOMIZED_DATA=productId124012&eventId=123412×tamp=12351239174&userId=14087534123&signature=cxvdghioweytadf
Sign the Callback URL
The Callback URL request has a signature attached to the URL parameters. The signature is a HDMAC-MD5 hash of a parameter string created by concatenating all of the URL parameters in key-value form (except the HMAC) in alphabetical order, separated by commas. The signature only takes the EVENT_ID, TIMESTAMP, and USER_ID parameters into consideration for validation, respectively. CUSTOMIZED_DATA and other optional parameters are not required to be included in the signature validation process.
The following is an example of a callback URL with an EVENT_ID, TIMESTAMP, and USER_ID:
https://developer.example.com/award.php?eventId=123412×tamp=12351239174&userId=14087534123
This callback has the following parameter string:
eventId=123412, timestamp=12351239174, userId=14087534123
This parameter string is hashed with the Secret Key generated in the Unity Dashboard that the rewarded video callback fires to a URL. In this specific example, the strings 123412
, 12351239174
, 14087534123
are hashed.
The following is an example of a formatted callback URL with the signature:
https://developer.example.com/award.php?eventId=123412×tamp=12351239174&userId=14087534123&signature=cxvdghioweytadf
Important: All of the parameters included in the Callback URL must be included in the signature calculation in alphabetical order, otherwise the signatures will not match.
Verify the signature in a Callback URL
The following is an example of how a publisher can validate the signature in their server by using Golang:
Golang example
func CreateHMAC(params, secret string) string {
key := [] byte(secret)
h := hmac.New(md5.New, key)
h.Write([] byte(params))
return hex.EncodeToString(h.Sum(nil))
}
func Verify(params map[string][] string, secret string) bool {
signatureReceived := params["signature"][0]
// order: eventId,timestamp,userId
orderedParams := fmt.Sprintf("%s,%s,%s", params["eventId"][0], params["timestamp"][0], params["userId"][0])
signatureCalculated := CreateHMAC(orderedParams, secret)
return signatureCalculated == signatureReceived
}
NodeJS example
const crypto = require("crypto");
function getHMAC(
parameters,
secret,
includeKeyList = ["timestamp", "eventId", "userId"]
) {
var sortedParameterString = sortParams(parameters, includeKeyList);
return crypto
.createHmac("md5", secret)
.update(sortedParameterString)
.digest("hex");
}
function sortParams(parameters, includeKeyList) {
var params = parameters || {};
return Object.keys(params)
.filter((key) => includeKeyList.includes(key))
.sort()
.map((key) => (params[key] !== null ? `${params[key]}` : ``))
.join(",");
}
Callback response
If the request passes validation and a user is granted an award, the callback URL must reply with a HTTP/1.1 200 OK
response and include character 1 in the body of the HTTP request.
The following is an example of a callback response:
HTTP/1.1 200 OK
Date: Wed, 21 Jan 2022 23:59:59 GMT
Content-Length: 8
1
If there is an error, the server returns an HTTP error in the 400
- or the 500
- range with a human-readable error. Reasons why there might be an error include if the EVENT_ID has already been used, a signature does not match, or if the user does not end up with the reward they are supposed to receive.
The following is an example of a callback error response:
HTTP/1.1 400 ERROR
Date: Wed, 21 Jan 2022 23:59:59 GMT
Content-Length: 12
Duplicate order
Set up Unity Mediation S2S callbacks
Configure S2S callback settings in the Unity Dashboard
Note: Only the owners and managers of a project can generate the Secret Key required for the Unity Mediation S2S redeem callback configurations on the Unity Dashboard.
On the Unity Monetization Dashboard , select your project, and then select Project Overview > Ad Units.
Select the Rewarded Ad Unit that you want to configure an S2S callback for.
On the Ad Unit's settings page, go to the S2S Callback Settings section, and then select the edit icon.
Enter a Callback URL by following the Callback URL format.
Note: Ensure that you use a valid URL for the Callback URL. You cannot use an IP address.
Generate a Secret Key to sign in and validate the callback.
Important:
- Copy and store this Secret Key in a safe place for future reference. When you save and finish the configuration, you cannot retrieve this key later because it is encrypted as a hash code.
- If you regenerate the Secret Key, all S2S callbacks in your project that use this existing key will no longer work. Ensure that you update your implementation with the new Secret Key wherever you are decrypting the signature.
- The Secret Key is generated once for your whole project at the project level. The callback URL is defined at the ad unit level, so even in the same project, each rewarded ad unit must be configured with a unique, one callback URL.
Implement S2S callbacks in your project code
To use S2S callbacks, you need to provide a callback URL to receive notifications from the Unity Mediation backend and generate a Secret Key from the Unity Dashboard. You also need to set the User ID before you show the rewarded ad in the SDK.
Unity example
RewardedAdShowOptions showOptions = new RewardedAdShowOptions();
S2SRedeemData s2SData;
s2SData.UserId = "my user id";
s2SData.CustomData = "{\"reward\":\"Gems\",\"amount\":20}";
showOptions.S2SData = s2SData;
m_RewardedAd.Show(showOptions);
Android example
RewardedAd rewardedAd = new RewardedAd(this, "adUnitId");
RewardedAdShowOptions adShowOptions = new RewardedAdShowOptions();
adShowOptions.setS2SRedeemData(new RewardedAdShowOptions.S2SRedeemData(
"my user id", "{\"reward\":\"Gems\",\"amount\":20}"));
rewardedAd.show(showListener, adShowOptions);
iOS example
UMSRewardedAdShowOptions * showOptions = [
[UMSRewardedAdShowOptions alloc]
init
];
showOptions.publisherData.userId = @ "my user id";
showOptions.publisherData.CUSTOMIZED_DATA = @ "{\"reward\":\"Gems\",\"amount\":20}";
[rewardedAd showWithViewController: viewController delegate: delegate showOptions: showOptions];