A brass price token follows a continuous green path from products through a shopping basket and checkout to a sealed parcel.
Product

How a signed price survives the journey from product page to order

Follow a signed basket price through checkout and order management, including what happens when its products, promotions or validity change.

Chris KelletDirector, Kedos Consulting
6 min read

A shopper sees a price on a product page, adds the product to a basket and places an order. That sounds like one continuous action. In a headless commerce stack, it is usually several systems passing numbers between them: the storefront, the cart, checkout, payment and the order management system.

The practical question is not simply whether each system can fetch a price. It is whether the system taking payment can prove that the basket in front of it is the same basket the pricing engine approved.

Badger Pricing answers that question by returning a signed record with the basket quote. Checkout can verify the record without calling the pricing service again. If an item, quantity or price has changed, the record no longer matches and the basket must be priced again. The final signed record then travels with the order, leaving a verifiable account of what was quoted and charged.

Why passing the total is not enough

Suppose the pricing engine calculates a basket after applying a price list, a promotion and tax. The storefront receives the result and displays it. At checkout, another service receives the same line items and a total.

That total is only a number. On its own, it cannot tell checkout:

  • which pricing engine produced it;
  • which products and quantities it covered;
  • which promotions contributed to it;
  • whether it is still valid; or
  • whether anything changed after the quote was issued.

One response is to call the pricing engine again at every boundary. Repricing is necessary when the basket changes, but repeating the calculation simply to establish trust makes the pricing service part of every checkout and order-processing request. It also creates a subtler problem: if a promotion ends between two calls, the second calculation may be correct now while still being different from the price the shopper was shown.

You need both capabilities. Reprice when the commercial facts have changed; otherwise, verify the price you already have.

What a price signature actually is

When Badger Pricing prices a basket, it can return a Price Signature Token, or PST. This is a compact signed record created using a key belonging to your organisation. The corresponding public key lets your other systems verify the signature, but it cannot be used to create a replacement.

The record includes the commercial state needed to identify the quote:

  • the products, quantities, unit prices and currency;
  • line and basket totals;
  • the discounts, promotions and coupons that contributed to the result;
  • when the quote was issued and when it expires; and
  • a fingerprint of the complete basket.

That fingerprint is a cryptographic hash: a repeatable summary calculated from the ordered basket lines. Checkout calculates the same summary from the basket it is about to charge. If someone adds an item, removes one, changes a quantity or substitutes a unit price, the new summary does not match the signed one.

The signature does not ask checkout to trust a total. It lets checkout prove which basket that total belongs to.

The token also has a limited lifetime. Its expiry cannot extend beyond the earliest scheduled price change affecting its lines, so a quote cannot remain valid after one of its prices is due to change.

The journey from product page to order

The signed record has a different job at each stage. It is helpful to follow the basket rather than the underlying API calls.

  1. 1

    The product page presents the current price

    The storefront asks Badger Pricing for the current price in the relevant currency, channel and price-list context. A product-level signature is available when the storefront needs to carry proof forward, but it is optional: signing every product on a large listing page adds work even though most of those products will never enter a basket.

  2. 2

    The basket becomes the unit of trust

    Once the shopper has chosen products and quantities, the basket is priced as a whole. This is where basket-level promotions, coupons, tax and line apportionment are resolved. Badger Pricing returns the calculation and a signature bound to those exact lines and totals.

  3. 3

    Checkout verifies before it charges

    Checkout checks the signature using the organisation's published public keys, confirms that it has not expired and rebuilds the basket fingerprint from the order lines. While all three checks pass, checkout can honour the signed amount without making another pricing request.

  4. 4

    Order management keeps the final record

    The final token is stored with the order. Promotion and coupon usage can then be redeemed from the verified token, so the usage recorded is the usage Badger Pricing actually approved rather than a discount description supplied by the storefront.

The public keys are delivered through a JWKS endpoint: a standard document that tells a verifier which public key corresponds to the identifier on the token. Those keys are cacheable. During a key rotation, the new key starts signing immediately while the previous public key remains available long enough to verify tokens that have not yet expired.

What happens when the basket changes

A signature should fail when the facts it represents are no longer true. That is not an error in the design; it is the control working.

If the shopper changes a quantity, adds a product or removes one, the storefront sends the changed basket for a fresh calculation. The same applies when the token has expired. Badger Pricing can accept the previous token with the new request and return both a new signed quote and a structured account of what changed.

That difference can distinguish between a unit price changing, a promotion expiring, a new promotion applying or a coupon becoming unavailable. The storefront therefore has enough context to explain the new total instead of displaying a generic “basket updated” message.

Each replacement token can also contain a fingerprint of the previous one. This creates a chain from the first quote through subsequent quotes to the token redeemed with the order. The pricing service does not need to keep a server-side copy of every abandoned basket to create that history: the signed previous token carries its own trustworthy prior state.

Verification is not the same as repricing

The distinction matters operationally:

SituationWhat you should doWhy
The basket is unchanged and the token is validVerify it locallyYou are confirming the calculation already made.
A product or quantity changedRepriceThe signed calculation describes a different basket.
The token expiredRepriceThe promise to honour that quote has ended.
A coupon is exhausted during order placementReprice and show the correctionAvailability changed after the quote.
A high-value flow requires live revocation checksVerify onlineThe stricter control deliberately puts Badger Pricing back in the request path.

Offline verification is the default because it removes an avoidable network dependency from checkout and order handling. Badger Pricing also supports online verification for stricter flows, where checking whether a particular token has been revoked is worth the additional request.

This is a trade-off rather than a universal setting. A short token lifetime limits how long a quote can be honoured, but causes more baskets to be repriced. A longer lifetime makes the journey smoother, but extends the commercial promise. The appropriate lifetime depends on how frequently your prices and promotions change, not on a desire to maximise one technical metric.

The performance cost belongs where it adds value

Signing is not free, so Badger Pricing treats product pages and baskets differently. In the committed Phase 4 microbenchmark, signing a single-line basket measured 0.208 ms at p99, while verification measured 0.504 ms at p99. The same benchmark measured roughly 32 ms to sign 200 separate product results.

These are CPU microbenchmarks recorded on the build machine, not production-capacity claims. Their useful lesson is comparative: one basket signature is small, while signing every product in a large listing is material beside the price query itself. Basket signing is therefore on by default; product signatures are opt-in.

What the signature does not prove

A signed price is deliberately narrow. It proves that Badger Pricing issued a particular quote for a particular basket and that the record has not been altered. It does not prove that:

  • the catalogue description or product image is correct;
  • the item is still in stock;
  • the payment will succeed;
  • the delivery promise can be met; or
  • the commercial rule entered into the pricing engine was sensible.

If someone configures the wrong promotion, Badger Pricing can faithfully sign the wrong result. The signature gives you provenance and tamper evidence; it does not replace approval controls, testing or commercial judgement.

That boundary is important because “cryptographically signed” can otherwise sound like a broad claim that the entire order is correct. It is not. It is a precise answer to a precise question: did these basket lines and totals come from this organisation's pricing engine, and are they still within the period it promised to honour them?

What to implement first

Start at the basket rather than trying to sign every price on the site.

  1. Request a signed basket after promotions and tax have been calculated.
  2. Carry the token with the basket without treating its contents as editable application state.
  3. At checkout, verify the issuer, organisation, audience, expiry and basket fingerprint.
  4. Reprice whenever verification fails because the basket changed or the token expired.
  5. Store the final token on the order and use it when redeeming promotion or coupon usage.

That gives you the useful property first: the price shown at the end of the basket can reach the order as a statement your systems verify, rather than a number they repeatedly take on trust.

All articles