文档

支持

实现服务器到服务器兑换回调

Set up server-to-server callbacks to securely validate rewarded ad completions to help prevent fraud and ensure accurate reward distribution.
阅读时间5 分钟最后更新于 3 个月前

奖励玩家时可使用服务器到服务器 (S2S) 回调来检测和防止作弊。

工作原理

当玩家完整观看视频广告时,Unity 广告服务器会向您指定的 URL 发送已签名的回调。这个过程发生在视频实际结束之前,因此可以在玩家返回游戏之前完成奖励循环。
S2S redeem callback process

实现

要使用 S2S 回调,您需要在展示广告之前设置服务器 ID (sid)。默认情况下,S2S 兑换回调不可用。如果您需要为项目启用这些回调,请联系支持团队,并在消息中提供您的 Game ID(游戏 ID)及其各自的回调 URL。Unity 将向您发送用于签名和验证回调的密钥哈希值。
要在 C# 代码中实现回调,请将
ShowOptions.gamerSid
值设置为您的服务器 ID,然后通过
Show
方法传递 options 对象。
using UnityEngine;using System.Collections;using UnityEngine.Advertisements;public class UnityAdsManager : MonoBehaviour{ public string gameId; public string placement = "rewardedVideo" public void ShowAd() { ShowOptions options = new ShowOptions(); // setting the server ID options.gamerSid = "your-side-id"; Advertisement.Show(placementID, options); }}

回调信息

回调来源

回调将来自于此处列出的 IP 地址/网络。该列表将在每个月的第一天更新。发行商可以放心忽略或阻止来自任何其他地方的回调。

回调 URL 格式

该请求是对以下格式的 URL 的 HTTP/1.1
GET
请求:
[CALLBACK_URL][SEPARATOR1]sid=[SID][SEPARATOR]oid=[OID][SEPARATOR]hmac=[SIGNATURE]
有关 query 参数的信息,请参阅下表:

参数

内容

CALLBACK_URL
回调 URL 的基 URL,例如:
https://developer.example.com/award.php?productid=1234
。 要配置此参数,请联系支持团队
SEPARATOR1
如果 URL 中不存在
?
,请使用
?
。否则,使用
&
SID
用户 ID 或要发送到终端的任何自定义数据。
SEPARATOR
&
OID
Unity Ads 服务器生成的唯一 Offer ID(优惠 ID)。
SEPARATOR
&
SIGNATURE
参数字符串的 HDMAC-MD5 哈希值 例如:
106ed4300f91145aff6378a355fced73
回调 URL 示例
https://developer.example.com/award.php?productid=1234&sid=1234567890&oid=0987654321&hmac=106ed4300f91145aff6378a355fced73

回调 URL 的签名

回调 URL 请求会将一个签名附加到 URL 参数。该签名是通过以键值形式连接所有 URL 参数(HMAC 除外,按字母顺序排列并以逗号分隔)创建的参数字符串的 HDMAC-MD5 哈希值。 例如,一个包含 SID 和 OID 的回调 URL
https://developer.example.com/award.php?productid=1234&sid=1234567890&oid=0987654321
将具有以下参数字符串:
oid=0987654321,productid=1234,sid=1234567890
此字符串与您即将从支持团队收到的密钥进行哈希处理后,返回一个由奖励回调触发为 URL 的哈希值。例如:
https://developer.example.com/award.php?productid=1234&sid=1234567890&oid=0987654321&hmac=106ed4300f91145aff6378a355fced73

回调响应

如果该请求通过了所有检查并且用户获得了奖励物品,则 URL 必须以
HTTP/1.1 200 OK
响应作为应答并在 HTTP 请求的正文中包含字符
1
。例如:
回调响应示例
HTTP/1.1 200 OKDate: Wed, 22 Feb 2012 23:59:59 GMTContent-Length: 81
如果出现错误(例如,OID 已被使用,或签名不匹配,或者当用户未能获得承诺物品时的任何其他错误),服务器应返回
400
500
范围内的 HTTP 错误,并显示人类可读的错误。例如:
回调错误响应示例
HTTP/1.1 400 ERRORDate: Wed, 22 Feb 2012 23:59:59 GMTContent-Length: 12Duplicate order

node.js 中的回调示例

以下示例演示了如何使用 node.js + express 来验证签名: node.js 中的回调示例
// NODE.js S2S callback endpoint sample implementation// Unity Adsvar 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 中验证签名: PHP 中的回调示例
<?phpfunction 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 supporterror_log("req hmac".$hash);error_log("sig hmac".$signature);// check signatureif($hash != $signature) { header('HTTP/1.1 403 Forbidden'); echo "Signature did not match"; exit; }// check duplicate ordersif(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 checkingif(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";?>