<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[PrimeVoucher Dev Notes]]></title><description><![CDATA[PrimeVoucher Dev Notes]]></description><link>https://primevoucher.hashnode.dev</link><generator>RSS for Node</generator><lastBuildDate>Wed, 28 Oct 2026 16:58:00 GMT</lastBuildDate><atom:link href="https://primevoucher.hashnode.dev/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[The Maths Behind 10 Shopping Calculators (with JavaScript Snippets)]]></title><description><![CDATA[Discounts, stacked voucher codes, VAT, unit pricing and Pay in 3: the simple formulas behind 10 UK shopping calculators, in plain JavaScript.]]></description><link>https://primevoucher.hashnode.dev/the-maths-behind-10-shopping-calculators-with-javascript-snippets</link><guid isPermaLink="true">https://primevoucher.hashnode.dev/the-maths-behind-10-shopping-calculators-with-javascript-snippets</guid><category><![CDATA[JavaScript]]></category><category><![CDATA[webdev]]></category><category><![CDATA[Tutorial]]></category><dc:creator><![CDATA[Prime Voucher]]></dc:creator><pubDate>Thu, 22 Oct 2026 14:01:29 GMT</pubDate><content:encoded><![CDATA[<p><em>Originally published on</em> <a href="https://dev.to/prime_voucher_8ef9d71a951/the-maths-behind-10-shopping-calculators-with-javascript-snippets-1pgg"><em>DEV</em></a><em>.</em></p>
<p>Shopping maths looks trivial until you try to code it. "20% off, then an extra 10% with a voucher" is <strong>not</strong> 30% off. Removing VAT is <strong>not</strong> "minus 20%". And "free delivery over £50" can make you spend more than you save.</p>
<p>I recently helped build a set of free UK shopping calculators for <a href="https://primevoucher.co.uk/calculators">PrimeVoucher</a>, and here are the formulas behind each one, in plain JavaScript you can drop into your own project.</p>
<h2>1. Basic discount</h2>
<pre><code class="language-js">const salePrice = (price, pct) =&gt; price * (1 - pct / 100);
const saving = (price, pct) =&gt; price * (pct / 100);

salePrice(80, 25); // 60
</code></pre>
<p>Try it live: <a href="https://primevoucher.co.uk/calculators/discount-calculator">Discount Calculator</a></p>
<h2>2. Stacked discounts (sale + voucher code)</h2>
<p>The classic bug: adding percentages. Discounts multiply, they don't add.</p>
<pre><code class="language-js">const stacked = (price, ...pcts) =&gt;
  pcts.reduce((p, pct) =&gt; p * (1 - pct / 100), price);

const realPercentOff = (...pcts) =&gt;
  100 * (1 - pcts.reduce((m, pct) =&gt; m * (1 - pct / 100), 1));

realPercentOff(20, 10); // 28, not 30
</code></pre>
<p>Live version: <a href="https://primevoucher.co.uk/calculators/stacked-discount-calculator">Stacked Discount Calculator</a></p>
<h2>3. "% off" vs "£ off" - which voucher wins?</h2>
<p>A percentage code beats a fixed-amount code once the basket passes a break-even point:</p>
<pre><code class="language-js">const breakEven = (poundsOff, pctOff) =&gt; poundsOff / (pctOff / 100);

breakEven(10, 15); // £66.67 - above this, 15% off wins
</code></pre>
<p>Compare two codes: <a href="https://primevoucher.co.uk/calculators/voucher-comparison-calculator">Voucher Comparison Calculator</a></p>
<h2>4. Free delivery threshold</h2>
<p>Is it worth adding an item to hit free shipping? Only if what you add is something you'd buy anyway, or costs less than delivery.</p>
<pre><code class="language-js">const shortfall = (basket, threshold) =&gt; Math.max(0, threshold - basket);
const worthTopUp = (basket, threshold, deliveryFee) =&gt;
  shortfall(basket, threshold) &lt;= deliveryFee;

