Skip to content

fix(cart): store whole-line basket prices and send them as end_amount - #60

Merged
mekedron merged 4 commits into
mainfrom
fix/multi-count-line-price
Oct 17, 2026
Merged

mekedron merged 4 commits into
mainfrom
fix/multi-count-line-price

Conversation

@mekedron

Copy link
Copy Markdown
Owner

Summary

A basket built with wolt cart add --count 2 showed three different totals.
The Wolt app counted each such line once, wolt cart showed its own number,
and wolt checkout counted lines added in the Wolt app twice. For example,
a 37.80 basket previewed at 75.60.

Wolt stores a basket line's price as the total for the whole line. It reads
the checkout end_amount as that same total. The CLI stored the price of one
unit and multiplied it by the count again for checkout. Now the CLI stores
and sends prices the same way the Wolt app does. All three totals match.

Baskets built by older CLI versions still hold one-unit prices. Wolt shows
them too low. Rebuild such a basket after upgrading. If a line's price cannot
be split evenly by its count, the CLI refuses it and asks you to add the item
again.

Fixes #59 — #59

What wolt.com sends

Captured from wolt.com network traffic at Sultan Shish Kebab, Espoo:

Line Basket price Plan base_price Plan end_amount
2 x Coca-Cola at 3.50 700 350 700
2 x Kebab with fries at 14.40 + Yogurt 1.00 3080 1440 3080

Wolt's "Item subtotal" for that plan was 37.80 = 7.00 + 30.80. Option values
keep their per-unit price and count (100, count 1).

This settles the open question in the issue. end_amount is not a per-unit
amount. Wolt only appeared to multiply by count because the CLI sent count x
price while the basket held a unit price. With whole-line prices on both
sides, the totals agree.

Changes

  • cart add (CLI and MCP) saves count x (unit price + paid option values).
  • BuildBasketUpsertItem rescales a count-based line's price whenever a merge
    or a partial removal changes its count. Weighted lines keep the price their
    weight builders compute.
  • cart show sums line prices for the subtotal. It reports price as one
    unit (line price / count) and line_total as the line price.
  • checkout sends the line price as end_amount. It sends one unit without
    options as base_price. Weighted lines are unchanged.
  • The live smoke adds two units of the fixture item. It checks the line math,
    compares Wolt's own basket total with the CLI subtotal, and compares the
    checkout item subtotal with both.
  • Docs: the output contract and the cart add text describe the line price
    as the whole-line total.

Testing

  • Unit and e2e tests cover rescaling on merge and partial remove, rejecting
    an indivisible price, weighted lines, cart show totals, the checkout plan
    and MCP add/remove.
  • go build, the versioned bin/wolt build and version check,
    golangci-lint run, go test ./... and go test -race ./... all pass.
  • Live check on the real account, at the basket created on wolt.com:
    • the current main previewed an item subtotal of 75.60;
    • this branch previewed 37.80, the same as wolt.com.
  • After adding, merging and partially removing lines through this branch,
    three totals matched at every step: Wolt's basket total, the CLI subtotal
    and the checkout item subtotal. The last step was 69.10 for 1 x 15.40,
    3 x 3.50 and 3 x 14.40.
  • WOLT_SMOKE_CART=1 ./scripts/live-smoke.sh passed 29 of 29 steps. The new
    two-unit checks passed. The weighted leg was skipped because no
    sell-by-weight item was orderable at that hour.
  • Not checked live: a weighted line together with a count-based line in one
    checkout. The weighted code path is unchanged.

Wolt stores a basket line's price as the whole-line total, count x (unit
price + paid option values), and sums line prices without multiplying by
count. Its checkout purchase plan takes end_amount as that same total and
base_price as one unit without options. Captured from wolt.com: two 3.50
drinks are saved as price 700 and planned as base_price 350, end_amount 700.

The CLI stored the unit price and sent count x price as end_amount. A
basket built by `cart add --count N` therefore showed a total that ignored
the count in the Wolt app, and `checkout` counted lines from the Wolt app
twice (a 37.80 basket previewed at 75.60).

- cart add (CLI and MCP) saves count x unit price, options included.
- BuildBasketUpsertItem rescales a count-based line's price whenever a
  merge or partial removal changes its count; weighted lines keep the
  price their weight builders compute.
- cart show sums line prices and reports the unit price as price / count.
- checkout sends the line price as end_amount and the per-unit price
  without options as base_price. Weighted lines are unchanged.
- A line price that does not divide by its count is rejected with a hint
  to re-add the item instead of being rounded.

Fixes #59
The cart round-trip now adds two units of the fixture item. It checks that
the line total is count x unit price, that the basket total Wolt reports
equals the CLI subtotal, and that the checkout item subtotal Wolt computes
matches it. After removing one unit it checks the line again, and the
cleanup removes every unit of the fixture item, which was absent before
the run.
cart add saves count x (item price + paid option values) as the line price,
the way the Wolt app does. The output contract explains price, line_total
and subtotal in cart output.
@mekedron
mekedron merged commit a84195e into main Oct 17, 2026
4 checks passed
@mekedron
mekedron deleted the fix/multi-count-line-price branch October 17, 2026 21:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Multi-count basket lines are mispriced: Wolt basket total ignores count, checkout preview counts it twice

1 participant