> Portal Navigation: > > - Append `.md` to any URL under `https://dev.wix.com/docs/` to get its markdown version. > - Pages are either content pages (article or reference text) or menu pages (a list of links to child pages). > - To get a menu page, truncate any URL to a parent path and append `.md` (e.g. `https://dev.wix.com/docs/sdk.md`, `https://dev.wix.com/docs/sdk/core-modules.md`). > - Top-level index of all portals: https://dev.wix.com/docs/llms.txt > - Full concatenated docs: https://dev.wix.com/docs/llms-full.txt # Method name: createProduct(productInfo: ProductInfo) # Method package: wixStoresBackend # Method menu location: wixStoresBackend --> createProduct # Method Link: https://dev.wix.com/docs/velo/apis/wix-stores-backend/create-product.md # Method Description: Creates a new product. The `createProduct()` function receives a `ProductInfo` object and returns a Promise that resolves to a `Product` object when the product has been created. Creating a product is the first step in the process of enabling visitors to buy your products. After you create a product, you can add choices and variants to the product. > **Notes:** + If you create a product immediately before adding it to the cart, we suggest [setting a timeout](https://developer.mozilla.org/en-US/docs/Web/API/setTimeout) for `"1000"` milliseconds (1 second) before calling [`wix-stores.cart.addProducts()`](https://www.wix.com/velo/reference/wix-stores/cart/addproducts). While this slows down the operation slightly, it also ensures proper retrieval of the newly created product before adding it to the cart. + Do not pass important information from client-side code. Doing so opens a vulnerability that a malicious user can exploit to change information, such as a buyer’s personal details (address, email, etc.) or product price information. To learn more about how to keep your code secure, see [Security Considerations When Working with Wix Code](https://support.wix.com/en/article/velo-security-best-practices#code-visibility). # Method Code Examples: *** Note: do not assume any prop names or enum values other than the ones in the example. ## Create a new product ```javascript /******************************* * Backend code - products.jsw * *******************************/ import wixStoresBackend from 'wix-stores-backend'; export function createProduct(myProduct) { return wixStoresBackend.createProduct(myProduct); } /************* * Page code * *************/ import { createProduct } from 'backend/products'; // ... const myProduct = { "name": "Colombian Arabica", "description": "The best organic coffee that Colombia has to offer.", "price": 35, "pricePerUnitData": { "totalQuantity": 100, "totalMeasurementUnit": "G", "baseQuantity": 1, "baseMeasurementUnit": "G" }, "sku": "Colombian-001", "visible": true, "discount": { "type": "AMOUNT", "value": "5" }, "productOptions": { "Weight": { "choices": [{ "value": "250g", "description": "250g" }, { "value": "500g", "description": "500g" } ] } }, "manageVariants": true, "productType": "physical", "weight": 250, "ribbon": "Organic", "brand": "Coffee Company", "seoData": { "tags": [{ "type": "title", "children": "Colombian Arabica", "custom": false, "disabled": false }, { "type": "meta", "props": { "name": "description", "content": "The best organic coffee that Colombia has to offer." }, "custom": false, "disabled": false } ] } } createProduct(myProduct) .then((product) => { // product created const productId = product._id const description = product.description }) .catch((error) => { // product not created console.error(error) }); /* Example of returned product object * * { * "_id": "3ceafef8-7f07-413b-8f72-0229049fab19", * "_updatedDate": "Mon Feb 15 2021 17:03:18 GMT+0200 (Israel Standard Time)", * "name": "Colombian Arabica", * "description": "The best organic coffee that Colombia has to offer.", * "mainMedia": "wix:image://v1/614034_103e8f4ab0ae4536a38b319d3eb437ed~mv2.png/missing-media.png#originWidth=500&originHeight=500", * "mediaItems": [], * "ribbon": "Organic", * "brand": "Coffee Company" * "currency": "USD", * "price": 35, * "discountedPrice": 30, * "formattedPrice": "$35.00", * "formattedDiscountedPrice": "$30.00", * "pricePerUnit": 0.3, * "formattedPricePerUnit": "$0.30", * "pricePerUnitData": { * "totalQuantity": 100, * "totalMeasurementUnit": "G", * "baseQuantity": 1, * "baseMeasurementUnit": "G" * }, * "inventoryItemId": "c3150107-80f8-bec4-708d-fdd6fb6054e6", * "discount": { * "type": "AMOUNT", * "value": 5 * }, * "trackInventory": false, * "inStock": true, * "additionalInfoSections": [], * "productOptions": { * "Weight": { * "optionType": "drop_down", * "name": "Weight", * "choices": [ * { * "value": "250g", * "description": "250g", * "inStock": true, * "visible": true, * "mainMedia": "null", * "mediaItems": [] * }, * { * "value": "500g", * "description": "500g", * "inStock": true, * "visible": true, * "mainMedia": "null", * "mediaItems": [] * } * ] * } * }, * "productPageUrl": "/product-page/colombian-arabica", * "customTextFields": [], * "manageVariants": true, * "productType": "physical", * "slug": "colombian-arabica", * "seoData": { * "tags": [ * { * "type": "title", * "children": "Colombian Arabica", * "custom": false, * "disabled": false * }, * { * "type": "meta", * "props": { * "name": "description", * "content": "The best organic coffee that Colombia has to offer." * }, * "children": "", * "custom": false, * "disabled": false * } * ] * }, * "variants": [ * { * "_id": "33599a3c-73a6-4532-9786-8d70f096d669", * "choices": { * "Weight": "250g" * }, * "variant": { * "currency": "USD", * "price": 35, * "discountedPrice": 30, * "pricePerUnit": 0.3, * "formattedPrice": "$35.00", * "formattedDiscountedPrice": "$35.00", * "formattedPricePerUnit": "$0.30", * "weight": 250, * "sku": "Colombian-001", * "visible": true * } * }, * { * "_id": "4cf12a28-d493-47b1-8475-f45b043ac683", * "choices": { * "Weight": "500g" * }, * "variant": { * "currency": "USD", * "price": 35, * "discountedPrice": 30, * "pricePerUnit": 0.3, * "formattedPrice": "$35.00", * "formattedDiscountedPrice": "$35.00", * "formattedPricePerUnit": "$0.30", * "weight": 250, * "sku": "Colombian-001", * "visible": true * } * } * ] * } * */ ``` ## Full flow for creating a new product ```javascript /******************************* * Backend code - products.jsw * *******************************/ import wixStoresBackend from 'wix-stores-backend'; export function createProduct(product) { return wixStoresBackend.createProduct(product); } export function addProductsToCollection(product, collection) { return wixStoresBackend.addProductsToCollection(product, collection); } export function addProductMedia(product, mediaData) { return wixStoresBackend.addProductMedia(product, mediaData); } /************* * Page code * *************/ import { createProduct, addProductsToCollection, addProductMedia } from 'backend/products'; $w.onReady(function () { $w("#addProductButton").onClick(async () => { const product = { "name": "Pants", "description": "Straight-legged skinny jeans.", "price": 70, "productOptions": { "Color": { "choices": [{ "description": "Black", "value": "Black" }, { "description": "Blue", "value": "Blue" } ] } }, "manageVariants": true, "productType": "physical", } try { let newProduct = await createProduct(product); // The product was created. Now assign it // to a collection. Convert the product ID // to an array. const newProducts = [newProduct._id]; const collectionId = // get collection ID addProductsToCollection(collectionId, newProducts); // The product was assigned to a collection. // Now let's add media. const option = // get option, such as "Color." Can be undefined. const choice = // get choice, such as "Black." Can be undefined. const src = // get src const mediaData = [{ // add media item to the object src }] // If a choice and option are defined, // addProductMedia() adds media to choice if (choice !== "" && option !== "") { mediaData[0].choice = { choice, option } } addProductMedia(newProduct, mediaData); } catch (err) { // handle the error } }); }) /* Full product object: * * { * "_id": "9a10ada3-...-111c6babc398", * "_updatedDate": "2020-12-30T14:56:45.626Z", * "name": "Pants", * "description": "Straight-legged skinny jeans.", * "mainMedia": "wix:image://v1/1c...1111cc111~mv2.jpg#originWidth=50&originHeight=50", * "mediaItems": [], * "currency": "USD", * "price": 70, * "discountedPrice": 66, * "formattedPrice": "$100.00", * "formattedDiscountedPrice": "$66.00", * "inventoryItemId": "65ef525c-...-43c67", * "discount": { * "type": "AMOUNT", * "value": 5 * }, * "trackInventory": false, * "inStock": true, * "additionalInfoSections": [ ], * "productOptions": { * "Color": { * "optionType": "drop_down", * "name": "Color", * "choices": [ * { * "value": "Black", * "description": "Black", * "inStock": true, * "visible": true, * "mainMedia": "wix:image://v1/1c111c1...1111cc111~mv2.jpg/1c411c1...1111cc111~mv2.jpg#originWidth=50&originHeight=50", * "mediaItems": [ * { * "id" : 0d26de75...5379.jpg, * "src" : wix:image://v1/0d26de75...5379.jpg/file.jpg#originWidth=1000&originHeight=1776, * "description" : , * "title" : , * "type" : Image * } * ] * }, * { * "value": "Blue", * "description": "Blue", * "inStock": true, * "visible": true, * "mainMedia": null, * "mediaItems": [ ] * } * ] * } * }, * "productPageUrl": "/product-page/pants", * "customTextFields": [ ], * "manageVariants": true, * "productType": "physical", * "slug": "pants", * "collections": [e22737a6-...-3fcfd5a"] * "variants": [ * { * "_id": "00000000-...-9aed0d5c3297", * "choices": { * "Color": "Black" * }, * "variant": { * "currency": "USD", * "price": 70, * "discountedPrice": 66, * "formattedPrice": "$70.00", * "formattedDiscountedPrice": "$66.00", * "weight": 1, * "sku": "", * "visible": true * } * }, * { * "_id": "00000000-...-9aed0d5c3297", * "choices": { * "Color": "Blue" * }, * "variant": { * "currency": "USD", * "price": 70, * "discountedPrice": 66, * "formattedPrice": "$70.00", * "formattedDiscountedPrice": "$66.00", * "weight": 1, * "sku": "", * "visible": true * } * } * ] * } * } */ ``` ---