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}`);
    });
}