npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@commercengine/pos

v0.3.11

Published

TypeScript SDK for the POS API

Readme

@commercengine/pos

TypeScript SDK for the Commerce Engine Point of Sale (POS) API. This package provides a complete interface to manage POS operations including authentication, cart management, orders, promotions, and customer interactions.

Installation

npm install @commercengine/pos
# or
yarn add @commercengine/pos
# or
pnpm add @commercengine/pos

Quick Start

import { PosSDK } from '@commercengine/pos';

// Initialize the SDK
const pos = new PosSDK({
  storeId: 'your-store-id',
  apiKey: 'your-api-key',
});

// Login with email (returns OTP token)
const { data: loginData, error: loginError } = await pos.loginWithEmail({
  device_id: 'device-123',
  email: '[email protected]'
});

if (loginError) {
  console.error('Login failed:', loginError);
  return;
}

// Verify OTP to get access tokens
const { data: authData, error: authError } = await pos.verifyOtp({
  otp_token: loginData.otp_token,
  otp: '123456'
});

if (authError) {
  console.error('OTP verification failed:', authError);
  return;
}

// Now you can make authenticated requests
const { data: cartData, error: cartError } = await pos.createCart({
  items: [
    {
      product_id: "01H9XYZ12345ABCDE",
      variant_id: null,
      quantity: 2
    }
  ]
});

if (cartData) {
  console.log('Cart created:', cartData);
}

Configuration Options

The PosSDK constructor accepts a PosSDKOptions object with the following configuration:

Required Options

| Option | Type | Description | |--------|------|-------------| | storeId | string | Your Commerce Engine store ID | | apiKey | string | API key for authentication endpoints (required for all POS operations) |

Optional Options

| Option | Type | Description | |--------|------|-------------| | environment | Environment | API environment (Environment.Production, Environment.Staging, Environment.Development) | | baseUrl | string | Custom base URL (overrides environment setting) | | accessToken | string | Initial access token (if you already have one) | | refreshToken | string | Initial refresh token (requires tokenStorage) | | tokenStorage | TokenStorage | Automatic token management (recommended) | | onTokensUpdated | function | Callback when tokens are refreshed | | onTokensCleared | function | Callback when tokens are cleared/expired | | timeout | number | Request timeout in milliseconds | | defaultHeaders | SupportedDefaultHeaders | Default headers for all requests | | debug | boolean | Enable debug logging | | logger | DebugLoggerFn | Custom debug logger function |

BaseSDKOptions (inherited from @commercengine/sdk-core)

The POS SDK extends the base SDK configuration with these inherited options:

  • baseUrl: Custom API base URL
  • timeout: Request timeout (default: 30000ms)
  • defaultHeaders: Default headers applied to all requests
  • debug: Enable request/response logging
  • logger: Custom logger function for debug output

Advanced Configuration

const pos = new PosSDK({
  storeId: 'your-store-id',
  apiKey: 'your-api-key',
  environment: Environment.Production,
  
  // Token Management
  accessToken: 'initial-access-token',     // Initial access token
  refreshToken: 'initial-refresh-token',   // Initial refresh token (requires tokenStorage)
  
  // Custom base URL (optional, overrides environment)
  baseUrl: 'https://your-custom-api.example.com',
  
  // Request Configuration
  timeout: 10000,                          // Request timeout in milliseconds
  
  // Default Headers (auto applied to all applicable requests)
  defaultHeaders: {
    customer_group_id: '01JHS28V83KDWTRBXXJQRTEKA0', // For pricing and promotions
  },
  
  // Debug and Logging
  debug: true,                             // Enable detailed request/response logging
  logger: console.log,                     // Custom logger function
});

Supported Default Headers

interface SupportedDefaultHeaders {
  /**
   * Customer group ID used for pricing and promotions
   */
  customer_group_id?: string;
}

Token Management

The POS SDK supports three token management strategies:

1. Automatic Token Management (Recommended)

