How does one go about creating a new product with variations via the API?
Let's say I want to create a brand new product with 2 types of variation: Size (S, M, L) and Color (Red, Green).
It sounds like to do this, I need to use the SKU endpoint instead of the normal product endpoint. But to create a product SKU, I need to call https://developer.bigcommerce.com/api/stores/v2/products/skus#update-a-product-sku . To call that API, I need a product ID... so clearly I need to make the product first.
To make the product I call https://developer.bigcommerce.com/api/stores/v2/products#create-a-product . I want inventory_tracking=sku, but I get an error on a new product saying I cannot do inventory_tracking=sku without skus being enabled. So I guess I need to make a simple product first and update it later?
So I am trying to do something like this as my workflow
1) Create a new product with inventory tracking = simple
2) Create a new Option for Size via a post to /options
3) Add the values, S, M, L via posts to /options/option id from #2/values
4) Create a new Option for Color via a post to /options
5) Add the values Red, Green via posts to /options/option id from #4/values
6) Post to the skus endpoint 6 times, one per combination of Size / Color. For each I list a SKU, Price, option_value_id, product_option_id
{
"sku": "SKU-RED-SMALL",
"price": 5.00,
"weight": 1.00,
"options": [
{
"option_value_id": id-for-red,
"product_option_id": id-for-color
},
{
"option_value_id": id-for-small,
"product_option_id": id-for-size
},
],
}
7) I go back and update the product inventory_tracking to be SKU
This is the best plan I can figure out to get a single product listed.. but at #6 I am hitting an error "The field 'product_option_id' is invalid." I am guessing it could be because I created an "option" instead of a "product_option", but I do not see a way to create product_options.
Clearly there has to be an easier way? What is the best course to create this single listing with variations via the API?
Hopefully this helps clarify some of the workflow for how you create variants for something like small, medium, large, and red, blue, green. Colors are an option and sizes are an option. Both of these have to be assigned to an option set which is then associated with a product.
Create your option(s).
Create option values associated with the option above.
Create an option set.
Create option set options (associating the option set with the option you created above).
Related
I have a simple Zap that is triggered on a Shopify New Order (with line details) and then creates a new account in a system called Trainerize. Works perfectly, but it is triggered by ANY new Shopify order. I need to trigger the Zap for a specific product in the Shopify order. Is this possible in Zapier, and how would I go about it? It seems you can't talk to Zapier support unless you have a plan, and I don't want a plan if it is not possible!
Yes, it is possible. The exact implementation depends on how you want to identify the specific product. I am listing 2 possible ways
In case, the criteria to identify product is quite simple, you can use Filter by Zap. For example, if you want to identify product by product Id, you can just add a Filter by Zap and add the following conditions.
Line Items Product ID | Text Contains | Your Product ID - 12345
If you have some complex matching condition for your Product, you can also use Code by Zapier to run JavaScript code. To do so, pass the required data as input to code and return output that can be used later to see if the match was found. A simple example that gets LineItems productIds as input.
const TARGET_PRODUCT_ID = 12345;
const productIds = inputData.productIds.split(",");
output = {targetProductFound: false};
productIds.forEach(id => {
// Add more conditions if needed
if(Number(id) === TARGET_PRODUCT_ID){
output.targetProductFound = true;
}
});
return output
Then use Filter to proceed or abort.
Let's say that I'm developing an application about shopping. I have defined the following endpoints, which are quite self-explanatory:
GET /items
GET /items/{item-id}
GET /stores
GET /stores/{store-id}
Now, I want to create another endpoint that displays the price of individual item at different stores. This price information is not included in /items/{item-id} since I don't think it's suitable to be an attribute of item, and getting the list of prices requires a bit more calculation as I cannot return the object directly. I will name the endpoint /items/{item-id}/prices and expect a response like this:
[
{
"store_id": "store_1",
"price": 13.00
},
{
"store_id": "store_2",
"price": 12.99
}
]
I want to extend this further and create another endpoint that returns the price information for all items, but I'm having trouble naming this endpoint. So far I've thought of /items/prices or /items?display=prices but the former might be confusing as it matches with /items/{item-id}, and the latter just.. does not seem to make sense for me.
What is the best name to pick for my endpoint so that it stays consistent with the convention?
For all items pricelist endpoint for a single store, I'd recommend GET /stores/{store-id}/prices or GET /stores/{store-id}/pricelist.
For all items/stores pricelist, I'd use GET /items/pricelist or GET /items/*/pricelist, (both special before /items/{item-id}), which could be store-specified on demand by ?store={store-id}.
Adding prices endpoint to items would make no sense as item itself has nothing to do. It is store's responsibility to dictate the price.
I would suggest renaming stores endpoint to /stores/description/{id} and adding prices subcategory /stores/prices/by-item/{id} and /stores/prices/by-store/{id}.
I would say that for sepecfic item /prices/{store-id}/{item-id}
and for all prices /prices/{store-id}
It is not at all clear to me how to update the price/stock for a listing once it has been created initally using listing->createListing().
To update the stock/price, Etsy's documentation says to call listing->updateInventory(). However, this call requires something called products together with a couple of properties (price_on_property, quantity_on_property and sku_on_property):
listing_id
products*
price_on_property
quantity_on_property
sku_on_property
where:
products is further defined in their documentation as a combination of property_values and offerings which I have no clue about.
listing_id is returned from the call to createListing() initially.
Etsy's footnote about price_on_property, stock_on_property and sku_on_property adds to the confusion:
price_on_property is an array of the property_ids of the properties which price depends on (if any).
quantity_on_property is an array of the property_ids of the properties which quantity depends on (if any).
sku_on_property is an array of the property_ids of the properties
which sku depends on (if any).
The update will fail if the supplied values for product sku and offering quantity and price are incompatible with the supplied values of the "on_property_*" fields.
When supplying a price, supply a float equivalent to amount divided by
divisor as specified in the Money resource.
The products parameter should be a JSON array of products, even if you only send a single product. All field names in the JSON blob should be lowercase.
Taken from https://www.etsy.com/developers/documentation/reference/listinginventory#method_updateinventory
Given that the starting point for adding things for sale on Etsy is just to call createListing() with details of the item that I wish to sell (inc stock quantity and price), I do not understand how to call updateInventory() to update the stock and/or price of this item and so can anybody provide some clarity on this matter please (and yes, I have contacted Etsy developer support, but it might take a while for them to respond).
In python - I assume you have the etsy_api module from github.
Etsy product listings have the following structure:
ListingProduct = {
"price_on_property": [
property_ids
],
"products": [
LIST OF PRODUCT VARIATIONS FOR THIS LIST. IF YOU HAVE NO VARIATIONS
THEN THIS LIST WILL HAVE ONLY 1 PRODUCT.
],
"quantity_on_property": [],
"sku_on_property": []
}
To update prices, you need to send back this ListingProduct model, but with the changes you want. Note
price_on_property is required if you have variations.
sku_on_property is optional if you have different skus for different
variations.
quantity_on_property is optional if you have different quantities on
variations.
The easiest way I have found is to do the following:
Get the listing_id for the product you want to change price on.
Make a call to the inventory URI to get this listing. I'm doing this to avoid having to construct ListingProduct['products']. It has too much going on with it.
listing_id = 'the product's listing_id'
ListingProduct = etsy_api.getInventory(listing_id=listing_id)
ListingProduct['products'] is a list of products for this listing. The size of this list is equal to the number of variations that you have.
Take ListingProduct['products'] and for each variation change the price.
If you take a look at ListingProduct['products'], you will see that the changes that need to be done are,
ListingProducts['products'][0]['offerings'][0]['price'] = NewPrice
If a listing has 2 variations, then change the price on that too
ListingProducts['products'][1]['offerings'][0]['price'] = OtherNewPrice
Once you do this make a call with the data.
data = {
'listing_id': listing_id
'products': json.dumps(ListingProduct['products'])
'price_on_property': 200 #If you have variation
}
etsy_api.updateInventory(**data)
To update the variations for a product in ETSY, you need to use update inventory call from the API (Expecting you are using Etsy module from GitHub).
refer to link https://www.etsy.com/developers/documentation/getting_started/inventory
The data you need to send with this call will include --
array (
products => json_encode($products),
price_on_property =>
quantity_on_property =>
)
price_on_property will include the variation property id provided by etsy
quantity_on_property will be included in case of more than one variation attribute
The products index will include an array of variations with the details --
[0] => (
product_id=> 1234,
property_values" => [
property_id => 500,
property_name => color,
'values => [ green ],
],
offerings" => [
(
price => 200
quantity => 1,
)
)
[1] => and so on...
Property Id will be provided by etsy for variation attributes.
With the legacy API, I can obtain product variant prices for productId 100 with the following:
https://something.com/api/v2/products/100/skus.json
But in the Stencil documentation for Product, there is no price property for a product attribute SKU, and the available properties that are available are limited vs the legacy API.
With product:
"values": [
{
"label": "Hardcover",
"id": 98,
"data": "Hardcover",
"selected": false
},
{
"label": "Paperback",
"id": 100,
"data": "Paperback",
"selected": false
}
],
From what I can gather, the variant pricing is only available via cart.items, but I need to display the prices before the user places an item in the cart.
Is there a way to get product variant pricing/info without using the cart.items object? Thanks!
I'm not aware of a way to do this via a stencil object.
On the product detail page I check if a product has_options, then make ajax calls to the variant URLs to get their prices to create a price range before the user selects their variants. This is pretty necessary when the vendor has huge price differences in variants.
ex.) "From $49.99 - $499.99" instead of "$49.99" default functionality.
I don't have a resolution for category pages as it doesn't make sense to make AJAX requests for each variant of each item on the category page on load. Once Stencil adds support for custom fields on the category page, you could add the child's prices to a parent SKUs custom field and perform some logic for whatever your trying to accomplish.
I don't know when custom fields will be available on the category page but I know they are working on it.
according to the documentation, the Create Shipment method requires the property "items" - an array of the items being shipped, for example:
{
"tracking_number": "EJ958083578US",
"comments": "Ready to go...",
"order_address_id": 1,
"items": [
{
"order_product_id": 15,
"quantity": 2
}
]
}
In our business, a shipment almost invariably contains ALL items from the relevant order.
That being the case, is there a way to create a shipment without listing all items (which would require iterating over the product line-items)? Or, alternatively, a way to include all items by default (without iterating)?
We are simply wishing to automate the process of adding tracking numbers to orders - which (as a manual process) involves uploading a csv with [order_number: tracking_number] - i.e. it self-evidently assumes that all items are being shipped. The API seems not to include that (very sensible) option, but I may be wrong.
From Bigcommerce Support:
There is not a way to add a tracking number without adding a shipment nor a way to default the shipment to include all products. This is a helpful suggestion though that I will be passing on to our Product Team for possible implementation into future versions of the API.
Unfortunately for now it is necessary that you GET to the products subresource of an order and iterate over all of the products to pull their 'id' values and 'order_address_id' values so you can generate your POST request to the shipment subresource. It is not necessary to make a GET request to the shipping address subresource directly unless you want the details of that shipping address. It is also not necessary to make a GET request to the base order object unless you want details found there or you are looking to automate the process of checking for orders ready to ship.
So assuming you know an order ID that you want to ship it should only take 2 requests total to both GET the products subresource and then POST to the shipment resource.