@kioskengine/sdk
TypeScript icon, indicating that this package has built-in type declarations

0.0.8 • Public • Published

KioskEngine SDK

A TypeScript SDK for interacting with KioskEngine Platform hardware devices. This SDK provides a simple and type-safe way to communicate with various hardware devices such as payment terminals, card dispensers and fiscal printers.

Features

  • 🔒 Type-safe API with full TypeScript support
  • 🎮 Easy device management and communication
  • 🔄 Automatic reconnection handling
  • 🏖 Sandbox mode for testing
  • 📝 Comprehensive logging system
  • 🎯 Event-driven architecture
  • ⚡ Promise-based async API

Currently supported hardware

  • Payment terminal
  • Fiscal printer
  • Thermal printer

Installation

npm install @kioskengine/sdk
# or
yarn add @kioskengine/sdk
# or
pnpm add @kioskengine/sdk

Quick Start

import {
  KioskEngineBuilder,
  DeviceType,
  SDKEventType,
  LogLevel,
  ProductItem,
} from "@kioskengine/sdk";

// Create SDK instance
const sdk = new KioskEngineBuilder()
  .withSandboxMode(process.env.NODE_ENV === "development")
  .withDevice(DeviceType.PAYMENT_TERMINAL)
  .build();

// Subscribe to events
sdk.on(SDKEventType.CONNECTED, (event) => {
  console.log("SDK Connected!", event);
});

// Initialize SDK
await sdk.initialize();

// Get payment terminal
const terminal = sdk.getPaymentTerminal();

// Get terminal status
const status = await terminal.getStatus();
console.log("Terminal status:", status);

// Define products for the transaction
const products: ProductItem[] = [
  {
    id: "SKU123",
    name: "Premium Coffee",
    quantity: 2,
    unit_price: 599, // $5.99 per unit
  },
  {
    id: "SKU456",
    name: "Croissant",
    quantity: 1,
    unit_price: 299, // $2.99 per unit
  },
];

// Initialize a transaction
// Total amount will be calculated automatically: (2 * $5.99) + (1 * $2.99) = $14.97
const result = await terminal.initializeTransaction(products);
console.log("Transaction result:", result);

Configuration

The SDK can be configured using the builder pattern:

const sdk = new KioskEngineBuilder()
  .withSandboxMode(true) // Enable sandbox mode for testing
  .withWebSocketUrl("ws://your-server:5000") // Custom WebSocket URL
  .withDevice(DeviceType.PAYMENT_TERMINAL) // Add payment terminal device
  .withTimeout(10000) // Set custom timeout (10 seconds)
  .build();

Processing Transactions

Product Structure

Each product in a transaction must include:

interface ProductItem {
  id: string; // Unique identifier of the product
  name: string; // Name of the product
  quantity: number; // Quantity being purchased
  unit_price: number; // Price per unit in cents (e.g., 599 for $5.99)
}

Transaction Example

// Get payment terminal instance
const terminal = sdk.getPaymentTerminal();

// Define products
const products: ProductItem[] = [
  {
    id: "COFFEE-001",
    name: "Espresso",
    quantity: 2,
    unit_price: 399, // $3.99 each
  },
  {
    id: "PASTRY-001",
    name: "Chocolate Muffin",
    quantity: 1,
    unit_price: 299, // $2.99 each
  },
];

try {
  // Initialize transaction
  // Total amount: (2 * $3.99) + (1 * $2.99) = $10.97
  const result = await terminal.initializeTransaction(products);

  if (result.auth_res === "approval") {
    console.log("Transaction approved!");
    console.log("Amount:", result.amount);
    console.log("Card type:", result.card_type);
    console.log("Authorization code:", result.card_payment_data.auth_code);
  } else {
    console.log("Transaction declined:", result.auth_res);
  }
} catch (error) {
  if (error instanceof TimeoutError) {
    console.error("Transaction timed out");
  } else {
    console.error("Transaction failed:", error);
  }
}

Testing Declined Transactions

In sandbox mode, you can test declined transactions by including [decline] in any product name. For example:

const products: ProductItem[] = [
  {
    id: "TEST-001",
    name: "Test Product [decline]", // This will trigger a declined transaction
    quantity: 1,
    unit_price: 1000,
  },
];

const result = await terminal.initializeTransaction(products);
// result.auth_res will be "refusal"
// result.card_payment_data.auth_response will be "ODMOWA"
// result.card_payment_data.auth_response_code will be "0005"

