WooCommerce Update Price
Version | Date | Created / Updated | Notes |
---|---|---|---|
v1.0 | 05/27/2025 | Hristiyan Georgiev | Initial version |
When we are doing price updates to WooCommerce, we have to consider two things - are we doing a product price update or variant price update. We have two separate calls for this and we will need to implement internal logic in order to know when to use the correct call.
All trigers, validations etc. are as per our abstraction - Price Update General requirements
Product Price Update
API Call : POST /wp-json/wc/v3/products/batch
API Docs : https://woocommerce.github.io/woocommerce-rest-api-docs/?shell#batch-update-products
We only want to use this call, when the product we are trying to update is NOT part of a variation i.e it is a single product. We could check this by the Listing
> Listing Variation Group
has to be empty.
Please note that we can include up to 100 objects to be updated.
Example call :
{
"update": [
{
"id": 62,
"regular_price": "110",
"sale_price": "99",
"date_on_sale_from_gmt": "2025-05-28T08:09:23",
"date_on_sale_to_gmt": "2025-06-28T08:09:23"
},
{
"id": 74,
"regular_price": "120",
"sale_price": "95"
}
]
}
Mapping :
WooCommerce Field | MCPro Field | Notes | |
---|---|---|---|
update |
Hardcoded as “update” | ||
id |
Listing > Channel Item ID |
||
regular_price |
Listing > RRP |
We need to have a logic and if RRP is empty, we send Price as regular_price and sale_price as empty |
|
sale_price |
Listing > Price |
Please note that it looks like Woo does not have any validations for prices whatsoever, so it is possible that we send sale_price higher than regular_price . They will still return success response but nothing will get updated. We want to have internal validation and if we have Price > RRP , we want to store internal error. |
|
date_on_sale_from_gmt |
Listing WooCommerce > Promotion Date Start |
We need to convert it into an ISO8601 format. We only need to send if both fields are filled. If one or both are not filled, we exclude them BOTH from the payload. | |
date_on_sale_to_gmt |
Listing WooCommerce > Promotion Date End |
We need to convert it into an ISO8601 format. We only need to send if both fields are filled. If one or both are not filled, we exclude them BOTH from the payload. |
Example success response :
{
"id": 62,
"name": "Hoodie with stripes",
"slug": "hoodie-with-stripes",
"permalink": "https://sociable-sable-b1ae91.instawp.xyz/product/hoodie-with-stripes/",
"date_created": "2025-05-20T13:13:22",
"date_created_gmt": "2025-05-20T13:13:22",
"date_modified": "2025-05-27T13:22:49",
"date_modified_gmt": "2025-05-27T13:22:49",
"type": "simple",
"status": "publish",
"featured": false,
"catalog_visibility": "visible",
"description": "<p style=\"text-align: left;\">Hoody very best and ogod</p>",
"short_description": "The best product in the whole world",
"sku": "123321",
"price": "115",
"regular_price": "115",
"sale_price": "",
"date_on_sale_from": null,
"date_on_sale_from_gmt": null,
"date_on_sale_to": null,
"date_on_sale_to_gmt": null,
"on_sale": false,
"purchasable": true,
"total_sales": 5,
"virtual": false,
"downloadable": false,
"downloads": [],
"download_limit": -1,
"download_expiry": -1,
"external_url": "",
"button_text": "",
"tax_status": "taxable",
"tax_class": "",
"manage_stock": false,
"stock_quantity": null,
"backorders": "no",
"backorders_allowed": false,
"backordered": false,
"low_stock_amount": null,
"sold_individually": false,
"weight": "",
"dimensions": {
"length": "",
"width": "",
"height": ""
},
"shipping_required": true,
"shipping_taxable": true,
"shipping_class": "",
"shipping_class_id": 0,
"reviews_allowed": true,
"average_rating": "0",
"rating_count": 0,
"upsell_ids": [],
"cross_sell_ids": [],
"parent_id": 0,
"purchase_note": "",
"categories": [
{
"id": 15,
"name": "Uncategorized",
"slug": "uncategorized"
}
],
"tags": [],
"images": [
{
"id": 63,
"date_created": "2025-05-20T13:13:53",
"date_created_gmt": "2025-05-20T13:13:53",
"date_modified": "2025-05-20T13:13:53",
"date_modified_gmt": "2025-05-20T13:13:53",
"src": "https://sociable-sable-b1ae91.instawp.xyz/wp-content/uploads/2025/05/1715726245686.jpg",
"name": "1715726245686",
"alt": ""
}
],
"attributes": [
{
"id": 0,
"name": "Size",
"slug": "Size",
"position": 1,
"visible": true,
"variation": true,
"options": [
"S"
]
}
],
"default_attributes": [],
"variations": [],
"grouped_products": [],
"menu_order": 0,
"price_html": "<span class=\"woocommerce-Price-amount amount\"><bdi><span class=\"woocommerce-Price-currencySymbol\">$</span>115.00</bdi></span>",
"related_ids": [],
"meta_data": [
{
"id": 248,
"key": "_children",
"value": [
74
]
}
],
"stock_status": "instock",
"has_options": false,
"post_password": "",
"global_unique_id": "",
"permalink_template": "https://sociable-sable-b1ae91.instawp.xyz/product/%pagename%/",
"generated_slug": "hoodie-with-stripes",
"brands": [
{
"id": 24,
"name": "Guma",
"slug": "guma"
},
{
"id": 23,
"name": "Puma",
"slug": "puma"
}
],
"_links": {
"self": [
{
"href": "https://sociable-sable-b1ae91.instawp.xyz/wp-json/wc/v3/products/62",
"targetHints": {
"allow": [
"GET",
"POST",
"PUT",
"PATCH",
"DELETE"
]
}
}
],
"collection": [
{
"href": "https://sociable-sable-b1ae91.instawp.xyz/wp-json/wc/v3/products"
}
]
}
}
Example Error Response :
{
"code": "woocommerce_rest_invalid_product_id",
"message": "To manipulate product variations you should use the /products/<product_id>/variations/<id> endpoint.",
"data": {
"status": 404
}
}
We don’t need to map anything from the success response.If we have errors want to store the error from message
and mark the product as per the abstraction Product Listing general requirements
Variant Price Update
API Call : POST /wp-json/wc/v3/products/{productId}/variations/batch
API Docs : https://woocommerce.github.io/woocommerce-rest-api-docs/?shell#batch-update-product-variations
The {productId}
is our parent id. We pick it from Listing
> Channel Item ID
.
We only want to use this call if we are updating product(s) that is/are part of a variation.
Please note that we can include up to 100 objects to be updated.
The call body is the same as the product price update call. The only difference in mapping is that for id
we want to pick Listing WooCommerce
> Variant ID
The responses and their mapping are the same as the product Price Update call.