SeriesPart 36 of Building a property procurement platform on MedusaView the cluster →
Medusa & ArchitectureArticle

The buyer returned two units. Which warehouse gets the stock—and which payment should change?

How we connected Medusa returns to seller locations, physical receipt, purchase-order adjustments and provider-aware refunds in a multi-vendor marketplace.

We Are Souk article cover: The buyer returned two units. Which warehouse gets the stock—and which payment should change?
Souk EngineeringCommerce architectureAug 2026·10 min read
Key takeaways
  • A return is often presented as one button: refund the customer.
  • In a multi-vendor procurement marketplace, that button hides several separate decisions.
  • That was the client problem on a marketplace built with Medusa.
  • The buyer request establishes what is coming back and to whom.

The client problem

A return is often presented as one button: refund the customer.

In a multi-vendor procurement marketplace, that button hides several separate decisions. The buyer must return only units that were delivered and have not already entered another return. The parcel must go to a stock location owned by the correct supplier. Inventory should move only when the supplier receives the goods. The financial effect depends on whether the order used a card payment or purchase-order terms, and whether that payment has already been captured.

That was the client problem on a marketplace built with Medusa. We designed the return journey around two connected but distinct facts: physical receipt and financial correction.

The buyer request establishes what is coming back and to whom. The vendor receipt confirms what physically arrived. Only then does the platform update the relevant purchase-order authority or refund target and synchronise the accounting view.

The return remains one business journey without pretending that stock and money are the same event.

Begin with seller ownership

A marketplace order belongs to a seller-specific fulfilment context.

The buyer return workflow verifies that the authenticated customer owns the order and resolves the seller attached to it. Vendor-side return routes independently verify that the authenticated seller owns the return before allowing changes or receipt.

That seller identity drives the rest of the process. It determines which stock locations may receive the goods, which return shipping options are eligible and which vendor may act on the request.

Without this boundary, a generic return endpoint can accidentally send a product back to the marketplace's default warehouse or allow one supplier to inspect another supplier's return.

The rule is straightforward: buyer ownership authorises the request; seller ownership authorises the operational response.

Prevent the buyer from returning the same units twice

An order line can move through delivery and several exception states.

The maximum quantity still returnable is calculated as:

delivered − return requested − return received

The value is never allowed below zero. A line that does not belong to the order is rejected. A line with no remaining returnable quantity is rejected. A request larger than the maximum receives an explicit error.

This protects the platform from a common lifecycle bug: validating a return only against the original ordered quantity. Once units have already been requested or received in another return, the available quantity must shrink.

The return request carries exact line-item identifiers, quantities, optional reasons and notes into Medusa's return workflow. It is not an unbounded instruction to reverse the order.

For the buyer, the interface can present what remains eligible. For the supplier, the incoming parcel is tied to quantities the commerce system recognises.

Resolve the seller's real return destination

“Return to warehouse” is incomplete in a multi-site marketplace.

The seller may have several stock locations and several shipping options. A return option for one location should not route goods to another. A caller-provided location cannot be trusted unless it belongs to the seller.

The return context resolves the seller and its stock locations. When a preferred location is supplied, it must match one of those locations. Otherwise, the implemented default selects the seller's oldest configured stock location deterministically.

The workflow then filters the seller's shipping options for an explicit is_return=true rule and the same fulfilment-set location. If several match, it selects the oldest deterministically and records a warning about the candidates.

If the seller has no configured return option, the platform can create or reuse a zero-amount manual return option scoped to that seller's default location.

The buyer receives a workable return path without the marketplace inventing cross-seller logistics.

Request now, receive later

The buyer request does not immediately add stock back.

The Medusa return is created with receive_now: false. That state reflects the physical truth: the buyer intends to send goods, but the supplier has not confirmed their arrival.

Vendor return operations can review the request, adjust allowed items or shipping context and later confirm receipt. The dedicated receipt route verifies seller ownership before invoking Medusa's receive workflow.

This delay matters for both inventory and finance. Restocking when the label is created would make unavailable goods appear sellable. Reducing a purchase-order amount before receipt would treat an intention as a completed commercial event.

The system waits for the supplier's receipt action. At that point, Medusa records received quantities and applies the physical return behaviour associated with the return location.

The architecture follows the parcel rather than the button click.

Inventory returns to the context that accepted it

Stock needs a location, not merely a positive quantity.

The buyer return was already linked to the seller and resolved stock location. The vendor receipt therefore completes the physical movement in the same context instead of using a global inventory pool.

This is especially important when one marketplace product is sold by several vendors or stocked across several sites. Returning two units to supplier A must not increase the available quantity for supplier B. Returning to one of a seller's locations should not silently restock another.

The return option and location resolution establish where the parcel is expected. Medusa's receive workflow handles the return receipt against that context.

The supported claim is precise: the journey preserves seller ownership and a validated seller stock location through request and receipt. It is not a claim that every warehouse-management scan or inspection outcome is automated.

A purchase-order return changes authority before settlement

Account-term purchasing has a different financial lifecycle from a card charge.

Before a purchase order is locked by later buyer-paid or captured states, receiving returned goods can reduce the amount the platform still authorises for that split order payment.

The adjustment workflow reads the received return items and matches each one to the original order line. The delta is the sum of original unit price multiplied by received quantity. Unknown items contribute nothing.

If the order has a split purchase-order payment in an eligible state, the workflow subtracts that delta from the authorised amount without going below zero. It also updates the associated payment collection amount.

The adjustment occurs after return receipt, not when the buyer merely requests it.

This keeps the amount due aligned with goods the supplier has actually accepted back.

