Referral structures

How referrals are recorded, how direct, binary and unilevel differ, why binary placement does not decide who gets paid, and what approval, spillover and structure changes do to an existing network.

6 min readUpdated 3 August 2026binary, unilevel, direct, referral, tree

Everything the programme pays is decided by two things: the referral record that says who introduced whom, and the structure that says how far up that chain a commission travels. The tree diagrams your members look at are a third thing, and they are not involved in the arithmetic at all.

The referral record

One row in mlm_referral per relationship: a referrerId, a referredId and a status of PENDING, ACTIVE or REJECTED.

It is created in exactly two ways.

By registration. A visitor arrives at /register?ref=<user id> and signs up. Both the email/password and the Google sign-up paths honour it. Note the parameter: it is the referrer's user UUID, not a short code, not a username. There is no separate referral-code table — the member's own id is the code, and the link generator simply pastes it into a URL.

By an administrator, on Admin → Affiliate → Referrals, by picking a referrer and a referred user.

Two rules are enforced at creation, and both fail closed:

  • No self-referral. Registering with your own id as ref is ignored, and the admin create route rejects referrer and referred being the same person.
  • One sponsor, permanently. referredId carries a unique index. A user can appear as referred exactly once, ever. There is no re-assignment, no "transfer to another sponsor", and a soft-deleted referral still occupies the slot.

When BINARY or UNILEVEL is active, a member who has no referral record of their own gets a self-referral row written for them (referrerId = referredId) the first time they need a tree root — when someone signs up under them, or when they open the Network page.

That row consumes their unique referredId slot. If you later want to record that this member was themselves introduced by somebody, you cannot: the insert violates the unique index. Decide your top-level sponsors before you turn on a multi-level structure.

Approval

Admin → Affiliate → Settings → Require Approval decides whether a new referral starts ACTIVE or PENDING.

A PENDING referral is not a member of anything. It earns no commission — both reward engines only consider ACTIVE rows — and it is deliberately not placed in the tree. Placement happens at the moment of approval instead.

That matters most under BINARY, where each node has only two child slots. If pending referrals were placed immediately, an application you were never going to approve would occupy a slot and push a genuine member into spillover somewhere else in the tree.

Rejecting works the other way round: the node is detached from its parent, the parent's freed child slot is cleared, and any children the rejected node had are re-parented to its parent so a rejection cannot orphan a live sub-tree.

The three structures

Set on Admin → Affiliate → Settings. One setting, platform-wide, applied to every future transaction.

DIRECT

The default. There is no tree and no node table. A commission goes to the immediate sponsor at the condition's full rate, and stops there.

If you are running a straightforward "refer a friend, earn 2% of their deposits" programme, this is what you want. It has no configuration beyond the conditions themselves and nothing about it can be misconfigured into paying nothing.

UNILEVEL

Every referral gets a node in mlm_unilevel_node whose parent is the sponsor's node. A sponsor may have any number of direct children.

A commission is split across 2–7 levels of sponsors by percentage. With levels set to 3 and shares of 50 / 30 / 20, a 2% deposit commission on a 1,000 USDT deposit produces 20 USDT of commission, distributed as 10 / 6 / 4 USDT to the member's sponsor, their sponsor's sponsor and so on.

BINARY

Every referral gets a node in mlm_binary_node, which holds a parent and exactly two children — left and right.

Placement is under the sponsor's node. If both of the sponsor's slots are already full, the system searches breadth-first from that node for the nearest free slot and places the new member there. That is spillover: a member you introduced appears underneath one of your existing downline rather than directly beneath you.

The tree is also cycle-checked before placement. If the person being placed is already an ancestor of the target node the request is refused with a 409 rather than creating a loop.

The thing that surprises everyone

Both BINARY and UNILEVEL resolve their payees by walking mlm_referral.referrerId — the sponsor chain, who invited whom. Neither consults mlm_binary_node when paying.

So "Level 1 … Level N" on the settings screen means levels of the sponsor chain, not depths of the binary tree, and a member placed by spillover is still paid through the person who invited them, not through their tree parent.

Binary placement, the two-child limit and the spillover diagram are presentation. If you are costing a binary compensation plan on the assumption that spillover changes payout paths, the numbers will not match what the platform does.

The consequence is blunt: BINARY and UNILEVEL pay identically for the same level percentages. Choosing binary changes what members see on the Network page and how the structure feels; it does not change anyone's earnings. Choose it for presentation, not economics.

How the upline walk actually runs

Starting from the member who transacted, the engine repeatedly asks "who referred this user?" and collects up to N sponsors, where N is your configured level count. It stops early on any of:

  • No referral record — the top of a chain. Normal, not an error.
  • A self-referral (referrerId = referredId). This marks the top of the tree. Without that stop, the person at the top would be paid at level 2, then again at level 3, 4 and so on for a single transaction.
  • A cycle — a sponsor already seen during this walk. Hand-edited or imported referral tables can contain them; the walk stops and logs a warning rather than looping.

Every level found is paid its configured share. Levels with nobody in them are simply not paid — the money is not redistributed to the levels above.

Level percentages

Between 2 and 7 levels, each with a percentage. Two hard rules:

  • A level with no configured percentage is skipped, not defaulted. If you set the level count to 5 but only fill in three boxes, levels 4 and 5 earn nothing.
  • The total must be 100% or less. Above that the engine logs an error and returns without creating a single reward — not just for the excess level, for the whole transaction. The settings screen shows a running total and turns it red for this reason.

The percentages are shares of the commission the condition produced, not additions to it. Setting all levels to 100% each does not multiply your payout by the number of levels; it stops payouts entirely.

Changing structure on a live programme

The structure setting is read at the moment a commission is calculated and at the moment a referral is placed. It is not a migration.

Switching from DIRECT to BINARY or UNILEVEL starts creating nodes for new referrals only. Historical referrals have no node, so they do not appear in the tree diagram — but they are still paid, because payouts walk the referral table rather than the nodes. Members will ask why their existing downline is missing from the Network page.

Switching between BINARY and UNILEVEL leaves the old node table populated and starts filling the other one. Nothing migrates. Payouts are unaffected, because neither table is consulted for payment.

Switching back to DIRECT stops multi-level payouts immediately — only the immediate sponsor earns from the next transaction onward. Existing unclaimed rewards keep their amounts; they were already calculated.

A reward row stores a settled amount. Changing the structure, the level percentages or a condition's rate changes what future activity earns and nothing about what has already been credited. There is no recalculation job and no back-dating.

What members see

The Network page renders the structure that is currently configured: a flat list of direct referrals under DIRECT, the sponsor hierarchy under UNILEVEL, and the binary node tree under BINARY. Depth is capped at your configured level count, and under BINARY at 10 regardless, so a deep tree renders as a manageable slice rather than trying to load everything.

If the structure is set to BINARY or UNILEVEL but no level count is configured, the page returns an empty structure containing only the member themselves — a valid response that looks like a bug. Set the levels.

Next: Commission conditions for the rules that decide what a transaction is worth in the first place.