@stylusapparel/opv3-merchant-api-nodejs
Version:
This is the official NodeJs wrapper for connecting to the StylusOP API V3
563 lines (459 loc) • 17.4 kB
Markdown
A NodeJS wrapper for connecting to the Stylus order processing system using an authenticated token provided by Stylus. You can view the full documentation of StylusOP Merchant APIs [here](https://stylusopapiv3-staging.stylusapparel.com/api-docs/)
```bash
$ npm install @stylusapparel/opv3-merchant-api-nodejs --save
```
OR
```bash
$ yarn add @stylusapparel/opv3-merchant-api-nodejs
```
Create a client instance:
```js
const stylusWrapper = require("@stylusapparel/opv3-merchant-api-nodejs");
const stylusClient = stylusWrapper.createClient("YOUR_MERCHANT_ID", "YOUR_API_SECRET_TOKEN",
// client configurations
{
"merchantName": "YOUR_MERCHANT_NAME" // Required, your Stylus-provided merchant name
"sandbox": true, // Optional, enable only for development mode
"apiVersion": "v3", // Optional, by default client connects to the latest API version
"tokenType": "basic" // Optional, you can use JWT token or Basic Auth token. Allowed values: "basic", "jwt". Default is "basic"
}
);
```
Note: If a STYLUSOP_API_URL environment variable is set, it will be used as the API endpoint and the "sandbox" setting will be ignored.
Create an access token (JWT) using the Oauth2 flow. ** This is now the preferred method to authenticate your client instance. **
The access token is valid for 1 hour and can be used to make API requests to Stylus. After the token expires, you will need to create a new one by using the same method.
```js
// Promise-based approach
stylusClient.oauthToken()
.then(accessToken => {
console.log(`Access token: ${accessToken}`);
console.log('Client is authenticated:', stylusClient.isAuthenticated());
})
.catch((error) => {
// Handle error here
handleError(error);
});
// Async/await approach
async function authenticate() {
const accessToken = await stylusClient.oauthToken();
return accessToken;
}
```
Once you have the access token, you can use it to make API requests to Stylus. To verify the token, you can use the `verifyToken` method:
```js
// Promise-based approach
stylusClient.verifyToken()
.then(tokenVerified => {
console.log('Token is valid! \nToken verification response:', tokenVerified);
})
.catch(error => {
console.error(`Error verifying the access token: ${error}`);
// Handle error here
handleError(error);
})
// Async/await approach
async function verifyToken() {
const verifySuccessResponse = await stylusClient.verifyToken();
return verifySuccessResponse;
}
```
<!--
Check the validity of your secret token before connecting to Stylus processing functions:
```js
// Promise-based approach
stylusClient.isTokenValid()
.then((response) => {
console.log("success", response); // true
// Continue...
})
.catch((error) => {
console.log("error", error.errorCode, error.message);
});
// Async/await approach
async function validateToken() {
const response = await stylusClient.isTokenValid();
return response;
}
``` -->
Push an order to Stylus OP API for production:
```js
// Promise-based usage
stylusClient.orders.create({
...orderObject,
})
.then(response => {
console.log("Order created:", response.orderKey);
})
.catch(handleError);
// Async/await usage
async function createOrder(orderObject) {
try {
const response = await stylusClient.orders.create(orderObject);
console.log("Order created:", response.orderKey);
return response;
} catch (error) {
handleError(error);
}
}
```
More information on the format of order object can be view [here](https://stylusopapiv3-staging.stylusapparel.com/api-docs/)
Note: **Store the `orderKey` on your side for future reference when using the Stylus API**
Fetch previous order details based on pagination. If no filter is provided, this will return all orders in descending order:
```js
// Promise-based approach
stylusClient.orders.list({
offset: 0,
limit: 15,
sort: {
field: "createdDate",
order: "asc"
},
filters: {
customerName: 'test',
dateRange: [
"2020-07-03T00:00:00.130Z",
"2020-08-03T00:00:00.130Z"
],
priority: "normal",
status: "printed,shipped"
}
})
.then((orders) => {
console.log("orders", orders); // Array of order objects
})
.catch(handleError);
// Async/await approach
async function fetchOrders(options) {
const orders = await stylusClient.orders.list(options);
return orders;
}
```
Fetch the details of an order by its key:
```js
// Promise-based approach
stylusClient.orders.get("ORDER_KEY") // ORDER_KEY will be got from 'pushOrder' response
.then( (orderDetails) => {
console.log("order Detail",orderDetails); // Order detail object
})
.catch(handleError);
// Async/await approach
async function getOrderDetails(orderKey) {
const orderDetails = await stylusClient.orders.get(orderKey);
return orderDetails;
}
```
Cancel an existing order that has already been pushed to Stylus for production:
```js
// Promise-based approach
stylusClient.orders.cancel("ORDER_KEY", {
"items": [
100001,
100003
],
"cancelReason": "Customer requested chargeback"
})
.then((cancelStatus) => {
console.log("cancel response: ", cancelStatus); // true, when cancellation success
})
.catch(handleError);
// Async/await approach
async function cancelOrder(orderKey, cancelOptions) {
const cancelStatus = await stylusClient.orders.cancel(orderKey, cancelOptions);
return cancelStatus;
}
```
More information on the format of order cancel object can be view [here](https://stylusopapiv3-staging.stylusapparel.com/api-docs/)
Update an existing order that has already been pushed to Stylus for production:
```js
// Promise-based approach
stylusClient.orders.update("ORDER_KEY", orderUpdateObject)
.then((updateStatus) => {
console.log("order updated status", updateStatus);
})
.catch(handleError);
// Async/await approach
async function updateOrder(orderKey, updateObject) {
const updateStatus = await stylusClient.orders.update(orderKey, updateObject);
return updateStatus;
}
```
More information on the format of order update object can be view [here](https://stylusopapiv3-staging.stylusapparel.com/api-docs/)
Update existing or add a new line item to an existing order that has already been pushed to Stylus for production:
```js
// Promise-based approach
stylusClient.orders.updateItems("ORDER_KEY", orderItemsUpdateObject)
.then((updateStatus) => {
console.log("order item updated status", updateStatus);
})
.catch(handleError);
// Async/await approach
async function updateOrderItems(orderKey, orderItemsUpdateObject) {
const updateStatus = await stylusClient.orders.updateItems(orderKey, orderItemsUpdateObject);
return updateStatus;
}
```
More information on the format of order update object can be view [here](https://stylusopapiv3-staging.stylusapparel.com/api-docs/)
Fetch the activities of an order by its key
```js
// Promise-based approach
stylusClient.orders.activities("ORDER_KEY")
.then((activities) => {
console.log("order activities", activities); // Array of order activity objects
})
.catch(handleError);
// Async/await approach
async function getOrderActivities(orderKey) {
const activities = await stylusClient.orders.activities(orderKey);
return activities;
}
```
Perform full/partial text-based search for your products by title, name, or SKU code. If no search value is provided, it will fetch all products:
```js
// Promise-based approach
stylusClient.products.list({
offset: 0,
limit: 15,
search: 'leggings',
filters: {
productIds: ['MERMTN1a70', 'MERMTN1a71'],
enabled: true,
decorationMethods: 'dtg',
},
sort: {
field: 'createdAt',
order: 'asc',
}
})
.then((products) => {
console.log("products", products);
})
.catch(handleError);
// Async/await approach
async function listProducts(options) {
const products = await stylusClient.products.list(options);
return products;
}
```
Fetch the details of an product by its id:
```js
stylusClient.products.get("PRODUCT_ID")
.then( (product) => {
console.log("Product", product); // Product details object
})
.catch(handleError);
// Async/await approach
async function getProductDetails(productId) {
const product = await stylusClient.products.get(productId);
return product;
}
```
Fetch the details of an product pricing by product id:
```js
stylusClient.products.pricing("PRODUCT_ID")
.then( (pricing) => {
console.log("Product Pricing",pricing); // Product pricing object
})
.catch(handleError);
// Async/await approach
async function getProductPricing(productId) {
const pricing = await stylusClient.products.pricing(productId);
return pricing;
}
```
Fetch the details of an product variant by variantid or variant sku:
```js
stylusClient.products.variants.get("VARIANT_ID | VARIANT_SKU")
.then( (productVariant) => {
console.log("Product Variant",productVariant); // Product variant object
})
.catch( (error) => {
console.log("error",error.errorCode,error.message,error.status);
});
// Async/await approach
async function getProductVariant(variantIdOrSku) {
const productVariant = await stylusClient.products.variants.get(variantIdOrSku);
return productVariant;
}
```
Fetch the details of an product variant pricing by variantid or variant sku:
```js
stylusClient.products.variants.pricing("VARIANT_ID | VARIANT_SKU")
.then( (variantPricing) => {
console.log("Product Variant Pricing", variantPricing); // Product variant pricing object
})
.catch(handleError);
// Async/await approach
async function getProductVariantPricing(variantIdOrSku) {
const variantPricing = await stylusClient.products.variants.pricing(variantIdOrSku);
return variantPricing;
}
```
Fetch the inventory details by inventory id or inventory sku:
```js
stylusClient.inventory.get("INVENTORY_ID | INVENTORY_SKU")
.then( (inventory) => {
console.log("inventory",inventory); // Inventory detail object
})
.catch(handleError);
// Async/await approach
async function getInventoryDetails(inventoryIdOrSku) {
const inventory = await stylusClient.inventory.get(inventoryIdOrSku);
return inventory;
}
```
List inventories of all products:
```js
// Promise-based approach
stylusClient.inventory.products({
offset:0, // optional, offset value for pagination implementation
limit:15, // optional, if not provided fetch all matching result
sort: {
field: 'createdAt', // optional, Allowed values: 'createdAt' | 'updatedAt'
order: 'asc', // optional, Allowed values: 'asc' | 'desc'
}
})
.then( (inventories) => {
console.log("inventories",inventories); // Array of products
})
.catch(handleError);
// Async/await approach
async function listAllProductsInventories(options) {
const inventories = await stylusClient.inventory.products(options);
return inventories;
}
```
List inventories of a product by productId:
```js
// Promise-based approach
stylusClient.inventory.product("PRODUCT_ID")
.then( (inventories) => {
console.log("Product Inventories",inventories); // Array of products
})
.catch(handleError);
// Async/await approach
async function listAProductInventories(productId) {
const inventories = await stylusClient.inventory.product(productId);
return inventories;
}
```
List inventory of a product variant by variantid or variant sku:
```js
// Promise-based approach
stylusClient.inventory.variant("VARIANT_ID | VARIANT_SKU")
.then( (inventory) => {
console.log("Variant Inventory",inventory); // Array of products
})
.catch(handleError);
// Async/await approach
async function listAProductVariantInventory(variantIdOrSku) {
const inventory = await stylusClient.inventory.variant(variantIdOrSku);
return inventory;
}
```
List inventory of a product in a facility variant by variantid or variant sku:
```js
// Promise-based approach
stylusClient.inventory.variant("FACILITY_NAME", "VARIANT_ID | VARIANT_SKU")
.then( (inventory) => {
console.log("Variant Inventory",inventory); // Array of products
})
.catch(handleError);
// Async/await approach
async function listAProductVariantInventory(facilityName, variantIdOrSku) {
const inventory = await stylusClient.inventory.variant(facilityName, variantIdOrSku);
return inventory;
}
```
List all shipments:
```js
// Promise-based approach
stylusClient.shipments.list({
offset:0, // optional, offset value for pagination implementation
limit:15, // optional, if not provided fetch first recent 100
status: 'in_transit', //optional, Allowed values: 'unknown', 'pre_transit', 'in_transit', 'out_for_delivery', 'delivered', 'available_for_pickup', 'return_to_sender', 'failure', 'cancelled', 'error', 'voided', 'voided_and_refunded', 'awaiting_payment', 'awaiting_shipment', 'shipped', 'on_hold', 'pending_fulfillment'
trackingNumber: 123433, // fetch shipment based on a tracking provided
shipDate: '2024-04-29T18:46:44.000Z' | ['2024-01-24T18:46:44.000Z', '2024-042-27T16:22:44.000Z'], // optional, fetching shipments based on dates. Support as array of start and end date as well as a single date
orderRefId: '2344sdc4342323sa43' // optional, fetch all shipments of an order
sort: {
field: 'createdAt', // optional, Allowed values: 'createdAt' | 'shipDate'
order: 'asc', // optional, Allowed values: 'asc' | 'desc'
}
})
.then( (shipments) => {
console.log("shipments",shipments); // Array of shipments
})
.catch(handleError);
// Async/await approach
async function listAllShipments(options) {
const shipments = await stylusClient.shipments.list(options);
return shipments;
}
```
Fetch the shipment details by shipment id:
```js
stylusClient.shipments.get("SHIPMENT_ID")
.then( (shipment) => {
console.log("shipment",shipment); // shipment detail object
})
.catch(handleError);
// Async/await approach
async function getShipmentDetails(shipmentId) {
const shipment = await stylusClient.shipments.get(shipmentId);
return shipment;
}
```
Fetch the shipment status by shipment id:
```js
stylusClient.shipments.status("SHIPMENT_ID")
.then( (status) => {
console.log("shipment status",status);
})
.catch(handleError);
// Async/await approach
async function getShipmentStatus(shipmentId) {
const status = await stylusClient.shipments.status(shipmentId);
return status;
}
```
- **TOKEN_MISSING** - Secret token is missing in client configuration
- **MERCHANT_MISSING** - merchantName is missing in client configuration
- **VERSION_ISSUE** - The apiVersion provided in the client configuration is not valid/supported
- **TOKEN_EXPIRE** - Your token has expired and cannot access Stylus service(s)
- **TOKEN_INVALID** - Your token is not valid or you don't have access to Stylus service(s)
- **UNKNOWN_ERROR** - Error occurred due to internal connectivity issues on Stylus's side
- **PAGINATION_LIMIT_ERROR** - An unprocessable value was passed for 'limit' in the 'getOrders' function
- **ORDER_ID_INVALID** - An invalid order ID was passed to 'getOrder', 'updateOrder', or 'cancelOrder' function
- **ORDER_PAYLOAD_INVALID** - An invalid order payload was pushed to Stylus for order creation
- **ORDER_PRODUCT_INVALID** - Order payload contains item(s) that are not mapped to Stylus
- **ORDER_ITEM_PROPERTY_INVALID** - Order payload contains item(s) with properties unknown to Stylus
- **ORDER_DUPLICATE** - Same order was pushed again or order contains item numbers from a previous order
- **ORDER_STATUS_ISSUE** - Attempted to change the status of an order that is already in a non-updatable status (e.g., trying to cancel an order that is already printed/shipped)
- **PRODUCT_NOT_FOUND** - Product not found in our database or not found under the client's account
- **PRODUCT_VARIANT_NOT_FOUND** - Product variant not found in our database or not found under the client's account
- **INVENTORY_NOT_FOUND** - Inventory details not found
- **SHIPMENT_NOT_FOUND** - Shipment details not found