Available for projects & agency overflow · Quick reply, from the person who does the work

Selling B2B: per-account pricing, quotes and credit limits

A trade store looks like a consumer store right up to the moment you look at the price. From there almost everything diverges: who sees which rate, from what quantity, ex-VAT or inc-VAT, and paid when.

Describe my issue Send a message

Price is not a property of the product

In trade selling, price belongs to the triplet customer × product × quantity. In PrestaShop that runs through the specific_price table, which takes an id_group, an id_customer, an id_product_attribute and a from_quantity, with a priority rule deciding which row wins. It is the first thing to check the day a buyer swears they can see a rate nobody ever granted them: there is almost always a more specific row than the one you had in mind.

Then comes display. Ex-VAT or inc-VAT by group, but above all rounding: rounding each line and rounding the total do not produce the same figure, and across an order of several dozen lines the gap eventually shows on the invoice. A trade buyer reconciles their invoices; they will report the penny.

What no CMS handles on its own for trade selling

  • Intra-community VAT number: format check, validation against the European VIES service, automatic exemption when validation succeeds, and above all defined behaviour when the service is unavailable — which happens.
  • Full quote cycle: basket, quote request, sales approval, conversion into an order. None of the three CMS platforms ships it, and it is the development most often asked for on this kind of store.
  • Document generation and revision tracking: a quote gets discussed and amended, every version must stay readable, and conversion must carry the accepted amounts rather than today’s list prices.
  • Deferred payment and credit limits: an order confirmed with no immediate charge, an invoice due later, a ceiling per account and an automatic block beyond it. Checkout must accept a payment method that collects nothing but commits.
  • Pack sizes: the selling unit is not the stock unit. An item is ordered by cases of twelve or by pallet, with enforced multiples and a quantity step applied server-side, not only as an attribute on the input field.
  • Fast entry by product code and basket upload from a file: a buyer who knows the catalogue does not browse categories, they key in codes one after another.
  • Partitioning: some ranges must only appear to certain accounts, and a negotiated rate must never show to a logged-out visitor or leak into a product feed.

How I take over a trade store

  1. Map the pricing rules already in place

    Before touching code I inventory what applies: groups, cart rules, per-account prices, quantity breaks, forgotten validity dates. On a store running for several years that map alone explains a good share of the rates people call inconsistent.

  2. Settle rounding once and for all

    I fix the rounding mode and the number of decimals, apply them from basket to accounting document, then check on a deliberately long order that the displayed, stored and printed amounts agree to the penny.

  3. Make VAT number checking dependable

    The check relies on the European service, with the result cached and an explicit status when it is unreachable. An order must neither sit blocked with no explanation nor be exempted by default when verification could not complete.

  4. Model the quote as its own object

    The quote gets its own states, numbering, revisions, validity date and document. Conversion copies the accepted amounts and locks the lines, so a change in list price never alters a quote already agreed.

  5. Enforce pack sizes server-side

    Quantity step, order minimum and enforced multiple are re-validated on add to basket and again at confirmation. An input field can be bypassed, and an uploaded basket never goes through the interface at all.

Related topics covered elsewhere

Frequently asked questions

Why does a customer see a price I never gave them?
Because a more specific rule applies before the one you have in mind. A price tied to the account beats a price tied to the group, a quantity break can stack with a cart rule, and an expired rule sometimes stays active for want of an end date. Diagnosis means listing every row touching that pair, not just the one you created.
Should prices show with or without VAT?
That is driven per customer group, not globally. One catalogue can show ex-VAT amounts to trade accounts and inc-VAT amounts to consumers, provided the basket, the carriage and the documents follow the same convention end to end.
Does the quote cycle exist as standard?
No, not on PrestaShop, WooCommerce or Shopify. Extensions cover part of the journey, usually the request itself. Sales approval, successive revisions and conversion with locked amounts are development work.
How is a credit limit enforced?
By computing the account’s real exposure at confirmation time — invoices issued and unpaid, orders in progress — then allowing or refusing the deferred payment method on that basis. The message shown has to be understandable, otherwise the sales desk takes the call instead of you.
What if the VAT checking service is down?
That has to be decided in advance. The two defensible options are accepting the order flagged for later verification, or treating it as not exempt and correcting afterwards. What you must not do is exempt without proof or block without a message.
How do I allow ordering by product code?
Through a multi-line entry form taking code and quantity, backed by a file upload. Both paths go through the same validation as normal checkout: the code exists, the account may see it, the multiple is respected and stock allows it.

Describe your need in one minute

A few targeted questions so I can reply with an estimate rather than another questionnaire.

type
existant
stack (facultatif)
utilisateurs (facultatif)
echeance (facultatif)
Please provide an email or a phone number so I can get back to you.

Please provide an email or a phone number so I can get back to you.