Skip to content

Catalog API ​

Toss POS 플러그인에서 매장의 메뉴 정보를 관리하는 API예요. 메뉴의 기본 정보, 가격, 옵션 등을 포함하여 종합적인 메뉴 관리를 제공해요.

Types ​

PluginCatalogItem ​

메뉴의 기본 정보를 나타내는 객체예요.

ts
{
    id: number;              // 메뉴의 고유 ID
    code?: string;           // 플러그인에서 만들면 토스 POS 서버에 저장되어 항상 같이 내려옴
    title: string;           // 메뉴명
    titleI18n?: PluginLanguagePack;  // 다국어 지원 메뉴명
    state: 'ON_SALE' | 'SOLD_OUT' | 'UNAVAILABLE' | 'DELETED';  // 메뉴 상태
    description?: string;    // 메뉴 설명
    descriptionI18n?: PluginLanguagePack;  // 다국어 지원 설명
    category: PluginCatalogCategory;  // 메뉴 카테고리
    labels: {                // 메뉴 라벨
        title: string;       // 라벨명
        color: string;       // 라벨 색상
    }[];
    imageUrl?: string;       // 메뉴 이미지 URL
    price: PluginCatalogItemPrice;  // 가격 정보
    options: PluginCatalogItemOption[];  // 옵션 목록
    color?: string;          // POS에서 메뉴를 표시할 색상
    provenance?: {           // 제조 및 유통 정보
        displayProvenance: string;  // 제조사
    };
}
필드타입필수설명예시
idnumber필수메뉴의 고유 ID1
codestring선택플러그인에서 만든 메뉴 코드. 만들면 토스 POS 서버에 저장되어 항상 같이 내려와요'PLUGIN-001'
titlestring필수메뉴명'아메리카노'
titleI18nPluginLanguagePack선택다국어 지원 메뉴명
state'ON_SALE' | 'SOLD_OUT' | 'UNAVAILABLE' | 'DELETED'필수메뉴 상태'ON_SALE'
descriptionstring선택메뉴 설명'아메리카노'
descriptionI18nPluginLanguagePack선택다국어 지원 설명
categoryPluginCatalogCategory필수메뉴 카테고리
labels.titlestring필수라벨명'HOT'
labels.colorstring필수라벨 색상'#FF0000'
imageUrlstring선택메뉴 이미지 URL'https://toss.imimages/americano.png'
pricePluginCatalogItemPrice필수가격 정보
optionsPluginCatalogItemOption[]필수옵션 목록
colorstring선택POS에서 메뉴를 표시할 색상'#3182F6'
provenance.displayProvenancestring선택제조사'토스푸드'

PluginCatalogItemPrice ​

메뉴의 가격 정보를 나타내는 객체예요.

ts
{
    title: string;           // 가격명
    isDefault: boolean;      // 기본 가격 여부
    state: 'ON_SALE' | 'SOLD_OUT' | 'UNAVAILABLE' | 'DELETED';  // 가격 상태
    sku: string | null;      // 재고 관리 코드
    barcode: string | null;  // 바코드 정보
    priceType: 'FIXED' | 'VARIABLE' | 'UNIT';  // 가격 유형 (unit : kg당 가격)
    priceUnit: number;       // 기본 수량
    priceValue: number;      // 부가세 포함 가격
    isTaxFree: boolean;      // 비과세 여부
    isStockable: boolean;    // 재고 관리 여부
    stockQuantity: {         // 재고 정보
        remainQuantity: number;      // 현재 재고
        lastChangeDateTime: string;  // 마지막 변경 시간
    } | null;
}
필드타입필수설명예시
titlestring필수가격명'기본가격'
isDefaultboolean필수기본 가격 여부true
state'ON_SALE' | 'SOLD_OUT' | 'UNAVAILABLE' | 'DELETED'필수가격 상태'ON_SALE'
skustring선택재고 관리 코드'123456'
barcodestring선택바코드 정보'123456'
priceType'FIXED' | 'VARIABLE' | 'UNIT'필수가격 유형'FIXED'
priceUnitnumber필수기본 수량1
priceValuenumber필수부가세 포함 가격10000
isTaxFreeboolean필수비과세 여부false
isStockableboolean필수재고 관리 여부true
stockQuantity.remainQuantitynumber필수현재 재고10
stockQuantity.lastChangeDateTimestring필수마지막 변경 시간'2021-01-01T00:00:00Z'

Methods ​

getCatalog ​

매장의 카탈로그를 조회해요.

ts
import { posPluginSdk } from '@tossplace/pos-plugin-sdk';

