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

One company has 200 properties. Which one is actually buying?

How we propagate one authorised property through Medusa catalogue, pricing, delivery and cart state without rewriting historical orders.

We Are Souk article cover: One company has 200 properties. Which one is actually buying?
Souk EngineeringCommerce architectureAug 2026·10 min read
Key takeaways
  • A procurement manager signs into one account and buys for many sites.
  • At the headquarters property, Supplier A can deliver tomorrow.
  • Most commerce platforms understand the customer and the cart.
  • For a multi-property marketplace built on Medusa, we made the active property a first-class input to the buying journey.

The client problem

A procurement manager signs into one account and buys for many sites.

At the headquarters property, Supplier A can deliver tomorrow. At a remote property, that supplier may not deliver at all. One site belongs to a negotiated pricing group. Another has a different budget and approved assortment. The cart being prepared for Property 12 must not silently become a cart for Property 37 because the user changed a dropdown.

Most commerce platforms understand the customer and the cart. They do not automatically understand that the same authenticated customer can act for different operating locations, each with its own commercial context.

For a multi-property marketplace built on Medusa, we made the active property a first-class input to the buying journey. The storefront resolves an accessible site before its catalogue queries run. The Medusa SDK sends that selection with requests. The backend validates and expands it into organisation and geographic context. Catalogue, pricing, delivery and budgets consume the same decision. Cart creation then fixes the property onto the cart.

The selector is visible in the interface. The architecture behind it prevents the rest of the platform from guessing what it means.

The client problem: one identity buys in several operating contexts

The signed-in person is not enough to determine the offer.

A Master may oversee the whole organisation. A Manager may operate several properties. A local Buyer may have access to only one. The same person can switch sites during the day without changing login.

What they can buy depends on the active site. Geography changes deliverability and pickup distance. Property groups can change negotiated prices. Supplier credentialing, exclusions and shopping lists shape the visible catalogue. Budgets and approval rules belong to the property funding the order.

If every feature chooses its own property source, the journey fragments. Search uses the dropdown, pricing uses a stale cart field, delivery uses an address, and budgets use the first property attached to the account.

The client needed one answer to “which site is this buying journey for?” and explicit rules for when that answer becomes durable.

Resolve the selection before the storefront starts shopping

The storefront first fetches the properties accessible to the signed-in customer.

It may find a previously selected ID in browser storage, but persistence is not authority. The stored ID must still exist in the newly fetched accessible set. If it does not, the application falls back to the first available property.

A Master can deliberately choose an all-properties view where the product permits a global scope. Other marketplace roles receive a concrete property. Accountant journeys bypass the shopping-property initialiser because their work uses a different reporting context.

The active property, SDK header and cart store are set before property-scoped dashboard descendants mount. Catalogue hooks therefore issue their first request with a coherent selection instead of briefly loading organisation-wide results and invalidating them afterward.

The first visible catalogue already belongs to the chosen site.

Keep the selection consistent across browser tabs

Procurement users often keep several tabs open.

The active property is retained in browser storage for continuity, and the application listens for storage changes from sibling tabs. When another tab selects a new valid property, the in-memory selection, SDK header and cart context update together.

Property-scoped query keys include the resulting scope, so data for one site does not masquerade as cache data for another.

This is a usability feature with architectural consequences. A header stored once at SDK construction would become stale. A React label updated without the network client would create a storefront that displays Property B while still requesting Property A.

The state transition must update every client-side representation of the current buying context as one product action.

Send a small selector, resolve a rich context on the server

The browser sends the active property ID in an x-property-id request header.

The backend resolves that ID into structured context: property, organisation, country, province, city, postal code, coordinates and the Medusa region associated with the country when available.

Downstream functions do not each need to load and reinterpret the property. They receive a stable request context containing the fields required for catalogue and delivery decisions.

The header itself is not trusted as proof of access. Customer-organisation middleware and route-specific guards verify organisation ownership and member scope on the paths that need it. Some routes require a property. Some allow a Master to omit it for a global view. Others treat it as optional enrichment.

Selection identifies the requested context; server-side membership determines whether the identity may use it.

Make catalogue visibility property-aware

Search results should reflect what the selected site can actually buy.

The Elasticsearch access resolver receives the server-resolved property geography alongside organisation policy. Delivery zones, excluded products, excluded suppliers, credentialed suppliers and supplier-specific shopping lists can be compiled into the discovery query.

When the storefront hydrates product IDs through Medusa, the same organisation-and-property access model guards those known identifiers. A product hidden from the site's catalogue should not reappear merely because its ID was bookmarked.

The property also powers product-to-site distance and delivery eligibility paths. Country, province, city, postal code and coordinates are structured business inputs rather than free-text filters supplied independently by every screen.

Changing the active property can therefore change the catalogue because the commercial reality changed, not because the UI applied a cosmetic category filter.

Resolve the price for the site that is buying

The project supports pricing rules attached to property groups.