import { PosSDK, BrowserTokenStorage } from '@commercengine/pos';

const pos = new PosSDK({
  storeId: 'your-store-id',
  apiKey: 'your-api-key',
  tokenStorage: new BrowserTokenStorage(), // or new MemoryTokenStorage()
  onTokensUpdated: (accessToken, refreshToken) => {
    console.log('Tokens updated');
  },
  onTokensCleared: () => {
    console.log('User logged out');
  }
});

2. Manual Token Management

const pos = new PosSDK({
  storeId: 'your-store-id',
  apiKey: 'your-api-key',
  accessToken: 'existing-access-token'
});

// Update tokens manually
await pos.setTokens('new-access-token', 'new-refresh-token');

3. Initialize with Existing Tokens

const pos = new PosSDK({
  storeId: 'your-store-id',
  apiKey: 'your-api-key',
  accessToken: 'existing-access-token',
  refreshToken: 'existing-refresh-token',
  tokenStorage: new BrowserTokenStorage() // Enables automatic refresh
});

Token Storage Options

BrowserTokenStorage

Stores tokens in localStorage with customizable prefix:

import { BrowserTokenStorage } from '@commercengine/pos';

const storage = new BrowserTokenStorage('my_pos_'); // prefix: default 'pos_'

MemoryTokenStorage

Stores tokens in memory (lost on page refresh):

import { MemoryTokenStorage } from '@commercengine/pos';

const storage = new MemoryTokenStorage();

Custom TokenStorage

Implement the TokenStorage interface for custom storage:

import { TokenStorage } from '@commercengine/pos';

class CustomTokenStorage implements TokenStorage {
  async getAccessToken(): Promise<string | null> { /* ... */ }
  async setAccessToken(token: string): Promise<void> { /* ... */ }
  async getRefreshToken(): Promise<string | null> { /* ... */ }
  async setRefreshToken(token: string): Promise<void> { /* ... */ }
  async clearTokens(): Promise<void> { /* ... */ }
}

Authentication Flow

The POS SDK uses a two-step authentication process:

Step 1: Login (Request OTP)

// Login with email
const { data: emailData, error: emailError } = await pos.loginWithEmail({
  device_id: 'unique-device-id',
  email: '[email protected]'
});

if (emailError) {
  console.error('Email login failed:', emailError);
  return;
}

// Login with phone
const { data: phoneData, error: phoneError } = await pos.loginWithPhone({
  device_id: 'unique-device-id',
  phone: '+1234567890'
});

// Login with WhatsApp
const { data: whatsappData, error: whatsappError } = await pos.loginWithWhatsapp({
  device_id: 'unique-device-id',
  phone: '+1234567890'
});

Step 2: Verify OTP

const { data: authData, error: authError } = await pos.verifyOtp({
  otp_token: emailData.otp_token,
  otp: '123456'
});

if (authError) {
  console.error('OTP verification failed:', authError);
  return;
}

// Access token and refresh token are now automatically stored
// if tokenStorage is configured
console.log('Authentication successful:', authData);

Device Pairing

For new devices, you may need to pair first:

const { data: pairData, error: pairError } = await pos.pairDevice({
  pairing_code: 'ABC123'
});

if (pairError) {
  console.error('Device pairing failed:', pairError);
  return;
}

console.log('Device paired successfully:', pairData);

API Operations

The POS SDK provides access to all POS operations directly on the SDK instance:

Authentication

  • loginWithEmail() - Login with email address
  • loginWithPhone() - Login with phone number
  • loginWithWhatsapp() - Login with WhatsApp
  • pairDevice() - Pair a new device
  • verifyOtp() - Verify OTP and get tokens
  • refreshAccessToken() - Refresh access token
  • logout() - Logout from POS device

Cart Management

  • createCart() - Create a new cart with items
  • getCart() - Get cart details
  • updateCart() - Add/update/remove cart items
  • deleteCart() - Delete entire cart
  • createCartAddress() - Set billing/shipping addresses
  • updateCartCustomer() - Associate customer with cart

