广告主上报归因后APP转化数据接口
监测接口
百度服务器通过监测接口调用广告主监测平台服务器
请求方
百度服务器
处理方
广告主提供的监测平台服务器
请求协议
Http GET/POST
返回Http状态码小于400视为接口请求成功
请求示例
- IOS
http://xxxx.xx.com?idfa={{IDFA}}&os={{OS}}&ip={{IP}}&ua={{UA}}&ts={{TS}}&pid={{PLAN_ID}}&uid={{UNIT_ID}}&aid={{IDEA_ID}}&click_id={{CLICK_ID}}&callback_url={{CALLBACK_URL}}
- Android
http://xxxx.xx.com?imei_md5={{IMEI_MD5}}&os={{OS}}&ip={{IP}}&ua={{UA}}&ts={{TS}}&pid={{PLAN_ID}}&uid={{UNIT_ID}}&aid={{IDEA_ID}}&click_id={{CLICK_ID}}&callback_url={{CALLBACK_URL}}
callback_url接口
百度后台在回调监测URL时提供给广告主或者第三方平台的数据回传URL,使用双大括号{{参数}}的形式来设置所需返回的数据,callback url由百度server端调用监测URL时直接传输给广告主,产生转化时广告主替换转化相关参数(a_type、a_value)后生成签名进行回调
请求方
广告主服务器或第三方监测平台服务器
处理方
百度服务器
请求协议
Http GET/POST
返回错误码说明
错误码 | 说明 |
---|---|
0 | 接口回调成功 |
100 | 签名错误 |
101 | 数据错误 |
请求示例
- IOS&Android
http://ocpc.baidu.com/ocpcapi/cb/actionCb?a_type={{ATYPE}}&a_value={{AVALUE}}&s=1234&ext_info=abcd&sign={{SIGN}}
app激活时,请将{{ATYPE}}替换为activate,{{AVALUE}}替换为0
返回结果示例
- 回调成功
{ "error_code":0, "error_msg":"success" }
- 签名错误
{ "error_code": 100, "error_msg":"签名错误" }
- 数据错误
{ "error_code": 101, "error_msg":"数据错误" }
监测url参数说明
参数名 | 通配符 | 描述 | 说明 | 备注 |
---|---|---|---|---|
akey |
- | 双方加密 秘钥,推广后台创建转化时自动生成,同一账户akey唯一 | 百度为广告主配置的转化追踪监测地址自动追加akey参数, 例:&akey=JQV6d3SytFYJvj6p= 监测URL签名:替换通配符后的完整监测URL(不包含&sign=) +akey进行标准32位md5,生成签名值,在监测URL后添加&sign=签名值 |
- |
userid |
{{USER_ID}} | 账户ID | 账户ID | - |
aid |
{{IDEA_ID}} | 创意ID | 创意ID | - |
pid |
{{PLAN_ID}} | 计划ID | 计划ID | - |
uid |
{{UNIT_ID}} | 单元ID | 单元ID | - |
callback_url |
{{CALLBACK_URL}} | 效果数据回传URL | 由百度server端调用监测URL时传给广告主,产生转化时广告主替换相关参数 (a_type,a_value) 后生成签名进行回调,callback url中的s、o、ext_info 由百度server端处理 | - |
click_id |
{{CLICK_ID}} | 点击唯一ID | 点击唯一标识 | - |
idfa |
{{IDFA}} | IOS设备标识 | 原值,例:40879ADB-E3E8-4FD4-BE28-86DF97532DC7 | 无值时替换为NULL |
imei_md5 |
{{IMEI_MD5}} | 安卓设备标识 | md5加密值,对原值进行标准32位小写MD5编码 | 无值时替换为NULL |
oaid |
{{OAID}} | Android Q 及更高版本的设备号 | 原值,例:47befdff-fb1f-4b96-ddff-bf3fb77f744e | 无值时替换为NULL |
android_id_md5 |
{{ANDROID_ID_MD5}} | 安卓id,该设备识别号与设备可能存在多对一或一对多的关系 | md5加密值,对原值进行标准32位小写MD5编码 | 无值时替换为NULL |
mac |
{{MAC}} | MAC地址 | md5加密值,去除分隔符 ":"(例:32738C807A28),再进行标准32位小写MD5编码 | 入网硬件地址,无值时替换为NULL |
mac_md5 |
{{MAC_MD5}} | 用户终端的eth0接口的MAC地址 | md5加密值,保留分隔符 ":"(例:32:73:8C:80:7A:28),再进行标准32位小写MD5编码 | 无值时替换为NULL |
ip |
{{IP}} | IP地址 | 用户端公网ip | 无值时替换为NULL |
ip_type |
- | IP地址类型 | v4: ipv4 v6: ipv6 |
百度为广告主配置的转化追踪监测地址自动追加ip_type参数, 例:&ip_type=v6 |
ua |
{{UA}} | 数据上报终端设备User Agent | IOS样例:Mozilla/5.0 (iPhone; CPU iPhone OS 14_4_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 swan/2.26.0 swan-baiduboxapp/12.6.5.10 baiduboxapp/12.6.5.10 (Baidu; P2 14.4.2) Android样例:Mozilla/5.0 (Linux; Android 8.1.0; DUB-AL00 Build/HUAWEIDUB-AL00; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/76.0.3809.89 Mobile Safari/537.36 T7/12.9 SP-engine/2.21.0 matrixstyle/0 lite baiduboxapp/5.4.0.10 (Baidu; P1 8.1.0) NABar/1.0 |
ua中可分离出系统版本信息(样例标红处),无值时替换为NULL |
os |
{{OS}} | 操作系统类型 | - | IOS:1 安卓:2 |
ts |
{{TS}} | 时间戳,单位:毫秒(ms) | 点击时间 | - |
device_info |
{{DEVICE_INFO}} | 设备信息, 发生广告点击的设备机型 | IOS样例:iPhone13,4 Android样例:EVA-AL10 |
客户端获取的原始数据,无值时替换为NULL |
callback_url参数说明
参数名 | 通配符 | 描述 | 参数值 | 说明 |
---|---|---|---|---|
akey |
- | 双方加密 秘钥,推广后台创建转化时自动生成,同一账户akey唯一 | Callbackurl签名:替换通配符后的完整回调URL(不包含&sign=)+akey进行标准32位md5,生成签名值,在回调URL后添加&sign=签名值 | |
a_type |
{{ATYPE}} | 转化类型 | activate register orders user_defined retain_1day highvalue_customer |
表明用户的转化数据 activate: 激活 register: 注册 orders: 成单 user_defined: 客户自定义 retain_1day: 次日留存 highvalue_customer: 深度使用 |
a_value |
{{AVALUE}} | 转化指标(整型),单位:分 | 转化类型为成单时可以填写订单金额,无转化金额时填0,例:转化金额为12.3元,a_value设置1230 |
程序调用示例
Java代码调用示例(点击右上角切换语言)
点击这里下载代码Demo
package com.demo;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URLDecoder;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
/**
* APP激活callback url 调用Demo
*/
public class CallbackDemo {
private static final Integer RETRY_TIMES = 3;
/**
* callbackFunc 调用callback url 向百度回传app激活转化数据
*
* @param callbackUrl 监测地址中callback_url参数值
* @param akey 当前账户对应akey
* @return 调用成功返回true
*/
public static Boolean callbackFunc(String callbackUrl, String akey) {
String url = null;
CloseableHttpClient client = HttpClients.createDefault();
HttpGet httpGet = new HttpGet();
try {
url = URLDecoder.decode(callbackUrl, "UTF-8");
// 注意:示例为app激活转化类型需要替换的参数,当想要优化其他类型时,请按照文档要求替换
url = url.replace("{{ATYPE}}", "activate");
url = url.replace("{{AVALUE}}", "0");
// 计算sign值
String sign = md5Func(url + akey);
// 得到最终callback url
url += "&sign=" + sign;
httpGet.setURI(new URI(url));
// TODO: do some log
// 打印要调用的callbackrl
System.out.println(url);
} catch (UnsupportedEncodingException | URISyntaxException e) {
// TODO: do some log
e.printStackTrace();
return false;
}
// 调用callback url,判断返回结果,添加重试次数3次
for (int i = 0; i < RETRY_TIMES; i++) {
try {
HttpResponse httpResponse = client.execute(httpGet);
int statusCode = httpResponse.getStatusLine().getStatusCode();
if (statusCode == 200) {
// TODO: do some log
String resp = EntityUtils.toString(httpResponse.getEntity());
System.out.println("retry times: " + i + " res: " + resp);
JsonObject jsonResp = new JsonParser().parse(resp).getAsJsonObject();
int code = jsonResp.get("error_code").getAsInt();
// error_code=500时为服务异常,可添加重试
if (code != 500) {
return code == 0; // 返回error_code为0时接口调用成功,否则需排查具体原因
}
}
} catch (IOException e) {
// TODO: do some log
e.printStackTrace();
}
}
return false;
}
/**
* 字符串md5
*
* @param string 需要md5加密的字符串
* @return md5结果
*/
private static String md5Func(String string) {
byte[] hash;
try {
hash = MessageDigest.getInstance("MD5").digest(string.getBytes("UTF-8"));
} catch (NoSuchAlgorithmException | UnsupportedEncodingException e) {
// TODO: do some log
return "";
}
StringBuilder hex = new StringBuilder(hash.length * 2);
for (byte b : hash) {
int i = (b & 0xFF);
if (i < 0x10) {
hex.append('0');
}
hex.append(Integer.toHexString(i));
}
return hex.toString();
}
public static void main(String[] args) {
// 需替换为推广账户akey
String akey = "账户akey";
// 需替换为从监测url中解析出来的callback url
String callbackUrl = "http%3A%2F%2Focpc.baidu.com%2Focpcapi%2Fcb%2FactionCb%3Fa_type%3D%7B%7BATYPE%7D%7D%26a_value%3D%7B%7BAVALUE%7D%7D%26s%3D99329%26ext_info%3DHhGPIYdRNg-xPWnsnHRzg1T3rHnsrHcvg1czndtsg10snRNjrjnLn1D1n1FawWDzwHKDnbmdPbmsPbRdP1TLgdtkPHRdPHDvP1b3";
System.out.println(CallbackDemo.callbackFunc(callbackUrl, akey));
}
}
Php代码调用示例(点击右上角切换语言)
点击这里下载代码Demo
<?php
/**
* callbackFunc 调用callback url 向百度回传app激活转化数据
*
* @param 监测地址中callback_url参数值
* @param 当前账户对应akey
* @return bool 成功返回true,失败返回false
*/
function callback_func($callbackurl, $akey) {
$url = urldecode($callbackurl);
// 注意:示例为app激活转化类型需要替换的参数,当想要优化其他类型时,请按照文档要求替换
$url = str_replace('{{ATYPE}}', 'activate', $url);
$url = str_replace('{{AVALUE}}', '0', $url);
// 计算sign值
$sign = md5($url . $akey);
// 得到最终callback url
$url = $url . '&sign=' . $sign;
// do some log
print_r('url', $url);
// 调用callback url,判断返回结果
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
curl_setopt($ch, CURLOPT_TIMEOUT, 60);
// 添加重试,重试次数为3
for ($i = 0; $i < 3; $i++) {
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if ($httpCode === 200) {
// 打印返回结果
// do some log
echo 'retry times: ' . $i . ' res: ' . $response . "\n";
$res = json_decode($response, true);
$code = $res['error_code'];
// error_code为500,代表服务端异常,可添加重试
if ($code != 500) {
curl_close($ch);
return $code === 0; // 返回error_code为0时接口调用成功,否则需排查具体原因
}
}
}
curl_close($ch);
return false;
}
// 需替换为从监测url中解析出来的callback url
$callbackUrl = 'http%3A%2F%2Focpc.baidu.com%2Focpcapi%2Fcb%2FactionCb%3Fa_type%3D%7B%7BATYPE%7D%7D%26a_value%3D%7B%7BAVALUE%7D%7D%26s%3D99329%26ext_info%3DHhGPIYdRNg-xPWnsnHRzg1T3rHnsrHcvg1czndtsg10snRNjrjnLn1D1n1FawWDzwHKDnbmdPbmsPbRdP1TLgdtkPHRdPHDvP1b3';
// 需替换为推广账户akey
$akey = '账户akey';
callback_func($callbackUrl, $akey)
?>
Python代码调用示例(点击右上角切换语言)
点击这里下载代码Demo
版本:python2
# -*- coding: utf-8 -*-
import urllib
import urllib2
import hashlib
import json
RETRY_TIMES = 3
def package_url(callback_url, akey):
"""
计算callback url
:param callback_url: 监测url中callback_url参数
:param akey: 推广账户akey
:return: 计算完整的callback url
"""
callback_url = urllib.unquote(callback_url).encode("utf-8")
# 注意:示例为app激活转化类型需要替换的参数,当想要优化其他类型时,请按照文档要求替换
callback_url = callback_url.replace("{{ATYPE}}", "activate").replace("{{AVALUE}}", "0")
sign = get_md5_from_str(callback_url + akey)
callback_url += "&sign=" + sign
return callback_url
def get_md5_from_str(tar_string):
"""
字符串md5
:param tar_string:
:return:
"""
return hashlib.md5(tar_string).hexdigest()
def callback_func(callback_url):
"""
请求百度callback url
:param callback_url:
:return: 返回True代表调用成功 False代表调用失败
"""
request = urllib2.Request(callback_url)
for i in range(RETRY_TIMES):
try:
response = urllib2.urlopen(request)
except Exception as e:
# do something
print "retry times: " + str(i) + "exception: " + str(e)
continue
if response.getcode() == 200:
result = response.read()
print("retry times: {times} res: {res_content}".format(times=i, res_content=result))
json_rep = json.loads(result)
server_code = json_rep['error_code']
# 服务端返回500 可添加重试
if server_code != 500:
return server_code == 0
return False
if __name__ == "__main__":
# 需替换为推广账户akey
akey = "账户akey"
# 需替换为从监测url中解析出来的callback url
callbackUrl = "http%3A%2F%2Focpc.baidu.com%2Focpcapi%2Fcb%2FactionCb%3Fa_type%3D%7B%7BATYPE%7D%7D%26a_value%3D%7B%7BAVALUE%7D%7D%26s%3D99329%26ext_info%3DHhGPIYdRNg-xPWnsnHRzg1T3rHnsrHcvg1czndtsg10snRNjrjnLn1D1n1FawWDzwHKDnbmdPbmsPbRdP1TLgdtkPHRdPHDvP1b3";
packaged_url = package_url(callbackUrl, akey)
print(callback_func(packaged_url))
版本 python3
# -*- coding: utf-8 -*-
import hashlib
import requests
import urllib.parse as up
RETRY_TIMES = 3
def package_url(callback_url: str, akey: str) -> str:
"""
计算callback url
:param callback_url: 监测url中callback_url参数
:param akey: 推广账户akey
:return: 计算完整的callback url
"""
callback_url = up.unquote(callback_url)
# 注意:示例为app激活转化类型需要替换的参数,当想要优化其他类型时,请按照文档要求替换
callback_url = callback_url.replace("{{ATYPE}}", "activate").replace("{{AVALUE}}", "0")
sign = get_md5_from_str(callback_url + akey)
callback_url += "&sign=" + sign
return callback_url
def get_md5_from_str(tar_string: str, encoding="utf-8") -> str:
"""
字符串md5
:param tar_string:
:param encoding:
:return:
"""
return hashlib.md5(tar_string.encode(encoding)).hexdigest()
def callback_func(callback_url: str) -> bool:
"""
请求百度callback url
:param callback_url:
:return: 返回True代表调用成功 False代表调用失败
"""
for i in range(RETRY_TIMES):
try:
res = requests.get(callback_url)
except requests.RequestException as e:
# do something
print("retry times: {times} e: {e}".format(times=i, e=e))
continue
if res.ok:
resp = res.content.decode("UTF-8")
print("retry times: {times} res: {res_content}".format(times=i, res_content=resp))
server_code = res.json()['error_code']
# 服务端500 可添加重试
if server_code != 500:
return server_code == 0
return False
if __name__ == "__main__":
# 需替换为推广账户akey
akey = "your akey"
# 需替换为从监测url中解析出来的callback url
callbackUrl = "http%3A%2F%2Focpc.baidu.com%2Focpcapi%2Fcb%2FactionCb%3Fa_type%3D%7B%7BATYPE%7D%7D%26a_value%3D%7B%7BAVALUE%7D%7D%26s%3D99329%26ext_info%3DHhGPIYdRNg-xPWnsnHRzg1T3rHnsrHcvg1czndtsg10snRNjrjnLn1D1n1FawWDzwHKDnbmdPbmsPbRdP1TLgdtkPHRdPHDvP1b3";
packaged_url = package_url(callbackUrl, akey)
print(callback_func(packaged_url))