How to Edit an Order
In this document, you’ll learn how to create an order edit using the Admin API endpoints.
Overview
The Admin API can be used to edit a customer’s order using the Order Editing feature.
The following changes can be made on an order:
- Add a new item to the original order
- Edit an item’s quantity in the original order.
- Delete an item from the original order.
Medusa then takes care of the calculation of subtotals, taxes, and more.
The Order Edit can then either be confirmed using the Storefront API as a customer, or force-confirmed using the Admin API as a merchant.
The changes are only reflected on the original order once the Order Edit is confirmed.
Scenario
You want to add or use the following admin functionalities related to Order Editing:
- Create an order edit.
- Add, edit, and delete items from an order.
- Revert an item change in an order edit.
- Move order edit into request state.
- Force-confirm an order edit.

You can perform other functionalities related to order editing. To learn more, check out the API reference.
Prerequisites
Medusa Components
It is assumed that you already have a Medusa server installed and set up. If not, you can follow our quickstart guide to get started.
JS Client
This guide includes code snippets to send requests to your Medusa server using Medusa’s JS Client, among other methods.
If you follow the JS Client code blocks, it’s assumed you already have Medusa’s JS Client installed and have created an instance of the client.
Medusa React
This guide also includes code snippets to send requests to your Medusa server using Medusa React, among other methods.
If you follow the Medusa React code blocks, it's assumed you already have Medusa React installed and have used MedusaProvider higher in your component tree.
Authenticated Admin User
You must be an authenticated admin user before following along with the steps in the tutorial.
You can learn more about authenticating as an admin user in the API reference.
Previous Steps
You must have an existing order that you want to edit.
Create an Order Edit
Before you can start making changes to an order, you have to create a new order edit.
To do that, send a request to the Create an OrderEdit endpoint:
- Medusa JS Client
- Medusa React
- Fetch API
- cURL
medusa.admin.orderEdits.create({
order_id, // required
})
.then(({ order_edit }) => {
console.log(order_edit.id)
})
import { useAdminCreateOrderEdit } from "medusa-react"
const OrderEdit = () => {
const createOrderEdit = useAdminCreateOrderEdit()
const handleCreateOrderEdit = (orderId: string) => {
createOrderEdit.mutate({
order_id: orderId,
})
}
// ...
}
export default OrderEdit
fetch(`<YOUR_SERVER>/admin/order-edits`, {
method: "POST",
credentials: "include",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
order_id,
}),
})
.then((response) => response.json())
.then(({ order_edit }) => {
console.log(order_edit.id)
})
curl -L -X POST '<SERVER_URL>/admin/order-edits' \
-H 'Authorization: Bearer <API_TOKEN>' \
-H 'Content-Type: application/json' \
--data-raw '{
"order_id": "<ORDER_ID>"
}'
This endpoint has one required request body parameter order_id
Copy to Clipboard which is the ID of the order this edit is being created for.
This request returns the Order Edit under the order_edit
Copy to Clipboard property.

You can only create one Order Edit at a time. So, if you try to create a new Order Edit for an order that is already being edited, you will receive an error.
Make Changes to an Order’s Items
You can add new items into the original order, edit existing item in the original order, or delete items in the original order.

