Skip to navigation

Price a basket from a webshop

Get till-identical totals online, including every promotion the store is running.

View as Markdown

If your webshop calculates its own prices, it will eventually disagree with the till. Someone will bring a basket into a store, get a different number, and you will spend a day working out which system was right.

Basket API exists to remove that class of bug. It runs the same calculation logic a 52ViKING till runs, so the totals match by construction.

What it is

One endpoint:

POST /basket/calculatebasket/{chain}/{store}

Key properties, from the spec:

  • Stateless. Nothing is persisted: no basket, no receipt. You send the whole basket every time and get the whole answer back.
  • XML or JSON, on both request and response. Pick one with Content-Type and Accept.
  • Horizontally scalable. Multiple 52ViKING tills can serve the calls behind a load balancer.
  • Line-orientated. Each line you send stays one line in the response. Lines are neither collapsed nor expanded, so quantity three is one line, not three.

Basket API is part of the 52MASTERPRICER suite. It is also genuinely useful as a test harness: because it is stateless and side-effect free, you can assert on pricing behaviour in CI.

Chain and store are not optional

Promotions are configured per store. The same article can be on offer in one store and not in another, so the store number in the path decides the answer.

Passing a wrong-but-valid store number is the most common cause of “the API disagrees with the till”. Before debugging further, check that the store number you sent is the store you rang the basket up in.

Making the call

curl -X POST \
"https://api.fiftytwo.com/basket/basket/calculatebasket/1/0142" \
-H "Authorization: Bearer $FT_TOKEN" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{
"lines": [
{ "ean": "5701234000019", "quantity": 1 },
{ "ean": "5701234004512", "quantity": 3 }
]
}'

Check the request schema for the exact line-item field names. The spec carries 35 schemas, and which fields your chain expects depends on its configuration.

Reading the answer

All discounts are applied to articles eligible for discount, and each discount arrives as its own line referencing the rule that produced it.

That reference is the useful part. It lets you tell a customer why the price is what it is (“3 for 29.00, campaign 881”) rather than showing an unexplained total. Resolve the ID through Master Data if you want the promotion’s display name.

Where to call it from

1

On the basket page, not just at checkout

The promotion is a reason to add another item. Showing “add one more for 3 for 29.00” is only possible if you priced the basket early.

2

Again at checkout, authoritatively

Campaigns start and end on dates. Re-price immediately before payment so the customer is charged what they were shown.

3

Cache briefly, if at all

The call is stateless and fast. Caching risks serving a price from before a campaign flipped, which is usually a worse trade than the round trip.

Verifying it matches

Ring the same basket on a physical till in the same store and compare. If they differ:

Almost always the wrong store number, or a campaign that has not been distributed to that store yet.

Check rounding and deposit lines. Returnable-packaging deposits are separate receipt lines and are not discountable.

Check whether the promotion is a match discount (discount basket). Master Data does not support discount baskets on the Get side, so a rule built that way through the API can behave differently from one built in Store Management. See Buy side and Get side.