Do not mutate locked payment states

Financial state determines which correction is still legitimate.

The purchase-order authorised amount may be adjusted while the split payment is placed, awaiting validation or validated. Once the flow has progressed into locked states such as buyer paid or captured, the same step becomes a no-op.

That does not mean the return has no financial consequence. It means the consequence must use the appropriate post-capture refund or accounting workflow rather than rewriting prior authorisation.

The adjustment result explains why it skipped: no split payment, zero delta, already adjusted or status locked.

This makes failure modes operationally useful. A support user can distinguish “nothing to adjust” from “the payment has progressed and needs a refund path.”

Commerce systems become safer when state changes are constrained by where the money actually is.

Guard one purchase-order adjustment per return

A receipt endpoint or workflow can be retried.

Without a guard, the same two returned units could reduce the authorised amount twice. The purchase-order payment metadata therefore records a delta under the return identifier.

Before applying an adjustment, the workflow checks whether that return ID already exists in po_adjustments_by_return_id. If it does, the adjustment is skipped as already applied.

The marker also retains the amount associated with each return, making the authorised-value changes inspectable.

This is a narrow idempotency guarantee for the purchase-order adjustment. It does not make the complete multi-step return journey exactly once. Other provider and event operations keep their own contracts.

Narrow guarantees are more useful than broad slogans because they identify the exact retry that cannot duplicate a financial mutation.

Select the refund path from the actual payment

When money has already been captured, the seller may need to issue a refund.

The vendor refund workflow does not assume every order uses the same provider. It loads the order's seller, payment collections, payment identifiers and split purchase-order payment.

First, seller ownership is verified. Then the submitted payment ID must belong to that order. If the order has a captured split payment, the workflow selects the split-order refund path. Otherwise, it invokes Medusa's native payment refund path for the actual payment.

This prevents two dangerous mistakes: refunding a payment from another order and sending a purchase-order settlement through a card-provider workflow.

The route selects the responsible payment mechanism from current order context. It does not claim that every downstream provider behaves identically or that settlement is universally exactly once.

Synchronise the accounting total and document event

Return receipt changes more than inventory and payment authority.

After Medusa confirms receipt, the route runs the purchase-order adjustment and synchronises the platform's accounting total with return_received and the return identifier as its reason.

It also emits a return-received event for asynchronous credit-note document generation. Failure to emit that secondary event is logged without pretending the physical receipt did not happen.

This separation is deliberate. The stock receipt is the primary business action. Purchase-order adjustment, accounting projection and credit-note generation are connected consequences with their own observable results.

The API response exposes the updated return, adjustment result and accounting synchronisation result. Operations can see whether each part progressed instead of receiving one ambiguous success flag.

Why Medusa was the right foundation

Medusa supplied order returns, line quantities, receipt and refund workflows. The marketplace needed seller, location and account-term rules around them.

We added buyer ownership, seller return links, over-return validation, deterministic location and return-option resolution, purchase-order amount adjustment and provider-aware refund selection.

That is the architectural value of an extensible commerce engine. The client did not need separate return software merely because it operated a marketplace or offered purchase-order terms. We could preserve Medusa's transaction lifecycle and express the additional business boundaries where physical and financial context meet.

The platform stays coherent while supporting a return journey that a standard single-vendor card checkout does not automatically provide.

A practical multi-vendor return checklist

Before automating a return, define these contracts:

  1. Does the authenticated buyer own the order?
  2. Which seller owns the returned lines?
  3. How is remaining returnable quantity calculated?
  4. Can prior requested and received returns be counted twice?
  5. Which seller location should receive the parcel?
  6. How is a preferred location validated?
  7. Which shipping option is explicitly a return option for that location?
  8. What happens when no return option exists?
  9. Is stock updated at request or at physical receipt?
  10. Who may confirm receipt?
  11. How is the received-value delta calculated?
  12. Which purchase-order states may still change authorisation?
  13. What marker prevents the same return adjustment twice?
  14. Does the payment ID belong to the order?
  15. Which provider path handles captured split payment versus native payment?
  16. How do accounting totals and credit-note work follow the receipt?

These decisions keep one buyer return from becoming several disconnected corrections.

The broader lesson

The client did not need a refund button attached to every order.

They needed the platform to understand where the goods were, who owned them and what financial state could still be changed.

We connected buyer request, seller ownership, return location and physical receipt. Over-return is blocked. Inventory moves only when goods are received. Purchase-order authorisation is reduced only in eligible states and only once per return. Captured payments use the provider path that actually owns the money. Accounting and credit-note work remain linked to the same event.

For the buyer, it is one return journey. Underneath, each physical and financial decision stays honest.

That is what makes returns dependable in a multi-vendor commerce architecture.

Read next
Keep the useful ideas coming

One practical commerce field note at a time.

Join the WeAreSouk journal for grounded stories about Medusa, Shopify, AI, integrations and the systems behind serious commerce.

Working on a similar problem?Bring us the business constraint. We’ll help map the system behind it.Talk to Souk →
Souk AI · online now

Turn the article into an implementation plan.

Ask how this applies to your store, your stack, or your current bottleneck.

01 Describe your current setup.02 Name the workflow or signal that feels unreliable.03 Get a practical first architecture back.
I can help map this article to your stack. Tell me what you sell, what platform you use, and where the medusa & architecture question hurts.
Continue the cluster

Building a property procurement platform on Medusa

Start a conversation

Tell us what commerce needs to do for your business.

No scheduling maze. Send the context, the constraint or the idea. We will read it and come back to you directly.