# B2B Commerce on GoCommerce — Price Lists, Quantity Breaks

> Tiered B2B pricing on an open-source backend: customer groups, price lists with quantity breaks, scoped API keys, numbered invoices. No quotes or approvals yet.

- Canonical: https://kitcommerce.store/solutions/b2b/
- Last updated: 2026-09-25

---

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.

- **core/pricing.go** groups, lists, resolution
- **core/api_keys.go** scoped keys
- **ext/invoices** numbered invoices

### 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.

- **A key carries a role** — The same rights model the admin uses: 52 granular rights, read and write separately, grouped into roles.
- **A prefix in every log line** — You can tell which integration made a request without the secret ever appearing.
- **Last used, and revoked** — A key records when it last authenticated and who revoked it. Revoked keys stay listed; they just stop working.
- **Idempotent checkout** — A system that retries a timed-out request does not place the order twice.
- **Numbered invoices** — The invoices module issues one per paid order — a module, so opt in.
- **Webhooks out** — Order and payment events delivered to the buyer’s system, or yours, from the webhooks module.

### 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.

[Deploy in minutes](https://kitcommerce.store/#one-command) · [Per-channel pricing](https://kitcommerce.store/solutions/multi-store/) · [Marketplace](https://kitcommerce.store/solutions/marketplace/) · [All solutions](https://kitcommerce.store/solutions/)
