Commission Engine (Differential Model)
The IWM Platform uses a Differential Commission Model with 7 income types. Partners earn commissions based on the difference between their rank rate and their downline's rank rate, with unlimited depth.
Commission Model Overview
| Property | Value |
|---|---|
| Model Type | Differential (not Unilevel) |
| Depth | Unlimited |
| Income Types | 7 (3 Active + 3 Passive + 1 Pool) |
| Primary Currency | USD |
| Rate Range | 3% - 20% based on rank |
Core Calculation Formula
IF consultant_rank > source_partner_rank:
commission = (consultant_rate - source_rate) × amount
ELSE:
commission = 0 // No commission when rank is equal or lowerThe 7 Income Types
Active Income (Types 1-3)
| Type | Name | Trigger | Calculation |
|---|---|---|---|
| 1 | Personal Sales | Direct sale to own client | personal_rate × amount |
| 2 | Team Sales | Downline partner makes sale | Differential on sale amount |
| 3 | Repeat Sales | Existing client repurchases | Same as Personal Sales |
Passive Income (Types 4-6)
| Type | Name | Trigger | Calculation |
|---|---|---|---|
| 4 | Portfolio Returns | Own investment generates profit | Strategy-specific returns |
| 5 | Client Profits | Personal client earns profit | passive_rate × client_profit |
| 6 | Network Profits | Downline's client earns profit | Differential on profit amount |
Leadership Income (Type 7)
| Type | Name | Trigger | Calculation |
|---|---|---|---|
| 7 | Leadership Pool | Weekly/Monthly distribution | Equal share among qualified |
Calculation Flow
Transaction Completed
│
▼
┌─────────────────────┐
│ Identify Income Type│
│ (1-7) │
└──────────┬──────────┘
│
▼
┌─────────────────────┐
│ Get Referral │
│ Attribution │
└──────────┬──────────┘
│
▼
┌─────────────────────┐
│ Get Upline Chain │
│ (Unlimited Depth) │
└──────────┬──────────┘
│
▼
┌────────────────────────────────┐
│ For Each Partner in Upline: │
│ 1. Get partner rank & rate │
│ 2. Compare to source rate │
│ 3. Calculate differential │
│ 4. Create transaction record │
│ 5. Update pending balance │
└────────────────────────────────┘
│
▼
┌─────────────────────┐
│ Emit Commission │
│ Calculated Events │
└─────────────────────┘Differential Commission Processor
typescript
interface DifferentialCommissionPayload {
idempotencyKey: string;
incomeType:
| "PERSONAL_SALES"
| "TEAM_SALES"
| "REPEAT_SALES"
| "CLIENT_PROFITS"
| "NETWORK_PROFITS"
| "LEADERSHIP_POOL";
sourceType:
| "ORDER"
| "INVESTMENT"
| "INVESTMENT_PROFIT"
| "POOL_DISTRIBUTION";
sourceId: string;
amountUsd: number;
sourcePartnerId: string; // Partner who triggered this event
sourcePartnerRank: string;
sourcePartnerRate: number;
}
async function processDifferentialCommission(
job: DifferentialCommissionPayload,
) {
const {
idempotencyKey,
sourceId,
sourcePartnerId,
sourcePartnerRate,
amountUsd,
} = job;
// 1. Check idempotency
const existing = await db.idempotencyKey.findUnique({
where: { key: idempotencyKey },
});
if (existing) return existing.response;
// 2. Process with proper locking
return await db.$transaction(
async (tx) => {
// 2a. Get ENTIRE upline chain (unlimited depth)
const upline = await tx.$queryRaw`
SELECT
p.id as partner_id,
p.status,
r.code as rank_code,
r.personal_sales_rate,
r.passive_income_rate,
r.entrance_fee_rate,
ptp.depth
FROM mlm.partner_tree_paths ptp
JOIN mlm.partners p ON p.id = ptp.ancestor_id
JOIN mlm.ranks r ON r.id = p.current_rank_id
WHERE ptp.descendant_id = ${sourcePartnerId}::uuid
AND ptp.depth >= 1
ORDER BY ptp.depth ASC
`;
if (upline.length === 0) {
await saveIdempotencyKey(tx, idempotencyKey, { commissions: [] });
return { commissions: [] };
}
// 2b. Lock all partner balances in consistent order
const partnerIds = upline.map((u) => u.partner_id).sort();
await tx.$queryRaw`
SELECT id FROM mlm.partner_balances
WHERE partner_id = ANY(${partnerIds}::uuid[])
ORDER BY partner_id
FOR UPDATE
`;
// 2c. Calculate differential commissions
const commissions = [];
let currentSourceRate = sourcePartnerRate;
for (const ancestor of upline) {
if (ancestor.status !== "ACTIVE") continue;
// Get the appropriate rate based on income type
const ancestorRate = getApplicableRate(job.incomeType, ancestor);
// Differential calculation
const differentialRate = ancestorRate - currentSourceRate;
if (differentialRate > 0) {
const grossAmountUsd = amountUsd * (differentialRate / 100);
const netAmountUsd = grossAmountUsd;
// Create commission record
const commission = await tx.commissionTransaction.create({
data: {
partnerId: ancestor.partner_id,
incomeType: job.incomeType,
sourceType: job.sourceType,
sourceId,
sourcePartnerId,
ownRate: ancestorRate,
sourceRate: currentSourceRate,
differentialRate,
grossAmountUsd,
netAmountUsd,
currency: "USD",
status: "PENDING",
idempotencyKey: `${idempotencyKey}:${ancestor.partner_id}`,
},
});
// Update pending balance
await tx.partnerBalance.update({
where: { partnerId: ancestor.partner_id },
data: {
pendingBalanceUsd: { increment: netAmountUsd },
version: { increment: 1 },
lastCalculatedAt: new Date(),
updatedAt: new Date(),
},
});
commissions.push(commission);
// Update current source rate for next iteration
currentSourceRate = ancestorRate;
}
// Stop if we've reached the maximum rate (20%)
if (currentSourceRate >= 20) break;
}
await saveIdempotencyKey(tx, idempotencyKey, {
commissionIds: commissions.map((c) => c.id),
});
return { commissions };
},
{
isolationLevel: "Serializable",
timeout: 30000,
},
);
}
function getApplicableRate(incomeType: string, partner: any): number {
switch (incomeType) {
case "PERSONAL_SALES":
case "TEAM_SALES":
case "REPEAT_SALES":
return partner.personal_sales_rate;
case "CLIENT_PROFITS":
case "NETWORK_PROFITS":
return partner.passive_income_rate;
default:
return partner.personal_sales_rate;
}
}Passive Income Calculation
Type 5: Client Profits
When a partner's direct client earns profit from an investment:
typescript
async function processClientProfitCommission(
clientId: string,
profitAmountUsd: number,
investmentId: string,
) {
// Get the partner who referred this client
const attribution = await db.referralAttribution.findUnique({
where: { userId: clientId },
});
if (!attribution) return;
const partner = await db.partner.findUnique({
where: { id: attribution.partnerId },
include: { rank: true },
});
if (!partner || partner.status !== "ACTIVE") return;
// Calculate passive income
const passiveRate = partner.rank.passiveIncomeRate;
const commissionUsd = profitAmountUsd * (passiveRate / 100);
// Create commission transaction
await createCommission({
partnerId: partner.id,
incomeType: "CLIENT_PROFITS",
sourceType: "INVESTMENT_PROFIT",
sourceId: investmentId,
grossAmountUsd: commissionUsd,
netAmountUsd: commissionUsd,
});
// Trigger network profit calculation for upline
await triggerNetworkProfitCalculation(partner.id, commissionUsd, passiveRate);
}Type 6: Network Profits (Differential on Passive Income)
typescript
async function triggerNetworkProfitCalculation(
sourcePartnerId: string,
clientProfitAmount: number,
sourceRate: number,
) {
// Queue job for differential calculation on network profits
await boss.send("network-profit-calculation", {
idempotencyKey: `network-profit:${sourcePartnerId}:${Date.now()}`,
incomeType: "NETWORK_PROFITS",
sourceType: "INVESTMENT_PROFIT",
sourcePartnerId,
amountUsd: clientProfitAmount,
sourcePartnerRate: sourceRate,
});
}Leadership Pool Distribution
Pool Configuration
| Pool | Ranks | % of Turnover | Frequency | Qualification |
|---|---|---|---|---|
| POOL_5 | 5, 5_PRO | 1% | Weekly | $5,000 / $10,000 weekly volume |
| POOL_6 | 6, 6_PRO | 0.5% | Weekly | $20,000 / $30,000 weekly volume |
| POOL_7 | 7, 7_PRO | 0.5% | Weekly | $45,000 / $60,000 weekly volume |
| POOL_8 | 8, 8_PRO | 0.5% | Weekly | $90,000 / $120,000 weekly volume |
| POOL_9 | 9, 9_PRO | 1% | Monthly | Rank achievement only |
| POOL_10 | 10, 10_PRO | 1% | Monthly | Rank achievement only |
| POOL_11 | 11, 11_PRO | 1% | Monthly | Rank achievement only |
Note: Pools 9-11 do not require separate volume qualification. Partners who have achieved and maintain these ranks automatically participate in monthly distribution. The rank's turnover requirement ($10M-$800M) serves as the qualification threshold.
Distribution Process
typescript
async function distributeLeadershipPool(
poolCode: string,
periodStart: Date,
periodEnd: Date,
) {
const pool = await db.leadershipPool.findUnique({
where: { poolCode },
});
// 1. Calculate total company turnover for period
const totalTurnover = await calculatePeriodTurnover(periodStart, periodEnd);
const poolAmount = totalTurnover * pool.percentageOfTurnover;
// 2. Find qualified participants
const qualifiedPartners = await findQualifiedPartners(
pool,
periodStart,
periodEnd,
);
if (qualifiedPartners.length === 0) {
return { distributed: false, reason: "No qualified participants" };
}
// 3. Calculate per-person share
const perPersonAmount = poolAmount / qualifiedPartners.length;
// 4. Create distribution record
const distribution = await db.poolDistribution.create({
data: {
poolId: pool.id,
periodStart,
periodEnd,
totalTurnoverUsd: totalTurnover,
poolAmountUsd: poolAmount,
qualifiedParticipants: qualifiedPartners.length,
perPersonAmountUsd: perPersonAmount,
status: "PROCESSING",
},
});
// 5. Distribute to each qualified partner
for (const partner of qualifiedPartners) {
await db.$transaction(async (tx) => {
// Create participation record
await tx.poolParticipation.create({
data: {
distributionId: distribution.id,
partnerId: partner.id,
qualified: true,
qualificationVolumeUsd: partner.qualificationVolume,
amountReceivedUsd: perPersonAmount,
branchVolumes: partner.branchVolumes,
},
});
// Create commission transaction
await tx.commissionTransaction.create({
data: {
partnerId: partner.id,
incomeType: "LEADERSHIP_POOL",
sourceType: "POOL_DISTRIBUTION",
sourceId: distribution.id,
grossAmountUsd: perPersonAmount,
netAmountUsd: perPersonAmount,
currency: "USD",
status: "APPROVED", // Pool distributions are immediate
},
});
// Add directly to available balance (no pending period for pools)
await tx.partnerBalance.update({
where: { partnerId: partner.id },
data: {
availableBalanceUsd: { increment: perPersonAmount },
totalEarnedUsd: { increment: perPersonAmount },
incomeLeadershipPoolUsd: { increment: perPersonAmount },
version: { increment: 1 },
updatedAt: new Date(),
},
});
});
}
// 6. Mark distribution as complete
await db.poolDistribution.update({
where: { id: distribution.id },
data: {
status: "DISTRIBUTED",
distributedAt: new Date(),
},
});
return {
distributed: true,
poolAmount,
participants: qualifiedPartners.length,
perPerson: perPersonAmount,
};
}50% Branch Rule Validation
typescript
async function findQualifiedPartners(
pool: LeadershipPool,
periodStart: Date,
periodEnd: Date,
) {
const eligibleRanks = pool.eligibleRanks;
const qualificationVolumes = pool.qualificationVolumes as Record<
string,
number
>;
// Get all partners with eligible ranks
const candidates = await db.partner.findMany({
where: {
status: "ACTIVE",
rank: { code: { in: eligibleRanks } },
},
include: { rank: true },
});
const qualifiedPartners = [];
for (const partner of candidates) {
const requiredVolume = qualificationVolumes[partner.rank.code];
// Calculate branch volumes
const branchVolumes = await calculateBranchVolumes(
partner.id,
periodStart,
periodEnd,
);
// Apply 50% cap per branch
const maxPerBranch = requiredVolume * 0.5;
const cappedTotal = Object.values(branchVolumes).reduce(
(sum, vol) => sum + Math.min(vol, maxPerBranch),
0,
);
if (cappedTotal >= requiredVolume) {
qualifiedPartners.push({
...partner,
qualificationVolume: cappedTotal,
branchVolumes,
});
}
}
return qualifiedPartners;
}
async function calculateBranchVolumes(
partnerId: string,
periodStart: Date,
periodEnd: Date,
): Promise<Record<string, number>> {
// Get direct referrals (branch roots)
const directReferrals = await db.partner.findMany({
where: { sponsorId: partnerId },
});
const branchVolumes: Record<string, number> = {};
for (const branch of directReferrals) {
// Get all descendants of this branch
const branchDescendants = await db.partnerTreePath.findMany({
where: { ancestorId: branch.id },
});
const descendantIds = branchDescendants.map((d) => d.descendantId);
descendantIds.push(branch.id);
// Sum turnover for this branch
const turnover = await db.commissionTransaction.aggregate({
where: {
sourcePartnerId: { in: descendantIds },
createdAt: { gte: periodStart, lte: periodEnd },
incomeType: { in: ["PERSONAL_SALES", "REPEAT_SALES"] },
},
_sum: { grossAmountUsd: true },
});
branchVolumes[branch.id] = turnover._sum.grossAmountUsd || 0;
}
return branchVolumes;
}Batch Processing Schedule
| Job | Frequency | Time | Description |
|---|---|---|---|
| Commission Approval | Daily | 02:00 UTC | Move pending to approved |
| Balance Settlement | Daily | 03:00 UTC | Move approved to available |
| Weekly Pool Distribution | Sunday | 23:00 UTC | Distribute Pools 5-8 |
| Monthly Pool Distribution | 1st of month | 01:00 UTC | Distribute Pools 9-11 |
| Rank Recalculation | Hourly | :00 | Check for rank promotions |
Commission Status Flow
PENDING → APPROVED → PAID
↓
REVERSED/CLAWBACK (if refund/chargeback)| Status | Description | Balance Impact |
|---|---|---|
| PENDING | Calculated, awaiting holding period | +pending_balance |
| APPROVED | Holding period complete | pending → available |
| PAID | In partner's available balance | Already in available |
| REVERSED | Order refunded before payout | -pending_balance |
| CLAWBACK | Order refunded after payout | -available_balance |