TypeScript SDK for the POS API
npm install @commercengine/posTypeScript 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.
``bash`
npm install @commercengine/posor
yarn add @commercengine/posor
pnpm add @commercengine/pos
`typescript
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: 'cashier@store.com'
});
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);
}
`
The PosSDK constructor accepts a PosSDKOptions object with the following configuration:
| Option | Type | Description |
|--------|------|-------------|
| storeId | string | Your Commerce Engine store ID |apiKey
| | string | API key for authentication endpoints (required for all POS operations) |
| 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 |
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
`typescript`
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
});
`typescript`
interface SupportedDefaultHeaders {
/**
* Customer group ID used for pricing and promotions
*/
customer_group_id?: string;
}
The POS SDK supports three token management strategies:
`typescript
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');
}
});
`
`typescript
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');
`
`typescript`
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
});
with customizable prefix:`typescript
import { BrowserTokenStorage } from '@commercengine/pos';const storage = new BrowserTokenStorage('my_pos_'); // prefix: default 'pos_'
`$3
Stores tokens in memory (lost on page refresh):`typescript
import { MemoryTokenStorage } from '@commercengine/pos';const storage = new MemoryTokenStorage();
`$3
Implement the TokenStorage interface for custom storage:`typescript
import { TokenStorage } from '@commercengine/pos';class CustomTokenStorage implements TokenStorage {
async getAccessToken(): Promise { / ... / }
async setAccessToken(token: string): Promise { / ... / }
async getRefreshToken(): Promise { / ... / }
async setRefreshToken(token: string): Promise { / ... / }
async clearTokens(): Promise { / ... / }
}
`Authentication Flow
The POS SDK uses a two-step authentication process:
$3
`typescript
// Login with email
const { data: emailData, error: emailError } = await pos.loginWithEmail({
device_id: 'unique-device-id',
email: 'user@example.com'
});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'
});
`$3
`typescript
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);
`$3
For new devices, you may need to pair first:
`typescript
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:
$3
- 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$3
- 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$3
- 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$3
- redeemCreditBalance() - Apply credit balance to cart
- removeCreditBalance() - Remove credit balance from cart
- redeemLoyaltyPoints() - Apply loyalty points to cart
- removeLoyaltyPoints() - Remove loyalty points from cart$3
- updateFulfillmentPreference() - Set pickup/delivery options
- getFulfillmentOptions() - Get available fulfillment methods$3
- 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)$3
- 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$3
- listInventories() - List inventory levels
- listInventoryActivities() - List inventory activities
- getInventoryDetail() - Get inventory details$3
- getCustomers() - List customers
- getCustomer() - Get customer details$3
- listShipments() - List shipments
- getShipment() - Get shipment details
- updateShipment() - Update shipment status
- getShipmentInvoice() - Get shipment invoice
- checkInventory() - Check inventory for order
- refundShortfall() - Process refund for shortfallUser Information
Access user information from JWT tokens:
`typescript
// 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 objects with consistent error handling:`typescript
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
$3
`typescript
const pos = new PosSDK({
storeId: 'your-store-id',
apiKey: 'your-api-key',
// Uses production environment by default
});
`$3
`typescript
import { PosSDK, Environment } from '@commercengine/pos';const pos = new PosSDK({
storeId: 'your-store-id',
apiKey: 'your-api-key',
environment: Environment.Staging
});
`$3
`typescript
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:
`typescript
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:
$3
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:`typescript
// 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.
`typescript
import type {
PosCreateCartBody,
PosCreateCartContent,
UserInfo,
TokenStorage,
ApiResult
} from '@commercengine/pos';// All API methods are fully typed
const cart: ApiResult = await pos.createCart({
items: [
{
product_id: "01H9XYZ12345ABCDE",
variant_id: null,
quantity: 2
}
] // TypeScript validates this structure
});
`Best Practices
$3
Enable automatic token management to handle expiry and refresh:`typescript
const pos = new PosSDK({
storeId: 'your-store-id',
apiKey: 'your-api-key',
tokenStorage: new BrowserTokenStorage()
});
`$3
Listen for token events to update your application state:`typescript
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
Always check for error before accessing data:`typescript
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);
}
`$3
Keep device IDs consistent across sessions:`typescript
// 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: 'user@example.com'
});
`Migration from Other SDKs
If you're migrating from the storefront SDK:
$3
- 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$3
`typescript
// 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 clientDevelopment
$3
Types are auto-generated from the OpenAPI specification:`bash
pnpm run codegen
`$3
`bash
pnpm run build
`$3
`bash
pnpm run check-exports
``For issues, questions, or feature requests, please contact the Commerce Engine team or check the main repository documentation.