### Settings Management Class Example Source: https://docs.tossplace.com/reference/plugin-sdk/front/storage.html Demonstrates a class for managing settings using the Storage API, including methods for setting, getting, removing, and clearing settings with a prefix. ```javascript class SettingsManager { constructor() { this.PREFIX = "settings_"; } /** * 설정 저장 * @param {string} key 설정 키 * @param {string} value 설정 값 */ async setSetting(key, value) { try { await sdk.storage.set({ key: this.getFullKey(key), value, }); } catch (error) { console.error("설정 저장 실패:", error); throw error; } } /** * 설정 조회 * @param {string} key 설정 키 * @returns {string|null} 설정 값 */ async getSetting(key) { try { const item = await sdk.storage.get({ key: this.getFullKey(key), }); return item.value; } catch (error) { console.error("설정 조회 실패:", error); throw error; } } /** * 설정 삭제 * @param {string} key 설정 키 */ async removeSetting(key) { try { await sdk.storage.remove({ key: this.getFullKey(key), }); } catch (error) { console.error("설정 삭제 실패:", error); throw error; } } /** * 모든 설정 삭제 */ async clearSettings() { try { await sdk.storage.clear(); } catch (error) { console.error("설정 초기화 실패:", error); throw error; } } /** * 전체 키 생성 * @param {string} key 기본 키 * @returns {string} 네임스페이스가 포함된 키 */ getFullKey(key) { return `${this.PREFIX}${key}`; } } // 사용 예시 async function manageSettings() { const settings = new SettingsManager(); try { // 설정 저장 await settings.setSetting("theme", "dark"); // 설정 조회 const theme = await settings.getSetting("theme"); console.log("현재 테마:", theme); // 설정 삭제 await settings.removeSetting("theme"); // 모든 설정 초기화 await settings.clearSettings(); } catch (error) { console.error("설정 관리 중 오류 발생:", error); } } ``` -------------------------------- ### Onboarding Page Code Example Source: https://docs.tossplace.com/reference/plugin-sdk/front/template.html Example of rendering an onboarding page with ID and password inputs, including a numeric keypad mode for the password. ```javascript sdk.template.renderOnboardingPage({ title: "___ 로그인", inputs: { id: { label: "매장 아이디", type: "text", placeholder?: "매장 아이디를 입력해주세요", }, password: { label: "숫자 비밀번호", type: "password", mode?: 'numeric', // numeric 키패드 모드 지원 (default: 'text') placeholder?: "비밀번호를 입력해주세요", maxLength?: 4, onChange?: (value) => { console.log(value) }, }, }, onSubmit: async (values) => { try { const { serialNumber } = await sdk.app.getSerialNumber(); const response = await fetch("https://example.com", { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ ...values, serialNumber }), }); const { token } = await response.json(); await sdk.storage.set({ key: "token", value: token }); location.href = "./home"; } catch (e) { throw new Error("서버 오류가 발생했습니다."); } }, logoUrl?: '' // 커스텀 로고 URL }) ``` -------------------------------- ### Start WebSocket Server with Event Listeners Source: https://docs.tossplace.com/reference/plugin-sdk/front/websocket.html Initialize and start a WebSocket server using the `start` method. This method allows configuring connection, message, disconnection, and error event handlers all at once. It returns a server object with methods to send messages, disconnect clients, and stop the server. ```javascript // 1. 서버 시작 — start 하나로 서버 열기 + 이벤트 리스너 설정을 한 번에 처리 const server = await sdk.websocket.start({ port: 8080, onConnection: (payload) => { console.log("새 연결:", payload.connectionId); // 연결된 클라이언트에 환영 메시지 송신 server.send(payload.connectionId, JSON.stringify({ type: "welcome" })); }, onMessage: (payload) => { const message = JSON.parse(payload.data); console.log(`메시지 수신 (${payload.connectionId}):`, message); }, onDisconnection: (payload) => { console.log("연결 종료:", payload.connectionId, payload.reason); }, onError: (payload) => { console.error("오류:", payload.message); }, }); console.log(`서버 시작: ws://${server.host}:${server.port}${server.path}`); // 2. 특정 클라이언트에 메시지 송신 await server.send(connectionId, JSON.stringify({ type: "ping" })); // 3. 특정 연결 종료 await server.disconnect(connectionId); // 4. 서버 종료 (모든 연결 정리 + 리스너 해제) await server.stop(); ``` -------------------------------- ### Example Usage of renderAgreementPage Source: https://docs.tossplace.com/reference/plugin-sdk/front/template.html An example demonstrating how to configure the agreement page with a title, subtitle, required and optional agreements, and an onSubmit handler. ```javascript sdk.template.renderAgreementPage({ title: "약관 동의", subtitle: "서비스 이용을 위해 약관에 동의해주세요", agreements: { required: [ { id: "terms", title: "서비스 이용약관", href: "https://example.com/terms", }, { id: "privacy", title: "개인정보 처리방침", href: "https://example.com/privacy", }, ], optional: [ { id: "marketing", title: "마케팅 정보 수신 동의", href: "https://example.com/marketing", }, ], }, onSubmit: async (agreementIds) => { console.log("동의한 약관:", agreementIds); // 서버에 약관 동의 정보 전송 await fetch("/api/agreements", { method: "POST", body: JSON.stringify({ agreementIds }), }); }, }); ``` -------------------------------- ### start Source: https://docs.tossplace.com/reference/plugin-sdk/front/websocket.html Starts a WebSocket server, handling connections, messages, disconnections, and errors. ```APIDOC ## start ### Description Starts a WebSocket server and allows configuration of event handlers for connections, messages, disconnections, and errors. ### Parameters - `options` (Object) - Required - Configuration options for the server. - `port` (number) - Required - The port number to run the server on. - `onConnection` (Function) - Optional - Callback function invoked when a new client connects. - `payload.connectionId` (string): The ID of the new connection. - `onMessage` (Function) - Optional - Callback function invoked when a message is received from a client. - `payload.connectionId` (string): The ID of the connection sending the message. - `payload.data` (string): The received message data. - `onDisconnection` (Function) - Optional - Callback function invoked when a client disconnects. - `payload.connectionId` (string): The ID of the disconnected connection. - `payload.reason` (string): The reason for disconnection. - `onError` (Function) - Optional - Callback function invoked when an error occurs. - `payload.message` (string): The error message. ### Returns - `Promise` - A promise that resolves to a server object with methods to manage the server and connections. - `server.host` (string): The host address of the server. - `server.port` (number): The port the server is running on. - `server.path` (string): The path of the WebSocket server. - `server.send(connectionId, data)`: Sends data to a specific client. - `server.disconnect(connectionId)`: Disconnects a specific client. - `server.stop()`: Stops the WebSocket server. ### Example ```javascript // Start a WebSocket server with event listeners const server = await sdk.websocket.start({ port: 8080, onConnection: (payload) => { console.log("New connection:", payload.connectionId); // Send a welcome message to the connected client server.send(payload.connectionId, JSON.stringify({ type: "welcome" })); }, onMessage: (payload) => { const message = JSON.parse(payload.data); console.log(`Message received (${payload.connectionId}):`, message); }, onDisconnection: (payload) => { console.log("Connection closed:", payload.connectionId, payload.reason); }, onError: (payload) => { console.error("Error:", payload.message); }, }); console.log(`Server started: ws://${server.host}:${server.port}${server.path}`); // Send a message to a specific client await server.send(connectionId, JSON.stringify({ type: "ping" })); // Terminate a specific connection await server.disconnect(connectionId); // Stop the server (cleans up all connections and listeners) await server.stop(); ``` ``` -------------------------------- ### Select Page Code Example Source: https://docs.tossplace.com/reference/plugin-sdk/front/template.html Example of rendering a selection page with two language options, each with a placeholder for an icon URL and a console log on click. ```javascript sdk.template.renderSelectPage({ title: '반가워요', subtitle: '언어를 선택해주세요', options: [ { title: '한국어로 주문', onClick: () => { console.log('한국어로 주문'); }, iconUrl?: '', // 이미지 URL }, { title: 'Order English', onClick: () => { console.log('Order English'); }, iconUrl?: '', // 이미지 URL }, ], onBack?: () => {}, }) ``` -------------------------------- ### Example Usage of renderOrderResultPage Source: https://docs.tossplace.com/reference/plugin-sdk/front/template.html An example demonstrating how to populate the order items, summary, and call-to-action for the order result page. ```javascript sdk.template.renderOrderResultPage({ order: { items: [ { label: "손 젤 케어", quantity: 1, value: 50_000, }, { label: "젤 기본", quantity: 1, value: 50_000, }, ], summary: { totalAmount: 100_000, items: [ { label: "포인트", value: "10,000P", theme: "blue", }, { label: "금액권", value: "30,000원", theme: "blue", }, { label: "젤네일", value: "5회", theme: "blue", }, { label: "VIP 회원권", value: "2026-11-04", theme: "blue", }, ], }, }, cta: { text: "확인했어요", onClick: () => { location.href = "./home"; }, }, }); ``` -------------------------------- ### App Installation Event Payload Source: https://docs.tossplace.com/reference/open-api/app.html This JSON payload is received when an app is installed in a store. It contains detailed information about the merchant and confirms the app installation. ```json { "id": "000000000000000000000000", "type": "app.installation.created.v1", "createdAt": "2026-01-01T00:00:00.000Z", "merchantId": 42, "app": "my-awesome-app", "data": { "merchant": { "id": 42, "name": "플레이스 베이커리", "businessNumber": "0000000000", "ownerName": "김토스", "displayName": "플레이스 베이커리", "address": "서울특별시 서초구 강남대로 459 (서초동)", "latitude": 37.5031925, "longitude": 127.0247527, "operatingHours": [ { "dayOfWeek": "MONDAY", "openAt": "10:00:00", "closeAt": "22:00:00" }, { "dayOfWeek": "TUESDAY", "openAt": "10:00:00", "closeAt": "22:00:00" }, { "dayOfWeek": "WEDNESDAY", "openAt": "10:00:00", "closeAt": "22:00:00" }, { "dayOfWeek": "THURSDAY", "openAt": "10:00:00", "closeAt": "22:00:00" }, { "dayOfWeek": "FRIDAY", "openAt": "10:00:00", "closeAt": "22:00:00" }, { "dayOfWeek": "SATURDAY", "openAt": "10:00:00", "closeAt": "22:00:00" }, { "dayOfWeek": "SUNDAY", "openAt": "10:00:00", "closeAt": "22:00:00" } ] } } } ``` -------------------------------- ### open Source: https://docs.tossplace.com/reference/plugin-sdk/front/serial.html Opens a serial port and starts communication. Allows configuration of communication speed. ```APIDOC ## open ### Description Opens a serial port and starts communication. ### Method `open` ### Parameters #### Path Parameters - `options` (Object) - Optional - Description: Serial port settings - `options.baudRate` (number) - Optional - Default: 9600 - Description: Communication speed ### Request Example ```javascript /** * 시리얼 포트 열기 * @param {Object} options 시리얼 포트 설정 * @param {number} options.baudRate 통신 속도 (기본값: 9600) */ await sdk.serial.open({ baudRate: 9600 }); ``` ``` -------------------------------- ### Get Options Source: https://docs.tossplace.com/reference/plugin-sdk/pos/option.html Retrieves a list of all available options. ```APIDOC ## getOptions ### Description Retrieves a list of all available options. ### Method `getOptions()` ### Response #### Success Response (200) - **options** (PluginCatalogItemOption[]) - An array of option objects. ### Request Example ```typescript import { posPluginSdk } from '@tossplace/pos-plugin-sdk'; const options = await posPluginSdk.option.getOptions(); ``` ``` -------------------------------- ### Webhook Event Request Example Source: https://docs.tossplace.com/reference/open-api/webhook.html This example demonstrates the structure of an incoming webhook event request, including essential headers and the JSON payload. Ensure your endpoint can process these details. ```http POST /webhook HTTP/1.1 Host: example.com Content-Type: application/json x-toss-event-id: 000000000000000000000000 x-toss-webhook-id: 000000000000000000000000 x-toss-delivery-id: 000000000000000000000000 x-toss-timestamp: 1767225600000 x-toss-signature: v1=0398718113ed9a277320953cd613e4ecad4fed4a6dc843064ec311e14368774e {"id":"000000000000000000000000","type":"_test.v1","createdAt":"2026-01-01T00:00:00Z","merchantId":42,"app":"my-awesome-app","data": {}} ``` -------------------------------- ### Get All Options Source: https://docs.tossplace.com/reference/plugin-sdk/pos/option.html Fetches a list of all available options. This is useful for initializing option data. ```typescript import { posPluginSdk } from '@tossplace/pos-plugin-sdk'; /** * 옵션 목록 조회 * @returns 옵션 목록 */ const options = await posPluginSdk.option.getOptions(); ``` -------------------------------- ### Start Payment Source: https://docs.tossplace.com/reference/plugin-sdk/pos/draftOrder.html Initiates the payment process for the current draft order. ```APIDOC ## startPayment ### Description Initiates the payment process for the current draft order. ### Method `posPluginSdk.draftOrder.startPayment` ### Endpoint N/A (Method call) ### Request Example ```javascript await posPluginSdk.draftOrder.startPayment(); ``` ``` -------------------------------- ### Option Management Class Example Source: https://docs.tossplace.com/reference/plugin-sdk/pos/option.html A class demonstrating how to initialize options, set up event listeners for updates, additions, and deletions, and retrieve options by ID or filter for required options. ```typescript import { posPluginSdk } from '@tossplace/pos-plugin-sdk'; class OptionManager { private options: PluginCatalogItemOption[] = []; /** * 옵션 목록 조회 및 초기화 */ async initialize() { try { this.options = await posPluginSdk.option.getOptions(); this.setupEventListeners(); } catch (error) { console.error('옵션 초기화 실패:', error); } } /** * 이벤트 리스너 설정 */ private setupEventListeners() { posPluginSdk.option.on('update', this.handleUpdate.bind(this)); posPluginSdk.option.on('add', this.handleAdd.bind(this)); posPluginSdk.option.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); } /** * 필수 옵션 목록 조회 */ getRequiredOptions(): PluginCatalogItemOption[] { return this.options.filter((option) => option.isRequired); } /** * 옵션 ID로 조회 */ getOptionById(id: number): PluginCatalogItemOption | undefined { return this.options.find((option) => option.id === id); } } // 사용 예시 async function manageOptions() { const optionManager = new OptionManager(); await optionManager.initialize(); } ``` -------------------------------- ### 매장에 앱 설치됨 (app.installation.created.v1) Source: https://docs.tossplace.com/reference/open-api/app.html This event is triggered when an app is installed in a store. It allows access to store information via Open API and enables receiving webhook events from the store. ```APIDOC ## Event: app.installation.created.v1 ### Description This event is sent when an app is installed in a store. From this point, you can query the store's information using the Open API and receive webhook events about the store's activities. ### Event Type `app.installation.created.v1` ### Payload #### `merchant` (Merchant) - Required Information about the store. ### Request Example ```json { "id": "000000000000000000000000", "type": "app.installation.created.v1", "createdAt": "2026-01-01T00:00:00.000Z", "merchantId": 42, "app": "my-awesome-app", "data": { "merchant": { "id": 42, "name": "플레이스 베이커리", "businessNumber": "0000000000", "ownerName": "김토스", "displayName": "플레이스 베이커리", "address": "서울특별시 서초구 강남대로 459 (서초동)", "latitude": 37.5031925, "longitude": 127.0247527, "operatingHours": [ { "dayOfWeek": "MONDAY", "openAt": "10:00:00", "closeAt": "22:00:00" }, { "dayOfWeek": "TUESDAY", "openAt": "10:00:00", "closeAt": "22:00:00" }, { "dayOfWeek": "WEDNESDAY", "openAt": "10:00:00", "closeAt": "22:00:00" }, { "dayOfWeek": "THURSDAY", "openAt": "10:00:00", "closeAt": "22:00:00" }, { "dayOfWeek": "FRIDAY", "openAt": "10:00:00", "closeAt": "22:00:00" }, { "dayOfWeek": "SATURDAY", "openAt": "10:00:00", "closeAt": "22:00:00" }, { "dayOfWeek": "SUNDAY", "openAt": "10:00:00", "closeAt": "22:00:00" } ] } } } ``` ``` -------------------------------- ### Manage API Key with Secure Store Source: https://docs.tossplace.com/reference/plugin-sdk/pos/secureStore.html Example demonstrating how to save, retrieve, and remove an API key using the SecureStore API. This is useful for securely storing sensitive credentials. ```typescript import { posPluginSdk } from '@tossplace/pos-plugin-sdk'; const API_KEY = 'api_key'; async function saveApiKey(apiKey: string) { await posPluginSdk.secureStore.set(API_KEY, apiKey); } async function getApiKey(): Promise { return await posPluginSdk.secureStore.get(API_KEY); } async function removeApiKey() { await posPluginSdk.secureStore.del(API_KEY); } ``` -------------------------------- ### Webhook Signature Secret Key Example Source: https://docs.tossplace.com/reference/open-api/webhook.html This is an example of a secret key used for signing webhook events. Keep this key secure and use it to verify the authenticity of incoming requests. ```text GA1k8THAGeGihd_Z0rW0MqpRTDQGYIktHBfmCWbsZn0 ``` -------------------------------- ### Catalog Rule Example Source: https://docs.tossplace.com/reference/open-api/catalog/catalog-rule.html This JSON defines a display rule. It specifies conditions under which the rule should apply, such as when a specific option choice is selected. ```json { "id": "42", // 전시 규칙 ID /* 조건: '온도' 옵션에서 'ICE' 선택지를 고른 경우 */ "conditions": [ { "type": "RESOURCE_SELECTED", "operator": "ANY", "targets": [ { "type": "OPTION_CHOICE", "id": "30" } // 'ICE' 선택지의 ID ] } ], "conditionsOperator": "AND" } ``` -------------------------------- ### Add Item and Start Payment Source: https://docs.tossplace.com/reference/plugin-sdk/pos/draftOrder.html Adds a catalog item to the draft order and then initiates the payment process. Ensure the catalogItem object contains all necessary details. ```typescript import { posPluginSdk } from '@tossplace/pos-plugin-sdk'; async function addItemAndPay(catalogItem: PluginCatalogItem) { await posPluginSdk.draftOrder.addLineItem({ item: { id: catalogItem.id, title: catalogItem.title, category: catalogItem.category, options: catalogItem.options, code: catalogItem.code, type: 'ITEM', }, itemPrice: catalogItem.price, quantity: 1, memo: '', discount: [], optionChoices: [], diningOption: 'HERE', }); await posPluginSdk.draftOrder.startPayment(); } ``` -------------------------------- ### get Source: https://docs.tossplace.com/reference/plugin-sdk/front/storage.html Retrieves the value associated with a specific key from the storage. ```APIDOC ## get ### Description Retrieves the value associated with a specific key from the storage. If the key does not exist, it returns null. ### Parameters #### Path Parameters - None #### Query Parameters - None #### Request Body - **params** (Object) - Required - The parameters for the retrieval. - **params.key** (string) - Required - The key to retrieve the value for. ### Request Example ```javascript /** * Retrieve value from storage * @param {Object} params Retrieval parameters * @param {string} params.key Key to retrieve * @returns {Object} Stored value (null if not found) */ const item = await sdk.storage.get({ key: "test-key" }); console.log("Retrieved value:", item.value); // null or string ``` ### Response #### Success Response (200) - **value** (string | null) - The retrieved value, or null if the key is not found. #### Response Example ```json { "value": "retrieved-value" } ``` ``` -------------------------------- ### Get Option Source: https://docs.tossplace.com/reference/plugin-sdk/pos/option.html Retrieves a specific option by its ID. ```APIDOC ## getOption ### Description Retrieves a specific option by its ID. ### Method `getOption(optionId: number)` ### Parameters #### Path Parameters - **optionId** (number) - Required - The ID of the option to retrieve. ### Response #### Success Response (200) - **option** (PluginCatalogItemOption) - The retrieved option object. ### Request Example ```typescript import { posPluginSdk } from '@tossplace/pos-plugin-sdk'; const option = await posPluginSdk.option.getOption(123); ``` ``` -------------------------------- ### Catalog Combo Created Event Payload Source: https://docs.tossplace.com/reference/open-api/catalog/catalog-combo.html Example payload for the `catalog.combo.created.v1` event. This shows the structure of a newly created combo, including its items and categories. ```json { "id": "000000000000000000000000", "type": "catalog.combo.created.v1", "createdAt": "2026-01-01T00:00:00.000Z", "merchantId": 42, "app": "my-awesome-app", "data": { "combo": { "id": "42", "merchantId": 42, "title": "음료+디저트 세트", "code": "COMBO_CODE", "enabled": true, "order": 1, "description": "음료+디저트 세트 설명", "imageUrl": "https://example.com/image.png", "labels": ["할인"], "basePriceValue": 9000, "originalPriceValue": 10000, "targetGroups": [ { "id": "43", "merchantId": 42, "title": "디저트", "description": "디저트를 선택해주세요.", "order": 1, "minQuantity": 1, "maxQuantity": 1, "targets": [ { "id": "44", "merchantId": 42, "groupId": "43", "item": { "id": "44", "merchantId": 42, "category": { "id": "43", "merchantId": 42, "title": "디저트", "code": "DESSERT", "enabled": true, "order": 2, "createdAt": "2026-01-01T00:00:00Z", "updatedAt": "2026-01-01T00:00:00Z" }, "title": "쿠키", "code": "ITEM_CODE", "state": "ON_SALE", "enabled": true, "order": 1, "description": "쿠키 설명", "imageUrl": "https://example.com/image.png", "labels": ["신규"], "price": { "title": "기본", "priceType": "FIXED", "priceUnit": 1, "priceValue": 5000, "barcode": "1234567890" }, "diningOptions": ["HERE", "TOGO"], "options": [], "createdAt": "2026-01-01T00:00:00Z", "updatedAt": "2026-01-01T00:00:00Z" }, "order": 1, "default": false, "additionalPriceValue": 0 } ] } ], "createdAt": "2026-01-01T00:00:00Z", "updatedAt": "2026-01-01T00:00:00Z" } } } ``` -------------------------------- ### Catalog Item Created Event Payload Source: https://docs.tossplace.com/reference/open-api/catalog.html Example payload for the `catalog.item.created.v1` event, detailing the structure of a newly created catalog item. ```json { "id": "000000000000000000000000", "type": "catalog.item.created.v1", "createdAt": "2026-01-01T00:00:00.000Z", "merchantId": 42, "app": "my-awesome-app", "data": { "item": { "id": "42", "merchantId": 42, "category": { "id": "42", "merchantId": 42, "title": "커피", "code": "CATEGORY_CODE", "enabled": true, "order": 1, "createdAt": "2026-01-01T00:00:00Z", "updatedAt": "2026-01-01T00:00:00Z" }, "title": "아메리카노", "code": "ITEM_CODE", "state": "ON_SALE", "enabled": true, "order": 1, "description": "아메리카노 설명", "imageUrl": "https://example.com/image.png", "labels": ["신규"], "price": { "title": "기본", "priceType": "FIXED", "priceUnit": 1, "priceValue": 3000, "barcode": "1234567890" }, "diningOptions": ["HERE", "TOGO"], "options": [ { "id": "42", "merchantId": 42, "title": "온도", "code": "OPTION_CODE", "enabled": true, "order": 1, "choices": [ { "id": "42", "merchantId": 42, "optionId": "42", "title": "ICE", "code": "CHOICE_CODE", "state": "ON_SALE", "enabled": true, "order": 1, "priceValue": 500, "quantityEnabled": false, "minQuantity": 0, "maxQuantity": 1, "createdAt": "2026-01-01T00:00:00Z", "updatedAt": "2026-01-01T00:00:00Z" } ], "required": true, "minChoices": 1, "maxChoices": 1, "createdAt": "2026-01-01T00:00:00Z", "updatedAt": "2026-01-01T00:00:00Z" } ], "createdAt": "2026-01-01T00:00:00Z", "updatedAt": "2026-01-01T00:00:00Z" } } } ``` -------------------------------- ### Catalog Combo Updated Event Payload Source: https://docs.tossplace.com/reference/open-api/catalog/catalog-combo.html Example payload for the `catalog.combo.updated.v1` event. This demonstrates the structure when a combo is updated, particularly noting changes in selectable item lists. ```json { "id": "000000000000000000000000", "type": "catalog.combo.updated.v1", "createdAt": "2026-01-01T00:00:00.000Z", "merchantId": 42, "app": "my-awesome-app", "data": { "combo": { "id": "42", "merchantId": 42, "title": "음료+디저트 세트", "code": "COMBO_CODE", "enabled": true, "order": 1, "description": "음료+디저트 세트 설명", "imageUrl": "https://example.com/image.png", "labels": ["할인"], "basePriceValue": 9000, "originalPriceValue": 10000, "targetGroups": [ { "id": "42", "merchantId": 42, "title": "음료", "description": "음료를 선택해주세요.", "order": 1, "minQuantity": 1, "maxQuantity": 1, "targets": [ { "id": "42", "merchantId": 42, "groupId": "42", "item": { "id": "42", "merchantId": 42, "category": { "id": "42", "merchantId": 42, "title": "커피", "code": "COFFEE", "enabled": true, "order": 1, "createdAt": "2026-01-01T00:00:00Z", "updatedAt": "2026-01-01T00:00:00Z" }, "title": "아메리카노", "code": "ITEM_CODE", "state": "ON_SALE", "enabled": true, "order": 1, "description": "아메리카노 설명", "imageUrl": "https://example.com/image.png", "labels": ["신규"], "price": { "title": "기본", "priceType": "FIXED", "priceUnit": 1, "priceValue": 5000, "barcode": "1234567890" }, "diningOptions": ["HERE", "TOGO"], "options": [], "createdAt": "2026-01-01T00:00:00Z", "updatedAt": "2026-01-01T00:00:00Z" }, "order": 1, "default": false, "additionalPriceValue": 0 } ] } ], "createdAt": "2026-01-01T00:00:00Z", "updatedAt": "2026-01-01T00:00:00Z" } } } ``` -------------------------------- ### renderOnboardingPage Source: https://docs.tossplace.com/reference/plugin-sdk/front/template.html Renders the onboarding (login) screen, handling user inputs for store ID and password, with options for numeric keypad mode and custom logo display. ```APIDOC ## renderOnboardingPage ### Description Renders the onboarding (login) screen. This API handles login inputs such as store ID and password. It supports a numeric keypad mode and allows for a custom logo display. ### Method ```javascript sdk.template.renderOnboardingPage(params) ``` ### Parameters #### Params - **title** (string) - Required - The title to display on the onboarding screen. - **inputs** (Record) - Required - An object defining the input fields. - **onSubmit** (function) - Required - A callback function that is executed when the form is submitted. It receives the input values. - **logoUrl** (string) - Optional - The URL for a custom logo to display. ### InputScheme - **label** (string) - Required - The label for the input field. - **type** ('text' | 'password') - Required - The input type. - **mode** ('numeric') - Optional - Specifies the input mode. Defaults to 'text'. - **placeholder** (string) - Optional - The placeholder text for the input field. - **maxLength** (number) - Optional - The maximum length of the input. - **onChange** (function) - Optional - A callback function that is executed when the input value changes. ### Code Example ```javascript sdk.template.renderOnboardingPage({ title: "___ 로그인", inputs: { id: { label: "매장 아이디", type: "text", placeholder: "매장 아이디를 입력해주세요", }, password: { label: "숫자 비밀번호", type: "password", mode: 'numeric', placeholder: "비밀번호를 입력해주세요", maxLength: 4, onChange: (value) => { console.log(value) }, }, }, onSubmit: async (values) => { try { const { serialNumber } = await sdk.app.getSerialNumber(); const response = await fetch("https://example.com", { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ ...values, serialNumber }), }); const { token } = await response.json(); await sdk.storage.set({ key: "token", value: token }); location.href = "./home"; } catch (e) { throw new Error("서버 오류가 발생했습니다."); } }, logoUrl: '' }) ``` ``` -------------------------------- ### Load SDK and Fetch Categories Source: https://docs.tossplace.com/guide/pos-integration/plugin/develop/umd.html Import the POS plugin SDK and demonstrate fetching a list of categories. Ensure proper error handling for the asynchronous operation. ```javascript // SDK 불러오기 importScripts('https://sdk.tossplace.com/pos-plugins/umd/0.0.8/pos-plugin-sdk.js'); // 카테고리 목록 조회 예시 (window as any).pos.category.getCategories() .then((categories) => { console.log('카테고리 목록:', categories); }) .catch((error) => { console.error('카테고리 조회 실패:', error); }); ``` -------------------------------- ### Render Onboarding Page Source: https://docs.tossplace.com/reference/plugin-sdk/front/template.html Renders the onboarding (login) page. Handles login inputs like store ID and password. Supports numeric keypad mode and custom logos. ```javascript sdk.template.renderOnboardingPage({ title, inputs, onSubmit }); ``` -------------------------------- ### Get Single Option Source: https://docs.tossplace.com/reference/plugin-sdk/pos/option.html Retrieves a specific option by its ID. Ensure the optionId is correctly provided. ```typescript import { posPluginSdk } from '@tossplace/pos-plugin-sdk'; /** * 옵션 조회 * @returns 옵션 */ const option = await posPluginSdk.option.getOption(optionId); ``` -------------------------------- ### Get Item from Storage Source: https://docs.tossplace.com/reference/plugin-sdk/front/storage.html Retrieves a value from storage by its key. Use this when you need to access previously stored data. ```javascript /** * 저장소에서 값 조회 * @param {Object} params 조회 파라미터 * @param {string} params.key 조회할 키 * @returns {Object} 저장된 값 (없으면 null) */ const item = await sdk.storage.get({ key: "test-key" }); console.log("조회된 값:", item.value); // null 또는 string ``` -------------------------------- ### Onboarding Page Parameters Source: https://docs.tossplace.com/reference/plugin-sdk/front/template.html Defines the structure for onboarding page parameters, including input schemes for text and password fields. ```typescript interface Params { title: string; inputs: Record; onSubmit: (data: Record) => Promise; logoUrl?: string; } interface InputScheme { label: string; type: "text" | "password"; mode?: "numeric"; // default: 'text' placeholder?: string; maxLength?: number; onChange?: (value: string) => void; } ``` -------------------------------- ### Get Value from Secure Store Source: https://docs.tossplace.com/reference/plugin-sdk/pos/secureStore.html Retrieves the value associated with a specified key from the encrypted local storage. Ensure `posPluginSdk` is imported. ```typescript import { posPluginSdk } from '@tossplace/pos-plugin-sdk'; const value = await posPluginSdk.secureStore.get('key'); ``` -------------------------------- ### renderSelectPage Source: https://docs.tossplace.com/reference/plugin-sdk/front/template.html Renders a single selection screen, displaying options in a list format. Each option can include an icon, and clicking an option triggers an `onClick` event. ```APIDOC ## renderSelectPage ### Description Renders a single selection screen. This API displays options in a list format, allowing each option to have an associated icon. Clicking an option executes a provided `onClick` callback. ### Method ```javascript sdk.template.renderSelectPage(params) ``` ### Parameters #### Params - **title** (string) - Required - The main title for the selection screen. - **subtitle** (string) - Required - A subtitle displayed below the main title. - **options** (array) - Required - An array of option objects to display. - **onBack** (function) - Optional - A callback function executed when the back button is pressed. ### Options Object - **title** (string) - Required - The title of the option. - **subtitle** (string) - Optional - A subtitle for the option. - **description** (string) - Optional - A more detailed description for the option. - **iconUrl** (string) - Optional - The URL of an icon to display with the option. - **onClick** (function) - Required - The callback function to execute when the option is clicked. ### Code Example ```javascript sdk.template.renderSelectPage({ title: '반가워요', subtitle: '언어를 선택해주세요', options: [ { title: '한국어로 주문', onClick: () => { console.log('한국어로 주문'); }, iconUrl: '', }, { title: 'Order English', onClick: () => { console.log('Order English'); }, iconUrl: '', }, ], onBack: () => {}, }) ``` ``` -------------------------------- ### listen Source: https://docs.tossplace.com/reference/plugin-sdk/front/serial.html Receives data from the serial port. Registers a callback function to handle incoming data. ```APIDOC ## listen ### Description Receives data from the serial port. Registers a callback function to handle incoming data. ### Method `listen` ### Parameters #### Path Parameters - `callback` (Function) - Required - Description: Callback function to process received data **Callback Function Parameters**: * `params.data` (Uint8Array): Array of received data ### Request Example ```javascript /** * 시리얼 데이터 수신 이벤트 리스너 등록 * @param {Function} callback 수신된 데이터를 처리할 콜백 함수 * @returns {Function} 이벤트 리스너 해제 함수 */ const unlisten = sdk.serial.listen((params) => { console.log("수신된 데이터:", params.data); }); // 이벤트 리스너 해제 unlisten(); ``` ``` -------------------------------- ### Render Sign Page with Navbar Options Source: https://docs.tossplace.com/reference/plugin-sdk/front/template.html Renders a signature page, supporting optional back navigation and a custom navbar button. ```javascript sdk.template.renderSignPage({ ..., onBack?: () => {}, navbarButton?: { label: '우상단버튼', onClick: () => {}, }, }) ``` -------------------------------- ### 매장에서 앱 설치 해제됨 (app.installation.deleted.v1) Source: https://docs.tossplace.com/reference/open-api/app.html This event is triggered when an app is uninstalled from a store. Access to store information via Open API and receiving webhook events will be terminated. ```APIDOC ## Event: app.installation.deleted.v1 ### Description This event is sent when an app is uninstalled from a store. You will no longer be able to access the store's information via the Open API or receive webhook events from the store. ### Event Type `app.installation.deleted.v1` ### Payload #### `merchantId` (Long) - Required The ID of the store. ### Request Example ```json { "id": "000000000000000000000000", "type": "app.installation.deleted.v1", "createdAt": "2026-01-01T00:00:00.000Z", "merchantId": 42, "app": "my-awesome-app", "data": { "merchantId": 42 } } ``` ```