> 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/common/monetization/iaa/web-banner.md).

# 인앱 광고 - 배너 광고(WebView)

서비스 소개와 콘솔 설정 방법은 인앱 광고 소개 문서를 참고해 주세요.

WebView에서 배너 광고를 표시할 수 있는 광고 라이브러리예요.

### 시작하기

배너 광고 API는 토스 앱 5.241.0 이상에서 사용할 수 있어요.

| 토스 앱 버전        | 지원 여부 | 설명              |
| -------------- | ----- | --------------- |
| **5.241.0 이상** | 지원    | 배너 광고 사용 가능     |
| **5.241.0 미만** | 미지원   | 배너 광고 API 사용 불가 |

{% hint style="info" %}
**5.241.0 미만 버전 예외 처리**

토스앱 5.241.0 미만에서는 빈 화면이 노출될 수 있으니 반드시 예외 처리를 해 주세요. 토스앱 버전 가져오기 기능을 사용해 예외 처리를 해 주세요.
{% 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' }} />;
}

// 초기화 및 배너 부착을 위한 커스텀 훅
function useTossBanner() {
  const [isInitialized, setIsInitialized] = useState(false);

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

    TossAds.initialize({
      callbacks: {
        onInitialized: () => setIsInitialized(true),
        onInitializationFailed: (error) => {
          console.error('Toss Ads SDK initialization failed:', 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);
      // 대체 컨텐츠 표시 또는 재시도
    },
  },
});
```

***

**재사용 가능한 커스텀 훅**

여러 화면에서 배너 광고를 사용할 때 커스텀 훅으로 분리하면 편리해요.

**useTossBanner**

SDK 초기화와 배너 부착을 함께 처리하는 훅이에요.

```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 initialization failed:', 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>

#### 토스 애즈 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>광고 영역을 주기적으로 Refresh 처리</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 운영 원칙**

광고도 토스의 UX 원칙을 따라야 해요.

| **Toss Principle**             | **적용 기준**                              | **예시**                       |
| ------------------------------ | -------------------------------------- | ---------------------------- |
| **Simplicity**                 | 광고는 명료해야 하며, 추가 설명 없이 의미를 이해할 수 있어야 해요 | "지금 보기", "광고 보기" 등 명확 CTA 사용 |
| **Clear Action**               | 광고 클릭 후 어떤 행동이 발생할지 사용자가 예측 가능해야 해요    | 리디렉션·새창 이동 시 고지 문구 노출        |
| **No Deception (UX Red Rule)** | 광고가 예상치 못한 순간, 형태, 위치에서 등장하지 않아야 해요    | 서비스 진입 직후 전면 배너 금지           |
| **Value First**                | 광고는 고객의 서비스 목표를 방해하지 않아야 해요            | 결제/계좌 개설 흐름 중 광고 삽입 금지       |

#### 이용 제한 및 제재 조치

앱인토스 광고 지면 또는 서비스가 본 정책을 위반한 경우 제재가 적용될 수 있어요.

***

**제한 절차**

제한 조치는 원칙적으로 위반 행위의 누적 정도에 따라 단계적으로 적용돼요. 다만, 위반의 유형이나 중대성에 따라 단일 위반에도 즉시 30일 이용 제한 또는 영구 이용 제한이 적용될 수 있어요.

※ 동시에 확인된 위반은 위반 슬롯의 개수와 관계없이 1회 위반으로 처리돼요. 이후 별도로 위반이 확인되는 경우 위반 횟수가 누적돼요.

<figure><img src="/files/CdzR027vPvc45B2GnSZ9" alt=""><figcaption></figcaption></figure>

***

**부당 수익 처리**

정책 위반, 무효 트래픽 또는 기타 부정한 방식으로 발생한 수익은 부당 수익으로 간주될 수 있어요.

부당 수익이 확인되면 해당 금액에 대해 지급 보류 또는 지급 거절이 이루어질 수 있으며, 이미 지급된 금액도 동일하게 환수될 수 있어요.

***

**이의제기 절차**

* 이용 제한 통지를 받은 경우 **30일 이내 이의제기를 신청**할 수 있어요.
  * 이의제기 자료는 채널톡을 통해 제출할 수 있어요.
* 제출된 자료는 내부 기준에 따라 검토되며, 필요한 경우 추가 자료를 요청할 수 있어요.
  * 검토에는 영업일 기준 약 1주일이 소요될 수 있어요.
  * 이의제기 신청에 대해서는 **제재가 적절했는지 여부를 중심으로 검토**하며, 위반 사항을 수정했거나 재발 방지 계획을 제출한 사실만으로는 제재가 해제되지 않아요.
  * 제출된 이의제기 자료를 통해 제재의 근거가 된 위반 사실이 인정되지 않거나 제재 판단에 명백한 오류가 있는 것으로 확인되는 경우에는 제재가 해제될 수 있어요.
* 반복적이거나 중대한 위반의 경우 서비스 이용이 영구적으로 제한될 수 있어요.

***

**테스트하기**

개발 단계에서는 반드시 테스트용 광고 ID를 사용해요. 실제 광고 ID로 테스트하면 정책 위반으로 간주해 불이익을 받을 수 있어요.

WebView 배너 광고 테스트 ID는 [시작하기](#시작하기)에서 확인할 수 있어요.

출시 전에 아래 항목을 꼭 확인해 주세요.

* 광고가 정상적으로 로드되는지 확인해요.
* 클릭 시 의도한 화면으로 이동하는지 확인해요.
* 뒤로 가기 동작이 정상적으로 작동하는지 확인해요.
* 결제나 인증 흐름을 방해하지 않는지 확인해요.

***

### 자주 묻는 질문

<details>

<summary>\"This feature is not supported in the current environment\" 에러가 발생해요</summary>

1. 토스 앱 환경에서 실행 중인지 확인해 주세요.
2. 앱 버전이 요구사항을 충족하는지 확인해 주세요.
3. `isSupported()` 메서드로 지원 여부를 먼저 확인해 주세요.

</details>

<details>

<summary>SDK 초기화가 실패했어요</summary>

1. `onInitializationFailed` 콜백에서 구체적인 에러 메시지를 확인해 주세요.
2. 네트워크 연결 상태를 확인해 주세요.
3. 이미 초기화된 경우 `[toss-ad] Already initialized.` 에러가 발생해요. 초기화는 앱에서 한 번만 해야 하므로, 상태를 전역으로 관리해 중복 호출을 방지해 주세요.

</details>

<details>

<summary>TossAds.attachBanner를 호출했는데 광고가 표시되지 않아요</summary>

1. `TossAds.initialize`를 먼저 호출하고 `onInitialized` 콜백을 받았는지 확인해 주세요.
2. DOM 요소가 실제로 존재하는지 확인해 주세요. React의 경우, `useEffect`에서 `ref.current`가 `null`이 아닌지 확인해 주세요.
3. `onAdFailedToRender` 또는 `onNoFill` 콜백에서 에러를 확인해 주세요.
4. `adGroupId`가 올바른지 확인해 주세요. 앱인토스 콘솔에서 발급받은 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>

샌드박스에서는 인앱 광고 기능을 지원하지 않아요.

불편하시겠지만 콘솔 내 QR 코드로 테스트를 진행해 주세요.

</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/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.
