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

A £300 order can be riskier than a £3,000 order. Should approval depend on basket value alone?

How we connected Medusa purchase approvals to property and GL budgets, external spend, marketplace spend and the current order—not basket value alone.

We Are Souk article cover: A £300 order can be riskier than a £3,000 order. Should approval depend on basket value alone?
Souk EngineeringCommerce architectureAug 2026·10 min read
Key takeaways
  • Most purchasing approval systems begin with one rule: if the order exceeds a fixed amount, send it to a manager.
  • That rule is easy to explain, but it misses the situation procurement teams actually manage.
  • That was the client problem on a B2B procurement marketplace built with Medusa.
  • We extended the approval decision to evaluate the financial context of the purchase.

The client problem

Most purchasing approval systems begin with one rule: if the order exceeds a fixed amount, send it to a manager.

That rule is easy to explain, but it misses the situation procurement teams actually manage. A £3,000 order may fit comfortably inside the property's maintenance budget. A £300 order may push an already exhausted GL account further beyond plan. The first can be routine; the second may deserve attention.

That was the client problem on a B2B procurement marketplace built with Medusa. Buyers purchased for individual properties, allocated lines to general-ledger accounts and worked against budgets that also contained spend from outside the marketplace.

We extended the approval decision to evaluate the financial context of the purchase. For each GL allocation, the platform combines imported budget and external spend, spend already recorded in the marketplace and the value of the current basket. It evaluates both the current month and year to date, then routes approval when the configured overage policy is crossed.

The objective is not to approve more orders. It is to approve the orders that actually change the organisation's risk position.

Basket value answers the wrong question

An amount threshold asks: how large is this transaction?

A budget rule asks: what does this transaction do to the relevant budget?

Those are different questions. A universal £1,000 limit treats every property, GL account and time of year as if they had the same capacity. It ignores whether the buyer is purchasing cleaning supplies, building repairs or safety equipment. It ignores what has already been committed and what the organisation has spent elsewhere.

The result is usually one of two bad extremes.

Set the amount threshold low and managers approve routine purchases all day. Set it high and small but cumulative overspend passes unnoticed.

We kept amount-based routing as a useful general control, but added a budget-aware path for organisations whose spend-management data was enabled. The system can now distinguish transaction size from budget consequence.

Start from the allocation attached to each line

A basket total cannot tell the platform which budget the purchase consumes.

Each relevant cart or quote line carries one or more allocations to GL accounts. The evaluator reads those allocations, ignores invalid or zero quantities and groups the current purchase by GL account.

The amount assigned to an account is calculated from the line's unit price and allocated quantity. Item titles are retained so the approval summary can explain which products contributed to the trigger.

This matters when one order spans several purposes. A single basket might contain routine housekeeping products and an unplanned repair item. The total is one number, but the governance decision belongs to the individual budget lines.

The platform therefore does not ask whether “the cart” is over budget in the abstract. It asks whether each GL allocation changes the monthly or annual position for the active property.

Make property context mandatory

Budgets belonged to properties, not merely to user accounts.

The same buyer could purchase for several sites. The same GL code could have a different available amount at each property. Evaluating the organisation globally would hide local overspend; using the buyer's identity would attach finance rules to the wrong entity.

The evaluator resolves the selected property from the cart, quote or authenticated property context. If allocations exist but no property can be resolved, it does not pretend there is no approval requirement. The budget evaluation fails into an approval path with an explicit evaluation-error reason.

The same protective behaviour applies when an allocation references a GL account that cannot be resolved inside the organisation.

This is important for finance controls: missing context should become visible work, not silent permission. The approver sees that the platform could not establish a safe budget answer and can investigate the underlying property or allocation data.

Combine three views of spend

The projected position has three components.

First, the latest imported spend-management dataset provides the budget and external encumbered spend for the property and GL code. This captures purchasing activity that may have happened outside the marketplace.

Second, the platform queries spend already recorded through its own commerce flows for the same property, GL code and period.

Third, it adds the current allocation being considered.

The formula is deliberately understandable:

projected spend = external spend + marketplace spend + current allocation

This avoids two common errors. Looking only at marketplace orders ignores the wider financial picture. Adding the current basket to an external export that already contains the same marketplace spend would double-count it; the integration contract must define how those sources relate.

In this implementation, the imported source and marketplace query remain visible components of the decision summary, so the trigger can be explained rather than presented as a mysterious risk score.

Evaluate month and year to date separately

An organisation can be healthy annually and still have a serious monthly overspend. The reverse can also happen: a busy month may fit the seasonal plan while year-to-date consumption is running ahead.

The platform evaluates two periods for every GL allocation.

The monthly check uses the active reporting month, including the organisation's configured spend date range where applicable. The year-to-date check covers the calendar year through the current month.

Each period has its own budget, accumulated spend, projected spend and overage calculation. Either period can trigger approval.

The approval summary records the period, year, month or through-month, threshold percentage, budget, each spend component, current allocation and resulting overage.

For an approver, that changes the conversation. Instead of “this order exceeded £1,000,” the request can explain that a particular GL account at a particular property would cross its monthly or year-to-date policy because of the listed items.

Use tolerance percentages, not a brittle zero line

Crossing the budget by one penny does not necessarily require escalation.

The organisation can configure monthly and year-to-date overage percentages. The evaluator first checks whether projected spend exceeds budget. It then calculates the excess as a percentage of that budget and triggers only when the overage is greater than the configured tolerance.

