A customer disputes their total and asks why. Can your system answer?
Only if it recorded which rules fired, in what order, against which lines, at the moment of the order. Recomputing today gives a different answer because prices and campaigns have moved, so the price becomes unexplainable exactly when someone needs it explained.
What the interviewer is scoring
- Does the candidate record the applied rules at order time rather than recomputing
- Whether line-level attribution is proposed and the returns consequence is named
- That resolution order and exclusivity are treated as configuration with an audit trail
- Whether a simulator is raised as the way to make an unpredictable engine safe
- Does the candidate connect explainability to a legal or conduct requirement
Answer
Recomputing is not answering
The tempting implementation is to re-run the pricing engine against the order and show the result. It does not work, and the reason is worth stating plainly.
Prices change. Campaigns start and end. Rules get edited. Recomputing an order from March against today's configuration produces a number that is correct for today and has nothing to do with what the customer was charged. If it happens to match, you have learned nothing; if it does not, you cannot tell whether the original was wrong or the world moved.
So the price has to be explained from a record made at the time, not reconstructed. That single requirement determines most of the design.
Record the resolution, not just the result
What gets stored with the order is not a total and a discount. It is the sequence of decisions that produced them.
Order ORD-77120, priced 2026-03-14T10:22:41Z, engine config v148
line 1 SKU-2201 qty 3 list 20.00 each = 60.00
rule PROMO-BUY3PAY2 (multi-buy) -20.00 applied to line
rule CODE-SPRING10 (10% basket) n/a excluded by PROMO-BUY3PAY2
line 2 SKU-8890 qty 1 list 45.00 = 45.00
rule CODE-SPRING10 (10% basket) -4.50 applied to line
basket subtotal 105.00 discount 24.50 total 80.50
coupon SPRING10 consumed, 1 of 1 uses for customer C-4471
Three things are being captured that people leave out. Which rules were considered and rejected, with the reason — "excluded by" is the answer to "why didn't my code work", which is the most common contact of all. The engine configuration version, so the rule definitions themselves are recoverable. And the discount attributed per line, which is the next section and the one with real money attached.
Line-level attribution, because of returns
Recording a single basket-level discount is easier and is wrong, and the reason is not tidiness — it is that returns become uncomputable.
Basket: 3 shirts at 20.00, promotion "buy three, pay for two"
Charged: 40.00
Customer returns one shirt. What is the refund?
Naive refund 20.00, leaving 2 shirts for 20.00 total.
The promotion is still applied to a basket that no longer
qualifies, and the customer has two shirts for the price of one.
Correct the remaining 2 shirts do not qualify, so they cost 40.00.
The customer already paid 40.00, so the refund is 0.00.
Neither number is obtainable from a basket-level total. You need to know how much discount each line carried and whether the promotion's condition still holds after the return, which means the promotion's qualifying condition has to be stored alongside the attribution rather than inferred.
The generalisation is that a return does not reverse a payment, it unwinds a priced basket — and unwinding requires the pricing to have been recorded at the granularity the return operates on.
Order and exclusivity are configuration, and they are contested
Once there is more than one campaign, the outcome depends on decisions nobody made explicitly.
Does a percentage off a category apply before or after a basket-threshold amount? Can a multi-buy and a coupon both apply to the same line? If two campaigns are eligible and mutually exclusive, which wins? Is the customer entitled to the best available combination, or to the first that matched?
These have real money attached and no default is neutral. They belong in configuration with an owner and an effective date, not in the order the rules happened to be evaluated, and the resolution order should appear in the record above so that a dispute about the outcome is a dispute about a stated rule.
The answer to "who decides" is a pricing or trading function, not engineering. What engineering owes them is that the decision is expressible and visible.
A simulator is what makes it safe
Once a promotion engine has grown teeth — stacking, priority, per-customer limits, exclusions, date windows — nobody can predict what a configuration will do, including the person who wrote it. Rules interact, and the interactions are where the expensive mistakes live: the combination that takes a basket to zero, the code traded on a deals forum faster than you can revoke it.
The mitigation is a simulator: run a proposed configuration against a corpus of real historical baskets and report what would change. It answers the question a merchandiser cannot otherwise answer — what does this actually do — before it is live rather than after, and it catches the interaction nobody imagined because the corpus contains baskets nobody imagined.
The same corpus doubles as a regression suite, in the way a rating engine's replay corpus does in insurance. A change aimed at one campaign that moves the price of an unrelated one is caught by a failing comparison rather than by a customer.
Why this is not optional
Worth naming the driver, because it explains why the effort is funded. An unexplainable price is a problem in three separate directions: a customer service agent who cannot tell someone why they were charged, a finance team that cannot reconcile discount spend to campaigns, and — where a promotion was advertised on particular terms — a conduct question about whether the customer got what was offered.
Being able to produce the block at the top of this page, for any order, from a support screen, is the deliverable.
Prices and campaigns move, so an order's price can only be explained from what was recorded when it was placed. Store the rules that fired, the ones that were excluded and why, and attribute every discount to a line.
Likely follow-ups
- Why can you not just re-run the pricing engine against the order?
- The customer returns one of three items in a multi-buy. What do you refund?
- Two campaigns overlap and both are eligible. Who decides which applies?
- How would a merchandiser find out what a new rule will do before it goes live?
Related questions
- Your promotions engine lets two discounts stack when it should not. How do you fix it and stop it recurring?hardAlso on promotions and pricing6 min
- A shopper adds items on their phone while logged out, then signs in on a laptop where they already had a cart. What should happen?mediumAlso on pricing4 min
- How would you build a rating engine, and how do you reproduce a quote you gave someone eighteen months ago?hardAlso on pricing5 min
- How would you price a feature that no customer asked for?hardAlso on pricing6 min
- Marketing want to raise the price of a plan a million subscribers are already on, and change what it includes. What has to happen in the catalogue?hardAlso on pricing5 min
- How do you size and price an engagement when the scope is still uncertain, and what do you do when you are told to cut the number?hardAlso on pricing7 min
- The monthly bill run dies two thirds of the way through and the cycle closes tomorrow. What do you do?hardSame kind of round: scenario5 min
- A corporate action is confirmed with an effective date in the past, after you have already struck positions and sent statements. How does your system cope?hardSame kind of round: design5 min