15. Refunds & Returns
[← Payments]/14-payments/ · [Index]/00-index/
15. Refunds & Returns
Verified against: Medusa admin dashboard 2.18.0 (order-create-return,
order-receive-return, order-create-refund — source-read directly) and Medusa’s core
workflow logic (@medusajs/core-flows cancel-order.js, cancel-order-fulfillment.js —
read directly, not assumed), plus .ai/features/gst.md.
INFO: Refunds, returns, claims, and exchanges are all standard Medusa capability — nothing here was custom-built for Sindhu Naturals (unlike GST invoicing/credit notes, which are this project’s own addition). They should work as Medusa designed them, but — like the rest of order processing — have never been exercised on a real completed order by this project. Treat the first real one as a chance to validate this section, not routine execution.
Cancellation before shipment
Real, verified mechanics (read directly from Medusa’s cancelOrderWorkflow):
- The order-level Cancel action (top of the order detail page — see [Section 8]/08-order-management/) only succeeds if every fulfillment on the order is already canceled (or none were ever created).
- Canceling automatically cancels any uncaptured payment and refunds any already-captured payment — you do not need to separately run the Refund action after a straight cancellation; it’s part of the same action.
- It also automatically triggers this project’s own GST credit note generation, if an
invoice had been issued for the order (
.ai/features/gst.md— see [Section 16]/16-invoicing/).
If a fulfillment already exists (you clicked Fulfill Items) but hasn’t shipped yet, the order-level Cancel is blocked until you first cancel that fulfillment (a separate action, on the fulfillment itself — real and allowed, as long as it hasn’t shipped). Once the fulfillment is canceled, the order-level Cancel becomes available again.
Cancellation after shipment
IMPORTANT — this is a hard system rule, not a policy choice. Once a fulfillment’s “shipped” timestamp is set, Medusa’s own code refuses to cancel it — the real error message is “The fulfillment has already been shipped. Shipped fulfillments cannot be canceled.” Likewise, a
completedorder cannot be canceled at all — the real error is “Cannot cancel a completed order. Please use the return process to handle refunds or exchanges.”
In practice, there is no true “cancel” after shipment in this system. What the original brief calls “cancellation after shipment” is actually the Return process below, ending in a refund rather than an order-level cancellation.
Return request
Staff-initiated in the admin (there is no customer-facing self-service return request on the storefront today — same gap noted for cancellation in [Section 8]/08-order-management/#order-level-cancellation). On the order, choose Return and fill in, per item:
- Quantity being returned
- Reason — a dropdown sourced from Settings → Return Reasons (see [Section 2]/02-admin-dashboard/#settings); no return reasons have been configured yet for this store
- Note — free text
Plus, for the return as a whole:
- Location — which stock location the returned items go back to (today, only “India Warehouse” exists)
- Inbound Shipping method
- A live summary: Return Total, Inbound Shipping cost, and Estimated Difference (what will ultimately be owed back to the customer)
- Send notification toggle
INFO: Unlike stock adjustments ([Section 5]/05-inventory-management/), a return does capture a real reason and note per item — this is one of the audit-friendly corners of the admin, alongside refunds (below).
Return approval
TO BE CONFIRMED / no distinct system gate exists. There is no separate multi-person “approve this return” screen for a standard Return in this admin — creating and confirming the return is the approval, done by whoever has admin access. (Medusa’s more advanced Claims and Exchanges flows — for sending a replacement item, with or without the original coming back — do exist as separate screens in this admin too, but are out of scope for this section; they’re a different workflow from a plain refund-return.)
Return received
When the returned items physically arrive, open the pending return and use Receive Return. Real fields:
- Items received — quantity actually received back, per line item
- “How many of the items are damaged?” — a separate write-off quantity, per line item
- Outstanding amount — shown automatically, the amount still owed back to the customer
IMPORTANT — verified, not assumed: receiving a return automatically adjusts inventory based on these two numbers. The system’s own description: “we will automatically adjust the inventory levels based on your input above.” Practically, this means a good-condition received quantity is expected to add back to sellable stock, while a quantity marked “damaged” is written off rather than restocked — always fill in the damaged count honestly, or stock levels will silently overstate what’s actually sellable.
Refund processing
Refunds are issued from the order’s Payment section (see [Section 8]/08-order-management/#payment-status-values), via Refund. Real fields:
- Payment — which payment to refund against, if the order has more than one
- Amount — supports a partial refund, not just full
- Refund Reason — a dropdown sourced from Settings → Refund Reasons; none configured yet
- Note — free text
Refund completed
Reflected in the order’s Payment status badge —refunded (full) or partially_refunded
(partial). There is no separate “refund completed” confirmation step beyond the payment status
itself updating.
Business policy — not yet defined
[REFUND POLICY TO BE CONFIRMED] None of the following has been decided by the business as of this wiki being written:
- Return window (how many days after delivery a return is accepted)
- Who bears inbound return shipping cost
- Restocking fees, if any
- Conditions under which a return is refused (e.g. opened/used product — relevant for an edible oil product specifically)
Do not quote a refund/return policy to a customer until this is confirmed — the storefront’s own refund-return page carries the same
[TO BE CONFIRMED]markers for this reason (.ai/next-tasks.md).
[← Payments]/14-payments/ · [Index]/00-index/ · [Next: Invoicing →]/16-invoicing/