Equality is intentional. If the overage equals the threshold exactly, it does not trigger under the tested rule; it must exceed it.

Different requester levels can also carry different tolerances. In the hierarchy built for this client, buyers use one pair of monthly and annual thresholds, while supervisors and managers can use a broader pair before their own purchase requires further escalation.

This is not a universal role model. The reusable idea is that delegated authority can be expressed through budget tolerance, not only through a larger absolute basket allowance.

Treat missing and zero budgets as explicit conditions

The difficult branch is not a normal positive budget. It is missing budget data.

If no budget exists for a GL code and projected spend is positive, the evaluator creates a trigger with missing_budget. If the budget is zero and the purchase creates spend, it triggers with zero_budget. In both cases, percentage overage is not fabricated because there is no meaningful positive denominator.

If projected spend is zero, those conditions do not create pointless approval work.

This policy is stricter than quietly interpreting missing data as unlimited budget. It also avoids pretending that a zero budget and an unavailable budget mean exactly the same thing. The summary preserves the reason so finance can tell whether it needs to allocate funds or repair an import mapping.

The public lesson is not that every organisation must make the same choice. It is that missing-budget behaviour must be explicit, tested and visible in the approval reason.

Route the approval to the right level

Detecting an overage is useful only if the correct person receives it.

The budget decision returns a required approval together with the GL and period triggers. The wider order-approval module resolves the approval level through the organisation's property and responsibility hierarchy.

For this client, that hierarchy includes buyers, supervisors, property-assigned managers and organisation masters. A buyer's overage can escalate through the responsibility attached to the property rather than going to an arbitrary global inbox. Supervisors and managers are evaluated with their own configured tolerance before a further escalation is required.

The exact role names belong to this marketplace. The architecture pattern is portable: budget policy decides whether approval is needed; delegation policy decides who is authorised to make it.

Keeping those concerns separate makes both rules easier to change.

Store the financial reason with the request

An approval record should preserve why it existed.

The request stores an approval reason such as amount threshold, budget overage or budget-evaluation error. For budget decisions, it also stores the structured summary containing property, periods, thresholds and triggering GL allocations.

That summary can travel into the approval email and buyer or approver interface. The recipient does not have to reconstruct the decision from today's budget screen after spend has changed.

This is especially important for year-to-date calculations. A request created on one date reflects the data and current allocation evaluated at that moment. Saving the reason makes the workflow intelligible during review and later support.

It also prevents every approval from looking identical. A manager can distinguish a high-value exceptional purchase from a modest order that exceeds a depleted maintenance account.

Keep direct purchasing possible

Budget governance should not become a queue for every order.

If a buyer has no GL allocations on the current purchase, the budget evaluator has nothing to assess and does not invent a trigger. If all projected monthly and year-to-date positions remain within tolerance, the budget path returns no required approval for a buyer.

The broader approval policy can still apply an amount threshold where appropriate. For elevated roles, the routing layer can continue evaluating their delegated authority.

This layered design is the commercial point. The platform is not choosing between “approval enabled” and “approval disabled.” It is choosing the narrow reason that makes this purchase exceptional.

Routine orders continue. Budget-impacting orders receive scrutiny. Configuration or data failures become visible instead of being mistaken for permission.

Why Medusa was the right foundation

Medusa supplied the carts, quotes, orders, line prices and extensible workflow layer. It did not automatically know this client's properties, GL allocations, external budget files, approval hierarchy or tolerance policy.

We added those business capabilities around the commerce journey rather than exporting the basket to a disconnected approval form.

The evaluator can inspect the same line allocations and property context that will follow the order. The approval request can retain the cart or quote, shipping and payment context while the organisation decides. Completion routes use the same decision before progressing the purchase.

That is why choosing an extensible commerce engine was an architecture decision. The client did not have to choose between standard commerce primitives and precise procurement governance. We could keep Medusa's transaction model and build the approval rule where the relevant business facts meet.

A practical budget-approval checklist

Before routing purchases from budget state, define these contracts:

  1. Which cart or order lines carry GL allocations?
  2. How is allocation value calculated from quantity and price?
  3. Which property owns the budget decision?
  4. What happens when property context is missing?
  5. Which imported dataset supplies budget and external spend?
  6. Which marketplace states count as internal spend?
  7. How do you prevent source overlap from double-counting?
  8. Are monthly and year-to-date periods both relevant?
  9. What tolerance percentage applies to each period?
  10. Is the threshold inclusive or exclusive?
  11. What do missing and zero budgets mean?
  12. Do different delegated roles receive different tolerances?
  13. Who approves for each property and responsibility level?
  14. Does the request preserve the exact financial trigger?
  15. Does an evaluation failure escalate visibly rather than silently allowing purchase?

These decisions turn a threshold feature into a purchasing-control system.

The broader lesson

The client did not need every large order blocked and every small order waved through.

They needed approval to follow financial consequence.

We connected line-level GL allocations and property context to imported budgets, external spend, marketplace spend and the current basket. Monthly and year-to-date tolerance rules identify the exact accounts that require attention. The approval request preserves the reason and routes it through the organisation's delegation structure.

The result is more precise control with less unnecessary bureaucracy.

A £300 purchase can receive the scrutiny it deserves. A £3,000 purchase can proceed when it remains inside delegated policy. That is the difference between an approval threshold and a procurement 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.