You can only make changes to items that have not been fulfilled yet in the order.
Add an Item
To add a new item to the original order, send a request to the Add Line Item endpoint:
- Medusa JS Client
- Medusa React
- Fetch API
- cURL
medusa.admin.orderEdits.addLineItem(orderEditId, {
quantity: 1,
variant_id,
})
.then(({ order_edit }) => {
console.log(order_edit.changes)
})
import { useAdminOrderEditAddLineItem } from "medusa-react"
const OrderEdit = () => {
const addLineItem = useAdminOrderEditAddLineItem(orderEditId)
const handleAddLineItem = (quantity: number, variantId: string) => {
addLineItem.mutate({
quantity,
variant_id: variantId,
})
}
// ...
}
export default OrderEdit
fetch(`<YOUR_SERVER>/admin/order-edits/${orderEditId}/items`, {
method: "POST",
credentials: "include",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
quantity: 1,
variant_id,
}),
})
.then((response) => response.json())
.then(({ order_edit }) => {
console.log(order_edit.changes)
})
curl -L -X POST '<SERVER_URL>/admin/order-edits/<ORDER_EDIT_ID>/items' \
-H 'Authorization: Bearer <API_TOKEN>' \
-H 'Content-Type: application/json' \
--data-raw '{
"quantity": 1,
"variant_id": "<VARIANT_ID>"
}'
This request requires the ID of the order edit as a path parameter.
In the body of the request, you pass the two parameters quantity
Copy to Clipboard and variant_id
Copy to Clipboard which will be used to add a new item into the original order.
This request returns the Order Edit object. You can access returned item changes using order_edit.changes
Copy to Clipboard.
Update an Item
You can edit an item’s quantity in the original order.
To update an item, send a request to the Update Line Item endpoint:
- Medusa JS Client
- Medusa React
- Fetch API
- cURL
medusa.admin.orderEdits.updateLineItem(orderEditId, itemId, {
quantity: 2,
})
.then(({ order_edit }) => {
console.log(order_edit.changes)
})
import { useAdminOrderEditUpdateLineItem } from "medusa-react"
const OrderEdit = () => {
const updateLineItem = useAdminOrderEditUpdateLineItem(
orderEditId,
itemId
)
const handleUpdateLineItem = (quantity: number) => {
updateLineItem.mutate({
quantity,
})
}
// ...
}
export default OrderEdit
fetch(`<YOUR_SERVER>/admin/order-edits/${orderEditId}/items/${itemId}`, {
method: "POST",
credentials: "include",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
quantity: 2,
}),
})
.then((response) => response.json())
.then(({ order_edit }) => {
console.log(order_edit.changes)
})
curl -L -X POST '<SERVER_URL>/admin/order-edits/<ORDER_EDIT_ID>/items/<ITEM_ID>' \
-H 'Authorization: Bearer <API_TOKEN>' \
-H 'Content-Type: application/json' \
--data-raw '{
"quantity": 2
}'
This request requires the ID of the order edit and the ID of the item in the original order as path parameters.
In the body of the request, you can pass the quantity
Copy to Clipboard parameter, with its value being the new item quantity. In this example, you change the quantity of the item to 2
Copy to Clipboard.
This request returns the Order Edit object. You can access returned item changes using order_edit.changes
Copy to Clipboard.
Remove an Item
You can remove an item from the original order by sending a request to the Remove Line Item endpoint:
- Medusa JS Client
- Medusa React
- Fetch API
- cURL
medusa.admin.orderEdits.removeLineItem(orderEditId, itemId)
.then(({ order_edit }) => {
console.log(order_edit.changes)
})
import { useAdminOrderEditDeleteLineItem } from "medusa-react"
const OrderEdit = () => {
const removeLineItem = useAdminOrderEditDeleteLineItem(
orderEditId,
itemId
)
const handleRemoveLineItem = () => {
removeLineItem.mutate()
}
// ...
}
export default OrderEdit
fetch(`<YOUR_SERVER>/admin/order-edits/${orderEditId}/items/${itemId}`, {
method: "DELETE",
credentials: "include",
})
.then((response) => response.json())
.then(({ order_edit }) => {
console.log(order_edit.changes)
})
curl -L -X DELETE '<SERVER_URL>/admin/order-edits/<ORDER_EDIT_ID>/items/<ITEM_ID>' \
-H 'Authorization: Bearer <API_TOKEN>'
This request requires the order edit’s ID and the ID of the item in the original order as path parameters.
This request returns the Order Edit object. You can access returned item changes using order_edit.changes
Copy to Clipboard.
Revert an Item Change
A merchant might make a mistake while making a change to the original order’s items. Using the Admin API, you can revert item changes previously created.
To revert an item change, send a request to the Delete Item Change endpoint:
- Medusa JS Client
- Medusa React
- Fetch API
- cURL
medusa.admin.orderEdits.deleteItemChange(orderEditId, changeId)
.then(({ id, object, deleted }) => {
console.log(id)
})
import { useAdminDeleteOrderEditItemChange } from "medusa-react"
const OrderEdit = () => {
const deleteItemChange = useAdminDeleteOrderEditItemChange(
orderEditId,
itemChangeId
)
const handleDeleteItemChange = () => {
deleteItemChange.mutate()
}
// ...
}
export default OrderEdit
fetch(
`<YOUR_SERVER>/admin/order-edits/${orderEditId}/changes/${changeId}`,
{
method: "DELETE",
credentials: "include",
}
)
.then((response) => response.json())
.then(({ id, object, deleted }) => {
console.log(id, object, deleted)
})
curl -L -X DELETE '<SERVER_URL>/admin/order-edits/<ORDER_EDIT_ID>/changes/<CHANGE_ID>' \
-H 'Authorization: Bearer <API_TOKEN>'
This request requires the order edit’s ID and the item change’s ID as path parameters.
This request returns an object with the following properties:
id
Copy to Clipboard: The ID of the deleted object. In this case, it’s the ID of the item change.object
Copy to Clipboard: A string indicating the type of deleted object. In this case, it’sitem_change
Copy to Clipboard.deleted
Copy to Clipboard: A boolean value indicating whether the item change was deleted.
Move into Request State
After an Order Edit is created and all the item changes are added, it must be moved into the request state.
To move an Order Edit into the request state, send a request to the Request Confirmation endpoint:
- Medusa JS Client
- Medusa React
- Fetch API
- cURL
medusa.admin.orderEdits.requestConfirmation(orderEditId)
.then(({ order_edit }) => {
console.log(order_edit.requested_at, order_edit.requested_by)
})
import { useAdminRequestOrderEditConfirmation } from "medusa-react"
const OrderEdit = () => {
const requestOrderConfirmation =
useAdminRequestOrderEditConfirmation(
orderEditId
)
const handleRequestConfirmation = () => {
requestOrderConfirmation.mutate()
}
// ...
}
export default OrderEdit
fetch(`<YOUR_SERVER>/admin/order-edits/${orderEditId}/request`, {
method: "POST",
credentials: "include",
})
.then((response) => response.json())
.then(({ order_edit }) => {
console.log(order_edit.requested_at, order_edit.requested_by)
})
curl -L -X POST '<SERVER_URL>/admin/order-edits/<ORDER_EDIT_ID>/request' \
-H 'Authorization: Bearer <API_TOKEN>'
This request requires the order edit’s ID as a path parameter.
It returns the Order Edit object. You can access the following properties related to the confirmation request:
requested_at
Copy to Clipboard: A timestamp indicating when the request confirmation was created.requested_by
Copy to Clipboard: The ID of the user that requested this order edit.

