chinese_sdk_metadata_s2s_callbacks - unity-cn/unityads-help-cn GitHub Wiki

服务器端回调会在游戏玩家完整观看了一个广告后,发送到您的服务器。您可以使用这些回调作为奖励玩家的依据,和检测并预防玩家作弊。
提示:
目前服务器端回调设置还没有在开发者后台开放。
如果您有游戏需要设置,请联系广告技术支持并提供以下信息:
Unity Game ID
callback URL(s)
我们会回复您一个用于签名和验证回调的秘钥。
在您的游戏玩家完整观看了一个广告后,Unity Ads服务器会发送一个签名回调至您提供的URL。这个过程会在广告即将播放结束前完成,以便能够在玩家返回游戏前完成奖励流程。但请在广告播放完毕后再提示玩家领取激励,以免干扰玩家观看完广告。
因网络因素,接收激励回调会有一定时延。为了使玩家有流畅的体验,请在广告播放完毕后立刻下发奖励,然后使用服务器端回调作为防作弊用途。
想要使用服务器端回调,您需要在展示广告前设置 server ID (sid)。
Unity 集成样例:
using UnityEngine;
using System.Collections;
using UnityEngine.Advertisements;
public class UnityAdsManager : MonoBehaviour
{
// an integer string of usually 5-7 digits, example: "12345"
public string gameId;
public string placement = "rewardedVideo"
// Call this function when Advertisement.IsReady == true
public void showAd() {
ShowOptions options = new ShowOptions();
// setting the server ID
options.gamerSid = "example";
Advertisement.Show (placement, options);
}
}
在 Android 和 iOS 原生集成环境下,则需要使用 Unity Ads SDK的 PlayerMetaData
类实现。
Android 实现样例:
if(UnityAds.isReady()) {
PlayerMetaData playerMetaData = new PlayerMetaData(context);
playerMetaData.setServerId("example");
playerMetaData.commit();
UnityAds.show(activity);
}
iOS 实现样例:
if([UnityAds isReady]) {
id playerMetaData = [[UADSPlayerMetaData alloc] init];
[playerMetaData setServerId:@"example"];
[playerMetaData commit];
[UnityAds show:self];
}
服务器端回调是从 https://static.applifier.com/public_ips.json 内的 IP地址/网络发出,这些IP地址/网络会在每月第一天更新。开发者可以放心的忽略或屏蔽从其他地方发送来的回调。
回调请求是一个如下格式的 HTTP/1.1 GET 请求:
[CALLBACK_URL][SEPARATOR1]sid=[SID][SEPARATOR]oid=[OID][SEPARATOR]hmac=[SIGNATURE]
格式中的各参数值的解释:
参数 | 内容 |
---|---|
CALLBACK_URL | 回调的base URL, 例如:https://developer.example.com/award.php?productid=1234 设置此URL需要联系广告技术支持。 |
SEPARATOR1 | ? 或者 & 如果 base URL 里没有使用 ? 则使用 ? 否则使用 & |
SID | 玩家ID 或 其他任何您想要发送至您服务器的数据项,比如 1234567890 。上文中的代码样例展示了如何在不同平台上设置 server ID。 |
SEPARATOR | & |
OID | Unity Ads 服务器生成的唯一 Offer ID, 比如 0987654321
|
SIGNATURE | 一个 HDMAC-MD5 加密的字符串,比如 106ed4300f91145aff6378a355fced73
|
回调请求里有一个签名参数。这个签名是通过对,串联回调URL里除hmac
外的所有key=value参数对(以字母顺序排序,英文逗号,
分隔)得到的字符串,进行 HDMAC-MD5 加密得到的。
例如:
https://developer.example.com/award.php?productid=1234&sid=1234567890&oid=0987654321
串联 参数对 得到字符串 (字母顺序排序,英文逗号,
隔开)
oid=0987654321,productid=1234,sid=1234567890
以密钥xyzKEY
加密字符串得到签名 (技术支持在帮您设置回调时会为您提供这个密钥)
106ed4300f91145aff6378a355fced73
注意:
在生成签名时,请包含回调URL中的所有的参数(除hmac),并以字母顺序排列,用英文逗号,
隔开。否则生成的签名将无法匹配。
如果回调通过了全部验证且玩家拿到了游戏奖励,请返回 HTTP/1.1 200 OK,同时在返回的 body 里包含字符 “1″:
HTTP/1.1 200 OK
Date: Wed, 22 Feb 2012 23:59:59 GMT
Content-Length: 8
1
如果出现错误,则需要返回 400- 或 500- 段的 HTTP error 并包含可读的报错信息 (例如,OID已经使用过;签名不匹配;或其他任何导致玩家无法获得奖励的报错):
HTTP/1.1 400 ERROR
Date: Wed, 22 Feb 2012 23:59:59 GMT
Content-Length: 12
Duplicate order
下面举例如何使用 node.js + express 实现签名验证:
// NODE.js S2S callback endpoint sample implementation
// Unity Ads
var express = require('express');
var crypto = require('crypto')
var app = express();
app.listen(process.env.PORT || 3412);
function getHMAC(parameters, secret) {
var sortedParameterString = sortParams(parameters);
return crypto.createHmac('md5', secret).update(sortedParameterString).digest('hex');
}
function sortParams(parameters) {
var params = parameters || {};
return Object.keys(params)
.filter(key => key !== 'hmac')
.sort()
.map(key => params[key] === null ? `${key}=` : `${key}=${params[key]}`)
.join(',');
}
app.get('/', function (req, res) {
var sid = req.query.sid;
var oid = req.query.oid;
var hmac = req.query.hmac;
// Save the secret as an environment variable. If none is set, default to xyzKEY
var secret = process.env.UNITYADSSECRET || 'xyzKEY';
var newHmac = getHMAC(req.query, secret);
if (hmac === newHmac) {
// Signatures match
// Check for duplicate oid here (player already received reward) and return 403 if it exists
// If there's no duplicate - give virtual goods to player. Return 500 if it fails.
// Save the oid for duplicate checking. Return 500 if it fails.
// Callback passed, return 200 and include '1' in the message body
res.status(200).send('1');
} else {
// no match
res.sendStatus(403);
}
});
下面举例如何使用 PHP 实现签名验证:
<?php
function generate_hash($params, $secret) {
ksort($params); // All parameters are always checked in alphabetical order
$s = '';
foreach ($params as $key => $value) {
$s .= "$key=$value,";
}
$s = substr($s, 0, -1);
$hash = hash_hmac('md5', $s, $secret);
return $hash;
}
$hash = $_GET['hmac'];
unset($_GET['hmac']);
$signature = generate_hash($_GET, 'xyzKEY'); // insert here the secret hash key you received from Unity Ads support
error_log("req hmac".$hash);
error_log("sig hmac".$signature);
// check signature
if($hash != $signature) { header('HTTP/1.1 403 Forbidden'); echo "Signature did not match"; exit; }
// check duplicate orders
if(check_duplicate_orders($_GET['oid']) { header('HTTP/1.1 403 Forbidden'); echo "Duplicate order"; exit; }
// if not then give the player the item and check that it succeeds.
if(!give_item_to_player($_GET['sid'], $_GET['product']) { header('HTTP/1.1 500 Internal Server Error'); echo "Failed to give item to the player"; exit; }
// save the order ID for duplicate checking
if(save_order_number($_GET['oid']) { header('HTTP/1.1 500 Internal Server Error'); echo "Order ID saving failed, user granted item"; exit; }
// everything OK, return "1"
header('HTTP/1.1 200 OK');
echo "1";
?>