Pandatech.CommissionCalculator 6.0.0

dotnet add package Pandatech.CommissionCalculator --version 6.0.0
                    
NuGet\Install-Package Pandatech.CommissionCalculator -Version 6.0.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Pandatech.CommissionCalculator" Version="6.0.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Pandatech.CommissionCalculator" Version="6.0.0" />
                    
Directory.Packages.props
<PackageReference Include="Pandatech.CommissionCalculator" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Pandatech.CommissionCalculator --version 6.0.0
                    
#r "nuget: Pandatech.CommissionCalculator, 6.0.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Pandatech.CommissionCalculator@6.0.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Pandatech.CommissionCalculator&version=6.0.0
                    
Install as a Cake Addin
#tool nuget:?package=Pandatech.CommissionCalculator&version=6.0.0
                    
Install as a Cake Tool

Pandatech.CommissionCalculator

High-performance commission calculation engine for .NET 8+ supporting proportional and absolute commission models with tiered ranges, min/max constraints, and automatic validation.

Installation

dotnet add package Pandatech.CommissionCalculator

Quick Start

Define Commission Rule

using CommissionCalculator.DTO;

var rule = new CommissionRule
{
    CalculationType = CalculationType.Proportional,
    DecimalPlace = 4,
    CommissionRangeConfigs = new List<CommissionRangeConfigs>
    {
        new()
        {
            RangeStart = 0,
            RangeEnd = 500,
            Type = CommissionType.FlatRate,
            CommissionAmount = 25,
            MinCommission = 0,
            MaxCommission = 0
        },
        new()
        {
            RangeStart = 500,
            RangeEnd = 1000,
            Type = CommissionType.Percentage,
            CommissionAmount = 0.1m,
            MinCommission = 70,
            MaxCommission = 90
        },
        new()
        {
            RangeStart = 1000,
            RangeEnd = 10000,
            Type = CommissionType.Percentage,
            CommissionAmount = 0.2m,
            MinCommission = 250,
            MaxCommission = 1500
        },
        new()
        {
            RangeStart = 10000,
            RangeEnd = 0, // 0 = infinity
            Type = CommissionType.FlatRate,
            CommissionAmount = 2000,
            MinCommission = 0,
            MaxCommission = 0
        }
    }
};

Calculate Commission

Standard (principal-based):

decimal principal = 1000m;
decimal commission = Commission.ComputeCommission(principal, rule);
// Result: 25 (flat) + 70 (min enforced) = 95

Selector-based (different selection and application values):

decimal orderPrice = 2000m;     // Amount to calculate commission on
decimal ticketCount = 3m;       // Value to select the range

// Select range based on ticketCount, apply commission to orderPrice
decimal commission = Commission.ComputeCommission(orderPrice, ticketCount, rule);

Use case: When the value that determines which range to use (e.g., ticket quantity) differs from the amount you calculate commission on (e.g., order total).

Calculation Types

Proportional (Tiered)

Commission accumulates across tiers as the amount increases:

var proportional = new CommissionRule
{
    CalculationType = CalculationType.Proportional,
    CommissionRangeConfigs = new List<CommissionRangeConfigs>
    {
        new() { RangeStart = 0, RangeEnd = 100, Type = CommissionType.Percentage, CommissionAmount = 0.05m },
        new() { RangeStart = 100, RangeEnd = 0, Type = CommissionType.Percentage, CommissionAmount = 0.03m }
    }
};

// For $200:
// - First $100: $100 * 5% = $5
// - Next $100: $100 * 3% = $3
// Total: $8

Absolute (Flat per tier)

Only the matching tier's commission applies:

var absolute = new CommissionRule
{
    CalculationType = CalculationType.Absolute,
    CommissionRangeConfigs = new List<CommissionRangeConfigs>
    {
        new() { RangeStart = 0, RangeEnd = 100, Type = CommissionType.FlatRate, CommissionAmount = 10 },
        new() { RangeStart = 100, RangeEnd = 0, Type = CommissionType.FlatRate, CommissionAmount = 25 }
    }
};

// For $200: $25 (uses second tier only)

Range Configuration

CommissionRangeConfigs Properties

Property Type Description
RangeStart decimal Start of range (inclusive)
RangeEnd decimal End of range (exclusive), 0 = infinity
Type CommissionType FlatRate or Percentage
CommissionAmount decimal Commission value (flat amount or percentage like 0.1 for 10%)
MinCommission decimal Minimum commission for this range
MaxCommission decimal Maximum commission for this range, 0 = infinity

CommissionType

  • FlatRate: Returns CommissionAmount directly (min/max ignored)
  • Percentage: Calculates principal × CommissionAmount, clamped by min/max

Percentage Limits

For safety, percentage commissions are limited to ±1000%:

// ✅ Valid: 10% = 0.1
CommissionAmount = 0.1m

// ❌ Invalid: 1500% = 15 (throws exception)
CommissionAmount = 15m

Validation

Automatic Validation

Validation occurs automatically on first use:

decimal commission = Commission.ComputeCommission(1000m, rule);
// Validates rule, caches normalized version, computes result

Manual Validation

bool isValid = Commission.ValidateRule(rule);

Validation Rules

Required:

  • At least one range starting at 0
  • Ranges must be contiguous (no gaps)
  • Ranges must cover [0, ∞)
  • MaxCommission ≥ MinCommission (when MaxCommission ≠ 0)