💡 This request triggers the event order-edit.requested
Copy to Clipboard. You can use a subscriber to send an email to the customer with a link to view the order edit on the storefront. You can learn more in the Events reference.
Force-Confirm an Order Edit
There are two ways to confirm an Order Edit:
- Using the Storefront API, which would confirm the Order Edit as a customer;
- Or using the Admin API, which would force-confirm the Order Edit as a merchant.
Once an Order Edit is confirmed, the changes to the items defined in the Order Edit will be reflected on the original order. So, a change in the totals of the original order, such as the subtotal, will be reflected as well.
This change can lead to either required additional payments from the customer, or a refund to be made to the customer.
When the merchant force-confirms the order edit, however, it bypasses the payment flow. This means that the admin can’t capture any additional payment.
This section covers how the Admin API can be used to force-confirm the Order Edit. You can refer to this documentation to learn how to implement Order Edit confirmation on the storefront.
To confirm an Order Edit, send a request to the Confirm Order Edit endpoint:
- Medusa JS Client
- Medusa React
- Fetch API
- cURL
medusa.admin.orderEdits.confirm(orderEditId)
.then(({ order_edit }) => {
console.log(order_edit.confirmed_at, order_edit.confirmed_by)
})
import { useAdminConfirmOrderEdit } from "medusa-react"
const OrderEdit = () => {
const confirmOrderEdit = useAdminConfirmOrderEdit(orderEditId)
const handleConfirmOrderEdit = () => {
confirmOrderEdit.mutate()
}
// ...
}
export default OrderEdit
fetch(`<YOUR_SERVER>/admin/order-edits/${orderEditId}/confirm`, {
method: "POST",
credentials: "include",
})
.then((response) => response.json())
.then(({ order_edit }) => {
console.log(order_edit.confirmed_at, order_edit.confirmed_by)
})
curl -L -X POST '<SERVER_URL>/admin/order-edits/<ORDER_EDIT_ID>/confirm' \
-H 'Authorization: Bearer <API_TOKEN>'
This request accepts the order edit ID as a path parameter.
It returns the Order Edit object. You can access the following properties related to the order edit confirmation:
confirmed_at
Copy to Clipboard: A timestamp indicating when the order edit was confirmed.confirmed_by
Copy to Clipboard: The ID of the user that confirmed the order edit.
Receive Additional Payment
When the total after the order edit is greater than the total of the original order, the merchant can capture the difference from the customer.
For order edits that are confirmed by the customer, the customer authorizes the payment before confirming it. So, the merchant can capture the payment.
For force-confirmed order edits, as the customer didn’t authorize the payment, the merchant can’t capture the payment. It has to be handled manually by the merchant.

