Ownware
Home›Commissa›Manual
Commissa · Manual

Commissa Manual, as shipped in the download

Commissa — User Manual

Sales commission: schemes, statements, adjustments and disputes. Version 3.1.4 [src: app/controllers/api.php:18].

About this manual

Every statement here was written by reading Commissa's own source, and each one carries the file it came from in a bracketed src marker. Paths are relative to the folder this docs directory sits in. If a sentence disagrees with the application, the application is right and this manual has a bug — the markers exist so you can check rather than take our word for it.

Nothing is described that the code does not do. Where something is deliberately limited, that is said plainly rather than left out.

What Commissa is

It computes what is owed to a sales representative. The source calls the engine the moat, because here the maths is the product [src: app/src/Commission.php:3].

It never moves money — no cards, no bank rails, no crypto, no payment processor of any kind [src: app/src/Commission.php:6].

Money is integer cents and commission rates are integer basis points, where 10,000 is 100%. Floats never touch a stored or computed amount [src: app/src/Commission.php:5].

Three schemes

[src: app/src/Commission.php:9]

  • Flat — one rate on every pound of a representative's won sales.
  • Tiered — progressive bands on cumulative won volume in the period, exactly like marginal tax brackets: say 5% up to £10,000, then 8% above. A single deal that straddles a band boundary is split across the bands correctly.
  • Category — a rate per product category, with a default for anything uncategorised [src: app/src/Commission.php:148].

Only won deals earn commission [src: app/src/Commission.php:32].

The penny-exactness guarantee, and what it does and does not promise

The source states four penny-exact guarantees and says all four are covered by the test suite [src: app/src/Commission.php:16]. They are unusually strong, and one of them has a consequence people find surprising.

Why the lines always add up

Under flat and tiered schemes, a deal's commission is defined as C(volume after) − C(volume before), where C is the cumulative commission on cumulative volume [src: app/src/Commission.php:17].

Because the per-deal lines are consecutive deltas of one monotonic function, they telescope: the sum of the statement lines equals C(period total) exactly, for any tier structure and any deal sequence. No penny is ever created or lost at a band boundary [src: app/src/Commission.php:19].

The source notes this is the same split-invariant used in the consignment product, applied to progressive tiers [src: app/src/Commission.php:21].

Under a category scheme the guarantee is simpler: each deal is rounded independently, half up, and the lines sum to the period total by construction [src: app/src/Commission.php:23].

⚠️ The total is order-independent. The individual lines are not.

This follows from the definition and is worth stating plainly, because it is the question a representative will eventually ask.

A deal's line is the delta at the point in the sequence where that deal falls [src: app/src/Commission.php:140]. Two identical deals therefore earn different amounts depending on how much volume preceded them: the earlier one may sit entirely in a 5% band while the later one sits in the 8% band.

The period total is unaffected. Whatever order the deals arrive in, the statement sums to the same figure.

If a representative asks why their colleague's identical deal shows a larger commission, that is the answer: not a bug, and not favouritism — the bands are cumulative, so position in the sequence decides which band a deal falls in, while the period total is fixed regardless.

The product helps you explain it: each tiered line carries a label naming the band or bands it actually touched — "8%", or "5% → 8%" for a straddle [src: app/src/Commission.php:216].

Adjustments and net pay

Net payout is gross commission plus the signed sum of the period's adjustments — bonuses positive, clawbacks negative — in integer cents with a final safe clamp [src: app/src/Commission.php:25].

Adjustment kinds are bonus, clawback and manual [src: app/src/Commission.php:39].

Disputes

A dispute hangs off the deal whose commission is being questioned, and resolves into at most one adjustment — the same adjustments row the payout maths already reads, so a resolved dispute moves money through exactly one path [src: app/src/Database.php:149].

That is the right design: a dispute settlement is not a second, parallel way for money to reach a representative.

Two details from the schema worth knowing [src: app/src/Database.php:152]:

  • Representatives have no logins in this product. The person who raised a dispute is the user who recorded it; the representative is who it concerns.
  • The decision timestamp is what makes a decision once-only [src: app/src/Database.php:153].

Statements are derived until the period is closed

A statement is computed from the deals, the scheme and the adjustments each time it is asked for [src: app/src/Auth.php:21].

That has a consequence the source states directly, and it is the reason for the permission rule below: changing a rate or a band boundary changes what every representative is owed, and it changes it retroactively for any open period recomputed afterwards.

Closing a period (from 3.1.4) stops that for the period you have paid. A manager or an administrator closes a period once it has ended; every representative's statement is stored as it stands [src: app/controllers/v3.php:89], and from then on the period page, the statement, its PDF and CSV, the rep email, the API and the AI tools all read the stored statements [src: app/src/Commission.php:358]. Editing a deal, a rule or an adjustment afterwards no longer changes them; the period page shows what today's figures would compute beside what was paid. Nothing can be added to or removed from a closed period, and it cannot be deleted [src: app/controllers/v3.php:73]; settle a difference in the next open period. Only an administrator can reopen a period, and the reopening is audited [src: app/controllers/v3.php:116].

Users and roles

Three roles: viewer, manager, admin [src: app/src/Auth.php:27].

A manager runs the plan — deals, adjustments, disputes, periods and representatives [src: app/src/Auth.php:28]. Rules stay with the owner.

Permissionviewermanageradmin
.view permissionsyesyesyes
audit.viewyesyesyes
deal.*, adjustment.*, dispute.*, period.*, rep.*—yesyes
view.save—yesyes
schemes, rates, tier bands, settings, users——yes

Why rules are admin-only

A specific reason rather than a generic one [src: app/src/Auth.php:19]:

A rate or a band boundary changes what every representative is owed, and it changes it retroactively for any period recomputed afterwards — the statement is derived, never stored. Deciding what the plan pays is an owner's decision; running the plan is the manager's.

(From 3.1.4 a closed period is the exception: its statements are stored at the close and a later rule change does not reach them.)

The audit trail is granted to a viewer explicitly — audit.view is named in the viewer's list rather than arriving through the wildcard [src: app/src/Auth.php:27].

The API and agent access

Six tools are exposed to an agent [src: app/controllers/v3.php:354]: listing representatives, representative detail, a statement preview, a period report and listing disputes on the read side; recording a deal on the write side.

An agent can therefore add the inputs and read the results. It cannot change the scheme, the rates or the bands — those are admin-only for the reason above.

The agent endpoint reports the same version as the rest of the product [src: app/controllers/v3.php:353].

What Commissa does not do

It does not move money [src: app/src/Commission.php:6]. It computes what is owed; paying it happens elsewhere.

It does not lose or invent a penny at a band boundary [src: app/src/Commission.php:19].

It does not give a representative a login [src: app/src/Database.php:152].

It does not let a dispute pay out through a second path [src: app/src/Database.php:150].

It does not store a statement for an open period [src: app/src/Auth.php:21] — which is why a rule change is retroactive for open periods, and why rules are the owner's. A closed period's statements are stored [src: app/controllers/v3.php:89].

← Back to Commissa · Quickstart · API · Test run

Affiliate program
Recommend tools people own — earn 35% on every sale. 90-day tracking, instant delivery, payouts by Lemon Squeezy.
Become an affiliate →