node-red-contrib-commerce7-api-client
v1.2.2
Published
Node-RED nodes for Commerce7 API
Maintainers
Readme
Commerce7 API Client
A clean, simple, and type-safe JavaScript/TypeScript client for the Commerce7 REST API.
Features
- ✅ Type-Safe: Full TypeScript support with type definitions
- ✅ Simple API: Clean, intuitive interface
- ✅ Automatic Authentication: Handles Basic Auth and tenant headers
- ✅ Built-in Pagination: Automatic cursor-based pagination
- ✅ Rate Limiting: Respects
Retry-Afterheaders - ✅ Error Handling: Comprehensive error handling with typed errors
- ✅ Node-RED Support: Includes Node-RED nodes for easy integration
- ✅ Zero Dependencies: Only uses
axios(peer dependency)
Installation
As a Node.js Package
npm install commerce7-api-clientAs a Node-RED Package
Install via Node-RED's palette manager or manually:
cd ~/.node-red
npm install node-red-contrib-commerce7-api-clientThen restart Node-RED. You'll find two new nodes:
- commerce7 config: Configuration node for API credentials
- commerce7 request: Node for making API requests
Quick Start
import { createClient } from 'commerce7-api-client';
// Create a client
const client = createClient({
appId: 'your-app-id',
appSecret: 'your-app-secret',
tenant: 'your-tenant-id'
});
// Make a request
const response = await client.get('/customer', { limit: 10 });
console.log(response.data);
// Paginate through results
const allMemberships = await client.paginate('/club-membership', {
updatedAt: 'gte:2024-01-01'
}, {
recordTag: 'clubMemberships'
});API Reference
Creating a Client
import { Commerce7Client, createClient } from 'commerce7-api-client';
// Using factory function
const client = createClient({
appId: 'your-app-id',
appSecret: 'your-app-secret',
tenant: 'your-tenant-id',
baseURL: 'https://api.commerce7.com/v1', // optional
timeout: 30000, // optional, default 30s
maxRetries: 3 // optional, default 3
});
// Or using class directly
const client = new Commerce7Client({
appId: 'your-app-id',
appSecret: 'your-app-secret',
tenant: 'your-tenant-id'
});Making Requests
GET Request
// Simple GET
const response = await client.get('/customer/{id}');
// GET with query parameters
const response = await client.get('/customer', {
q: 'john',
lifetimeValue: 'gt:100000',
orderCount: 'gte:2'
});POST Request
const customer = await client.post('/customer', {
firstName: 'John',
lastName: 'Doe',
emails: [{ email: '[email protected]' }]
});PUT Request
const updated = await client.put('/customer/{id}', {
firstName: 'Jane'
});PATCH Request
const patched = await client.patch('/customer/{id}', {
metaData: { customField: 'value' }
});DELETE Request
await client.delete('/customer/{id}');Pagination
Automatic Pagination (Collect All)
// Collects all pages automatically
const allMemberships = await client.paginate('/club-membership', {
updatedAt: 'gte:2024-01-01'
}, {
recordTag: 'clubMemberships', // Field containing records
maxPages: 1000 // Safety limit
});
console.log(`Found ${allMemberships.length} memberships`);Pagination with Callback
// Process pages as they arrive
const allRecords = await client.paginate('/club-membership', {
updatedAt: 'gte:2024-01-01'
}, {
recordTag: 'clubMemberships',
onPage: (page, pageNumber) => {
console.log(`Processing page ${pageNumber}...`);
// Process page.data here
}
});Multi-Tenant Support
// Create client for tenant 1
const client1 = createClient({
appId: 'app-id',
appSecret: 'secret',
tenant: 'tenant-1'
});
// Create client for tenant 2 (reuses config)
const client2 = client1.withTenant('tenant-2');
// Both clients share the same app credentials
await client1.get('/customer');
await client2.get('/customer');Error Handling
import { Commerce7Error } from 'commerce7-api-client';
try {
const response = await client.get('/customer/invalid-id');
} catch (error) {
if (error instanceof Commerce7Error) {
console.error(`API Error ${error.statusCode}:`, error.message);
console.error('Response:', error.responseData);
} else {
console.error('Network error:', error.message);
}
}Examples
Get Customer by ID
const response = await client.get('/customer/a36b6ff1-7190-49a0-895e-fd2c001eb2a6');
const customer = response.data;
console.log(customer.firstName, customer.lastName);Search Customers
const response = await client.get('/customer', {
q: 'john',
lifetimeValue: 'gt:100000',
orderCount: 'gte:2',
createdAt: 'gte:2024-01-01'
});
const customers = response.data.customers;
console.log(`Found ${response.data.totalCount} customers`);Create Customer
const response = await client.post('/customer', {
firstName: 'John',
lastName: 'Doe',
emails: [{ email: '[email protected]' }],
phones: [{ phone: '+15551234567' }],
isSendTransactionEmail: false
});
const newCustomer = response.data;
console.log('Created customer:', newCustomer.id);Update Customer
const response = await client.put('/customer/{id}', {
firstName: 'Jane',
metaData: {
customField: 'value'
}
});List Club Memberships with Pagination
// Get all active memberships
const memberships = await client.paginate('/club-membership', {
status: 'Active',
updatedAt: 'gte:2024-01-01'
}, {
recordTag: 'clubMemberships'
});
console.log(`Total memberships: ${memberships.length}`);Create Club Membership
// 1. Create customer
const customer = await client.post('/customer', {
firstName: 'John',
lastName: 'Doe',
emails: [{ email: '[email protected]' }]
});
// 2. Create address
const address = await client.post('/customer-address', {
customerId: customer.data.id,
address1: '123 Main St',
city: 'Napa',
stateCode: 'CA',
zipCode: '94558',
countryCode: 'US'
});
// 3. Create credit card
const card = await client.post('/customer-credit-card', {
customerId: customer.data.id,
// ... card details
});
// 4. Create membership
const membership = await client.post('/club-membership', {
customerId: customer.data.id,
clubId: 'club-uuid',
billToCustomerAddressId: address.data.id,
shipToCustomerAddressId: address.data.id,
customerCreditCardId: card.data.id,
orderDeliveryMethod: 'Ship',
signupDate: new Date().toISOString(),
isSendEmailConfirmation: false
});Node-RED Usage
This package includes two Node-RED nodes for easy integration with Commerce7 API:
- commerce7 config: Configuration node for storing API credentials
- commerce7 request: Request node for making API calls
Installation
Install via Node-RED's palette manager:
- Open Node-RED
- Go to Menu → Manage palette
- Click Install tab
- Search for
node-red-contrib-commerce7-api-client - Click Install
Or install manually:
cd ~/.node-red
npm install node-red-contrib-commerce7-api-clientThen restart Node-RED.
Setup
Create a Config Node
- Drag a commerce7 config node onto your flow (found in the
configcategory) - Double-click to configure:
- Name: Give it a descriptive name (e.g., "Commerce7 Production")
- App ID: Your Commerce7 application ID
- App Secret: Your Commerce7 application secret (stored securely)
- Base URL: API base URL (default:
https://api.commerce7.com/v1) - Timeout: Request timeout in milliseconds (default:
30000)
- Click Done
- Drag a commerce7 config node onto your flow (found in the
Create a Request Node
- Drag a commerce7 request node onto your flow (found in the
commerce7category) - Double-click to configure:
- Name: Optional node name
- Config: Select your commerce7 config node (or click edit button to create/edit)
- Tenant: The Commerce7 tenant identifier
- Endpoint: Select from dropdown or enter custom endpoint (e.g.,
customer,club-membership) - Method: HTTP method (GET, POST, PUT, PATCH, DELETE)
- Query Params:
- None: No query parameters
- JSON: Enter query parameters as JSON object (e.g.,
{"limit": 10, "q": "search"}) - msg.params: Use
msg.paramsfrom the incoming message
- Body:
- None: No request body
- JSON: Enter request body as JSON object
- msg.payload: Use
msg.payloadfrom the incoming message
- Click Done
- Drag a commerce7 request node onto your flow (found in the
Available Endpoints
The request node includes a dropdown with common Commerce7 API endpoints:
customer- Customer managementcustomer-address- Customer addressescustomer-credit-card- Customer payment methodsclub- Wine clubsclub-membership- Club membershipsorder- Ordersproduct- Productscollection- Product collectionsdepartment- Departmentscoupon- Couponspromotion- Promotionsgift-card- Gift cardsshipping- Shipping methodstax- Tax configurationsvendor- Vendorsreservation- Reservationsreservation-type- Reservation typesnote- Notestag- Tagswebhook- Webhooksapp- Apps- Custom... - Enter any custom endpoint path
Output
The request node has two outputs:
First output (top): Success responses
msg.payload: API response datamsg.statusCode: HTTP status codemsg.headers: Response headersmsg.pagination: Pagination information (cursor, totalCount) if available
Second output (bottom): Error responses
msg.payload: Error response datamsg.statusCode: HTTP status codemsg.error: Error object with details
Dynamic Configuration
All request parameters can be set dynamically via message properties, which take priority over node configuration:
// In a function node before the commerce7 request node
msg.tenant = "my-tenant-id"; // Override tenant
msg.endpoint = "/customer"; // Override endpoint
msg.method = "GET"; // Override method
msg.params = { limit: 10, q: "john" }; // Query parameters (or use msg.query)
msg.body = { firstName: "John" }; // Request body (for POST/PUT/PATCH)
return msg;Note: For query parameters, you can use either msg.params or msg.query. For request body, you can use msg.body or msg.payload (if body type is set to "msg").
Example Flows
Get Customer List
[inject] -> [commerce7 request] -> [debug]commerce7 request configuration:
- Config: Select your config node
- Tenant:
my-tenant-id - Endpoint:
customer - Method:
GET - Query Params: JSON →
{"limit": 10}
Search Customers Dynamically
[inject] -> [function] -> [commerce7 request] -> [debug]function node code:
msg.tenant = "my-tenant-id";
msg.endpoint = "/customer";
msg.method = "GET";
msg.params = {
q: "john",
lifetimeValue: "gt:100000",
orderCount: "gte:2"
};
return msg;Create Customer
[inject] -> [function] -> [commerce7 request] -> [debug]function node code:
msg.tenant = "my-tenant-id";
msg.endpoint = "/customer";
msg.method = "POST";
msg.body = {
firstName: "John",
lastName: "Doe",
emails: [{ email: "[email protected]" }]
};
return msg;Handle Errors
[inject] -> [commerce7 request] -> [switch]
├─ [success handler] (output 1)
└─ [error handler] (output 2)switch node configuration:
- Property:
msg.statusCode - Rules:
200-299→ Route to success handler400-599→ Route to error handler
Multi-Tenant Support
A single config node can be used with multiple tenants. Simply set the tenant parameter differently in each request node, or use msg.tenant to switch tenants dynamically.
TypeScript Support
The package includes full TypeScript definitions:
import { Commerce7Client, Customer, ClubMembership } from 'commerce7-api-client';
const client = createClient({ /* config */ });
// Typed responses
const response = await client.get<Customer>('/customer/{id}');
const customer: Customer = response.data;
// Typed pagination
const memberships = await client.paginate<ClubMembership>('/club-membership', {}, {
recordTag: 'clubMemberships'
});Configuration Options
interface Commerce7Config {
appId: string; // Required: Your Commerce7 App ID
appSecret: string; // Required: Your Commerce7 App Secret
tenant: string; // Required: Tenant identifier
baseURL?: string; // Optional: API base URL (default: https://api.commerce7.com/v1)
timeout?: number; // Optional: Request timeout in ms (default: 30000)
maxRetries?: number; // Optional: Max retry attempts (default: 3)
}Error Types
Commerce7Error
Thrown for API errors (4xx, 5xx):
class Commerce7Error extends Error {
statusCode: number;
responseData?: any;
responseHeaders?: Record<string, string>;
}Rate Limiting
The client automatically handles rate limiting:
- Detects
429 Too Many Requestsresponses - Checks for
Retry-Afterheader - Automatically retries after the specified delay
- No manual retry logic needed
Browser Support
This package is designed for Node.js environments. For browser use, you'll need to:
- Use a bundler (webpack, rollup, etc.)
- Provide polyfills for Node.js built-ins (Buffer, etc.)
- Consider CORS restrictions
License
MIT
