Complete AppsInToss (앱인토스) SDK reference for building Toss mini-apps with @apps-in-toss/web-framework. Covers all SDK APIs (login, ads, payments, share, storage, navigation, device), mandatory review rules that cause rejection if violated, production-ready code patterns, and TDS design system. Applies when implementing any AppsInToss feature, checking SDK API signatures, verifying review compliance, configuring granite.config.ts, or building Toss mini-apps. Key terms: 앱인토스, AppsInToss, 토스 로그인, TDS, 미니앱, Granite, 인앱결제, 인앱광고, 프로모션, 배너광고, 리워드광고, 토스페이, SDK, 심사, 반려.
Reference for @apps-in-toss/web-framework 2.0.1 on Granite 1.0+ WebView.
Every SDK call requires dynamic import + isSupported() check. Static imports crash in web and cause review rejection.
// Correct — dynamic import
const { someAPI } = await import('@apps-in-toss/web-framework');
if (someAPI.isSupported() !== true) { /* mock or return */ }
const cleanup = someAPI({ options, onEvent, onError });
return () => cleanup?.();
// Wrong — static import causes crash + rejection
import { someAPI } from '@apps-in-toss/web-framework';
Exception: TossAds (banner ads) uses static import because it's a namespace object.
| API | Returns |
|---|---|
appLogin() |
{ authorizationCode, referrer } |
Flow: User action → appLogin() → send authorizationCode to server → server exchanges via mTLS → server returns app JWT to client.
Show intro/landing screen first. Calling appLogin() on app start causes rejection.
| API | Purpose |
|---|---|
loadFullScreenAd({ options, onEvent, onError }) | Pre-load fullscreen ad |
showFullScreenAd({ options, onEvent, onError }) | Display loaded ad |
TossAds.initialize({ callbacks }) | Initialize banner SDK |
TossAds.attachBanner(adGroupId, element) | Attach banner to DOM |
Load → Show order is mandatory (reverse causes rejection). Handle userEarnedReward event for rewarded ads: event.data = { unitType, unitAmount }.
| API | Purpose |
|---|---|
getProductItemList({ options: { productIds } }) | Fetch product info |
createOneTimePurchaseOrder({ options: { productId } }) | Purchase item |
Before payment: show product name, quantity, total, refund policy. Pause media during payment.
| API | Purpose |
|---|---|
getTossShareLink(deepLink, ogImageUrl?) | Generate Toss share link |
share({ title, text, url }) | Native share dialog |
contactsViral({ options }) | Contact-based viral invite |
Use getTossShareLink() for all links — sharing links to your own website causes rejection.
| API | Purpose |
|---|---|
Storage.setItem(key, value) | Save to native storage |
Storage.getItem(key) | Read from native storage |
Storage.removeItem(key) | Remove from native storage |
| API | Purpose |
|---|---|
getOperationalEnvironment() | Detect: toss / sandbox / web |
requestPermission({ options }) | Request camera, location, etc. |
getDeviceLocale() | Get device language/region |
getNetworkStatus() | Check connectivity |
haptic({ type }) | Trigger haptic feedback |
openCamera({ options }) | Take photo |
openAlbum({ options }) | Pick from gallery |
setClipboardText({ text }) | Copy to clipboard |
| API | Purpose |
|---|---|
executePromotion (server-side) | Grant Toss Points reward via mTLS |
export default {
appName: 'my-app',
brand: {
displayName: '내 앱이름', // Must match <title> exactly
primaryColor: '#3182F6', // 6-digit hex with #
},
navigationBar: {
withBackButton: true, // Required
withHomeButton: true, // Required
initialAccessoryButton: { // Optional, max 1
id: 'action',
title: 'Action',
icon: { name: 'icon-heart-mono' }, // Mono icons only
},
},
};
export function isTossApp(): boolean {
return /TossApp|AppsInToss/.test(navigator.userAgent);
}
export function getEnvironment(): 'toss' | 'sandbox' | 'web' {
const ua = navigator.userAgent;
if (/SANDBOX|sandbox/.test(ua)) return 'sandbox';
if (/TossApp|AppsInToss/.test(ua)) return 'toss';
return 'web';
}
Violations cause immediate rejection. See references/review-rules.md for the complete list with examples.
Critical prohibitions (violation = rejection):
alert(), confirm(), prompt()appLogin() on app start (show intro first)user-scalable=no in viewport metaMandatory requirements:
navigationBar: { withBackButton: true, withHomeButton: true }<title>, og:title, and all surfacesRead the specific reference file based on your task:
| Task | Reference |
|---|---|
| Need full API signatures, parameters, or event types | references/sdk-api-catalog.md |
| Checking review compliance or preparing for submission | references/review-rules.md |
| Implementing hooks (auth, ads, IAP, share, banner) | references/code-examples.md |
| Finding official doc URLs for deep reference | references/official-doc-urls.md |
Non-game mini-apps should use @toss/tds-mobile for Toss UX consistency.
npm install @toss/tds-mobile
Key components: Button, Dialog, BottomSheet, TextField, Toggle, Tabs, Toast.
Tab bar: floating style, 2-5 items, proper spacing.