worthTopUp(42, 50, 4.99); // false - £8 top-up costs more than £4.99 delivery
</code></pre>
<p><a href="https://primevoucher.co.uk/calculators/free-delivery-calculator">Free Delivery Calculator</a></p>
<h2>5. UK VAT (add and remove)</h2>
<p>Removing VAT means dividing by 1.2, not subtracting 20%.</p>
<pre><code class="language-js">const addVat = (net, rate = 20) =&gt; net * (1 + rate / 100);
const removeVat = (gross, rate = 20) =&gt; gross / (1 + rate / 100);

removeVat(120); // 100 (not 96!)
</code></pre>
<p><a href="https://primevoucher.co.uk/calculators/vat-calculator">VAT Calculator</a></p>
<h2>6. Price per unit</h2>
<p>Normalise everything to the same unit before comparing multipacks.</p>
<pre><code class="language-js">const perUnit = (price, qty, unitSize = 1) =&gt; price / (qty * unitSize);

perUnit(3.5, 6, 330) * 100;  // pence per 100ml for a 6x330ml pack
</code></pre>
<p><a href="https://primevoucher.co.uk/calculators/price-per-unit-calculator">Price Per Unit Calculator</a></p>
<h2>7. Voucher + cashback + gift card</h2>
<p>Order matters: the voucher comes off first, and cashback is usually paid on the post-voucher amount (excluding delivery).</p>
<pre><code class="language-js">const realCost = ({ price, voucherPct = 0, cashbackPct = 0, giftCardDiscountPct = 0 }) =&gt; {
  const afterVoucher = price * (1 - voucherPct / 100);
  const cashback = afterVoucher * (cashbackPct / 100);
  const paid = afterVoucher * (1 - giftCardDiscountPct / 100);
  return paid - cashback;
};
</code></pre>
<p><a href="https://primevoucher.co.uk/calculators/cashback-calculator">Cashback &amp; Voucher Calculator</a></p>
<h2>8. Pay in 3 / Buy Now Pay Later</h2>
<p>Split evenly, but put the rounding remainder on the first instalment so the total always adds up to the penny.</p>
<pre><code class="language-js">const instalments = (total, n) =&gt; {
  const pence = Math.round(total * 100);
  const base = Math.floor(pence / n);
  const first = pence - base * (n - 1);
  return [first, ...Array(n - 1).fill(base)].map(p =&gt; p / 100);
};

instalments(100, 3); // [33.34, 33.33, 33.33]
</code></pre>
<p><a href="https://primevoucher.co.uk/calculators/pay-in-3-calculator">Pay in 3 Calculator</a></p>
<h2>9. Sale savings tracker</h2>
<pre><code class="language-js">const totalSaved = items =&gt;
  items.reduce((s, { was, now }) =&gt; s + (was - now), 0);
</code></pre>
<p><a href="https://primevoucher.co.uk/calculators/sale-savings-calculator">Sale Savings Calculator</a></p>
<h2>10. Annual savings</h2>
<pre><code class="language-js">const yearly = (avgSavingPerOrder, ordersPerMonth) =&gt;
  avgSavingPerOrder * ordersPerMonth * 12;
</code></pre>
<p><a href="https://primevoucher.co.uk/calculators/annual-savings-calculator">Annual Savings Calculator</a></p>
<h2>A note on money and floating point</h2>
<p><code>0.1 + 0.2 !== 0.3</code> in JavaScript. For anything shown to users, either work in integer pence (as in the Pay in 3 example) or round at the end with <code>Math.round(x * 100) / 100</code>. Display with <code>Intl.NumberFormat('en-GB', { style: 'currency', currency: 'GBP' })</code>.</p>
<hr />
<p>All ten calculators are free to use at <a href="https://primevoucher.co.uk/calculators">primevoucher.co.uk/calculators</a>. Source code: <a href="https://github.com/primevoucher786-source/uk-shopping-calculators">uk-shopping-calculators on GitHub</a>.</p>
]]></content:encoded></item></channel></rss>