You can learn how to allow customers to authorize payment on the storefront in this documentation.
Capture Payment
If the payment is authorized by the customer, it can be captured by sending a request to the Capture Payment endpoint:
- Medusa JS Client
- Medusa React
- Fetch API
- cURL
medusa.admin.payments.capturePayment(paymentId)
.then(({ payment }) => {
console.log(payment.captured_at)
})
import { useAdminPaymentsCapturePayment } from "medusa-react"
const OrderEditPayment = () => {
const capturePayment = useAdminPaymentsCapturePayment(paymentId)
const handleCapturePayment = () => {
capturePayment.mutate()
}
// ...
}
export default OrderEditPayment
fetch(`<YOUR_SERVER>/admin/payments/${paymentId}/capture`, {
method: "POST",
credentials: "include",
})
.then((response) => response.json())
.then(({ payment }) => {
console.log(payment.captured_at)
})
curl -L -X POST '<SERVER_URL>/admin/payments/<PAYMENT_ID>/capture' \
-H 'Authorization: Bearer <API_TOKEN>'
This request requires the ID of the payment as a path parameter. The payment can be retrieved from the order by accessing the array property order.payments
Copy to Clipboard.
It returns in the response the full Payment object.
Refund Payment
When the total after the order edit is less than the original order total, the merchant can refund the difference to the customer.
To refund the difference to the customer, send a request to the Refund Payment endpoint:
- Medusa JS Client
- Medusa React
- Fetch API
- cURL
import { RefundReason } from "@medusajs/medusa"
// ...
medusa.admin.payments.refundPayment(paymentId, {
amount,
reason: RefundReason.DISCOUNT, // for example
})
.then(({ refund }) => {
console.log(refund.id)
})
import { useAdminPaymentsRefundPayment } from "medusa-react"
import { RefundReason } from "@medusajs/medusa"
const OrderEditPayment = () => {
const refundPayment = useAdminPaymentsRefundPayment(paymentId)
const handleRefundPayment = (amount: number, reason: RefundReason) => {
refundPayment.mutate({
amount,
reason,
})
}
// ...
}
export default OrderEditPayment
fetch(`<YOUR_SERVER>/admin/payments/${paymentId}/refund`, {
method: "POST",
credentials: "include",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
amount,
reason: "discount",
}),
})
.then((response) => response.json())
.then(({ refund }) => {
console.log(refund.id)
})
curl -L -X POST '<SERVER_URL>/admin/payments/<PAYMENT_ID>/refund' \
-H 'Authorization: Bearer <API_TOKEN>' \
-H 'Content-Type: application/json' \
--data-raw '{
"amount": 1000,
"reason": "discount"
}'
This request requires the ID of the payment as a path parameter. The payment can be retrieved from the order by accessing the array property order.payments
Copy to Clipboard.
In the request’s body parameters, the amount
Copy to Clipboard field parameter is required. It is the amount to be refunded.
The reason
Copy to Clipboard request body parameter is also required. Its value is a string that can be one of the following:
discount
Copy to Clipboardreturn
Copy to Clipboardswap
Copy to Clipboardclaim
Copy to Clipboardother
Copy to Clipboard

Check out what other parameters can be sent in the API reference.
It returns in the response the full Refund object.