Numbers Math Money Snippets
Custom Code Snippets — Numbers, Math & Money
Copy-paste examples for arithmetic, rounding, currency formatting, percentages, and other numeric tasks inside a Custom Code workflow step. Reach for the Num helper for rounding, formatting, and clamping; standard Math is also available for trig / logs / square roots.
The Num helper covers round, floor, ceil, abs, min, max, random, randomInt, and format.
Compute a line total with tax
// Inputs: price (record_val), qty (record_val), tax_rate (custom_val 0.0875)
const price = Number(params["price"]) || 0;
const qty = Number(params["qty"]) || 0;
const rate = Number(params["tax_rate"]) || 0;
const subtotal = price * qty;
const total = Num.round(subtotal * (1 + rate), 2);
returnData("subtotal", subtotal);
returnData("tax", Num.round(subtotal * rate, 2));
returnData("total", total);
Format currency for display
// 1234.5 -> "$1,234.50"
const amount = Number(record.amount) || 0;
const formatted = `$${Num.format(amount, 2)}`;
returnData("amount_display", formatted);
Display amounts in any currency
// Inputs: amount (record_val), currency (custom_val "USD"/"EUR"/"GBP"/"ILS")
const amount = Number(params["amount"]) || 0;
const currency = (params["currency"] || "USD").toUpperCase();
const symbols = { USD: "$", EUR: "€", GBP: "£", ILS: "₪", CAD: "$", AUD: "$" };
const symbol = symbols[currency] || "";
returnData("display", `${symbol}${Num.format(amount, 2)} ${currency}`);
Clamp a value between min and max
const score = Number(params["score"]) || 0;
returnData("score_clamped", Num.min(100, Num.max(0, score)));
Percent change between two numbers
// Inputs: previous, current
const prev = Number(params["previous"]) || 0;
const curr = Number(params["current"]) || 0;
const change = prev === 0 ? null : Num.round(((curr - prev) / prev) * 100, 2);
returnData("pct_change", change);
returnData("trend", change == null
? "n/a"
: change > 0 ? "up" : change < 0 ? "down" : "flat");
Convert cents to dollars (Stripe-style)
const cents = Number(params["amount_cents"]) || 0;
returnData("dollars", Num.round(cents / 100, 2));
Convert dollars to cents (for Stripe API calls)
// Stripe wants integer cents — never floats
const dollars = Number(params["amount"]) || 0;
returnData("amount_cents", Math.round(dollars * 100));
Calculate tip and split among diners
// Inputs: subtotal, tip_pct (e.g. 0.18), party_size
const subtotal = Number(params["subtotal"]) || 0;
const tipPct = Number(params["tip_pct"]) || 0.18;
const partySize = Math.max(1, Number(params["party_size"]) || 1);
const tip = Num.round(subtotal * tipPct, 2);
const total = Num.round(subtotal + tip, 2);
const each = Num.round(total / partySize, 2);
returnData("tip", tip);
returnData("total", total);
returnData("per_person", each);
Apply a percentage or flat-amount discount
// Inputs: subtotal, discount_type ("pct" or "flat"), discount_value
const subtotal = Number(params["subtotal"]) || 0;
const type = params["discount_type"] || "pct";
const value = Number(params["discount_value"]) || 0;
let discount;
if (type === "pct") discount = subtotal * (value / 100);
else discount = value;
discount = Math.min(subtotal, Math.max(0, discount)); // never negative, never bigger than subtotal
const total = Num.round(subtotal - discount, 2);
returnData("discount", Num.round(discount, 2));
returnData("total", total);
Weighted average of grades
// Inputs: grades (array of {score, weight})
const grades = Array.isArray(params["grades"]) ? params["grades"] : [];
let sum = 0, weight = 0;
for (const g of grades) {
const s = Number(g.score) || 0;
const w = Number(g.weight) || 0;
sum += s * w;
weight += w;
}
const avg = weight === 0 ? null : Num.round(sum / weight, 2);
returnData("weighted_average", avg);
Compound interest over N years
// Inputs: principal, rate (0.05 for 5%), years, periods_per_year (12 = monthly)
const p = Number(params["principal"]) || 0;
const r = Number(params["rate"]) || 0;
const t = Number(params["years"]) || 0;
const n = Number(params["periods_per_year"]) || 12;
const amount = p * Math.pow(1 + r / n, n * t);
returnData("future_value", Num.round(amount, 2));
returnData("interest_earned", Num.round(amount - p, 2));
Convert between currencies
// Inputs: amount_usd, eur_per_usd (e.g. 0.92)
const usd = Number(params["amount_usd"]) || 0;
const rate = Number(params["eur_per_usd"]) || 0;
returnData("eur", Num.round(usd * rate, 2));
Progress percentage with safe divide
// Inputs: completed, total
const done = Number(params["completed"]) || 0;
const total = Number(params["total"]) || 0;
const pct = total === 0 ? 0 : Num.round((done / total) * 100, 1);
returnData("pct_complete", pct);
returnData("status", pct >= 100 ? "done" : pct === 0 ? "not_started" : "in_progress");
Distance between two lat/lng points (miles)
// Inputs: lat1, lng1, lat2, lng2
function toRad(d) { return d * Math.PI / 180; }
const lat1 = Number(params["lat1"]) || 0;
const lng1 = Number(params["lng1"]) || 0;
const lat2 = Number(params["lat2"]) || 0;
const lng2 = Number(params["lng2"]) || 0;
const R = 3958.8; // Earth radius in miles
const dLat = toRad(lat2 - lat1);
const dLng = toRad(lng2 - lng1);
const a = Math.sin(dLat / 2) ** 2 +
Math.cos(toRad(lat1)) * Math.cos(toRad(lat2)) *
Math.sin(dLng / 2) ** 2;
const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
returnData("miles", Num.round(R * c, 2));
Round to the nearest 0.05 / 0.25 / 5 / 100
// "Bankers" snap-to-step rounding
const value = Number(params["value"]) || 0;
const step = Number(params["step"]) || 0.05;
const rounded = Math.round(value / step) * step;
returnData("rounded", Num.round(rounded, 2));
We'd love to hear your feedback.