One price on the screen, and a purchase that cannot fail silently

Fixkamo-internal
Shipped
September 6, 2026 at 10:17 PM UTC
Author
Kamo
Commit
b0bb3a2

The console showed a customer three different numbers for one plan and let them buy with no card. Rendering it against the live catalogue, Business at five seats: the plan card headlined $79.73 a seat under a "33% off" badge, the estimate below it totalled $595.00, and BillingService would have charged $360 — none of them the price of anything. This is the surface half of that; the BillingService half is 5cfc969. buildQuote is now the only place a price is resolved. It takes the promotion and applies it exactly where **************** does — to the plan's seat subtotal, after the term discount, and not to add-ons — so the cards and the total are the same arithmetic rather than two implementations of it. It also quotes the $99-per-seat startup fee, which no surface mentioned: a five-seat Business order says "Due today $893.65" where it used to say "$595.00 a month" and nothing else. Per-mailbox add-ons are priced on the mailbox count instead of falling through to the seat count, and quote nothing at all when that count is unknown rather than confidently quoting the wrong thing. A paid plan now needs a card. Nothing asked for one and nothing checked: the console posted the purchase, Stripe opened a subscription it could not charge and answered `incomplete` — an ordinary response, not an error — and the screen said "Your plan is updated" over a subscription that paid for nothing and would be deleted within the day. The confirm button is disabled until there is a card, with a line saying so and a link to the tab that fixes it. The header reads `status` now. INCOMPLETE, PAST_DUE, CANCELED and PAUSED all rendered identically to a healthy plan because it branched on `source` alone; each has its own state saying what is true, what it means for access, and what to do. A live trial has one too — a trialling organization has plan_code FREE while the entitlement engine grants it everything, so it fell into "your organization is on the free tier" while using every paid app, with the deadline that actually matters to it nowhere on the page. Elsewhere on the tab: cancelling an organization's subscription was a bare onClick with no confirmation and no catch, so a failure looked like a button that did nothing — it uses the same dialog the self-serve seat panel does, which names the day cover runs to. Removing a card is confirmed, and says when it is the one the subscription is billed to. The "Account Title" field is gone: it was editable, Save reported success, and displayName is derived server-side from the billing name — no column was ever behind it. The create-account dialog no longer demands a title it discards. Two "Member ID" boxes wanting a nineteen-digit id are directory pickers. And `?sub=organization` — the URL an owner copies out of their address bar — no longer renders an empty page for everyone else. Money and dates are formatted for the reader: the amounts were pinned to en-US/USD on a product shipping 21 locales and a catalogue carrying a currency per plan, quote lines were assembled as English string concatenation, invoice dates were raw ISO, and Stripe's own statuses were printed verbatim — "uncollectible" reads as an accusation rather than as "we could not charge your card". Also carries the /myplan preselect projects-2d handed over: ?plan=BUSINESS arrives with Business chosen, through choosePlan so the seat count is clamped to the plan the same way a click is, and a link naming Enterprise opens the sales dialog rather than appearing to do nothing. 61 tests in the billing suite, 32 of them new; typecheck clean; no new lint errors against a HEAD baseline. Copy is in kamo-translation-dictionary 4fbd8e31, pushed first so the build guard has it.

All changes

Like what you see shipping?

Every one of these updates lands in your workspace automatically. Start free and watch it grow week after week.

Start Free ForeverView Pricing