Forbidden:

  • Overlapping ranges
  • Gaps in coverage
  • Equal RangeStart and RangeEnd (except single range: both 0)
  • Percentage commission outside ±1000% (±10 as decimal)

DateTime Overlap Checker

Utility for validating commission period overlaps:

using CommissionCalculator.Helper;
using CommissionCalculator.DTO;

var period1 = new List<DateTimePair>
{
    new(new DateTime(2024, 1, 1), new DateTime(2024, 1, 10))
};

var period2 = new List<DateTimePair>
{
    new(new DateTime(2024, 1, 5), new DateTime(2024, 1, 15))
};

bool hasOverlap = DateTimeOverlapChecker.HasOverlap(period1, period2);
// Result: true

Performance

  • 5+ million calculations/second (after initial validation/normalization)
  • Zero allocations per calculation (after cache hit)
  • Binary search for range lookup: O(log n)
  • Prefix sum optimization for proportional calculations
  • ConditionalWeakTable caching of normalized rules

Performance characteristics:

First calculation: ~50μs (validation + normalization + computation)
Subsequent calculations: ~200ns (cache hit + binary search + math)
Memory: ~1KB per cached rule

Advanced Usage

Single Range (Flat Commission)

var flatRule = new CommissionRule
{
    CalculationType = CalculationType.Absolute,
    CommissionRangeConfigs = new List<CommissionRangeConfigs>
    {
        new()
        {
            RangeStart = 0,
            RangeEnd = 0, // Special case: both 0 for single range
            Type = CommissionType.FlatRate,
            CommissionAmount = 50,
            MinCommission = 0,
            MaxCommission = 0
        }
    }
};

// Any amount: $50 commission

Progressive Percentage with Caps

var capped = new CommissionRule
{
    CalculationType = CalculationType.Proportional,
    CommissionRangeConfigs = new List<CommissionRangeConfigs>
    {
        new()
        {
            RangeStart = 0,
            RangeEnd = 1000,
            Type = CommissionType.Percentage,
            CommissionAmount = 0.05m,
            MinCommission = 10,   // At least $10
            MaxCommission = 50    // No more than $50 per tier
        },
        new()
        {
            RangeStart = 1000,
            RangeEnd = 0,
            Type = CommissionType.Percentage,
            CommissionAmount = 0.02m,
            MinCommission = 20,
            MaxCommission = 0     // Unlimited on second tier
        }
    }
};

Selector-Based Example

// Event ticketing: commission based on ticket count, applied to total price
var ticketRule = new CommissionRule
{
    CalculationType = CalculationType.Absolute, // Required for selector-based
    CommissionRangeConfigs = new List<CommissionRangeConfigs>
    {
        new() { RangeStart = 0, RangeEnd = 10, Type = CommissionType.Percentage, CommissionAmount = 0.1m },
        new() { RangeStart = 10, RangeEnd = 0, Type = CommissionType.Percentage, CommissionAmount = 0.05m }
    }
};

decimal orderTotal = 500m;
decimal ticketsSold = 15m;

// Uses second range (15 tickets), applies 5% to $500 order
decimal commission = Commission.ComputeCommission(orderTotal, ticketsSold, ticketRule);
// Result: $25

Conventions

  • Infinity as 0: Set RangeEnd = 0 or MaxCommission = 0 to represent ∞
  • Complete coverage: Rules must cover [0, ∞) with no gaps
  • Exclusive end: RangeEnd is exclusive (range is [Start, End))
  • Decimal precision: Use DecimalPlace to control rounding (default: 4)

Common Patterns

Affiliate Marketing

// Higher commission for higher sales
CalculationType = CalculationType.Absolute
Ranges:
  $0-$1000: 5%
  $1000-$5000: 7%
  $5000+: 10%

Payment Processing

// Tiered fees that accumulate
CalculationType = CalculationType.Proportional
Ranges:
  $0-$10,000: 2.9% + $0.30 min
  $10,000+: 1.5%

Broker Fees

// Fixed fee per transaction tier
CalculationType = CalculationType.Absolute
Ranges:
  $0-$10,000: $9.99
  $10,000-$100,000: $19.99
  $100,000+: $49.99

License

MIT

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 is compatible.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • net10.0

    • No dependencies.
  • net8.0

    • No dependencies.
  • net9.0

    • No dependencies.

NuGet packages (1)

Showing the top 1 NuGet packages that depend on Pandatech.CommissionCalculator:

Package Downloads
Pandatech.SharedKernel

Opinionated ASP.NET Core 10 infrastructure kernel: OpenAPI (Swagger + Scalar), Serilog, MediatR, FluentValidation, CORS, SignalR, OpenTelemetry, health checks, maintenance mode, resilience pipelines, and shared utilities.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
6.0.0 160 2/28/2026
5.0.1 160 1/26/2026
5.0.0 141 12/28/2025
4.1.0 330 11/13/2025
4.0.2 322 11/13/2025
4.0.1 307 2/17/2025
4.0.0 229 11/21/2024
3.3.0 553 3/15/2024
3.2.1 240 3/13/2024
3.2.0 264 3/13/2024
3.1.0 245 3/11/2024
3.0.0 245 3/7/2024
2.1.2 251 3/5/2024
2.1.1 236 3/5/2024
2.1.0 287 1/31/2024
2.0.3 220 1/30/2024
2.0.2 276 1/11/2024
2.0.1 311 11/29/2023
2.0.0 242 11/29/2023
1.0.3 288 11/1/2023
Loading failed

Multi-target net8.0/9.0/10.0, improved documentation, enhanced README with examples