앱인토스 소개 – 인앱 광고(In-App Ads), 종류와 붙이는 방법
앱인토스 인앱 광고(In-App Ads)는 별도의 결제 기능 없이 미니앱에 수익 구조를 붙이는 방법이고, 공식 문서는 전면형·리워드·배너 세 가지 유형을 안내합니다. 유형마다 쓰는 SDK 함수가 다르고, 호출 방식을 어기면 노출 제한이나 정산 보류 같은 조치가 따라와요.
수익화 글이 전체 그림이었다면 이 글은 함수와 이벤트 단위로 내려갑니다. 개발자센터의 인앱 광고 문서를 읽고 유형별 차이, 호출 순서, 지켜야 할 정책을 정리했고, 끝에는 제 물마시기 미니앱 코드에서 광고가 붙은 부분을 옮겼어요.
인앱 광고는 전면형·리워드·배너로 나뉜다
문서는 광고 수익이 두 가지로 정해진다고 설명합니다. 광고가 얼마나 많이 보였는지를 뜻하는 노출 수, 그리고 1,000회 노출당 수익인 eCPM입니다. 두 값을 곱해 1,000으로 나눈 것이 예상 수익이라는 계산식이 문서에 나와요.
전면형은 화면 전환 시점에 전체 화면으로 나타나고 사용자가 반드시 보게 됩니다. 리워드는 사용자가 직접 광고 보기를 선택해야 재생되는 방식이라 자발적 시청이고, 배너는 상단이나 하단에 고정되어 계속 노출돼요. 문서는 노출 수가 배너에서 가장 많고 리워드에서 낮으며, eCPM은 리워드가 가장 높고 배너가 가장 낮다고 적었습니다.


인앱 광고 연동 전에 콘솔에서 준비하는 것
콘솔 설정은 사업자 정보 등록이 먼저이고, 그게 있어야 약관 동의와 정산 정보 입력을 이어서 할 수 있다고 문서에 적혀 있어요. 개인 계정으로도 광고가 되는지는 이 문서가 말하지 않아서 여기서는 다루지 않았습니다.
- 사업자 정보 등록. 광고 연동의 첫 조건입니다.
- 정산 정보 입력. 워크스페이스의 정보 탭에서 입력하고 검토를 요청하며, 검토는 영업일 기준 평균 2~3일이 걸립니다.
- 광고 그룹(Ad Group) 생성. 유형을 고르고, 리워드는 보상 이름과 수량을 넣습니다.
예금주명은 통장 사본과 같게
문서는 예금주명이 통장 사본에 적힌 이름과 한 글자도 다르지 않아야 한다고 안내합니다. 다르게 입력하면 정산이 지연될 수 있어요.
광고 그룹 이름에는 유형과 노출 위치를 함께 적으라는 권고가 있고 예시는 메인_전면광고, 게임종료_리워드광고입니다. 미디에이션(Mediation)은 여러 광고 네트워크를 연동해 실시간으로 수익이 가장 높은 광고를 고르는 기술인데, 앱 정보에 등록한 카테고리에 맞는 네트워크가 자동으로 설정돼요. 광고 그룹 ID는 만든 뒤 상세 화면에서 확인하며, 구글에 등록되기까지 최대 2시간이 걸릴 수 있다고 합니다. 인앱 광고는 구글 애드몹(Google AdMob) 광고 정책을 따르기 때문에 정책을 지키지 않으면 광고가 제한되거나 중단될 수 있어요.
전면형과 리워드는 load 다음에 show를 부른다
두 유형은 loadFullScreenAd와 showFullScreenAd를 똑같이 쓰고, 어느 쪽인지는 광고 그룹 ID로 자동 결정됩니다. 광고 2.0 ver2는 토스 애즈(Toss Ads)와 애드몹을 통합해 환경에 따라 SDK가 광고를 고르는 방식이에요. 지원 토스 앱 버전은 문서마다 다르게 적혀 있습니다. 전면형·리워드 문서는 5.247.0 이상을 통합 지원으로 적었고 SDK 레퍼런스는 5.239.0 이상으로 적었으며, 두 문서 모두 5.227.0 미만은 지원하지 않는다고 해요. 호출 전에 isSupported()로 확인하는 쪽이 안전합니다.
호출 순서는 문서가 못 박아 두었습니다.
- 화면에 들어올 때
loadFullScreenAd로 광고를 미리 불러옵니다. loaded이벤트가 온 뒤에야showFullScreenAd를 부릅니다.requested,show,impression순서로 이벤트가 오고,impression이 수익 발생 시점입니다.- 사용자가 클릭하면
clicked, 닫으면dismissed가 옵니다. 이미 보여 준 광고는 다시 못 보여 주므로 다음 광고를 새로 load 합니다.