/**
 * 카탈로그 목록 조회
 * @returns 카탈로그 목록
 */
const catalog = await posPluginSdk.catalog.getCatalog(catalogId);

Parameters ​

파라미터타입필수설명
catalogIdnumberO조회할 메뉴의 ID

Response ​

Promise<PluginCatalogItem> — 조회한 메뉴 정보예요.

getCatalogs ​

매장의 카탈로그 목록을 조회해요.

ts
import { posPluginSdk } from '@tossplace/pos-plugin-sdk';

/**
 * 카탈로그 목록 조회
 * @returns 카탈로그 목록
 */
const catalogs = await posPluginSdk.catalog.getCatalogs();

Parameters ​

파라미터가 없어요.

Response ​

Promise<PluginCatalogItem[]> — 매장에 등록된 메뉴 목록이에요.

on ​

이벤트 구독을 위한 메서드예요.

Parameters ​

파라미터타입필수설명
event'update' | 'add' | 'delete'O구독할 이벤트
callback(id: number) => voidO변경된 메뉴 ID를 받아 실행돼요

Response ​

반환값이 없어요.

update ​

메뉴의 정보가 업데이트되었을 때 발생하는 이벤트예요.

ts
import { posPluginSdk } from '@tossplace/pos-plugin-sdk';

posPluginSdk.catalog.on('update', (id: number) => {
    console.log('정보가 업데이트 된 메뉴 ID:', id);
});

add ​

메뉴가 추가되었을 때 발생하는 이벤트예요.

ts
import { posPluginSdk } from '@tossplace/pos-plugin-sdk';

posPluginSdk.catalog.on('add', (id: number) => {
    console.log('새로 추가 된 메뉴 ID:', id);
});

delete ​

메뉴가 삭제되었을 때 발생하는 이벤트예요.

ts
import { posPluginSdk } from '@tossplace/pos-plugin-sdk';

posPluginSdk.catalog.on('delete', (id: number) => {
    console.log('삭제 된 메뉴 ID:', id);
});

사용 예시 ​

카탈로그 관리 클래스 ​

ts
import { posPluginSdk } from '@tossplace/pos-plugin-sdk';

class CatalogManager {
    private catalogs: PluginCatalogItem[] = [];

    /**
     * 카탈로그 목록 조회 및 초기화
     */
    async initialize() {
        try {
            this.catalogs = await posPluginSdk.catalog.getCatalogs();
            this.setupEventListeners();
        } catch (error) {
            console.error('카탈로그 초기화 실패:', error);
        }
    }

    /**
     * 이벤트 리스너 설정
     */
    private setupEventListeners() {
        posPluginSdk.catalog.on('update', this.handleUpdate.bind(this));
        posPluginSdk.catalog.on('add', this.handleAdd.bind(this));
        posPluginSdk.catalog.on('delete', this.handleDelete.bind(this));
    }

    private handleUpdate(id: number) {
        console.log('업데이트 된 메뉴 ID:', id);
    }

    private handleAdd(id: number) {
        console.log('추가 된 메뉴 ID:', id);
    }

    private handleDelete(id: number) {
        console.log('삭제 된 메뉴 ID:', id);
    }

    /**
     * 메뉴 정보 조회
     * @param menuId 메뉴 ID
     * @returns 메뉴 정보
     */
    getMenu(menuId: number): PluginCatalogItem | undefined {
        return this.catalogs.find(menu => menu.id === menuId);
    }
}

// 사용 예시
async function manageCatalog() {
    const catalogManager = new CatalogManager();
    await catalogManager.initialize();
}

재고 관리 예시 ​

ts
import { posPluginSdk } from '@tossplace/pos-plugin-sdk';

/**
 * 재고 상태 확인
 * @param catalog 메뉴 정보
 * @returns 재고 상태 메시지
 */
function checkStockStatus(catalog: PluginCatalogItem): string {
    const price = catalog.price;
    if (!price.isStockable || !price.stockQuantity) {
        return '재고 관리 대상이 아니에요.';
    }

    const { remainQuantity } = price.stockQuantity;
    if (remainQuantity <= 0) {
        return '품절';
    } else if (remainQuantity <= 5) {
        return `재고 부족 (${remainQuantity}개 남음)`;
    }
    return `재고 있음 (${remainQuantity}개)`;
}

// 사용 예시
async function monitorStock() {
    const catalogs = await posPluginSdk.catalog.getCatalogs();
    catalogs.forEach(catalog => {
        const status = checkStockStatus(catalog);
        console.log(`${catalog.title}: ${status}`);
    });
}