Promotions & Coupons

  • listPromotions() - Get available promotions
  • evaluatePromotions() - Calculate promotion discounts for cart
  • listCoupons() - Get available coupons
  • applyCoupon() - Apply coupon to cart
  • removeCoupon() - Remove coupon from cart
  • evaluateCoupons() - Check applicable/inapplicable coupons

Credit Balance & Loyalty

  • redeemCreditBalance() - Apply credit balance to cart
  • removeCreditBalance() - Remove credit balance from cart
  • redeemLoyaltyPoints() - Apply loyalty points to cart
  • removeLoyaltyPoints() - Remove loyalty points from cart

Fulfillment

  • updateFulfillmentPreference() - Set pickup/delivery options
  • getFulfillmentOptions() - Get available fulfillment methods

Orders

  • createOrder() - Create order from cart
  • listOrders() - List orders (Admin)
  • getOrderDetail() - Get order details (Admin)
  • listOrderActivity() - Get order activity log (Admin)
  • getOrderInvoice() - Get order invoice (Admin)
  • getOrderReceipt() - Get order receipt (Admin)
  • getOrderShipments() - Get order shipments (Admin)

Catalog & Products

  • listCategories() - List product categories
  • listProducts() - List products with filtering
  • getProductDetail() - Get product details
  • listProductVariants() - Get product variants
  • getVariantDetail() - Get variant details
  • listProductReviews() - Get product reviews
  • searchProducts() - Search products with filters
  • listCrosssellProducts() - Get cross-sell recommendations
  • listSimilarProducts() - Get similar product recommendations
  • listUpsellProducts() - Get up-sell recommendations
  • listSkus() - List all SKUs

Inventory (Admin)

  • listInventories() - List inventory levels
  • listInventoryActivities() - List inventory activities
  • getInventoryDetail() - Get inventory details

Customers (Admin)

  • getCustomers() - List customers
  • getCustomer() - Get customer details

Shipments (Admin)

  • listShipments() - List shipments
  • getShipment() - Get shipment details
  • updateShipment() - Update shipment status
  • getShipmentInvoice() - Get shipment invoice
  • checkInventory() - Check inventory for order
  • refundShortfall() - Process refund for shortfall

User Information

Access user information from JWT tokens:

// Get complete user information
const userInfo = await pos.getUserInfo();
console.log(userInfo?.email, userInfo?.device, userInfo?.location);

// Get specific information
const userId = await pos.getUserId();
const deviceId = await pos.getDeviceId(); 
const locationId = await pos.getLocationId();
const role = await pos.getRole();

// Check authentication status
const isLoggedIn = await pos.isLoggedIn();
const isAuthenticated = await pos.isAuthenticated();

Error Handling

The SDK returns ApiResult<T> objects with consistent error handling:

const { data, error, response } = await pos.createCart({
  items: [
    {
      product_id: "01H9XYZ12345ABCDE",
      variant_id: null,
      quantity: 2
    }
  ]
});

if (error) {
  console.error('Error:', error.message);
  console.error('HTTP Status:', response?.status);
} else {
  console.log('Cart created:', data);
}

// Alternative pattern - checking for data
if (data) {
  console.log('Cart created:', data);
} else {
  console.error('Failed to create cart:', error);
}

Environment Configuration

Production (Default)

const pos = new PosSDK({
  storeId: 'your-store-id',
  apiKey: 'your-api-key',
  // Uses production environment by default
});

Staging

import { PosSDK, Environment } from '@commercengine/pos';

const pos = new PosSDK({
  storeId: 'your-store-id', 
  apiKey: 'your-api-key',
  environment: Environment.Staging
});

Custom Base URL

const pos = new PosSDK({
  storeId: 'your-store-id',
  apiKey: 'your-api-key', 
  baseUrl: 'https://custom-api.yourstore.com/api/v1/your-store-id/storefront'
});

