ProductChange instead of writing to the product, so it goes through the same review as an edit from the Vendor panel. Use this when you build your own edit surface, such as a bulk editor or an import.
Before you begin
You need the following in place:- A Mercur server with
@mercurjs/coreinstalled throughwithMercur() - A product id, and the id of the actor making the edit, such as a seller id (
sel_…)
Stage a field edit
productEditUpdateProductWorkflow compares your update with the product and stages one action per field that differs.
1
Create the route
Add a route under The route answers
/admin so Medusa authenticates the caller, and pass the update to the workflow. The workflow returns the staged change.src/api/admin/custom/products/[id]/edit/route.ts
202 because the edit isn’t on the product yet. With the default product_request flag on, result.status is pending.2
Handle an open change
If the same
created_by already has a pending change on the product, the workflow throws a NOT_ALLOWED error before it stages anything. Medusa’s error handler turns it into a 400 response. Cancel the open change with cancelProductChangeWorkflow, or wait for an operator to resolve it.3
Read the staged actions
Load the change with its actions to show the seller what’s waiting for review.Each
UPDATE action carries field, value, and previous_value in details.Stage variant and attribute edits
Variants and attributes have their own edit workflows, with the same pending check.productEditUpdateVariantsWorkflow takes a list of typed operations:
VARIANT_ADD, VARIANT_UPDATE, or VARIANT_REMOVE action. An update whose fields all match the current variant stages nothing. For attributes, pass add, remove, and update arrays to productEditUpdateAttributesWorkflow, in the same shapes as the attribute batch.
Stage actions directly
For a mixed change, build the actions yourself and pass them tostageProductChangeWorkflow. It skips the diff and the pending check, so check for an open change first.
product_id. The workflow fills in product_change_id for you.
Apply an edit without review
Passauto_confirm: true to stageProductChangeWorkflow or productEditDeleteProductWorkflow to confirm and apply the change in the same run. Use it for trusted sources, such as an operator tool. The change still lands in the trail as confirmed, and product-change.confirmed still fires.
Attach custom data with additional_data
productEditUpdateProductWorkflow and productEditUpdateAttributesWorkflow accept additional_data and pass it to their productChangeCreated hook. Use the hook to store your own data on the change:
src/workflows/hooks/product-change-created.ts
product_change is the record the workflow returns.