For live product hydration, the backend first verifies that the selected property belongs to the authenticated organisation. It then resolves the property groups for that site and passes those IDs into Medusa's calculated-price context.

When no property group applies, the context retains a sentinel that prevents property-scoped price lists from leaking into a generic request.

This gives listing and checkout the same commercial input: the price is calculated for the site represented by the current property context.

A browser cannot claim another organisation's property to obtain its negotiated price. When ownership does not match, price resolution fails rather than quietly falling back to an ambiguous catalogue price.

Use the same context for delivery and funding

Delivery availability is site-specific by definition.

Seller shipping options can be intersected with the active property's geography and region. Free-delivery eligibility can use the same property rather than asking the buyer to enter an unrelated address for every product card.

Funding and controls are site-specific too. Budget, spend, funding-report, quote, shopping-list and approval paths can read the property context when their business action belongs to the active buying journey.

The value is consistency. The product visible in search, the price displayed, the shipping option offered and the budget checked all refer to the same site.

The architecture does not claim every route uses property context. It gives named features one common source where site identity is relevant and lets other journeys define their own scope deliberately.

Fix the property onto the cart at creation

A request header is temporary. A cart is durable.

When Medusa creates a cart, middleware promotes the verified property ID into cart metadata. The value comes from the resolved server context, not an arbitrary property ID supplied in the request body.

That lets later pricing, allocation and checkout logic know which property owns the cart even outside the original browser request.

The property is then protected. Clients cannot mutate metadata.property_id through normal cart updates. A cart mutation carrying a selected property different from the cart's property is rejected.

This prevents a dangerous semantic change: build a cart under Property A's catalogue, price and delivery rules, switch the dropdown to Property B, then continue mutating the same cart as though nothing changed.

Changing shopping context may require selecting or creating the cart that belongs to the new property. The durable resource does not follow the header blindly.

Do not let today's selector rewrite yesterday's orders

Order history has different semantics from catalogue browsing.

If a user switches the active marketplace property, historical orders from other properties should not disappear unless the order screen explicitly asks for that filter. Order detail should be authorised from the order's stored ownership and property, not from whichever site happens to be active in the shopping header today.

The project therefore uses a separate optional order-property filter for history and statistics. The general x-property-id remains the active catalogue and cart context and is deliberately ignored by those order paths.

This is an important architectural boundary. Request context helps create durable business records. Once created, those records carry their own identity.

The property selector answers “where am I buying now?” It does not redefine “where was this order placed?”

Treat global scope as a capability, not a fake property

Some central users need a whole-organisation view.

The application represents that explicitly as all, and only the Master role can retain it for marketplace journeys that support global scope. The backend has guards that allow a Master to omit property context while requiring a concrete property from other roles.

This is cleaner than inventing a synthetic “Head Office” property or selecting the first site and pretending it represents the organisation.

Global scope is not automatically valid everywhere. A cart still needs a property when prices, delivery and ownership require one. A reporting view may legitimately aggregate.

Each route states whether it requires a site, permits a Master global view or does not consume shopping-property context at all.

Why Medusa was the right commerce foundation

Medusa provides products, prices, regions, carts, inventory and order workflows. It does not impose the client's property estate as a generic customer field.

The project extended the request and cart model with the client's operating unit: the property. That context can feed Medusa's existing price calculation, cart metadata and region-aware commerce while custom marketplace modules contribute visibility, budget and approval policy.

We did not build a separate commerce engine per site. We built one engine that can interpret the authenticated buyer within the correct site context.

That is why architecture choice matters. An extensible platform lets the business model become a coherent input across capabilities instead of a collection of storefront workarounds.

An active-property checklist

Before adding a site selector to B2B commerce, ask:

  1. Which properties may this user access?
  2. Is a persisted choice validated against current access?
  3. What is the fallback when the stored property disappears?
  4. Who may use a global scope?
  5. Is the network header set before scoped queries run?
  6. Do query keys separate one property's data from another?
  7. Does the server resolve structured geography and organisation?
  8. Which guard verifies ownership and member scope?
  9. Which catalogue rules consume the property?
  10. Does calculated pricing use the same context?
  11. Do delivery and budgets refer to the same site?
  12. When is the property copied onto the cart?
  13. Can a client overwrite the cart's property?
  14. What happens when the user switches with an existing cart?
  15. Which historical resources intentionally ignore the current selection?

A dropdown is complete only when those lifecycle questions have answers.

The broader lesson

In multi-property commerce, site context is not presentation state.

It influences which suppliers can serve the buyer, which products are visible, which price rules apply, which delivery options are valid and which budget funds the purchase. It must begin with an authorised selection, travel through the request and become fixed on durable resources at the right moment.

For this marketplace, we built one active-property contract across the storefront, Medusa request context and cart lifecycle, while keeping historical orders anchored to their own stored property.

The buyer can switch sites easily. The commerce system never has to guess which site a decision belongs to.

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.