# 服务器激励

注意

  1. 需要联系商务人员开启服务器回调并获取密钥(sec_key)
  2. 开发者可以在SDK的API传入UserID(用户唯一ID)、UserCustomData(用户自定义数据). 这些参数最终将通过回调URL通知开发者。
  3. 当用户看完激励视频时,平台将向回调URL地址通知开发者,由开发者自行判断并下发奖励。

# Android端示例代码

Android端接入服务器激励需要使用预加载方式:

public class PreloadReward {
    FNPreRewardAd preRewardAd;

    public void initReward() {
        // 获取预加载激励视频
        preRewardAd = Ads.preloadRewardVideoAd(context, "positionId", listener);
        // 设置服务器回调参数用户ID
        preRewardAd.setUserId("123456");
        // 设置服务器回调自定义参数
        Map<String, Object> map = new HashMap<>();
        map.put("test1", "1");
        // 请在加载前设置参数,否则回调参数会失效
        preRewardAd.setExtra(map);
    }
    ...
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

# 后端回调

当用户看完激励视频时,平台将通过设置的回调URL地址通知开发者,由开发者自行判断并下发奖励。

请求会以get方式发送,参数以url方式发送,示例:

http://yourdomain.com/callback?user_id=123456&extra_data=test1%3D1&adsource_id=1001&trans_id=123456&reward_name=reward&reward_amount=100

参数名 描述
trans_id 服务端生成广告唯一ID,强烈建议开发者在服务器发放激励前校验trans_id是否已发放激励,以规避对相同的trans_id重复发放激励
placement_id 广告位ID
adsource_id 广告源ID
user_id SDK中设置的ID
reward_amount 奖励数量,固定值:100,可联系商务修改
reward_name 奖励名称,固定值reward,可联系商务修改
extra_data SDK中设置的额外数据
sign 签名, 见签名规则

# 签名规则

签名规则需按指定顺序拼接参数,并对参数进行MD5加密,其中sec_key为商务提供给您的密钥。

拼接顺序如下:

trans_id=${trans_id}&placement_id=${placement_id}&adsource_id=${adsource_id}&reward_amount=${reward_amount}&reward_name=${reward_name}&sec_key=${sec_key}

然后对拼接的字符串进行MD5加密,得到sign值和回调中的sign进行比对. 例如:

md5(trans_id=123&placement_id=456&adsource_id=789&reward_amount=100&reward_name=reward&sec_key=your_secret_key)

注意

请确保所有参数都正确拼写,并且参数顺序与上述示例一致,请注意参数的顺序和大小写

请确保sec_key与您在商务获取的sec_key一致

Java SpringBoot后端示例:


@SpringBootApplication
@RestController
@Slf4j
public class CallbackApplication {
    public static final String SEC_KEY = "your_secret_key";

    public static void main(String[] args) {
        SpringApplication.run(CallbackApplication.class, args);
    }

    @GetMapping("/callback")
    public void callback(@RequestParam Map<String, Object> params) {
        log.info("params: {}", params);
        // 获取SDK中设置的用户ID
        String user_id = String.valueOf(params.get("user_id"));
        // 获取SDK中设置的自定义数据
        String extra_data = String.valueOf(params.get("extra_data"));
        String sign = String.valueOf(params.get("sign"));
        params.remove("sign"); // 签名前从参数中删除
        // 签名,请注意参数顺序,若参数顺序不对,会导致签名不正确
        String localSign = getSign(params);
        log.debug("localSign: {}, sign: {}", localSign, sign);
        //本地签名和服务器签名进行比对
        if (localSign.equals(sign)) {
            // TODO 业务校验,请注意校验同一广告是否已经发放过奖励
            log.debug("user_id: {}, extra_data: {}", user_id, extra_data);
        }

    }

    private static String getSign(Map<String, Object> params) {
        if (params == null || params.isEmpty()) return null;
        String trans_id = String.valueOf(params.get("trans_id"));
        String placement_id = String.valueOf(params.get("placement_id"));
        String adsource_id = String.valueOf(params.get("adsource_id"));
        String reward_amount = String.valueOf(params.get("reward_amount"));
        String reward_name = String.valueOf(params.get("reward_name"));
        // 请注意参数顺序和大小写
        // 签名示例: trans_id=123456&placement_id=123&adsource_id=123&reward_amount=100&reward_name=gold&your_secret_key
        String signTextTemplate = "trans_id=%s&placement_id=%s&adsource_id=%s&reward_amount=%s&reward_name=%s&sec_key=%s";
        String signText = String.format(signTextTemplate, trans_id, placement_id, adsource_id, reward_amount, reward_name, SEC_KEY);
        log.debug("signText:{}", signText);
        // 签名算法请使用MD5
        return md5(signText);
    }


    public static String md5(String input) {
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            byte[] messageDigest = md.digest(input.getBytes(StandardCharsets.UTF_8));
            BigInteger number = new BigInteger(1, messageDigest);
            String hashtext = number.toString(16);
            while (hashtext.length() < 32) {
                hashtext = "0" + hashtext;
            }
            return hashtext;
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException(e);
        }
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63

# 响应回调服务器

开发者收到请求后需要给服务器返回HTTP状态码,

状态码 说明
200 请求成功
601 签名验证失败
602 其他失败

平台服务器发起服务端激励回调后2秒内无响应则视为超时,超时后会每隔一会(比如2秒,4秒,8秒等)重试发送激励回调。最大重试5次还超时,则不再向开发者回调URL发起激励回调.