광고 로드에 걸리는 시간은 어느 네트워크 광고가 오느냐에 따라 달라요. 토스 애즈는 보통 1~2초 이내이고 최대 10초, 애드몹은 일반적으로 5~20초이며 네트워크 타임아웃인 60초까지 늘어질 수 있다고 문서가 밝혔습니다. 그래서 같은 광고 그룹 ID는 한 번에 하나만 미리 로드할 수 있다는 규칙과 함께, 광고를 보여 줄 화면에 들어가기 전에 미리 로드하라는 권고가 나옵니다. 버튼을 누른 뒤에 load를 부르는 것은 문서의 나쁜 예예요.
`userEarnedReward` 이벤트가 온 시점에 지급
광고를 끝까지 시청한 경우
`dismissed`만으로는 지급하지 않음
중간에 닫으면 리워드 미지급

테스트에 관한 안내도 있습니다. 전면형은 ait-ad-test-interstitial-id, 리워드는 ait-ad-test-rewarded-id라는 테스트용 ID를 쓰라고 하고, 샌드박스에서는 인앱 광고가 되지 않아서 콘솔의 QR 코드로 테스트해야 해요. 광고가 재생되는 동안에는 앱 사운드를 멈추고 끝나면 자동으로 다시 재생하라는 안내도 같이 있습니다.
배너 광고는 초기화한 뒤 슬롯에 붙인다
배너는 WebView와 React Native에서 쓰는 방법이 갈립니다. WebView는 TossAds.initialize를 한 번 부른 뒤 onInitialized 콜백을 받고 TossAds.attachBanner로 DOM 요소에 붙여요. React Native는 InlineAd 컴포넌트를 쓰고 initialize나 attachBanner를 기본 경로로 안내하지 않습니다.
| 환경 | 쓰는 것 | 문서가 적은 조건 |
|---|---|---|
| WebView | TossAds.initialize, attachBanner |
컨테이너 안은 비우고 너비는 100% |
| React Native | InlineAd |
IOScrollView로 감싸거나 impressFallbackOnMount |
고정형 배너는 높이 96px(React Native는 96)을 권장하고, 인라인 형태는 높이를 지정하지 않습니다. 너비를 320px처럼 고정값으로 주는 것은 문서의 잘못된 예였어요. attachBanner는 destroy()를 가진 객체를 돌려주므로 화면이 사라질 때 호출하라고 합니다. 스타일 옵션은 theme(auto·light·dark), tone(blackAndWhite·grey), variant(expanded·card) 세 가지예요.
배너는 SDK가 알아서 갱신합니다. 광고가 렌더링된 지 10초 이상 지났고, 화면 visibility가 false에서 true로 바뀔 때(광고를 누르고 돌아오거나 앱이 백그라운드에서 돌아올 때)라는 두 조건을 모두 채워야 해요. 이 갱신과 별개로 광고 영역을 직접 주기적으로 새로고침하는 것은 정책 위반 예시에 올라 있습니다. 이벤트는 onAdRendered, onAdImpression, onAdViewable, onAdClicked 순서이고 표시할 광고가 없을 때는 onNoFill, 그리기에 실패하면 onAdFailedToRender가 호출돼요.


