Koovira Dev Docs
40-financial/commission.md

Commission & Settlement

Status: ๐ŸŸก Partially implemented (engine complete; a key rule table is empty) ยท Last validated: 2026-09-06

The platform's take on module transactions, including franchisee/territory revenue sharing. Validated against classs/CommissionEngineModule.php and the live schema.


Tables (2026-09-06)

TableRowsRole
platform_commission_settings11commission % per setting key (per module)
commission_transactions92recorded platform take per order
kv_commission_rules0plan/cycle/territory/partner rule matrix โ€” EMPTY

The engine (CommissionEngineModule)

MethodLineWhat
kvRulesReady()34true only if kv_commission_rules has usable rows โ€” currently false
getPlatformCommissionPercent(settingKey)117base % from platform_commission_settings
resolveCommission(moduleKey, planCode, billingCycle, companyId, territoryId, partnerId, revenueType, gross)149full resolution incl. membership/territory
resolveFranchiseeIdByPincode(pincode)246map a pincode โ†’ franchisee/TCP partner
computeFranchiseePercent(franchiseeId, amount, maxAllowed)266franchisee share (capped by getMaxFranchiseePercent)
recordTransaction(payload)304write a commission_transactions row
computeAndRecord(settingKey, txnUid, orderTable, orderId, amount, sellerId, pincode, applicable, membership)566the main entry point modules call
cancelCommissionForOrder(orderTable, orderId)510reverse on cancel/refund
getFranchiseeStatement(id, y, m) / getPlatformStatement(y, m, type)702 / 736reporting

How a module records commission (the pattern)

On a paid order, a module calls computeAndRecord($settingKey='ecommerce', $txnUid, $orderTable='orders_master', $orderId, $orderAmount, $sellerId, $pincode, $applicable=true, $membership). This:

  1. resolves the % (platform_commission_settings + membership/territory via resolveCommission),
  2. writes commission_transactions,
  3. is mirrored into the central ledger as a platform party entry

(see central-finance-ledger.md). On cancel/refund the module calls cancelCommissionForOrder($orderTable, $orderId) โ€” note the polymorphic key (order tables collide across modules; always pass both).

The critical gap (validated)

kv_commission_rules = 0 rows, so kvRulesReady() is false. Any code path that resolves a fee through the rule matrix (notably pay-per-lead LeadUnlockService, and per-application job fees) falls back to fee = 0.00. Evidence: existing lead unlocks recorded fee_charged=0.00, plan_code='free'. Base per-order commission (platform_commission_settings, 11 rows) does fire โ€” commission_transactions has 92 real rows โ€” so CommerceX/Food/etc. order commission works; the rule-matrix products are the ones giving away value for free. Seeding kv_commission_rules is the single switch that turns on lead/territory monetization.

Settlement

Merchant settlement moves the merchant's net (gross โˆ’ commission โˆ’ fees) out of escrow/holding to the merchant wallet/bank. Per-module settlement modules exist (e.g. CommerceSettlementModule.php, TruckSettlementModule.php, CommerceReturnsModule.php). Off- platform movements are logged in wallet_ledger via WalletModule::recordOffplatformLedger. Formal double-entry books are AccountingEngine โ†’ accounting_journal (see admin docs; note the confirmed revenue-mistagging defect documented in wallet.md and central-finance-ledger.md).

Live money-config snapshot (validated 2026-09-06, direct DB read โ€” not code defaults):

  • Escrow platform fee = 2.5%. admin_global_settings.escrow_modules (settings_json) =

{"default":{"platform_fee_percent":2.5,"tax_percent":0,"fees_charged_to_buyer":0,...}}. admin_global_settings.ecommerce.platform_fee_value agrees ("2.5", platform_fee_type: "percent"). This is distinct from the per-order commission below.

  • Settlement commission defaults to 0%, not the 5% base rate.

commerce_settlement_settings has 0 rows (confirmed via COUNT()), so CommerceSettlementModule's settings resolver (queries at company-level then company_id = 0 as the platform default) falls through to its own hardcoded fallback โ€” ['commission_pct' => 0.0, 'settlement_delay_days' => 1] โ€” whenever no row exists, which today is always*. This is separate from platform_commission_settings (11 rows, all currently 5.00%, is_active=1) used by CommissionEngineModule::computeAndRecord() โ€” do not conflate the two: base order commission fires at 5%, but the settlement-layer commission read by CommerceSettlementModule resolves to 0% because its own settings table was never seeded.

  • GST is disabled platform-wide. All 12 rows in kv_gst_settings (ecommerce_order,

event_ticket, shipping_standard, realestate_listing_fee, posting_credits_classifieds, posting_credits_jobs, jobs_onboarding, realestate_onboarding, food_restaurant_6h, food_membership_onboarding, merchant_module_activation, wallet_membership_card) have gst_enabled = 0 (each carries a dormant gst_percent = 18.00 that is not applied). No invoice or order currently carries a GST line regardless of module.

Business rules

  • BR-COM-FIN-001 โ€” base commission % comes from platform_commission_settings keyed by module.
  • BR-COM-FIN-002 โ€” rule-matrix fees require kv_commission_rules; empty โ‡’ fee defaults to 0.
  • BR-COM-FIN-003 โ€” commission is reversed on cancel/refund via cancelCommissionForOrder.
  • BR-COM-FIN-004 โ€” franchisee share is capped by getMaxFranchiseePercent(settingKey).
  • BR-COM-FIN-005 (new, 2026-09-06) โ€” settlement-layer commission is a separate setting from

base order commission; it is read from commerce_settlement_settings, not platform_commission_settings, and currently defaults to 0% because that table is empty.

Errors / gaps (prefix FIN-E)

  • FIN-E001 fee unexpectedly 0 โ€” root cause: kv_commission_rules empty; inspect kvRulesReady().
  • FIN-E002 commission attached to wrong module's order โ€” root cause: order-id collision; ensure

both orderTable and orderId passed.

  • FIN-E003 real-estate commission stuck pending โ€” recorded but never processed (historical:

โ‚น1.3M pending); inspect commission_transactions.status.

  • FIN-E004 (new, 2026-09-06) settlement commission unexpectedly 0% despite a non-zero base

commission on the same order โ€” root cause: commerce_settlement_settings has 0 rows, so CommerceSettlementModule falls back to its hardcoded commission_pct = 0.0 default; seed the table (company_id = 0 row for the platform default) to fix.

Change-impact

Affects every module's revenue line, the finance ledger platform entries, franchisee/TCP payouts, and settlement. Re-test: an order records exactly one commission row at the right %, cancel reverses it, and the polymorphic key isolates modules.