Overview
Selling to businesses breaks an assumption most storefronts make: that a customer is a person. A business buyer is a person acting for an organization — one that has other buyers, several delivery sites, a VAT number, and a finance team who wants to see everything anyone ordered. A company in Spree models that. And because real organizations aren’t flat, a company can be a tree: a parent with subsidiaries, divisions, regional units, each with its own people and addresses. A node is one of two kinds, and the difference is about tax, not hierarchy:
Trees are capped at five levels, and the root must always be a
company.
Membership covers a subtree
Someone belongs to a company through a membership, and that standing reaches everything below the node — not just the node itself. So a buyer attached to “Acme Europe” can act for Sales and Operations beneath it, without anyone creating three memberships. Give someone standing at the root and they cover the whole group. This is why authorization always asks “does this person have standing on this node or any of its ancestors”, never “is this person a member of exactly this node”.In open source, every member can do everything within their standing — buy, see the subtree’s orders, and manage addresses and members. There are no company roles; the
role label on a membership is cosmetic.To restrict what individual people may do, see company governance below.Adding people
Both the dashboard and the storefront add members the same way — by email:- An existing customer becomes a member straight away.
- An unknown email produces an invitation, valid for 30 days, and an email with a link.
cmem_ for a membership, cinv_ for an invitation.
Accepting an invitation either signs an existing customer in, or registers a new account with the invited email. Either way it ends as a membership:
Buying for a company
A cart and an order can name a company. That’s what turns a personal purchase into a company one — it decides which addresses are on offer, whose tax registration applies, and who else will see the order.The shared address book
A company keeps its own addresses — ship-to sites, a billing address — separate from any individual’s. They’re labelled, and one of each kind can be the default.Addresses inherit downwards
Listing a node’s addresses returns its own entries and the ones it inherits from the nodes above it, so a division can ship to the headquarters site it shares. Writing one stays with the node that owns it: a division can add and edit its own entries, and reads its parent’s without being able to change them. Each entry’sowner names the node it belongs to, so a client can tell inherited entries apart from the node’s own.
Picking an address at checkout
A member buying for their company ships to the company’s sites, not only to their own saved addresses. Set the company on the cart withcompany_id first, then ask the cart which addresses it can use:
shipping_address_id or billing_address_id, so a picker built from it never offers an address the checkout cannot use. A buyer who belongs to a single company still has to set it on the cart: until then, only their own addresses are listed and accepted. An address belonging to anyone else is rejected, and completing the order copies the chosen address onto it, leaving the book entry free to be renamed or retired later.
Each entry carries the owner it is filed under — { id, type, name }, where type is customer or company — so a picker can group and label the two books from one response. An inherited site names the node that owns it rather than the one the cart is for, so a division’s own docks and the headquarters docks it shares are told apart.
Staff placing an order get the same reach: shipping_address_id and billing_address_id on the Admin API’s order creation accept the company’s sites, and use_customer_default_address fills the slots from the company’s defaults when the request names a company with company_id. Without one it takes the customer’s own defaults, even for a buyer who belongs to a single company — prefilling follows what the caller asked for rather than inferring an organization on their behalf.
Tax
Tax registrations and exemption certificates live only on legal entities, and a purchase resolves tax through the node’s nearestcompany ancestor.
active rather than reading its status — a verified certificate stops exempting once it expires, and active accounts for that.
See Taxes for how these reach the tax calculation.
Company governance
Open source deliberately trusts every member equally. That’s the right default for a company of five people, and the wrong one for a company of five hundred — where a junior buyer should not be able to place a £40,000 order, remove their manager, or see what another division spent. Company governance adds that control. It works through the same endpoints and the same data, so nothing about your storefront integration changes when it’s switched on — the calls you already make simply start enforcing.Requires a Spree Enterprise licence
Company roles, order approvals, spending limits and governance audit history are part of Spree Enterprise. See what’s included, or talk to the team about your use case.
Company roles
Where open source has a cosmetic label, Enterprise has real roles built from a fixed set of capabilities:
Roles are data, edited by the company’s own administrator rather than by your staff — the buying organization manages its own structure, which is the point of self-service. Guards prevent someone granting themselves more than they hold.
These are entirely separate from staff roles. A company role never reaches anything belonging to the store.
Order approvals
A member withoutplace_orders submits their basket instead of completing it. Someone with approve_orders reviews and releases it.
Checkout returns a well-known approval_required response rather than a generic failure, so a storefront can show the right message and the right next step. The approval history is append-only — who asked, who decided, when.
Spending limits
Limits are set per member or per node, with a reset period — £5,000 a month for a buyer, £50,000 for a division. They’re enforced at completion, alongside approvals, so an over-limit basket is caught before payment rather than after.Restricted self-service
The same storefront endpoints — the company directory, address book, member management, order history — become capability-gated. A member withoutview_company_purchases sees their own node’s orders and not the group’s; a member without manage_company_members can read the team but not change it.
Nothing about the data model changes. Governance enforces through a policy layer and the checkout validation hooks, over the same companies, memberships and endpoints described on this page. You can build a B2B storefront against open source today and have it work unchanged when governance is enabled.
Managing companies as staff
parent_id. Deleting a node removes its whole subtree, and is refused outright once any order exists beneath it — history doesn’t get deleted to tidy up an org chart.
Each row carries children_count and members_count. children_count is the node’s direct sub-units. members_count is the number of distinct customers holding a membership on the node or on any node below it, so somebody who is a member of both a parent and one of its sub-units is counted once rather than twice.

