自管理虚拟货币当您使用您自己的服务器管理货币时使用。这种方式可以让您更好的管理您的用户的货币,同时也意味着您要负责存储和分发用户的货币。getCurrencyBalance, awardCurrency, 和 spendCurrency接口只在Tapjoy管理货币可用。Tapjoy并不提供自管理虚拟货币任何客户端或者App端的通知,当我们给您的服务器回调时,您要负责通知app和用户。您必须为自管理虚拟货币设置回调服务器。
注意: Tapjoy会以最快的速度奖励用户,但是我们不能保证每次奖励都是实时的,因为有很多因素都会影响到奖励的花费时间。我们推荐您定期在某些地方检查用户余额,比如应用启动,应用重新激活,升级时,视频关闭时,打开应用商店之前等。我们建议您可以通知客户完成广告需要一定的时间。
注意: 即使自管理虚拟货币,每一个平台都必须定义虚拟货币。
当用户完成广告并获得奖励时,我们会发一个an HTTP GET request到如下URL。参数的格式如下
<callback_url>?snuid=<user_id>¤cy=<currency>&mac_address=<mac_address>
//Example
http://www.sampledoman.com/payments/offers/tapjoy?&snuid=42&currency=50&mac\_address=00-16-41-34-2C-A6
默认的回调参数包括snuid, currency(给用户奖励数目)和用户的wifi mac_address (如果可用).
Tapjoy服务器期望从您的服务器得到200或者403响应。
您的服务器只有在如下情况下给200响应:
您的服务器在如下情况下给403响应:
如果收到了200和403之外的响应,Tapjoy会重试。(注意如果回复非200响应,请不要奖励客户,因为Tapjoy会重试回调,这样的话有可能会导致重复奖励。) 我们会在4天之内每两分钟尝试一次。如果5秒之内没有收到任何响应,我们会任何回调失败。
注意:响应的主体需要是UTF-8。如果不是UTF-8,即使响应200,我们还是会重试。
您可以通过控制面板 > 变现 > 虚拟货币 > 创建/编辑来得到您虚拟货币的安全密钥。这个密钥不同于应用的SDK密钥。使用在回调中使用虚拟货币密钥:
如果在虚拟货币中设置了secret key,我们将会在回调中添加如下参数:I
verifier是利用通过冒号分割的id, snuid, currency 和密钥MD5哈希而成,在Ruby代码如下:
Digest::MD5.hexdigest("#{id}:#{snuid}:#{currency}:#{secret_key}")
您的服务器要重新计算verifier,拒绝任何不匹配的请求。如果verifier不匹配,服务器响应403.
注意每个应用要使用不同的密钥,不要在所有的应用使用相同的密钥,如果使用相同的密钥,有可能会导致在多个应用中同时奖励用户。以上id代表的是request_id而不是currency_id。
为了提供更多信息和安全性,我们升级了上面列出的回调。如果您想使用此升级版本,请联系您的客户经理或我们的支持团队,以帮助您启用此版本的回调。
当用户通过完成广告获得虚拟货币时,我们将向您提供的URL发出POST请求。参数的格式为:
{
"id": "reward.id",
“rev”: 100,
“cp”: ”your_custom_string”
"currency": {
"id": "currency_id",
"reward": "xxx",
"currency_sale": "",
},
"offer": {
"name": "Some offer",
“type”: “”,
“icon_url”: “offer_icon_url,
},
“placement”: {
“content_type”: “offerwall”,
“name”: “placement_name”
},
"user": {
"id": "pub_user_id"
},
“timestamp”: “123491324”
}
参数 | 类型 | 说明 |
---|---|---|
id | string | 当前请求唯一的奖励ID |
rev | integer | 以美分计算的应得Revenue |
cp | string | 通过SDK中setCustomParameter方法传入的自定义传参数 |
currency.id | string | 当前虚拟货币ID |
currency.reward | integer | 应奖励给用户的虚拟货币数量 |
currency.currency_sale | float | 虚拟货币促销倍数(如适用) |
offer.name | string | 广告主广告名称 |
offer.type | 当前不支持 | |
offer.icon_url | string | 广告的Icon URL |
placement.name | string | 当前转化对应的展示位置名称 |
placement.content_type | string | 当前展示位置中的广告类型 |
user.id | string | 通过SDK setUserID方法设置的User ID |
timestamp | timestamp | 当前转化的时间 |
JSON主体将使用 SHA256 哈希算法进行哈希处理。验证器将根据POST虚拟货币货币回调请求主体和我们的共享密钥(可在Tapjoy后台上找到您的回调 URL)生成。此验证器将在POST虚拟货币回调请求标头中发送。
HMAC_SHA-256(<Request-Body>,<Secret-Key>)
Tapjoy header with signature示例:
X-Tapjoy-Signature => 7205ccfdfa1fe28cd05a1b56a9508d898cc938aa555a6c18848097fe4ee0975b
调用setUserID对于使用自管理虚拟货币非常重要。setUserID中的值即是在回调URL中snuid的值。请一定要调用Tapjoy connect成功之后和请求广告之前调用setUserID(在SDK 11.7之后版本,Tapjoy SDK实现了设置成功/失败的回调,建议在请求广告之前监听这些回调)。
如果设置不正确,您的App 用户将不会得到奖励并且您也无法得到收益。setUserID需要设置用户在游戏中的唯一ID(一般是数字)。
**出于数据安全和GDPR合规性的要求,setUserID参数不应该包括任何身份信息,比如用户名,真实姓名或者邮箱地址。**出于安全和反作弊的目的,user ID要是始终如一的。(比如不能随着用户的等级或者分数改变而改变)。
User ID支持最多190个字符的长度。
下面的示例代码指示了如何使用connect flag 和如何直接调用setUserID
API设置user id。我们推荐使用connect flag:
// Recommended approach using connect flag
NSDictionary *connectFlags = @{TJC_OPTION_USER_ID : @"<USER_ID_HERE>"};
[Tapjoy connect:@"SDK_KEY_GOES_HERE" options:connectFlags];
// Setting the user id directly
[Tapjoy setUserIDWithCompletion:@"<USER_ID_HERE>" completion:^(BOOL success, NSError *error) {
}];
// Recommended approach using connect flag
Hashtable<String, Object> connectFlags = new Hashtable<String, Object>();
connectFlags.put(TapjoyConnectFlag.USER_ID, "<USER_ID_HERE>"); // Important for self-managed currency
Tapjoy.connect(getApplicationContext(), "SDK_KEY_GOES_HERE", connectFlags, new TJConnectListener() {...});
// Setting the user id directly
Tapjoy.setUserID("<USER_ID_HERE>", new TJSetUserIDListener() {
@Override
public void onSetUserIDSuccess() {
}
@Override
public void onSetUserIDFailure(String error) {
}
});
// Recommended approach using connect flag
Dictionary<string,string> connectFlags = new Dictionary<string,string>();
connectFlags.Add("TJC_OPTION_USER_ID", "<USER_ID_HERE>");
#if UNITY_ANDROID
Tapjoy.Connect("your_android_sdk_key", connectFlags);
#elif UNITY_IOS
Tapjoy.Connect("your_ios_sdk_key", connectFlags);
#endif
// Callbacks for SetUserID
TJPlacement.OnSetUserIDSuccess += HandleOnSetUserIDSuccess;
TJPlacement.OnSetUserIDFailure += HandleOnSetUserIDFailure;
// Setting the user id directly
Tapjoy.SetUserID("<USER_ID_HERE>")
// Recommended approach using connect flag
try {
let flags: object = { TJC_OPTION_USER_ID: '<userId>' };
await Tapjoy.connect('<sdk_key>', flags);
} catch (error) {
console.log(error);
}
// Setting the user id directly
try {
await Tapjoy.setUserId('<userId>');
} catch (error) {
console.log(error);
}
您可以在iOS, Android, 和 Unity 文档中找到更详细的示例.
故障解决: 如果您调用了setUserID,但是在回调URL中并非您设置的值,您需要在调用积分墙或视频广告之前调用setUserID。如果没有设置userID,默认我们会使用设备id作为snuid,比如,用户在调用设置setUserID之前进入了积分墙,所以请一定在调用connect之后调用。
如果您没有设置user ID,我们会使用device ID作为user ID。一般情况下,我们使用广告ID。但是这取决于SDK版本,设备型号,设备操作系统版本和Google Play Service版本。其他可能的device ID包括Android ID,udid和mac地址。
每次请求展示位置时,您都可以告诉Tapjoy用户当前余额。您必须在请求展示位置内容之前设置此项。
TJPlacement *placement = [TJPlacement placementWithName:@"placementName" delegate:nil];
[placement setBalance:100 forCurrencyId:@"1234" withCompletion:^(NSError * _Nullable error) {
if (error != nil) {
//Failure
NSString *message = error.localizedDescription;
} else {
//Success
}
}];
TJPlacement placement = Tapjoy.getPlacement("placement", this);
placement.setCurrencyBalance("1234", 100, new TJSetCurrencyBalanceListener() {
@Override
public void onSetCurrencyBalanceSuccess() {
}
@Override
public void onSetCurrencyBalanceFailure(int code, String error) {
}
});
TJPlacement placement = TJPlacement.CreatePlacement("placementName");
placement.SetCurrencyBalance("[CURRENCY_ID]", 100);
// Optional callbacks
void OnEnable()
{
TJPlacement.OnSetCurrencyBalanceSuccess += HandleSetCurrencyBalanceSuccess;
TJPlacement.OnSetCurrencyBalanceFailure += HandleSetCurrencyBalanceFailure;
}
void OnDisable()
{
TJPlacement.OnSetCurrencyBalanceSuccess -= HandleSetCurrencyBalanceSuccess;
TJPlacement.OnSetCurrencyBalanceFailure -= HandleSetCurrencyBalanceFailure;
}
public void HandleSetCurrencyBalanceSuccess(TJPlacement placement)
{
}
public void HandleSetCurrencyBalanceFailure(TJPlacement placement, int code, string error)
{
}
let placement = new TJPlacement('placementName');
try {
await placement?.setCurrencyBalance('1234', 100);
} catch (e: any) {
let code = e.code;
let message = e.message;
}
如果您设置了余额,您还可以在placemnet上设置所需的虚拟货币数量。
TJPlacement* placement = [TJPlacement placementWithName:@"placementName" delegate:nil];
placement setRequiredAmount:100 forCurrencyId:@"1234" withCompletion:^(NSError * _Nullable error) {
if (error != nil) {
//Failure
NSString *message = error.localizedDescription;
} else {
//Success
}
}
TJPlacement placement = Tapjoy.getPlacement("placement", this);
placement.setCurrencyAmountRequired("1234", 100, new TJSetCurrencyAmountRequiredListener() {
@Override
public void onSetCurrencyAmountRequiredSuccess() {
}
@Override
public void onSetCurrencyAmountRequiredFailure(int code, String error) {
}
});
TJPlacement placement = TJPlacement.CreatePlacement("placementName");
placement.SetRequiredAmount("[CURRENCY_ID]", 200);
// Optional callbacks
void OnEnable()
{
TJPlacement.OnSetCurrencyAmountRequiredSuccess += HandleSetRequiredAmountSuccess;
TJPlacement.OnSetCurrencyAmountRequiredFailure += HandleSetRequiredAmountFailure;}
void OnDisable()
{
TJPlacement.OnSetCurrencyAmountRequiredSuccess -= HandleSetRequiredAmountSuccess;
TJPlacement.OnSetCurrencyAmountRequiredFailure -= HandleSetRequiredAmountFailure;
}
public void HandleSetCurrencyBalanceSuccess(TJPlacement placement)
{
}
public void HandleSetCurrencyBalanceFailure(TJPlacement placement, int code, string error)
{
}
public void HandleSetRequiredAmountSuccess(TJPlacement placement)
{
}
public void HandleSetRequiredAmountFailure(TJPlacement placement, int code, string error)
{
}
let placement = new TJPlacement('placementName');
try {
await offerwallPlacement?.setRequiredAmount(100, '100');
} catch (e: any) {
let code = e.code;
let message = e.message;
}
如果您的奖励回调服务器需要添加权限(白名单)才能访问,这是 Tapjoy 的 IP 列表。(最后更新时间:2024 年 5 月 12 日)
18.215.207.89
18.235.142.165
23.20.255.113
23.23.134.165
3.210.188.32
3.215.42.140
3.217.209.177
3.218.95.35
3.219.236.53
3.231.137.161
如果您的应用还没有正式启用,您可以在Tapjoy控制面板中编辑虚拟货币页面从Tapjoy管理虚拟货币切换到自管理虚拟货币。在切换时一定要填写正确的回调URL,要不然改变将不会起作用。
如果您线上的app正在使用Tapjoy管理虚拟货币,切换的流程比较复杂,您需要考虑如下的事情:
迁移用户余额,我们推荐如下步骤:
如果您正在考虑切换到自管理虚拟货币模式,但是您不确定怎样搭建您自己的服务器,我们推荐您参考下面链接中的方案 Parse 或者 UrbanAirship。