Skip to contact form
← BlogProcessJanuary 31, 2027 · 4 min read

Our pricing calculator won't sell you something broken

Check e-commerce without a backend and most quote tools just take your money. Ours won't let the selection be inconsistent in the first place. Try it below.

-commerce needs somewhere to store orders. A booking system needs somewhere to store bookings. Neither of those is optional — they're not features you could theoretically ship without a backend, they're features that are a backend with a nice interface on top. A pricing calculator that lets you check "E-commerce" without also accounting for the backend it structurally requires isn't being flexible, it's just wrong, and whoever sold it that way finds out at kickoff, not at checkout.

Checksomethingthatneedsabackend,andthebackendgetsaddedforyounotasanupsell,asacorrectiontokeeptheselectionactuallybuildable.

Try it

try checking e-commerce or booking without the backend

That checklist calls expandAddOnDependencies() imported directly from lib/pricing.ts — the exact function our real /start calculator runs on every selection change. It walks a small dependency map (ADD_ON_REQUIRES) and keeps expanding the selected set until nothing new gets pulled in — e-commerce and booking both silently require Custom Backend / API, and subscriptions requires that plus user accounts. Nothing about this is a growth trick to inflate the invoice; it's the calculator refusing to represent a combination that can't actually be built.

typescript

export const ADD_ON_REQUIRES: Partial<Record<AddOnKey, AddOnKey[]>> = { ecommerce: ['custom-backend'], booking: ['custom-backend'], subscriptions: ['custom-backend', 'user-accounts'], 'push-notifications': ['custom-backend'], 'admin-dashboard': ['custom-backend'], }; export function expandAddOnDependencies(selected: AddOnKey[]): AddOnKey[] { const result = new Set(selected); let grew = true; while (grew) { grew = false; for (const key of Array.from(result)) { for (const req of ADD_ON_REQUIRES[key] ?? []) { if (!result.has(req)) { result.add(req); grew = true; } } } } return Array.from(result); }

It also refuses to double-charge you

The reverse case matters just as much. A Web App's base price already assumes a backend and user accounts — that's what "an app people log into" means. If a client checked "Web App" and separately checked "Custom Backend / API," a naive calculator would just add both line items and charge twice for the same underlying thing. BASE_SERVICE_INCLUDES marks that add-on as already bundled for that base service — still shown as included in the summary, since the product genuinely has it, but priced at zero and locked, because unchecking it wouldn't actually remove a backend from a Web App.

Why bother, if most visitors would never notice

Most people configuring a quote don't know which add-ons quietly require a backend — that's exactly why this logic has to live in the tool instead of in a salesperson's head. The alternative isn't "nothing goes wrong," it's "something goes wrong quietly, later, when the mismatch surfaces mid-build instead of at the moment you picked the wrong combination." A calculator that can represent an impossible selection eventually will, for someone, and the honest fix is making the impossible selection unrepresentable in the first place.