UNPKG

@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
# StylusOP V3 API wrapper for NodeJS (Official Module) 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/) ## Installing ```bash $ npm install @stylusapparel/opv3-merchant-api-nodejs --save ``` OR ```bash $ yarn add @stylusapparel/opv3-merchant-api-nodejs ``` ## Basic Usage 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. ## Authentication using Oauth2 (NEW) 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; } ``` <!-- ## Validate Secret Token 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 Order 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 Orders 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 Order Details 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 Order 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 Order 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/Push Order Item 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 Order Activities 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; } ``` ## List Products 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; } ``` ## Get Product Details 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; } ``` ## Get Product Pricing Details 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; } ``` ## Get Product variant 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; } ``` ## Get Product Variant Pricing Details 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; } ``` ## Get Inventory Details 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 All Products Inventories 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 A Product 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 A Product Variant Inventory 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 A Product Variant Inventory By Facility Name 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 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; } ``` ## Get Shipment Details 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; } ``` ## Get Shipment Status 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; } ``` ## COMMON ERROR CODES - **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