Skip to content
All writing

Pricing rules that change per customer, per region, per week

In distribution, the difficulty in pricing is never the arithmetic. It is resolution order, effective dates and the fact that every price is a promise somebody made to somebody else.

Delivery3 min read

On a distributor portal we built for Modern Houseware, a household goods importer in North America, the same product can carry a different price for every dealer looking at it. Contract tier sets a base. A regional scheme adjusts it. A promotion runs for eleven days. One dealer has an override agreed by a sales manager in a phone call last spring. All of that resolves while the page is loading.

4,000+

Products in a single distributor catalogue, each priceable per dealer

Teams new to this picture a hard calculation. The calculation is addition and multiplication. The difficulty sits in two places the specification rarely mentions: which rule wins when several apply, and as of when each rule was true.

Resolution order is the actual specification

Rules arrive on three axes. Who the buyer is: contract, dealer tier, group membership, credit status. Where they are: region, tax treatment, freight zone, currency. When it is: promotion windows, contract effective dates, price-list versions, and the correction somebody applies retroactively in March for a period in January.

Any real catalogue produces cases where three or four rules apply at once, and the business has a firm opinion about which should win. That opinion is rarely written down, because until now it lived in the head of whoever handled the account. Getting it out is a commercial exercise rather than an engineering one, and it is the highest-value week on this kind of programme.

The pattern that has held up for us is a single ordered pipeline: one place where rules are evaluated, in a declared order, producing a number together with a trace of which rules fired and which were beaten. Everything else in the estate asks that component for a price and gets the explanation with it.

Keep it out of the checkout path

Evaluating twenty rules per line item while a dealer waits is how a catalogue with four thousand products becomes slow at exactly the moment it matters. It also makes the price awkwardly non-deterministic: a promotion expiring between the basket page and the confirmation page produces a support call that takes an hour to explain.

The separation that works is to resolve prices ahead of the request and cache them with an explicit validity window, so the checkout path performs a lookup rather than an evaluation. A price served from that cache carries the timestamp of its resolution and the version of the rule set behind it. Once the basket is confirmed, all three are frozen onto the order line. The number alone is not enough, because the dispute does not arrive today.

Six months later, with a printed invoice

The question that eventually arrives is always the same. A dealer has an invoice, believes the price is wrong, and wants to know how it was reached. If the system can only say what the price is today, the answer takes two people three days and ends in a goodwill credit. If the order line records the inputs and the rule set version, it takes ten minutes.

So pricing rules should be versioned and immutable rather than edited in place. Changing a rule creates a new version with an effective date; the old version stays queryable forever. It costs a little storage and one extra join. It removes an entire category of argument that has no engineering resolution, only negotiation.

Build the exception properly

There will be overrides. Somebody senior will agree a number with a large customer, outside every rule, and the system has to carry it. Teams that treat this as a failure of the model end up with the override living in a spreadsheet on a sales director's laptop, applied by hand at invoicing, invisible to every report the business runs.

Model the override as a first-class object instead: it has an owner, an approval, a reason, a scope and an expiry date. Expiry matters most. Without one an override becomes permanent by accident, and after a few years a meaningful share of revenue is priced by decisions nobody can explain. We have walked into estates in that condition, and untangling it is a commercial problem by then.

A pricing engine is a record of promises people made to other people, most of them verbally, some years ago. Treating it as a calculation is what makes it hard. Treating it as an auditable record of commitments, with dates on everything, is what makes it maintainable by whoever picks it up next.

Talk to our engineering team

Tell us what you need built, modernised or maintained. We will tell you whether we are the right firm for it and what it costs.