Transaction Events

Monitor transaction progress using events:

// Subscribe to transaction events
sdk.on(SDKEventType.TRANSACTION_STARTED, (event) => {
  console.log("Transaction started:", event.data);
  // event.data contains: { amount: number, products: ProductItem[] }
});

sdk.on(SDKEventType.TRANSACTION_COMPLETED, (event) => {
  console.log("Transaction completed:", event.data);
  // event.data contains the TransactionResponse
});

sdk.on(SDKEventType.TRANSACTION_ERROR, (event) => {
  console.error("Transaction failed:", event.data.error);
});

Transaction Response

The transaction response includes:

interface TransactionResponse {
  auth_res: "approval" | "refusal" | "unable_to_complete_transaction";
  amount: number;
  card_type: string;
  card_payment_data: {
    transaction_time: string;
    transaction_date: string;
    card_name: string;
    masked_card_number: string;
    auth_code: string;
    // ... additional payment details
  };
}

Working with Fiscal Printer

The SDK provides comprehensive support for fiscal printer operations. Here's how to use the fiscal printer:

Initializing the Fiscal Printer

import { KioskEngineBuilder, DeviceType } from "@kioskengine/sdk";

const sdk = new KioskEngineBuilder()
  .withSandboxMode(process.env.NODE_ENV === "development")
  .withDevice(DeviceType.FISCAL_PRINTER)
  .build();

await sdk.initialize();

// Get fiscal printer instance
const printer = sdk.getFiscalPrinter();

Checking Printer Status

const status = await printer.getStatus();
console.log("Printer status:", status);
// status contains:
// - command_queue: "empty" | "not_empty" | "unknown"
// - connection: "ok" | "error"
// - device: "ok" | "error_in_menu" | "error_waitin_for_key" | "error_waiting_for_user_reaction" | "unknown"
// - mechanism: "ok" | "error_lever_raised" | ... (various error states)
// - paper_sensor: "ok" | "no_paper" | "low_paper" | "not_ok"
// - connection_details: error details (when connection is "error")

Printing Fiscal Receipt

const products = [
  {
    name: "Coffee",
    number: 2,
    price: 5.99, // $5.99
    tax_code: 1, // Tax rate code
  },
  {
    name: "Croissant",
    number: 1,
    price: 2.99, // $2.99
    tax_code: 1,
  },
];

try {
  // Optional parameters
  const customerNip = "1234567890"; // Customer tax number
  const discount = "10"; // 10% discount
  const paymentMethod = "card"; // Payment method (cash, card, etc.)

  const result = await printer.printFiscalReceipt(
    products,
    customerNip,
    discount,
    paymentMethod
  );

  if (result.print_result === "ok") {
    console.log("Receipt printed successfully");
  } else {
    console.log("Print error:", result.print_result_details);
  }
} catch (error) {
  console.error("Failed to print receipt:", error);
}

Printing Card Payment Receipt

const cardPaymentData = {
  auth_res: "approval",
  transaction_nr: "1023",
  terminal_id: "82328135",
  merchandiser_id: "76328988",
  acceptor_id: "A0000000041010",
  auth_code: "471948",
  total_transaction_price: "535",
  card_name: "VISA",
  masked_card_number: "************1234",
  method_of_reading_card: "C", // C for chip, M for magnetic, E for contactless, etc.
  masked_card_expire_date: "**/**",
  transaction_date: "20240315", // Format: YYYYMMDD
  transaction_time: "143000", // Format: HHMMSS

  // Required fields
  auth_code_source: "1", // "1" for online authorization
  cardholder_authorization_method: "A", // Authorization method

  // EMV fields
  emv_transaction_cryptogram: "55E13384CCA22CFD",
  emv_application_identifier: "A0000000041010",
  terminal_printing_indicator: "0",

  // DCC (Dynamic Currency Conversion) fields
  transaction_currency_code: "EUR", // Set to EUR or USD for DCC mode
  terminal_currency: "PLN",
  transaction_amount_in_terminal_currency: "1000",
  currency_exchange_rate: "0.2400570",
  dcc_text1: "THIS CURRENCY CONVERSION SERVICE IS PROVIDED BY VISA",
  dcc_text2:
    "I HAVE BEEN OFFERED A CHOICE OF CURRENCIES AND HAVE CHOSEN TO PAY IN EUR",
};