Debug Mode

Enable debug logging to troubleshoot API requests:

const pos = new PosSDK({
  storeId: 'your-store-id',
  apiKey: 'your-api-key',
  debug: true,
  logger: (message, data) => {
    console.log(`[POS SDK] ${message}`, data);
  }
});

TypeScript Support

The SDK is written in TypeScript and provides full type safety with advanced schema handling:

Schema-Specific Typing

The POS SDK handles both regular storefront operations and admin operations with proper type safety. When both schemas define the same endpoint (like /pos/orders), the SDK automatically uses the appropriate schema based on the operation:

// Regular POS operation (POST) - uses storefront schema
await pos.createOrder({ cart_id: "cart-123" });

// Admin POS operation (GET) - uses admin schema  
await pos.listOrders({ page: 1, limit: 10 });

This ensures you get proper TypeScript autocompletion and validation for each operation without any type conflicts.

import type { 
  PosCreateCartBody,
  PosCreateCartContent,
  UserInfo,
  TokenStorage,
  ApiResult
} from '@commercengine/pos';

// All API methods are fully typed
const cart: ApiResult<PosCreateCartContent> = await pos.createCart({
  items: [
    {
      product_id: "01H9XYZ12345ABCDE",
      variant_id: null,
      quantity: 2
    }
  ] // TypeScript validates this structure
});

Best Practices

1. Always Use Token Storage

Enable automatic token management to handle expiry and refresh:

const pos = new PosSDK({
  storeId: 'your-store-id',
  apiKey: 'your-api-key',
  tokenStorage: new BrowserTokenStorage()
});

2. Handle Token Events

Listen for token events to update your application state:

const pos = new PosSDK({
  storeId: 'your-store-id',
  apiKey: 'your-api-key',
  tokenStorage: new BrowserTokenStorage(),
  onTokensUpdated: (accessToken, refreshToken) => {
    // User successfully authenticated or tokens refreshed
    updateUIForLoggedInState();
  },
  onTokensCleared: () => {
    // Tokens expired or user logged out
    redirectToLogin();
  }
});

3. Error Handling Pattern

Always check for error before accessing data:

const { data, error, response } = await pos.getCart({ id: 'cart-123' });

if (error) {
  if (response?.status === 404) {
    // Cart not found
    showMessage('Cart not found');
  } else {
    // Other error
    showErrorMessage(error.message);
  }
} else {
  displayCart(data);
}

4. Use Device IDs Consistently

Keep device IDs consistent across sessions:

// Store device ID in localStorage
const deviceId = localStorage.getItem('pos_device_id') || generateDeviceId();
localStorage.setItem('pos_device_id', deviceId);

// Use in all authentication calls  
await pos.loginWithEmail({
  device_id: deviceId,
  email: '[email protected]'
});

Migration from Other SDKs

If you're migrating from the storefront SDK:

Key Differences

  • API Key Required: POS SDK requires apiKey for all operations
  • Two-Step Auth: Login returns OTP token, must verify with verifyOtp()
  • Device Context: All operations are scoped to a specific device and location
  • No Anonymous Mode: POS SDK requires explicit authentication

Updated Initialization

// Old (storefront)
const storefront = new StorefrontSDK({
  storeId: 'your-store-id'
  // apiKey was optional
});

// New (POS) 
const pos = new PosSDK({
  storeId: 'your-store-id',
  apiKey: 'your-api-key' // Now required
});

Package Information

  • Version: 0.0.0 (pre-release)
  • License: All rights reserved
  • Dependencies:
    • @commercengine/sdk-core - Core SDK functionality
    • jose - JWT token handling
    • openapi-fetch - Type-safe API client

Development

Generate Types

Types are auto-generated from the OpenAPI specification:

pnpm run codegen

Build

pnpm run build

Type Checking

pnpm run check-exports

Support

For issues, questions, or feature requests, please contact the Commerce Engine team or check the main repository documentation.