B2B commerce

Sell to businesses with negotiated, tiered pricing

Pricing resolves by who is buying and how many. Customer groups share a price list, quantity breaks apply within it, and the cart enforces the same one-price-per-line rule it uses for everyone else — so a wholesale account and a walk-in shopper hit the same checkout.

How a B2B price is found

  • Customer groups hold members by email; a customer is priced by the groups they are in.
  • Price lists attach to a group, or to nobody — a list with no group is a launch or seasonal price for everyone.
  • Quantity breaks are rows of variant, minimum quantity and amount. Minimum quantity 1 means any quantity.
  • Priority breaks a tie when two lists cover a line; higher wins. Lists can also carry a start, an end and a channel.
  • Integer minor units throughout — no rounding drift on a 2,000-unit order.

PriceFor(variant, quantity, email) · PriceInChannel(…, channel)

One line, priced once

Customer

member of group: wholesale

group → active lists, by priority

Price list

wholesale, this channel, this quarter

quantity 250 → highest break ≤ 250

Unit price

resolved per line, not per cart

same rule as retail

Cart

integer minor units

Buyers that are systems, not people

A procurement system does not log in. It holds a key.

Where the edge is

What a dedicated B2B platform has that this engine does not, today.

No quotes or approvals

There is no request-for-quote flow and no order approval chain. An order is placed by whoever holds the key or the login.

No net terms

Payment is a payment module or cash on delivery. Credit limits and net-30 terms are not modelled.

Group pricing, not per-contract pricing

A group with one member is per-customer pricing; per-contract terms beyond price are not a concept in the engine.

FAQ

Questions about B2B

How does a wholesale customer get a different price?

Put them in a customer group, then attach a price list to that group. A price list holds rows of variant, minimum quantity and amount; when that customer’s cart is priced, the engine finds the row for the variant whose minimum quantity is highest but not above the quantity ordered. A list with no group applies to everybody, which is how a launch price or a seasonal price is expressed with the same mechanism.

What happens when two price lists both match?

Each list carries a priority and the higher one wins. A list can also be limited to a date window and to one channel, so a wholesale list for one storefront during one quarter is three fields, not a custom rule.

Can a buyer’s procurement system order without a person logging in?

Yes. Create an API key with a role. The key carries that role’s rights, a prefix that identifies it in a log line, its last-used time and a revocation, so an integration is a credential you can inspect and switch off rather than a shared password.

Are invoices generated?

The invoices module issues a numbered invoice for every paid order. It is a module under ext/, so a store that does not need invoices does not compile it in.

What B2B features are not there?

Quote requests, order approval chains, net payment terms and credit limits. None exists in the engine today, and this page will not describe them as if they did. What exists is pricing, machine access and invoicing, which is where most wholesale stores start.

Price lists are rows. Start with one.

Run the stack, create a group and a list from the admin, and price a cart from the API docs.

Chat on WhatsApp