Revenue Ops
TypeScript
Webhook Trigger

Tiered Commission & Quota Split Calculator

Calculate multi-tier commission rates (e.g. 8% base up to $50k, 12% accelerator above $50k) when a deal is closed won, and save the payout to HubSpot.

Why this automation is needed

Native HubSpot workflows often struggle with complex multi-object traversals, conditional lookback attribution windows, custom phone format standardizations, and custom scoring calculations.

With Workflood, this recipe runs in a secure gVisor container sandbox with pre-authenticated HubSpot SDK injection, avoiding HubSpot Data Hub execution limits, memory bottlenecks, and per-seat fees.

Action Source Code (TypeScript)

calculate-rep-commission-tiers.ts
TypeScript
export default async function main(input: {
  dealId?: string
  baseRate?: number
  acceleratorRate?: number
  tierThreshold?: number
  [key: string]: unknown
}): Promise<{
  dealId?: string
  amount?: number
  baseCommission?: number
  acceleratedCommission?: number
  totalCommission: number
  effectiveRate?: number
  processedDeals?: number
}> {
  const rawInput = (Array.isArray(input) ? input[0] : input) || {}
  const dealId = (rawInput.dealId || rawInput.deal_id || rawInput.objectId || (rawInput.object && (rawInput.object as Record<string, unknown>).objectId) || rawInput.hs_object_id || (rawInput.fields && (rawInput.fields as Record<string, unknown>).dealId)) as string | undefined

  const baseRate = input.baseRate ?? 0.08 // 8% base
  const acceleratorRate = input.acceleratorRate ?? 0.12 // 12% accelerator
  const tierThreshold = input.tierThreshold ?? 50000 // $50,000 threshold

  const dealList: Array<{ id: string; amount: number }> = []

  if (dealId) {
    const deal = await hubspot.client.crm.deals.basicApi.getById(
      dealId,
      ['dealname', 'amount', 'dealstage', 'closedate']
    )
    dealList.push({ id: dealId, amount: parseFloat(deal.properties.amount || '0') })
  } else {
    // Trigger-agnostic fallback: Scan recent closed-won deals
    const wonDeals = await hubspot.client.crm.deals.basicApi.getPage(
      25,
      0,
      ['dealname', 'amount', 'dealstage', 'closedate'],
      undefined,
      undefined,
      [{ value: 'closedwon', propertyName: 'dealstage', operator: 'EQ' }]
    )
    for (const d of wonDeals.results) {
      dealList.push({ id: d.id, amount: parseFloat(d.properties.amount || '0') })
    }
  }

  let totalCommissionSum = 0

  for (const item of dealList) {
    if (item.amount <= 0) continue

    let baseCommission = 0
    let acceleratedCommission = 0

    if (item.amount <= tierThreshold) {
      baseCommission = item.amount * baseRate
    } else {
      baseCommission = tierThreshold * baseRate
      acceleratedCommission = (item.amount - tierThreshold) * acceleratorRate
    }

    const totalCommission = Number((baseCommission + acceleratedCommission).toFixed(2))
    const effectiveRate = Number(((totalCommission / item.amount) * 100).toFixed(2))
    totalCommissionSum += totalCommission

    await hubspot.client.crm.deals.basicApi.update(item.id, {
      properties: {
        commission_payout: totalCommission.toString(),
        effective_commission_rate: `${effectiveRate}%`,
        commission_calculated_at: new Date().toISOString(),
      },
    })
  }

  const firstAmount = dealList[0]?.amount || 0
  const firstBase = firstAmount <= tierThreshold ? firstAmount * baseRate : tierThreshold * baseRate
  const firstAccel = firstAmount > tierThreshold ? (firstAmount - tierThreshold) * acceleratorRate : 0

  return {
    dealId,
    amount: dealList.length === 1 ? firstAmount : undefined,
    baseCommission: dealList.length === 1 ? Number(firstBase.toFixed(2)) : undefined,
    acceleratedCommission: dealList.length === 1 ? Number(firstAccel.toFixed(2)) : undefined,
    totalCommission: Number(totalCommissionSum.toFixed(2)),
    effectiveRate: dealList.length === 1 && firstAmount > 0 ? Number(((totalCommissionSum / firstAmount) * 100).toFixed(2)) : undefined,
    processedDeals: dealList.length,
  }
}

Configurable Parameters

ParameterTypeDefaultDescription
baseRatenumber8Base commission rate applied up to the tier threshold.
tierThresholdnumber50000Deal revenue threshold where accelerated commission rate starts.
acceleratorRatenumber12Elevated commission percentage for amount exceeding threshold.

How to deploy in Workflood

1

Connect your HubSpot Portal

Add your HubSpot Private App token once. Workflood securely encrypts it via libsodium XChaCha20 and injects pre-authenticated SDK clients.

2

Create Action from Template

Select this recipe in Workflood. Edit variables, customize logic in Monaco editor, or execute dry runs with sample JSON payloads.

3

Trigger via Webhook or Cron

Trigger from standard HubSpot workflows via Webhook action, or schedule recurring batch syncs with cron expressions and timezone handling.