const result = await printer.printCardPaymentReceipt(cardPaymentData);
console.log("Card payment receipt result:", result);

DCC (Dynamic Currency Conversion) Mode

The receipt will automatically be formatted as a DCC receipt when:

  • transaction_currency_code is EUR or USD (not PLN)
  • terminal_currency is set to PLN (local currency)

In DCC mode, the receipt will include:

  • Both original amount in PLN and converted amount in the foreign currency
  • Currency exchange rate information
  • Additional legal texts (provided in dcc_text1 and dcc_text2)
  • Special formatting based on the card brand (VISA vs MasterCard)

Standard Domestic Transaction (Non-DCC)

For standard domestic transactions:

  • Set transaction_currency_code to "PLN" or leave it empty
  • The receipt will be printed in standard Polish format with a single amount in PLN

Printing QR Code

// Print a QR code (simplified API)
const qrCode = "https://example.com/order/123";
const result = await printer.printQRCode(qrCode);
console.log("QR code print result:", result);

Printing Order Number

// Print an order number (must be exactly 3 digits)
const result = await printer.printOrderNumber("042"); // Valid: 3 digits

// Invalid examples (will throw an error):
// await printer.printOrderNumber("42");  // Error: less than 3 digits
// await printer.printOrderNumber("1234"); // Error: more than 3 digits
// await printer.printOrderNumber("abc"); // Error: non-numeric characters

console.log("Order number print result:", result);

The order number must:

  • Be exactly 3 numeric digits (000-999)
  • Be provided as a string
  • Contain only numeric characters

Daily Report

// Initialize and print daily report with optional ID
const reportId = 3; // Optional identifier for the report
const report = await printer.initDailyReport(reportId);

console.log("Daily report date:", report.report_date);
console.log("Print result:", report.print_result);
console.log("Completed:", report.completed); // Indicates if report generation completed successfully

Handling Print Events

// Subscribe to print events
sdk.on(SDKEventType.PRINT_STARTED, (event) => {
  console.log("Print operation started:", event.data);
});

sdk.on(SDKEventType.PRINT_COMPLETED, (event) => {
  console.log("Print operation completed:", event.data);
});

sdk.on(SDKEventType.PRINT_ERROR, (event) => {
  console.error("Print operation failed:", event.data.error);
});

Working with Thermal Printer

The SDK provides comprehensive support for thermal printer operations, allowing you to create receipts, labels, and other printed content.

Initializing the Thermal Printer

import { KioskEngineBuilder, DeviceType } from "@kioskengine/sdk";

const sdk = new KioskEngineBuilder()
  .withSandboxMode(process.env.NODE_ENV === "development")
  .withDevice(DeviceType.THERMAL_PRINTER)
  .build();

await sdk.initialize();

// Get thermal printer instance
const printer = sdk.getThermalPrinter();

Checking Printer Status

const status = await printer.getStatus();
console.log("Printer status:", status);
// status contains:
// - connection: "ok" | "error"
// - paper_level: "ok" | "low" | "empty"
// - error_status: "ok" | string
// - online: boolean
// - printer_type: string
// - last_check: string (timestamp)
// - connection_details: string (optional error details)

Basic Printing with Commands

The thermal printer uses a command-based API where you create an array of commands to execute:

// Create an array of print commands
const commands = [
  {
    command: "print_text",
    value: "Hello, World!",
    align: "center",
    bold: true,
    width_size: 2,
    height_size: 2,
  },
  {
    command: "feed_lines",
    value: 2,
  },
  {
    command: "print_qr",
    value: "https://example.com",
    size: 8,
  },
  {
    command: "feed_lines",
    value: 3,
  },
  {
    command: "cut_paper",
  },
];

// Send commands to the printer
const result = await printer.print(commands);
console.log("Print result:", result);

Using Command Generation Utilities

For convenience, the SDK provides utility methods to create properly formatted commands:

// Create commands using utility methods
const commands = [
  printer.createTextCommand("Hello, World!", {
    align: "center",
    bold: true,
    width_size: 2,
    height_size: 2,
  }),
  printer.createFeedLinesCommand(2),
  printer.createQRCommand("https://example.com", 8),
  printer.createFeedLinesCommand(3),
  printer.createCutPaperCommand(),
];

// Send commands to the printer
const result = await printer.print(commands);

Printing a Complete Receipt

The SDK includes a utility to generate a complete receipt with a single method call:

