> For the complete documentation index, see [llms.txt](https://developers-apps-in-toss.toss.im/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://developers-apps-in-toss.toss.im/documentation/api-and-sdk-zh/common/monetization/iaa/web-banner.md).

# 应用内广告 - 横幅广告(WebView)

服务介绍和控制台设置方法是 [应用内广告介绍文档](https://developers-apps-in-toss.toss.im/guide/monetization/in-app-ad)请参考。

这是一个可以在 WebView 中展示横幅广告的广告库。

### 开始使用

横幅广告 API 可在 Toss 应用 5.241.0 及以上版本中使用。

| Toss 应用版本       | 是否支持 | 说明           |
| --------------- | ---- | ------------ |
| **5.241.0 及以上** | 支持   | 可使用横幅广告      |
| **低于 5.241.0**  | 不支持  | 无法使用横幅广告 API |

{% hint style="info" %}
**低于 5.241.0 版本的异常处理**

在 Toss 应用低于 5.241.0 时可能会显示空白页面，因此请务必做好异常处理。请使用获取 Toss 应用版本的功能进行异常处理。
{% endhint %}

在开发阶段使用测试用广告 ID。

| 类型          | 测试 ID                         |
| ----------- | ----------------------------- |
| 横幅广告 - 列表型  | `ait-ad-test-banner-id`       |
| 横幅广告 - 信息流型 | `ait-ad-test-native-image-id` |

### API 参考

**概述**

| API                    | 说明                                                                            |
| ---------------------- | ----------------------------------------------------------------------------- |
| `TossAds.initialize`   | 初始化横幅广告 SDK。显示广告前必须调用一次。                                                      |
| `TossAds.attachBanner` | 将横幅广告附加到特定 DOM 元素。会应用样式预设（theme、tone、variant），并且返回对象的 `destroy()` 可通过该方法移除横幅。 |
| `TossAds.destroyAll`   | 移除所有已初始化的横幅槽位。                                                                |

每个 API 都 `isSupported()` 可通过该属性确认当前环境下该功能是否可用。

**事件流程**

```
调用 TossAds.initialize
↓
onInitialized 回调（初始化完成）
↓
调用 TossAds.attachBanner
↓
onAdRendered 事件（广告渲染完成）
↓
onAdImpression 事件（广告已展示到屏幕上）
↓
onAdViewable 事件（广告曝光已记录）
↓
onAdClicked 事件（可选 - 用户点击时）
```

{% hint style="info" %}
**横幅何时会刷新（refresh）？**

横幅广告在同时满足以下两个条件时，SDK 会自动刷新。

* 广告渲染后已超过 10 秒
* 屏幕的 visibility 从 false → true 发生变化时（例如：点击广告后返回，或应用从后台回到前台时）
  {% endhint %}

**横幅广告 SDK 初始化(`initialize`)**

初始化横幅广告 SDK。初始化过程异步进行，完成与否会通过回调传递。使用广告前必须初始化一次，并建议仅在应用最顶层组件中调用一次。

**签名**

```tsx
TossAds.initialize(options: TossAdsInitializeOptions): void;
```

**参数**

* **options** · `TossAdsInitializeOptions`

  这是在 SDK 初始化时传入的选项对象。可以设置初始化成功/失败的回调。
* **options.callbacks** · `{ onInitialized?: () => void; onInitializationFailed?: (error: Error) => void; }`

  定义 SDK 初始化过程中要调用的回调的对象。

  * **options.callbacks.onInitialized** · `() => void`

    SDK 初始化成功完成时调用。
  * **options.callbacks.onInitializationFailed** · `(error: Error) => void`

    SDK 初始化失败时调用。失败原因会以 `Error` 对象传递。

**TossAdsInitializeOptions**

```tsx
interface TossAdsInitializeOptions {
  callbacks?: {
    onInitialized?: () => void; // SDK 初始化成功时调用
    onInitializationFailed?: (error: Error) => void; // SDK 初始化失败时调用
  };
}
```

**属性**

* isSupported() => boolean

  在当前运行环境中 `TossAds.initialize` 用于确认该功能是否可用的函数。调用广告 SDK 初始化前必须先确认是否支持。

**示例**

{% tabs %}
{% tab title="tsx\[React]" %}

```tsx
import { TossAds } from '@apps-in-toss/web-framework';
import { useEffect, useState } from 'react';

function App() {
  const [isInitialized, setIsInitialized] = useState(false);

  useEffect(() => {
    // 检查是否支持
    if (!TossAds.initialize.isSupported()) {
      console.warn('无法使用横幅广告功能。');
      return;
    }

    // 初始化 SDK
    TossAds.initialize({
      callbacks: {
        onInitialized: () => {
          console.log('SDK 初始化完成');
          setIsInitialized(true);
        },
        onInitializationFailed: (error) => {
          console.error('SDK 初始化失败：', error);
        },
      },
    });
  }, []);

  return <div>{isInitialized ? '广告准备完成' : '广告准备中...'};
}
```

{% endtab %}

{% tab title="tsx\[ReactNative]" %}

```tsx
import React, { useEffect, useState } from 'react';
import { View, Text, Alert } from 'react-native';
import { TossAds } from '@apps-in-toss/framework';

export default function App() {
  const [isInitialized, setIsInitialized] = useState(false);

  useEffect(() => {
    // 检查是否支持
    if (!TossAds.initialize.isSupported()) {
      console.warn('无法使用横幅广告功能。');
      return;
    }

    // 初始化 SDK
    TossAds.initialize({
      callbacks: {
        onInitialized: () => {
          console.log('SDK 初始化完成');
          setIsInitialized(true);
        },
        onInitializationFailed: (error) => {
          console.error('SDK 初始化失败：', error);
          // 在原生环境中可以弹出 Alert 提示用户/开发者
          Alert.alert('横幅广告初始化失败', String(error?.message ?? error));
        },
      },
    });
  }, []);

  return (
    <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
      <Text>{isInitialized ? '广告准备完成' : '广告准备中...'}</Text>
    </View>
  );
}
```

{% endtab %}
{% endtabs %}

***

**横幅广告附加(`attachBanner`)**

将横幅广告附加到特定 DOM 元素。会应用样式预设（theme、tone、variant），并且返回对象的 `destroy()` 可通过该方法移除横幅。

`TossAds.initialize`需要先调用后初始化 SDK，之后才能使用。

{% hint style="info" %}
**广告附加指南**

* 附加广告的元素内部应保持为空。
* 容器的 `width`必须始终与屏幕宽度相同（`100%`).
* 如果以固定样式使用 `height: 96px` 推荐
  {% endhint %}

**签名**

```tsx
TossAds.attachBanner(
  adGroupId: string,
  target: string | HTMLElement,
  options?: TossAdsAttachBannerOptions
): TossAdsAttachBannerResult;
```

**参数**

* **adGroupId** · 必填 · `string`

  这是广告组级别 ID。请输入在控制台获取的值。
* **target** · 必填 · `string | HTMLElement`

  这是要附加广告的 DOM 元素。 `HTMLElement` 可以直接传入对象，或传入 CSS 选择器字符串。
* **options** · `TossAdsAttachBannerOptions`

  这是可设置横幅样式及广告事件回调的选项对象。
* **options.theme** · `'auto' | 'light' | 'dark'`

  设置横幅主题。默认值为 `'auto'`，并会根据系统深色模式设置自动切换。
* **options.tone** · `'blackAndWhite' | 'grey'`

  设置横幅背景色调。默认值为 `'blackAndWhite'`。
* **options.variant** · `'expanded' | 'card'`

  设置横幅形式。默认值为 `'expanded'`。
* **options.callbacks** · `AttachBannerCallbacks`

  这是可接收广告生命周期事件的回调对象。

  * **options.callbacks.onAdRendered** · `(payload) => void`

    广告渲染完成时调用。
  * **options.callbacks.onAdImpression** · `(payload) => void`

    当广告达到可在用户屏幕上曝光的状态时调用。
  * **options.callbacks.onAdViewable** · `(payload) => void`

    当广告曝光被记录并产生收益时调用。
  * **options.callbacks.onAdClicked** · `(payload) => void`

    广告被点击时调用。
  * **options.callbacks.onNoFill** · `(payload) => void`

    没有可展示广告时调用。
  * **options.callbacks.onAdFailedToRender** · `(payload) => void`

    广告渲染失败时调用。

**TossAdsAttachBannerOptions**

```tsx
interface TossAdsAttachBannerOptions {
  theme?: 'auto' | 'light' | 'dark'; // 主题（默认值：'auto')
  tone?: 'blackAndWhite' | 'grey'; // 背景色调（默认值：'blackAndWhite')
  variant?: 'card' | 'expanded'; // 横幅形式（默认值：'expanded')
  callbacks?: TossAdsBannerSlotCallbacks;
}
```

`TossAds.attachBanner` 这是函数的选项类型。

| 选项          | 类型                            | 默认值               | 说明                                       |
| ----------- | ----------------------------- | ----------------- | ---------------------------------------- |
| `theme`     | `'auto' \| 'light' \| 'dark'` | `'auto'`          | 主题设置。 `auto`会根据系统深色模式自动切换                |
| `tone`      | `'blackAndWhite' \| 'grey'`   | `'blackAndWhite'` | 背景色调                                     |
| `variant`   | `'card' \| 'expanded'`        | `'expanded'`      | 横幅形式。 `card`具有左右内边距 + `border-radius` 应用 |
| `callbacks` | `TossAdsBannerSlotCallbacks`  | -                 | 广告事件回调                                   |

**TossAdsAttachBannerResult**

```tsx
interface TossAdsAttachBannerResult {
  destroy: () => void;
}
```

`TossAds.attachBanner` 这是函数的返回类型。

* `destroy()`：移除已附加的横幅。建议在组件卸载时调用，以防止内存泄漏。

**TossAdsBannerSlotCallbacks**

```tsx
interface TossAdsBannerSlotCallbacks {
  onAdRendered?: (payload: TossAdsBannerSlotEventPayload) => void;
  onAdViewable?: (payload: TossAdsBannerSlotEventPayload) => void;
  onAdClicked?: (payload: TossAdsBannerSlotEventPayload) => void;
  onAdImpression?: (payload: TossAdsBannerSlotEventPayload) => void;
  onAdFailedToRender?: (payload: TossAdsBannerSlotErrorPayload) => void;
  onNoFill?: (payload: { slotId: string; adGroupId: string; adMetadata: {} }) => void;
}
```

这是横幅广告事件回调。

* `onAdRendered`：广告已渲染。
* `onAdImpression`：广告已在屏幕上曝光。
* `onAdViewable`：广告曝光已记录。（产生收益的时点）
* `onAdClicked`：用户点击了广告。
* `onAdFailedToRender`：广告渲染失败。
* `onNoFill`：没有可展示的广告。

**TossAdsBannerSlotEventPayload**

```tsx
interface TossAdsBannerSlotEventPayload {
  slotId: string;
  adGroupId: string;
  adMetadata: {
    creativeId: string;
    requestId: string;
  };
}
```

这是横幅广告事件载荷。

* `slotId`：生成的槽位 ID
* `adGroupId`：广告组 ID
* `adMetadata`：广告元数据（creativeId、requestId）

**TossAdsBannerSlotErrorPayload**

```tsx
interface TossAdsBannerSlotErrorPayload {
  slotId: string;
  adGroupId: string;
  adMetadata: {};
  error: {
    code: number;
    message: string;
    domain?: string;
  };
}
```

这是横幅广告错误载荷。

**返回值**

`TossAdsAttachBannerResult` 会返回对象。这个对象的 `destroy()` 可通过方法移除横幅。

**属性**

* isSupported() => boolean

  在当前运行环境中 `TossAds.attachBanner` 用于确认该功能是否可用的函数。附加横幅广告前必须先确认是否支持。

**示例**

```tsx
import { TossAds, TossAdsAttachBannerOptions } from '@apps-in-toss/web-framework';
import { useCallback, useEffect, useRef, useState } from 'react';

function BannerAdComponent({ adGroupId }: { adGroupId: string }) {
  const containerRef = useRef<HTMLDivElement>(null);
  const { isInitialized, attachBanner } = useTossBanner();

  useEffect(() => {
    if (!isInitialized || !containerRef.current) return;

    // 附加横幅
    const attached = attachBanner(adGroupId, containerRef.current, {
      theme: 'auto', // 根据系统设置自动切换
      tone: 'blackAndWhite', // 黑白背景
      variant: 'expanded', // 全宽展开形式
      callbacks: {
        onAdRendered: (payload) => {
          console.log('广告渲染完成：', payload.slotId);
        },
        onAdImpression: (payload) => {
          console.log('广告已曝光：', payload.slotId);
        },
        onAdViewable: (payload) => {
          console.log('广告曝光已记录（产生收益）：', payload.slotId);
        },
        onAdClicked: (payload) => {
          console.log('广告被点击：', payload.slotId);
        },
        onNoFill: (payload) => {
          console.warn('没有可展示的广告：', payload.slotId);
        },
        onAdFailedToRender: (payload) => {
          console.error('广告渲染失败：', payload.error.message);
        },
      },
    });

    // 清理：调用 destroy
    return () => {
      attached?.destroy();
    };
  }, [isInitialized, adGroupId, attachBanner]);

  // 固定型横幅：width 100% + height 96px
  return <div ref={containerRef} style={{ width: '100%', height: '96px' }} />;
}

// 用于初始化和附加横幅的自定义 Hook
function useTossBanner() {
  const [isInitialized, setIsInitialized] = useState(false);

  useEffect(() => {
    if (isInitialized) return;

    TossAds.initialize({
      callbacks: {
        onInitialized: () => setIsInitialized(true),
        onInitializationFailed: (error) => {
          console.error('Toss Ads SDK 初始化失败：', error);
        },
      },
    });
  }, [isInitialized]);

  const attachBanner = useCallback(
    (adGroupId: string, element: HTMLElement, options?: TossAdsAttachBannerOptions) => {
      if (!isInitialized) return;
      return TossAds.attachBanner(adGroupId, element, options);
    },
    [isInitialized],
  );

  return { isInitialized, attachBanner };
}
```

这是横幅广告错误载荷。

***

**移除所有横幅槽位(`destroyAll`)**

移除所有已初始化的横幅槽位。

**签名**

```tsx
TossAds.destroyAll(): void;
```

**属性**

* isSupported() => boolean

  在当前运行环境中 `TossAds.destroyAll` 用于确认该功能是否可用的函数。可在整体移除横幅广告实例前确认是否支持时使用。

**示例**

```tsx
// 页面跳转时移除所有横幅
useEffect(() => {
  return () => {
    TossAds.destroyAll();
  };
}, []);
```

***

### 使用模式

**初始化时机**

建议 SDK 只在应用启动时初始化一次。推荐在以下时机进行初始化：

* 在应用最顶层组件（App.tsx）挂载时
* 在进入首个要展示广告的页面之前

```tsx
// ✅ 好例子：在应用启动时初始化
function App() {
  useEffect(() => {
    if (TossAds.initialize.isSupported()) {
      TossAds.initialize({
        callbacks: {
          onInitialized: () => console.log('SDK 准备完成'),
        },
      });
    }
  }, []);

  return <Router />;
}

// ❌ 不好的例子：每个组件都重复初始化
function BannerComponent() {
  useEffect(() => {
    TossAds.initialize({
      /* ... */
    }); // 尝试重复初始化
  }, []);
}
```

**容器尺寸设置**

广告容器必须设置为正确的尺寸。

```tsx
// ✅ 固定型：推荐 width 100% + height 96px
<div ref={containerRef} style={{ width: '100%', height: '96px' }} />

// ✅ 内联：width 100% + 不指定 height
<div ref={containerRef} style={{ width: '100%' }} />

// ❌ 错误示例：width 为固定值
<div ref={containerRef} style={{ width: '320px', height: '96px' }} />
```

**内存管理**

组件卸载时应移除横幅，以防止内存泄漏。

`TossAds.attachBanner`是 `destroy()` 会返回包含该方法的对象，因此在清理时调用它即可。

```tsx
useEffect(() => {
  if (!isInitialized || !containerRef.current) return;

  // 附加横幅
  const attached = TossAds.attachBanner(adGroupId, containerRef.current, {
    callbacks: { ... },
  });

  // 清理：调用 destroy
  return () => {
    attached?.destroy();
  };
}, [isInitialized, adGroupId]);
```

**错误处理**

始终 `onInitializationFailed`和 `onAdFailedToRender` 请提供回调以应对错误。

```tsx
TossAds.initialize({
  callbacks: {
    onInitialized: () => {
      console.log('初始化成功');
    },
    onInitializationFailed: (error) => {
      console.error('初始化失败：', error);
      // 向用户提供适当反馈
    },
  },
});

TossAds.attachBanner(adGroupId, element, {
  callbacks: {
    onAdFailedToRender: (payload) => {
      console.error('广告渲染失败：', payload.error.message);
      // 显示替代内容或重试
    },
  },
});
```

***

**可复用的自定义 Hook**

在多个页面使用横幅广告时，拆分成自定义 Hook 会更方便。

**useTossBanner**

这是一个同时处理 SDK 初始化和横幅挂载的 Hook。

```tsx
import { useCallback, useEffect, useRef, useState } from 'react';
import { TossAds, type TossAdsAttachBannerOptions } from '@Apps in Toss/web-framework';

export function useTossBanner() {
  const [isInitialized, setIsInitialized] = useState(false);

  useEffect(() => {
    if (isInitialized) return;

    TossAds.initialize({
      callbacks: {
        onInitialized: () => setIsInitialized(true),
        onInitializationFailed: (error) => {
          console.error('Toss Ads SDK 初始化失败：', error);
        },
      },
    });
  }, [isInitialized]);

  const attachBanner = useCallback(
    (adGroupId: string, element: HTMLElement, options?: TossAdsAttachBannerOptions) => {
      if (!isInitialized) return;
      return TossAds.attachBanner(adGroupId, element, options);
    },
    [isInitialized],
  );

  return { isInitialized, attachBanner };
}
```

**使用示例**

```tsx
import { useRef, useEffect } from 'react';

function MyPage() {
  const bannerRef = useRef<HTMLDivElement>(null);
  const { isInitialized, attachBanner } = useTossBanner();

  useEffect(() => {
    if (!isInitialized || !bannerRef.current) return;

    const attached = attachBanner('your-ad-group-id', bannerRef.current, {
      theme: 'auto',
      tone: 'blackAndWhite',
      variant: 'expanded',
      callbacks: {
        onAdRendered: (payload) => console.log('广告渲染：', payload.slotId),
        onAdImpression: () => console.log('广告曝光'),
      },
    });

    return () => {
      attached?.destroy();
    };
  }, [isInitialized, attachBanner]);

  return (
    <div>
      <h1>我的页面</h1>
      {/* 固定型横幅：width 100% + height 96px */}
      <div ref={bannerRef} style={{ width: '100%', height: '96px' }} />

  );
}
```

> **参考**: `useTossBanner`即使在多个组件中调用也很安全。若已初始化，不会尝试重复初始化。

***

### 广告政策 <a href="#policy" id="policy"></a>

#### Toss Ads SSP 政策 <a href="#ssp" id="ssp"></a>

请务必遵守以下政策。若违反，广告展示可能会受到限制。

**即使本政策未明确规定，刻意诱导广告展示·点击·效果，或造成用户误解的行为，也可能被视为违反政策。**

所有合作方在因违反政策而终止服务时，都应遵守服务终止政策。

| 类型         | 禁止行为                                                         | 具体示例                                                                                                                                                                                                                                                                                                         | 政策标准                                                                                                              |
| ---------- | ------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------- |
| UI/UX 质量下降 | 将广告与内容的区分变得不明确，或引导用户在与自身意图无关的情况下消费或点击广告，或通过 UI 设计妨碍正常服务使用的行为 | <p></p><ul><li>将广告伪装成“推荐服务”、“金融技巧”等</li><li>修改非 Toss Ads 指南范围内广告单元的颜色·字体</li><li>擅自修改广告的标题·标签·CTA 文案及设计</li><li>将广告放置在用户交互元素（按钮、游戏区域等）附近，使其容易发生非预期点击的结构</li><li>在同一页面上放置 2 个以上相同格式广告的情况</li><li>让用户难以正常关闭页面或返回上一页的死路（Dead-end）结构</li><li>使用户难以区分广告与服务 CTA 功能的结构</li><li>使用户难以识别或访问正常使用服务所需 CTA 的结构</li></ul> | <p></p><ul><li>广告必须保留“Ad”标记</li><li>所有广告 UI 都必须使用 web-base 标准组件</li><li>禁止为人工诱导广告效果或损害用户体验而进行的 UI/UX 设计</li></ul> |
| 广告调用行为篡改   | 更改或绕过 SDK 默认事件流程或广告调用方式的行为                                   | <ul><li>SDK Click / Impression 事件篡改</li><li>不经过广告 SDK，而是用自有逻辑调用广告，或通过绕过 SDK 事件来实现的情况</li><li>阻止或异常控制 Back 按钮，妨碍用户正常关闭页面或返回上一页的情况</li></ul>                                                                                                                                                                   | <p></p><ul><li>禁止篡改 SDK 默认事件（Click / Impression）结构</li><li>不可调用 SDK 外部 API</li></ul>                              |
| 异常流量及效果操纵  | 以自动化或人为方式扭曲流量及广告效果的行为                                        | <ul><li>定期刷新广告区域</li><li>人为制造效果（点击·展示等）的活动</li></ul>                                                                                                                                                                                                                                                         | <ul><li>如确认基于流量质量的异常模式，将限制广告、施加处罚并暂停结算</li></ul>                                                                  |
| 奖励·参与型点击引导 | 在点击广告的同时提供奖励或优惠的行为                                           | <ul><li>“点击广告立即提供奖励”</li><li>“点击广告即可获得积分”</li></ul>                                                                                                                                                                                                                                                          | <ul><li>禁止将广告消费与奖励直接关联的结构</li><li>禁止与点击奖励性文案·活动联动</li></ul>                                                       |
| 广告隐藏或重叠    | 故意隐藏广告，或让广告被其他 UI 元素遮挡，使用户难以清楚识别广告存在的行为                      | <p>• 透明广告 </p><p>• 在其他卡片 UI 后插入广告 DOM</p>                                                                                                                                                                                                                                                                    | • 广告的展示状态必须能够被明确确认                                                                                                |

***

#### **UX / Product Principle 运营原则**

广告也应遵循 Toss 的 UX 原则。

| **Toss Principle**             | **适用标准**                | **示例**                 |
| ------------------------------ | ----------------------- | ---------------------- |
| **Simplicity**                 | 广告应当清晰明确，且无需额外说明也能理解其含义 | 使用“立即查看”、“查看广告”等明确 CTA |
| **Clear Action**               | 用户应能预测点击广告后会发生什么行为      | 在重定向·跳转新窗口时显示告知文案      |
| **No Deception (UX Red Rule)** | 广告不应在意料之外的时机、形式或位置出现    | 禁止在进入服务后立即展示全屏横幅       |
| **Value First**                | 广告不应妨碍客户的服务目标           | 禁止在支付/开户流程中插入广告        |

#### 使用限制及制裁措施

若 Apps in Toss 广告版位或服务违反本政策，可能会受到处罚。

***

**限制流程**

限制措施原则上会根据违规行为的累积程度分阶段实施。但根据违规类型或严重性，即使是单次违规，也可能立即适用 30 天使用限制或永久使用限制。

※ 同时确认的违规，无论违规槽位数量多少，都按 1 次违规处理。此后如另行确认违规，违规次数将累计。

<figure><img src="https://1402050940-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FbbsGTd7OgbyqnSM8Iwcy%2Fuploads%2FimMfi4dNaTr2GSgeonmV%2Fimage.png?alt=media&amp;token=a33263ee-dc74-4a07-8898-471f2194e201" alt=""><figcaption></figcaption></figure>

***

**不当收益处理**

因违反政策、无效流量或其他不正当方式产生的收益，可能会被视为不当收益。

一旦确认存在不当收益，相关金额可能会被暂停支付或拒绝支付，已支付金额也可能同样被追回。

***

**申诉流程**

* 收到使用限制通知时 **可在 30 天内提交申诉**可以。
  * 申诉资料可以通过 Channel Talk 提交。
* 提交的资料将依据内部标准进行审核，必要时可能会要求补充资料。
  * 审核可能需要约 1 个工作周。
  * 对于申诉申请 **会重点审查处罚是否适当**，仅因已修正违规事项或提交防止再发计划，并不会解除处罚。
  * 若通过提交的申诉资料确认，构成处罚依据的违规事实不成立，或处罚判断存在明显错误，则处罚可能会被解除。
* 对于重复或重大违规，服务使用可能会被永久限制。

***

**测试**

在开发阶段务必使用测试用广告 ID。若使用真实广告 ID 进行测试，可能会被视为违反政策并受到不利影响。

WebView 横幅广告测试 ID [开始使用](#시작하기)可在其中确认。

上线前请务必确认以下项目。

* 确认广告是否能正常加载。
* 确认点击后是否会跳转到预期页面。
* 确认返回操作是否正常工作。
* 确认是否不会干扰支付或认证流程。

***

### 常见问题

<details>

<summary>会出现“This feature is not supported in the current environment”错误</summary>

1. 请确认是否在 Toss App 环境中运行。
2. 请确认 App 版本是否满足要求。
3. `isSupported()` 请先通过该方法确认是否支持。

</details>

<details>

<summary>SDK 初始化失败了</summary>

1. `onInitializationFailed` 请在回调中确认具体的错误信息。
2. 请确认网络连接状态。
3. 已初始化的情况下 `[toss-ad] 已初始化。` 会发生错误。初始化在 App 中只能执行一次，因此请将状态全局管理，以防止重复调用。

</details>

<details>

<summary>调用 TossAds.attachBanner 后，广告没有显示</summary>

1. `TossAds.initialize`请先调用 `onInitialized` 请确认是否已收到回调。
2. 请确认 DOM 元素是否实际存在。对于 React， `useEffect`中 `ref.current`为 `null`请确认它不是空值。
3. `onAdFailedToRender` 或 `onNoFill` 请在回调中确认错误。
4. `adGroupId`请确认是否正确。必须使用在 Apps in Toss 控制台中发放的 ID。

</details>

<details>

<summary>会出现“[toss-ad] Failed to find target element”错误</summary>

1. 请确认 DOM 元素是否实际存在。
2. 请确认选择器字符串是否正确。例如 `#banner`, `.ad-container`可以这样传入。
3. 在 React 中 `ref.current`为 `null`请确认它不是空值。

</details>

<details>

<summary>广告已显示，但回调未被调用</summary>

1. `callbacks` 选项 `TossAds.attachBanner`请确认是否已传入。
2. 请确认回调函数是否正确定义。
3. 请确认控制台是否输出错误。

</details>

<details>

<summary>我想移除横幅</summary>

`TossAds.attachBanner`返回的对象的 `destroy()`请调用它。如果需要移除整个页面的横幅槽位， `TossAds.destroyAll`可以使用它。

</details>

<details>

<summary>在沙盒中无法使用应用内广告功能</summary>

沙盒不支持应用内广告功能。

很抱歉，请通过控制台内的二维码进行测试。

</details>


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://developers-apps-in-toss.toss.im/documentation/api-and-sdk-zh/common/monetization/iaa/web-banner.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
