# IAA 广告接入 SDK 文档
基于美团融合 SDK (MGC) — 纯 IAA 场景
版本:v2.0 | 更新日期:2026.01
厂商您好,本文档旨在为外部厂商提供清晰的指导,帮助您顺利将 IAA 广告接入到游戏中。如在接入过程中遇到任何问题,请随时联系我们的技术支持团队。
# ⚠️ 接入重要须知(必读)
- 广告请求失败重试:连续请求最多 3 次,若持续返回
onError则自动发奖,重试逻辑在代码内部完成,不被用户感知。 - 广告展示:直接调用 SDK 的
show(),通过onClose回调判断是否发奖,不通过onLoad判断内外广。 - show 调用限制:一次广告只调用一次
show(多次 show 会降低曝光成功率,影响广告收入和下发)。请在代码中添加 show 调用的日志打印。 - 版本要求:接入激励视频需美团版本 ≥ 12.45.200。约 17% 用户可能未更新,需添加版本检测与弹窗引导。
- 埋点逻辑:在物理广告位点击时,进行
load调用。Load调用完成后,调用adReport方法进行mv、mc的上报。注:物理广告位曝光时,无需进行load调用。
# 一、容器 API
# 1.1 mt.createCustomAd(Object args)
创建 CustomAd 对象,用于广告交互。调用后会自动进行一次广告拉取,拉取成功后回调 onLoad。
支持的广告类型:
| 广告类型 | 渲染方式 |
|---|---|
| 激励视频 | 外部 SDK 渲染 / 融合 SDK 渲染 |
| 插屏广告 | 融合 SDK 渲染 |
| 开屏广告 | 外部 SDK 渲染 / 融合 SDK 渲染 |
| 信息流广告 | 外部 SDK 渲染 / 融合 SDK 渲染 |
| 自渲染广告 | 玲珑资源、到家津贴、到店商增、到家异业、流量方自渲染 |
参数说明:
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
posId | String | 是 | 广告单元 ID,来源于炼金平台。解析后根据流量主配置请求各种类型广告(由美团运营提供) |
optionalParams | Object | 否 | 可选参数,详见下表 |
optionalParams 字段说明:
| 字段 | 类型 | 必传 | 含义 | 备注 |
|---|---|---|---|---|
adDemand | String | 否 | 广告请求个数,默认 1 | 混竞广告一次请求只返回一个广告 |
dockerType | String | 否 | 业务容器类型 | 可选值:mgc、msc、mrn、growth、knb |
dockerVersion | String | 否 | 业务 bundle 版本号 | |
reqExt | Object | 否 | 请求扩展参数 | 商增广告必传,须找广告 PM 确认。含 bizParams(透传至业务后端)、itemIndex、offset 等 |
返回值:CustomAd 广告入口对象
请求参数示例:
{
posId: "xxx",
optionalParams: {
adDemand: "1",
dockerType: "mgc",
dockerVersion: "1.0.0"
}
}
# 1.2 CustomAd 对象方法
# CustomAd.load()
主动拉取一次广告数据。返回 Promise(参考异常处理章节)。
# CustomAd.show(Object args)
展示广告。
⚠️ 重要提示:一次广告生命周期内只能调用一次 show,多次调用会降低曝光成功率,直接影响广告收入。
| 字段 | 类型 | 必传 | 含义 |
|---|---|---|---|
serialId | String | 条件必传 | 广告序列号,自渲染广告必传(从 onLoad 回调获取),非自渲染不传 |
# CustomAd.destroy()
销毁广告实例,释放资源(包括解绑 activity 等)。调用后实例不可再使用(包括 load、show)。如需再次使用同一资源位,需重新 create。
# CustomAd.adReport(Object args)
业务主动上报广告入口曝光与点击,影响广告计费。必须在 load 之后,根据曝光/点击触发调用。
| 字段 | 类型 | 必传 | 含义 | 备注 |
|---|---|---|---|---|
serialId | String | 条件 | 流水号 | 自渲染广告必传;无 serialId 则不传此字段,不可用 "-999" 等无效兜底值 |
behaviorId | String | 是 | 事件类型 | mv = 曝光,mc = 点击 |
cid | String | 是 | 业务 cid | |
bid | String | 是 | 业务 bid | 不带 _mv、_mc 后缀 |
gameLxParams | Object | 是 | 灵犀参数 | tagIdentifier:点击时必传;category:业务通道,默认 game;gameParams:选传,透传到 vallab |
macroInfo | Object | 条件 | 宏替换信息 | 上报点击时必传,包含点击坐标等 |
dockerType | String | 否 | 容器类型 | mgc、msc、mrn、growth、knb |
dockerVersion | String | 否 | 容器版本号 |
adReport 参数示例:
{
serialId: "xxx",
behaviorId: "mc",
cid: "xxx",
bid: "xxx",
gameLxParams: {
gameParams: { inner_source: "xxxx", item_index: 1 },
category: "game",
tagIdentifier: "game"
},
macroInfo: {
"__WIDTH__": 100, "__HEIGHT__": 100,
"__DOWN_X__": 50, "__DOWN_Y__": 50,
"__UP_X__": 50, "__UP_Y__": 50
},
dockerType: "mgc",
dockerVersion: "1.0.0"
}
# 1.3 事件监听
# CustomAd.onLoad(callback)
监听广告加载(填充)事件。回调参数:
| 字段 | 类型 | 说明 |
|---|---|---|
isRewardAd | Boolean | 必返回。表示下发广告是否为激励广告(内广、优量汇插屏、开屏为 false) |
adList | Array<Object> | 仅自渲染广告有此字段。包含 serialId、adTitle、bannerImage、adImage、adId |
# CustomAd.onClose(callback)
监听广告页面/组件关闭事件。激励视频在广告页面返回时回调;自渲染广告在落地页返回时回调。
| 字段 | 类型 | 说明 |
|---|---|---|
isRewarded | Boolean | 必下发。激励视频关闭时倒计时是否结束(是否奖励),仅激励视频场景有效 |
# CustomAd.onError(callback)
监听广告错误事件。回调参数参考异常处理章节。
# 取消监听方法
| 方法 | 说明 |
|---|---|
CustomAd.offLoad() | 取消监听广告加载事件 |
CustomAd.offClose() | 取消监听广告关闭事件 |
CustomAd.offError() | 取消监听广告错误事件 |
# 1.4 异常处理
返回时机:onError、load 的 reject、show 的 reject。返回参数包含 errCode(错误码)和 errMsg(错误信息)。
错误码表:
| 错误码 | 错误信息 | 处理建议 |
|---|---|---|
| -1 | 未知错误 | 记录日志,联系美团接口人 |
| 1002 | 广告单元失效或过期 | 重新调用 load() 拉取广告 |
| 1003 | 三方 SDK 内部错误 | 查看日志,联系美团接口人 |
| 1004 | 广告已被销毁 | 重新 create 广告实例 |
| 1005 | 广告无填充 | 重试拉取;多次无填充联系美团调整配置 |
| 1006 | 广告位信息解析失败或限流 | 重试拉取;多次限流联系美团调整配置 |
| 1007 | 广告请求失败 | 联系美团接口人查看 |
| 1008 | 广告数据转换失败 | 联系美团接口人查看 |
| 1009 | 广告创建失败,参数错误 | 检查参数是否正确 |
| 1010 | 广告展示失败 | 确认 serialId 是否正确 |
# 二、完整接入示例
以下示例结合项目中 AdManager 的实际实现,展示了包含重试机制、版本检测、show 保护等完整逻辑的接入代码。
# 2.1 基础接入流程
// ========== 第一步:创建广告实例 ==========
const customAd = mt.createCustomAd({
posId: "xxx", // 填入炼金平台申请的 posId
optionalParams: {
adDemand: "1",
bizScene: "default_game",
dockerType: "mgc",
dockerVersion: "1.0.0"
}
});
if (!customAd) {
console.error("customAd is undefined, 确认 posId 是否为空");
return;
}
// 缓存广告数据
let adCache = null;
let isRewardedAd = false;
let hasShown = false; // show 保护标记,防止重复调用
// ========== 第二步:注册事件监听 ==========
customAd.onLoad((res) => {
console.log("[Ad] onLoad:", res);
isRewardedAd = res.isRewardAd;
adCache = null;
hasShown = false; // 新广告加载后重置 show 标记
if (res && res.adList && res.adList.length > 0) {
// 自渲染广告,缓存素材数据
adCache = res.adList[0];
} else {
// 非自渲染广告
adCache = { status: "loaded" };
}
});
customAd.onError((err) => {
console.error("[Ad] onError:", err.errCode, err.errMsg);
// 错误处理逻辑见 2.2 节
});
# 2.2 请求失败重试与自动发奖机制
❗ 核心要求:广告请求连续失败 3 次后必须自动发奖,且重试过程对用户不可感知。
const MAX_RETRY = 3;
let retryCount = 0;
customAd.onError((err) => {
console.error("[Ad] onError:", err.errCode, err.errMsg);
retryCount++;
if (retryCount >= MAX_RETRY) {
console.log("[Ad] 连续失败 " + MAX_RETRY + " 次,自动发奖");
grantReward(); // 调用业务发奖逻辑
retryCount = 0;
return;
}
// 未达上限,静默重试
console.log("[Ad] 第 " + retryCount + " 次重试...");
setTimeout(() => {
customAd.load().catch(() => {
// load 的 reject 也会触发 onError,无需额外处理
});
}, 1000); // 延迟 1 秒重试
});
// 加载成功时重置计数器
customAd.onLoad((res) => {
retryCount = 0; // 成功后重置
// ... 其他 onLoad 逻辑
});
# 2.3 美团版本检测与引导升级
📱 版本要求:激励/插屏广告(弹窗样式)仅支持美团 12.45.200 及以上版本。低版本用户(约 17%)需弹窗引导升级。
function checkMeituanVersion() {
const MIN_VERSION = "12.45.200";
// 获取当前美团版本(根据实际容器 API 获取)
const currentVersion = mt.getSystemInfo?.()?.version || "";
if (!currentVersion || compareVersion(currentVersion, MIN_VERSION) < 0) {
// 版本过低,弹窗引导
showUpgradeDialog(
"当前美团版本过低,升级到最新版才能获取奖励哦~"
);
return false;
}
return true;
}
function compareVersion(v1, v2) {
const parts1 = v1.split(".").map(Number);
const parts2 = v2.split(".").map(Number);
for (let i = 0; i < Math.max(parts1.length, parts2.length); i++) {
const a = parts1[i] || 0;
const b = parts2[i] || 0;
if (a !== b) return a - b;
}
return 0;
}
// 在用户点击广告按钮时调用
function onAdButtonClick() {
if (!checkMeituanVersion()) return;
// 版本满足,继续广告流程...
loadAndShowAd();
}
# 2.4 广告展示与发奖判定
let adStartTime = -1;
// ========== 上报曝光(广告入口可见时调用) ==========
customAd.adReport({
serialId: adCache?.serialId, // 自渲染必传,非自渲染不传
behaviorId: "mv",
cid: "your_cid",
bid: "your_bid",
gameLxParams: { category: "game", gameParams: {} },
dockerType: "mgc",
dockerVersion: "1.0.0"
});
// ========== 上报点击 + 展示广告 ==========
function showAdWithReport() {
if (hasShown) {
console.warn("[Ad] 已调用过 show,跳过重复调用");
return;
}
// 先上报点击
customAd.adReport({
serialId: adCache?.serialId,
behaviorId: "mc",
cid: "your_cid",
bid: "your_bid",
gameLxParams: {
tagIdentifier: "game", // 点击时必传
category: "game"
},
macroInfo: {
"__WIDTH__": 100, "__HEIGHT__": 100,
"__DOWN_X__": 50, "__DOWN_Y__": 50,
"__UP_X__": 50, "__UP_Y__": 50
},
dockerType: "mgc",
dockerVersion: "1.0.0"
});
// 再调用 show
console.log("[Ad] 调用 show,serialId:", adCache?.serialId);
hasShown = true; // 标记已调用
customAd.show({
serialId: adCache?.serialId
}).then(() => {
if (!isRewardedAd) {
adStartTime = Date.now();
}
}).catch((err) => {
console.error("[Ad] show 失败:", err);
hasShown = false; // 失败后允许重试
// 可主动 load 重新拉取
customAd.load();
});
}
// ========== 监听关闭,判断发奖 ==========
customAd.onClose((res) => {
console.log("[Ad] onClose:", res);
if (isRewardedAd) {
// 激励广告:使用 SDK 返回的 isRewarded 判断
if (res.isRewarded) {
grantReward(); // 发奖
} else {
showTip("观看完整视频才能获得奖励哦~");
}
} else {
// 非激励广告:根据观看时长判断
const duration = Date.now() - adStartTime;
adStartTime = -1;
if (duration > 60 * 1000) {
grantReward(); // 观看超过 60 秒,发奖
} else {
showTip("再看一会儿就能获得奖励啦~");
}
}
});
// ========== 销毁 ==========
// 广告实例不再使用时必须销毁
customAd.offLoad();
customAd.offError();
customAd.offClose();
customAd.destroy();
# 三、接入说明
# 3.1 自渲染与非自渲染广告
区别在于 onLoad 回调中的 adList 是否非空。自渲染广告会返回素材数据(serialId、adTitle、bannerImage 等),需要业务方自行渲染广告 UI;非自渲染广告由 SDK 负责渲染。
广告类型一览:
| 广告类型 | 广告类别 | 渲染方式 |
|---|---|---|
| 优量汇插屏 | 插屏 | SDK 渲染 |
| 优量汇激励视频 | 激励视频 | SDK 渲染 |
| 穿山甲 | 激励视频 | SDK 渲染 |
| 玲珑 | 自渲染 | 业务方渲染 |
| 到店商增 | 自渲染 | 业务方渲染 |
| 到家津贴 | 自渲染 | 业务方渲染 |
| 到家异业 | 自渲染/激励视频 | 混合 |
# 3.2 注意事项
- 创建广告时,如果传入的
posId错误,SDK 内部请求异常场景下不会触发回调。请确保posId正确。 - 建议在
onLoad()返回后再调用show(),否则无法保证广告成功展示。也可在show失败后再次load,并在onLoad回调中展示广告。 - 必须注册
onError回调,并针对错误码进行兜底处理(即自动发奖)。 - 激励视频广告存在时效,
load成功后约 90 秒 未展示会失效,此时调用show会报错(errCode: 1002)。建议针对该错误重新load。 - 激励/插屏广告(弹窗样式)仅支持美团 12.45.200 及以上版本。低版本用户需弹窗引导升级。
- 判断广告拉取失败的方式:监听
customAd.onError。 - 一次广告只调用一次 show,多次 show 会降低曝光成功率,影响广告收入。
- 自渲染广告必须传
serialId,非自渲染广告不传serialId。 - 点击上报(
mc)时必须传tagIdentifier和macroInfo。 - 广告实例不再使用时必须调用
destroy()释放资源。
# 3.3 广告生命周期流程
完整的广告生命周期如下:
create → 自动触发首次 load
↓
onLoad → 缓存广告数据,判断是否激励广告
↓
adReport(mv) → 广告入口曝光时上报
↓
adReport(mc) → 用户点击广告入口时上报
↓
show → 展示广告(仅调用一次)
↓
onClose → 广告关闭,判断发奖
↓
destroy → 释放资源
🔄 重新加载:如需再次展示广告,可调用 load() 重新拉取,等待 onLoad 回调后再次走 show 流程。如果 load 失败,会触发 onError。
# 四、测试指南
# 4.1 测试自动发奖逻辑
将 posId 改为固定值 10401,该广告位没有任何广告资源配置,会稳定返回 onError,可用于测试连续失败 3 次后自动发奖的逻辑。
完整测试代码示例:
// ========== 自动发奖测试 ==========
// 使用测试 posId,模拟广告请求持续失败的场景
const MAX_RETRY = 3;
let retryCount = 0;
let hasGranted = false; // 防止重复发奖
const customAd = mt.createCustomAd({
posId: "10401", // 测试专用 posId,无广告资源配置,稳定触发 onError
optionalParams: {
adDemand: "1",
dockerType: "mgc",
dockerVersion: "1.0.0"
}
});
if (!customAd) {
console.error("[Ad-Test] customAd 创建失败");
return;
}
customAd.onLoad((res) => {
// 使用 posId=10401 时不会触发此回调
console.log("[Ad-Test] 意外收到 onLoad:", res);
retryCount = 0;
});
customAd.onError((err) => {
retryCount++;
console.log("[Ad-Test] onError 第 " + retryCount + " 次,",
"errCode:", err.errCode, "errMsg:", err.errMsg);
if (retryCount >= MAX_RETRY) {
// 连续失败达到上限,自动发奖
console.log("[Ad-Test] ✅ 连续 " + MAX_RETRY + " 次失败,触发自动发奖");
if (!hasGranted) {
hasGranted = true;
grantReward(); // 替换为实际的发奖逻辑
}
retryCount = 0;
return;
}
// 未达上限,静默重试(用户无感知)
console.log("[Ad-Test] 静默重试中...");
setTimeout(() => {
customAd.load().catch(() => {
// reject 会再次触发 onError,无需额外处理
});
}, 1000);
});
customAd.onClose((res) => {
console.log("[Ad-Test] onClose:", res);
});
// 预期输出:
// [Ad-Test] onError 第 1 次, errCode: 1005 errMsg: ...
// [Ad-Test] 静默重试中...
// [Ad-Test] onError 第 2 次, errCode: 1005 errMsg: ...
// [Ad-Test] 静默重试中...
// [Ad-Test] onError 第 3 次, errCode: 1005 errMsg: ...
// [Ad-Test] ✅ 连续 3 次失败,触发自动发奖
📋 测试要点:验证时请关注控制台日志:确认 onError 被连续触发 3 次、重试过程中无 UI 变化(用户无感知)、第 3 次失败后自动调用了发奖逻辑。测试完成后记得将 posId 改回正式值。
# 4.2 验证清单
| # | 验证项 | 预期结果 |
|---|---|---|
| 1 | 正常 posId 加载广告 | onLoad 回调触发,广告数据缓存成功 |
| 2 | 展示广告后关闭(激励视频) | onClose 回调 isRewarded=true,发奖 |
| 3 | 展示广告提前关闭(激励视频) | onClose 回调 isRewarded=false,不发奖 |
| 4 | 使用 posId=10401 测试 | 连续 3 次 onError 后自动发奖 |
| 5 | 低版本美团 App 点击广告按钮 | 弹窗提示升级 |
| 6 | 重复点击 show | 仅第一次生效,后续被拦截 |
| 7 | 广告加载后超过 90 秒再 show | show 失败(errCode 1002),自动重新 load |
| 8 | 曝光上报(mv) | adReport 调用成功,日志打印正确 |
| 9 | 点击上报(mc) | adReport 调用成功,包含 tagIdentifier 和 macroInfo |
| 10 | 销毁广告实例 | offLoad/offError/offClose + destroy 调用成功 |
# 4.3 技术支持
如在接入过程中遇到任何问题,请联系美团广告技术支持团队。
- 如发现多次返回无填充(1005)或限流(1006),请联系美团接口人调整广告位配置