const receiptCommands = printer.generateReceiptCommands({
  title: "ACME Store",
  subtitle: "123 Main Street, Anytown",
  items: [
    { name: "Coffee", quantity: 2, price: 599 }, // $5.99 each
    { name: "Croissant", quantity: 1, price: 299 }, // $2.99 each
    { name: "Orange Juice", quantity: 1, price: 349 }, // $3.49 each
  ],
  total: 1846, // $18.46
  orderNumber: "A42",
  footer: "Thank you for shopping with us",
  qrCode: "https://example.com/receipt/42",
});

const result = await printer.print(receiptCommands);

Supported Commands

The thermal printer supports the following commands:

  1. Print Text

    printer.createTextCommand("Text to print", {
      align: "left" | "center" | "right", // default: "left"
      font: "a" | "b", // default: "a"
      bold: true | false, // default: false
      width_size: 1 - 8, // default: 1
      height_size: 1 - 8, // default: 1
    });
  2. Feed Lines

    printer.createFeedLinesCommand(numberOfLines); // default: 1
  3. Cut Paper

    printer.createCutPaperCommand(partial); // default: true
  4. Print QR Code

    printer.createQRCommand("data", size); // size default: 6
  5. Print Barcode

    printer.createBarcodeCommand("5901234123457", {
      height: 64, // default: 64
      width: 2 - 6, // default: 3
      position: "below" | "above" | "both" | "none", // default: "below"
      font: "a" | "b", // default: "a"
    });
  6. Print Image

    printer.createImageCommand("/path/to/image.png", highDensity); // highDensity default: true
  7. Print Logo

    printer.createLogoCommand(logoNumber); // default: 1
  8. Initialize Printer

    printer.createInitializeCommand();
  9. Set Print Mode

    printer.createPrintModeCommand({
      font_b: true | false, // default: false
      emphasized: true | false, // default: false
      width_size: 1 - 8, // default: 1
      height_size: 1 - 8, // default: 1
      underline: true | false, // default: false
    });
  10. Set Paper Width

    printer.createPaperWidthCommand(58 | 80); // 58mm or 80mm

Handling Print Events

// Subscribe to print events
sdk.on(SDKEventType.PRINT_STARTED, (event) => {
  console.log("Print operation started:", event.data);
});

sdk.on(SDKEventType.PRINT_COMPLETED, (event) => {
  console.log("Print operation completed:", event.data);
});

sdk.on(SDKEventType.PRINT_ERROR, (event) => {
  console.error("Print operation failed:", event.data.error);
});

Testing with Sandbox Mode

In sandbox mode, all print operations will be simulated. To simulate printing failures, include the string [fail] in any text command:

const failingCommand = printer.createTextCommand("Test failure [fail]");
const result = await printer.print([failingCommand]);
// result.success will be false
// result.errors will contain details about the simulated failure

Logging

The SDK provides different log levels that can be configured:

import { KioskEngine, LogLevel } from "@kioskengine/sdk";

KioskEngine.setLogLevel(LogLevel.DEBUG); // Set to DEBUG for development

Available log levels:

  • DEBUG: Detailed information for debugging
  • INFO: General information about operations
  • WARN: Warning messages for potential issues
  • ERROR: Error messages for operation failures

Event System

The SDK uses an event-driven system to notify about various states and operations:

sdk.on(SDKEventType.DEVICE_READY, (event) => {
  console.log("Device is ready:", event.deviceType);
});

sdk.on(SDKEventType.TRANSACTION_COMPLETED, (event) => {
  console.log("Transaction completed:", event.data);
});

Available events:

  • CONNECTED: SDK successfully connected
  • DISCONNECTED: SDK disconnected
  • DEVICE_READY: Device is initialized and ready
  • DEVICE_ERROR: Device encountered an error
  • TRANSACTION_STARTED: Payment transaction started
  • TRANSACTION_COMPLETED: Payment transaction completed
  • TRANSACTION_ERROR: Payment transaction failed

API Documentation

The SDK is written in TypeScript and provides full type definitions. No additional @types packages are required.

License

Copyright © 2024 KioskEngine. All rights reserved.

Package Sidebar

Install

npm i @kioskengine/sdk

Weekly Downloads

11

Version

0.0.8

License

Copyright © 2025 Kiosk Engine

Unpacked Size

185 kB

Total Files

46

Last publish

Collaborators

  • kioskengine