광고 운영 정책에서 제재로 이어지는 행위
문서는 토스애즈 SSP 정책에 다섯 유형의 금지 행위를 적었습니다. 광고를 콘텐츠처럼 위장하거나 같은 화면에 같은 포맷 광고를 2개 이상 두는 UI/UX 품질 저하, SDK 이벤트를 바꾸거나 Back 버튼을 막는 호출 동작 변조, 주기적 새로고침 같은 비정상 트래픽, 클릭하면 보상을 주는 구조, 투명 광고처럼 광고를 숨기거나 겹치는 행위예요. 정책에 적히지 않았더라도 노출·클릭·성과를 인위적으로 유도하거나 사용자가 오해하게 만들면 위반으로 볼 수 있다는 문장이 앞에 붙어 있습니다.

제재는 원칙적으로 위반이 쌓인 정도에 따라 단계적으로 적용되지만, 유형이나 중대성에 따라서는 한 번의 위반으로도 30일 이용 제한이나 영구 이용 제한이 될 수 있어요. 정책 위반이나 무효 트래픽으로 생긴 수익은 지급이 보류되거나 거절되고 이미 지급된 금액도 환수될 수 있습니다. 이용 제한 통지를 받으면 30일 이내에 채널톡으로 이의제기를 할 수 있고, 검토에는 영업일 기준 약 1주일이 걸려요.
출시 체크리스트에도 같은 항목이 있습니다
비게임 출시 가이드의 광고 구역에는 광고가 사전에 로딩되어 있어야 하고 재생 시점에 실시간으로 로딩하지 않는다는 항목이 있습니다. 인트로·로딩·컷신·팝업 모달 같은 일시적인 화면에 광고를 노출하지 않는다는 항목은 UX 쪽에 따로 있어요. 결제나 계좌 개설 흐름 중에는 광고를 넣지 말라는 원칙도 정책 문서에 적혀 있습니다. 출시 체크리스트 글과 같이 보면 좋아요.
광고 성과는 요청부터 노출까지 네 단계로 본다
콘솔의 광고 분석 탭은 광고 요청, 광고 수신, 노출 시도, 노출 성공 네 단계로 어디까지 도달했는지 보여 줍니다. 문서는 요청 대비 수신이 낮으면 채울 광고가 부족한 No Fill일 수 있고, 수신 대비 노출 시도가 낮으면 load와 show 호출 타이밍을 확인하라고 해요. 이 탭은 SDK 2.7.0 이상으로 올려야 실제 데이터가 보이고, 성과 데이터는 매일 오전 10시에 갱신됩니다. 정산 내역은 월 단위로, 1일부터 말일까지의 수익이 다음 달 1일에 올라오고 확정된 수익은 그달 말일에 입금된다고 적혀 있어요.
물마시기 미니앱 코드에서 광고가 붙은 곳
제 물마시기 미니앱(app-factory88)에는 배너와 전면형이 들어 있습니다. 배너 컴포넌트는 앞에서 본 순서와 같게 짜여 있어요. 토스 앱 5.241.0 이상인지 먼저 확인하고, 초기화가 끝난 뒤에 붙이며, 컨테이너는 너비 100%에 높이 96으로 두고, 화면에서 사라질 때 destroy()를 부릅니다. 아래는 부착하는 부분이에요.
useEffect(() => {
if (!isInitialized || !containerRef.current) return;
if (!TossAds.attachBanner.isSupported()) return;
const attached = TossAds.attachBanner(BANNER_AD_GROUP_ID, containerRef.current, {
theme: 'light',
tone: 'blackAndWhite',
variant: 'expanded',
callbacks: {
onAdFailedToRender: (payload) => {
console.error('배너 광고를 표시하지 못했어요.', payload.error);
},
onNoFill: () => {
console.info('현재 표시할 수 있는 배너 광고가 없어요.');
},
},
});
return () => attached.destroy();
}, [isInitialized]);전면형은 홈 화면이 열릴 때 loadFullScreenAd로 미리 불러 두고, 불러온 상태일 때만 showFullScreenAd를 부릅니다. 광고가 닫히거나 표시에 실패하면 다음 단계로 넘어가고 곧바로 다음 광고를 새로 load 해요. 광고를 띄우기 전에는 앱 안에서 직접 그린 안내 시트가 먼저 나옵니다. 아래는 보여 주는 함수인데, 3초 안에 광고가 뜨지 않으면 기다리지 않고 진행하게 되어 있어요.
const show = useCallback((onClose: (watched: boolean) => void) => {
let done = false;
let impressed = false;
const finish = () => { if (!done) { done = true; onClose(impressed); load(); } };
if (!loadedRef.current || !cliffSupported()) { finish(); return; }
loadedRef.current = false;
cliffSession.shown += 1;
cliffSession.lastAt = Date.now();
const guard = window.setTimeout(finish, 3000);
try {
showFullScreenAd({
options: { adGroupId },
onEvent: (event) => {
if (event.type === 'show' || event.type === 'impression') { impressed = true; window.clearTimeout(guard); }
if (event.type === 'dismissed' || event.type === 'failedToShow') { window.clearTimeout(guard); finish(); }
},
onError: () => { window.clearTimeout(guard); finish(); },
});
} catch {
window.clearTimeout(guard);
finish();
}
}, [adGroupId, load]);코드에서 확인되는 것
- 전면형은
loadedRef가 참일 때만 보여 주고, 표시를 시작하면 바로 거짓으로 바꿔 같은 광고를 두 번 쓰지 않습니다. dismissed와failedToShow,onError세 경로가 모두 같은finish로 모이고, 이 안에서 다음 load가 다시 호출돼요.- 배너의
theme은light로 고정되어 있습니다. 체크리스트의 라이트 모드 항목과 관련된 설정으로 보이지만, 이유가 코드에 적혀 있지는 않아요.
이 앱 코드가 검수에서 어떤 판정을 받았는지는 이 글에 담지 않았습니다. 문서의 호출 순서와 맞닿는 부분만 옮겼어요.
참고한 공식 문서
지원 버전과 정책 항목은 바뀔 수 있으니 연동하기 전에 원문을 확인하세요.
인앱 광고 자주 묻는 질문
앱인토스 인앱 광고에는 어떤 종류가 있나요?
전면형, 리워드, 배너 세 가지입니다. 공식 문서는 세 가지를 함께 쓸 때 가장 효과적이라고 안내합니다. 전면형은 화면 전환 시점에 전체 화면으로, 리워드는 사용자가 광고 보기를 선택하면, 배너는 화면 상단이나 하단에 고정되어 노출됩니다.
리워드 광고의 보상은 언제 지급해야 하나요?
userEarnedReward 이벤트가 발생했을 때만 지급해야 합니다. 공식 문서는 dismissed 이벤트만으로는 리워드를 지급하면 안 된다고 적고 있고, 중간에 닫으면 리워드가 지급되지 않습니다.
광고를 테스트할 때 실제 광고 ID를 써도 되나요?
안 됩니다. 공식 문서는 개발 단계에서 반드시 테스트용 광고 ID를 쓰라고 안내하고, 운영 ID로 테스트하면 정책 위반으로 보아 제재를 받을 수 있다고 적고 있습니다. 샌드박스는 인앱 광고를 지원하지 않아서 콘솔의 QR 코드로 테스트해야 해요.
앱인토스는 토스 앱 안에서 미니앱을 서비스하는 플랫폼이고, 공식 안내는 앱인토스 개발자센터에 있습니다.
이 글은 직접 만들고 운영하며 남긴 기록입니다. 적힌 수치는 작성 시점의 제 계정 기준이며, 같은 결과나 수익을 보장하지 않습니다.
