@commercengine/pos
v0.3.11
Published
TypeScript SDK for the POS API
Maintainers
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/posQuick 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 addressloginWithPhone()- Login with phone numberloginWithWhatsapp()- Login with WhatsApppairDevice()- Pair a new deviceverifyOtp()- Verify OTP and get tokensrefreshAccessToken()- Refresh access tokenlogout()- Logout from POS device
Cart Management
createCart()- Create a new cart with itemsgetCart()- Get cart detailsupdateCart()- Add/update/remove cart itemsdeleteCart()- Delete entire cartcreateCartAddress()- Set billing/shipping addressesupdateCartCustomer()- Associate customer with cart
Promotions & Coupons
listPromotions()- Get available promotionsevaluatePromotions()- Calculate promotion discounts for cartlistCoupons()- Get available couponsapplyCoupon()- Apply coupon to cartremoveCoupon()- Remove coupon from cartevaluateCoupons()- Check applicable/inapplicable coupons
Credit Balance & Loyalty
redeemCreditBalance()- Apply credit balance to cartremoveCreditBalance()- Remove credit balance from cartredeemLoyaltyPoints()- Apply loyalty points to cartremoveLoyaltyPoints()- Remove loyalty points from cart
Fulfillment
updateFulfillmentPreference()- Set pickup/delivery optionsgetFulfillmentOptions()- Get available fulfillment methods
Orders
createOrder()- Create order from cartlistOrders()- 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 categorieslistProducts()- List products with filteringgetProductDetail()- Get product detailslistProductVariants()- Get product variantsgetVariantDetail()- Get variant detailslistProductReviews()- Get product reviewssearchProducts()- Search products with filterslistCrosssellProducts()- Get cross-sell recommendationslistSimilarProducts()- Get similar product recommendationslistUpsellProducts()- Get up-sell recommendationslistSkus()- List all SKUs
Inventory (Admin)
listInventories()- List inventory levelslistInventoryActivities()- List inventory activitiesgetInventoryDetail()- Get inventory details
Customers (Admin)
getCustomers()- List customersgetCustomer()- Get customer details
Shipments (Admin)
listShipments()- List shipmentsgetShipment()- Get shipment detailsupdateShipment()- Update shipment statusgetShipmentInvoice()- Get shipment invoicecheckInventory()- Check inventory for orderrefundShortfall()- 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
apiKeyfor 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 functionalityjose- JWT token handlingopenapi-fetch- Type-safe API client
Development
Generate Types
Types are auto-generated from the OpenAPI specification:
pnpm run codegenBuild
pnpm run buildType Checking
pnpm run check-exportsSupport
For issues, questions, or feature requests, please contact the Commerce Engine team or check the main repository documentation.
