{"slug": "whatsapp-automation-for-small-businesses-in-2026-ai-replies-lead-capture-tiered", "title": "WhatsApp Automation for Small Businesses in 2026: AI Replies, Lead Capture & Tiered Commissions", "summary": "A developer built a WhatsApp sales automation system for small businesses using Google Sheets and Apps Script, featuring AI replies, lead capture, and tiered commissions. The key innovation is a commission engine that correctly handles multi-tier calculations across sales and refunds, avoiding common spreadsheet errors.", "body_md": "Your customers would rather message you on WhatsApp than fill in a contact form. That's fine at ten conversations a day. At a hundred, messages get missed, nobody knows which rep is on which deal, and at month-end somebody rebuilds the commission sheet by hand and gets it wrong.\n\nThe usual answer is a $49–$499/month WhatsApp SaaS platform, priced per seat, with your customer data living in someone else's database. This post is the other answer: the same workflow on Google Sheets + Apps Script — and the one piece I see teams get wrong every single time, with the code to fix it.\n\nIt isn't the messaging. Wiring a WhatsApp webhook into a sheet is a couple of hours of work, and I've written that build up separately — the webhook, the AI reply, and the lock that stops two reps chasing the same lead are all in [Build a WhatsApp Sales Inbox in Google Sheets](https://magesheet.com/blog/automating-whatsapp-sales-google-sheets). I won't repeat it here.\n\nThe part that breaks is **the commission math**. Someone writes `=IF(revenue>10000, revenue*0.08, revenue*0.05)`\n\ninto a column, and three things kill it:\n\nSo that's what this post builds: a tiered commission engine that survives rule changes and refunds.\n\nThis is the whole trick. Make a `Commission Rules`\n\ntab, one row per rule:\n\n```\nrule_id | rep_id   | effective_from | effective_to | tier_1_cap | tier_1_pct |\n        |          |                |              | tier_2_cap | tier_2_pct | tier_3_pct\n--------+----------+----------------+--------------+------------+------------+-----------\nR1      | ALL      | 2026-01-01     |              | 10000      | 0.05       |\n        |          |                |              | 50000      | 0.08       | 0.10\nR2      | rep_ayse | 2026-06-01     |              | 10000      | 0.06       |\n        |          |                |              | 50000      | 0.09       | 0.12\n```\n\n`rep_id`\n\nis either a specific rep or `ALL`\n\n(the house default). Percentages are decimals — `0.05`\n\nis 5%. When the plan changes, you close the old rule with an `effective_to`\n\ndate and add a new row. History keeps calculating at the rate that was live on the day of the sale.\n\n``` js\nfunction findRule(rules, repId, saleDate) {\n  const d = new Date(saleDate);\n  const matches = rules.filter(r =>\n    (r.rep_id === repId || r.rep_id === 'ALL') &&\n    d >= new Date(r.effective_from) &&\n    (!r.effective_to || d <= new Date(r.effective_to))\n  );\n  // A rule written for this rep always beats the \"ALL\" fallback.\n  matches.sort((a, b) => (a.rep_id === 'ALL' ? 1 : 0) - (b.rep_id === 'ALL' ? 1 : 0));\n  return matches[0] || null;\n}\n```\n\nHere's the bug in every hand-written commission column. A rep has booked $45,000 this quarter and closes another $10,000. Tier 2 ends at $50,000. So $5,000 of that sale earns 8% and $5,000 earns 10% — not $10,000 at one rate.\n\n```\n// Commission for ONE sale, given how much the rep already booked this period.\n// A single sale can span two or three tiers — that's what formulas get wrong.\nfunction commissionForSale(bookedBefore, amount, rule) {\n  const bands = [\n    { upTo: Number(rule.tier_1_cap), pct: Number(rule.tier_1_pct) },\n    { upTo: Number(rule.tier_2_cap), pct: Number(rule.tier_2_pct) },\n    { upTo: Infinity,                pct: Number(rule.tier_3_pct) },\n  ];\n  let from = bookedBefore, left = amount, commission = 0;\n\n  for (const band of bands) {\n    if (left <= 0) break;\n    const room = Math.max(band.upTo - from, 0);\n    const take = Math.min(left, room);\n    commission += take * band.pct;\n    from += take;\n    left -= take;\n  }\n  return commission;\n}\n```\n\nWith the `R1`\n\nrule above: `commissionForSale(45000, 10000, R1)`\n\nreturns `900`\n\n— $5,000 at 8% plus $5,000 at 10%. The naive formula returns either $800 or $1,000, and your rep notices.\n\nNever edit or delete the original row. A refund is its own row with a negative `amount`\n\nand a `reverses_transaction_id`\n\npointing back at the sale. Then the engine reverses exactly the commission that sale earned — not a recalculated guess.\n\n``` js\nfunction runCommissions(transactions, rules) {\n  const sorted = transactions.slice()\n    .sort((a, b) => new Date(a.date) - new Date(b.date));\n  const booked = {};   // rep_id -> revenue booked so far\n  const earned = {};   // transaction_id -> commission it earned\n  const out = [];\n\n  sorted.forEach(t => {\n    if (t.reverses_transaction_id) {                    // refund row\n      const original = earned[t.reverses_transaction_id] || 0;\n      booked[t.rep_id] = (booked[t.rep_id] || 0) + Number(t.amount);  // negative\n      out.push({ id: t.transaction_id, rep: t.rep_id, commission: -original });\n      return;\n    }\n    const rule = findRule(rules, t.rep_id, t.date);\n    if (!rule) {\n      out.push({ id: t.transaction_id, rep: t.rep_id, commission: 0, note: 'no rule' });\n      return;\n    }\n    const before = booked[t.rep_id] || 0;\n    const c = commissionForSale(before, Number(t.amount), rule);\n    booked[t.rep_id] = before + Number(t.amount);\n    earned[t.transaction_id] = c;\n    out.push({ id: t.transaction_id, rep: t.rep_id, commission: c });\n  });\n  return out;\n}\n```\n\nBecause it walks transactions in date order and keeps a running total per rep, the tier boundaries land where they actually landed in real life. I unit-tested this before shipping it — the cases that matter are a sale spanning all three tiers, a rule that isn't effective yet falling back to `ALL`\n\n, and a refund netting to exactly zero.\n\nAt small-business volume, the running cost is LLM tokens plus Meta's conversation fees — roughly $0.005–$0.08 per conversation depending on category and country, which for most SMBs lands near $50/month all-in. Compare that to $49–$499/month per platform, plus per-seat fees. The bigger difference isn't the invoice, though: the sheet is yours, and so is the commission logic.\n\nWhatsApp's often-quoted ~98% open rate is a vendor benchmark rather than a controlled study — but you don't need the exact number to know the channel outperforms email for a reply-now conversation.\n\n`reverses_transaction_id`\n\n.The messaging half of WhatsApp automation is easy and well covered. The commission half is where teams quietly lose money and trust — and it's solved by two ideas: keep the tiers in a dated rules table, and split each sale across the bands it actually crosses.\n\nThe production version — multi-agent splits, clawback windows, and the payout approval flow — is written up on the [MageSheet blog](https://magesheet.com/blog/whatsapp-automation-small-businesses-2026).\n\nBuilt by the MageSheet team.", "url": "https://wpnews.pro/news/whatsapp-automation-for-small-businesses-in-2026-ai-replies-lead-capture-tiered", "canonical_source": "https://dev.to/hayrullahkar/whatsapp-automation-for-small-businesses-in-2026-ai-replies-lead-capture-tiered-commissions-4b89", "published_at": "2026-07-16 21:44:58+00:00", "updated_at": "2026-07-16 22:05:47.309857+00:00", "lang": "en", "topics": ["developer-tools", "ai-tools", "artificial-intelligence"], "entities": ["Google Sheets", "Apps Script", "WhatsApp"], "alternates": {"html": "https://wpnews.pro/news/whatsapp-automation-for-small-businesses-in-2026-ai-replies-lead-capture-tiered", "markdown": "https://wpnews.pro/news/whatsapp-automation-for-small-businesses-in-2026-ai-replies-lead-capture-tiered.md", "text": "https://wpnews.pro/news/whatsapp-automation-for-small-businesses-in-2026-ai-replies-lead-capture-tiered.txt", "jsonld": "https://wpnews.pro/news/whatsapp-automation-for-small-businesses-in-2026-ai-replies-lead-capture-tiered.jsonld"}}