---
title: "Run referral billing"
description: "Set the marginal commission brackets, read and settle the commission rows a scheduled job generates for every referrer, add manual payments, and understand why an Unconfirmed amount keeps changing."
type: "howto"
audience: [admin]
keywords: [referral billing, referral program billing, commission, brackets, marginal share, upper bound, Apply now, Schedule for next month, Hide referral details, ledger, Unconfirmed, Confirmed, Paid, Declined, Analytics status, manual payment, referral user, referred user, Manage Referral Program]
ui_path: "Admin → Billing & fees → Referral program billing"
---

Fetch the complete documentation index at: https://epom.com/ad-server/docs/llms.txt. Use this file to discover all available pages before exploring further. Append .md to any documentation page URL to get its markdown version.

# Run referral billing

Users who bring publishers in earn a commission on those publishers' revenue. **Referral program
billing** is where you set the commission brackets and settle the monthly commission rows. The
rows are not created by hand: a scheduled job regenerates the **current** month's rows every hour,
and a second job regenerates the **previous** calendar month once a day at 01:23 server time on
the first four days of the month. A row is rewritten only while it is *Unconfirmed*; once you
mark it *Confirmed*, *Paid* or *Declined* the job leaves it alone. Commissions below one cent
produce no row.

**Example.** Northwind Media's brackets are 10 % up to $1,000, 7 % from $1,000 to $5,000 and 5 %
above. In October the sites referred by one user earn $6,000, so their commission row reads
$100 + $280 + $50 = **$430** — each share applies only to the slice of revenue inside its bracket,
the way an income-tax band works. On 15 October the row still shows $210 (the month so far); on
1 November the job writes the full-month figure, and it stays at $430 once you mark it
*Confirmed*.

## Typical scenarios

| You want | Do | Where |
|---|---|---|
| Pay 10 % on the first $1,000 of referred revenue, 7 % up to $5,000, 5 % above | Three rows in the active bracket table: $1,000 / 10, $5,000 / 7, *and above* / 5 → **Apply now** | *Currently active brackets* |
| Change the rates from the 1st of next month without touching this month | Edit the right-hand table → **Schedule for next month** | *Brackets — activates on …* |
| Settle October: pay every referrer whose row you have checked | Filter **Year** / **Month**, tick the rows, **New status** *Paid* → **Apply** | The ledger |
| Give one referrer a one-off $150 | **Filter / add payment**: referral user, referred user, **Amount** 150 → **Add** | *Filter / add payment* |
| Keep referrers from seeing the referral details | Tick **Hide referral details** → its own **Save** | *Referral display preferences* |
| Hand the month's ledger to accounting | Filter it, **Export to CSV** | The ledger toolbar |

## Step by step

1. Go to **Admin → Billing & fees → Referral program billing**. It needs the *Referral Program
   Billing* admin permission, the referral program enabled and bracket percentages agreed — see
   [Referral program](https://epom.com/ad-server/docs/guides/collaboration/referral-program.md).

   ![Referral program billing page with bracket editors, the payment filter and the commission ledger](https://epom.com/docs-images/ad-server/referral-billing/referral-ledger.webp)

2. Maintain two bracket tables side by side. The left one, *Currently active brackets — in
   effect since \<the 1st of this month\>*, saves with **Apply now**. The right one, *Brackets —
   activates on \<the 1st of next month\>*, saves with **Schedule for next month**. Each row is
   an **Upper bound ($)** and a **Share (%)**; **Add bracket** inserts a row above the trailing
   *and above* row, which is always open-ended. Neither table is ever empty: a network that has
   never configured brackets shows one open-ended row carrying the network's flat referral rate,
   and adding rows above it turns that flat rate into the top band.
3. Rates are **marginal**: each bracket's share applies only to the slice of revenue inside that
   bracket, not to the whole amount.
4. Optionally tick **Hide referral details** in the **Referral display preferences** section and
   click its own **Save**. The checkbox does not save by itself.
5. Use **Filter / add payment** to narrow the ledger by referral user, referred user, year, month
   and status. **Year** starts at the current year. The same row adds a manual payment: pick both
   users, type an **Amount** and optional **Comments**, then click **Add**. **Add** stays
   disabled until a referral user, a referred user and an amount are all set. **Reset** returns
   the filters to that starting state.
6. Work the ledger grid. Columns are Referral, Referred users, Year, Month, Amount, **Status**,
   **Analytics status** and Comments. Tick rows and pick a **New status** + **Apply** to
   bulk-update, **Export to CSV** to download the filtered ledger, or **Delete** to remove rows.
   Double-click a row to edit its amount, status and comments in a dialog.
7. Read the footer: **Total** is every row except *Declined*, **Confirmed** is only the
   *Confirmed* rows, **Paid** only the *Paid* rows — all three over the current filter.

## Caveats and exceptions

- **The Referral users list is not every user who has referred someone.** A referrer only
  appears there when their own role has the **Manage Referral Program** permission enabled. With
  that permission off for every role, the list is empty and no manual payment can be added —
  even though the ledger below may be full of rows. The **Referred users** list then fills from
  whoever the chosen referrer actually referred.
- **An *Unconfirmed* amount is not stable.** The hourly job recomputes it from the month's
  revenue so far and overwrites the row, so a figure you noted this morning can be larger by the
  afternoon. Move a row to *Confirmed* before you treat its amount as settled — that is what
  stops the job rewriting it.
- **From the fifth of the month, last month's *Unconfirmed* rows stay as they are** until you
  settle them: the previous-month job runs only on the first four days.
- **Editing brackets does not restate a generated month.** **Apply now** changes what the current
  month's *Unconfirmed* rows are recomputed to on the next hourly run; rows already Confirmed or
  Paid, and closed earlier months, keep the numbers they were generated with.
- **An invalid bracket set is rejected as a whole.** If any row fails, nothing is saved. The
  error toast restates the rules rather than naming the offending row: *"Brackets are invalid.
  Upper bounds must increase. Share must be between 0 and 100. Last bracket may be unbounded."*
  With more than two or three bands, check them yourself against those three rules.
- **A per-user share bypasses the brackets.** A referral user with a per-user share configured
  gets a flat percentage of the referred user's revenue; the brackets on this page apply only to
  referral users without that override.
- **Analytics status is not the payment status.** It is the *lowest* accounting-period
  confirmation status across every advertiser whose traffic ran on that referred publisher's
  sites that month — the weakest link. It stays at *Incomplete Data* until every contributing
  advertiser's days have moved up, and reads *Unidentified* when no status has been recorded for
  them. See [Accounting periods](https://epom.com/ad-server/docs/guides/admin/accounting-periods.md).
- **The commission base is read live.** It is the sum of the Publisher-family *Revenue* for the
  referred user's sites, each row floored at its minimal revenue, taken straight from the daily
  statistics at generation time — no aggregate in between, so it can differ from the Billing
  page's publisher figures for days outside the 14-day aggregate window (see
  [Where the numbers come from](https://epom.com/ad-server/docs/guides/admin/accounting-periods.md#where-the-numbers-come-from)).

## Not working?

| Symptom | Check | Where |
|---|---|---|
| The **Referral users** list is empty although the ledger has rows | No role has **Manage Referral Program** enabled; the referrer must hold it on their own role. | **Admin → Users & access → User roles & permissions** |
| A row's amount changed since yesterday | It is *Unconfirmed*; the hourly job recomputed it. Confirm it to freeze it. | The ledger **Status** |
| Last month has no rows for a referrer | Commissions below one cent produce no row, or the referred sites had no revenue. A missing amount can still be booked by hand with *Filter / add payment*. | The referred user's sites in Billing; *Filter / add payment* |
| **Apply now** is refused with *Brackets are invalid…* | Upper bounds do not increase, a share is outside 0–100, or a bound is missing on a row that is not the last. The message does not name the row. | The bracket table |
| New brackets did not change an earlier month | Expected: closed months and Confirmed/Paid rows keep their generated numbers. | — |
| **Add** stays disabled | A referral user, a referred user and an amount must all be set. | *Filter / add payment* |
| **Hide referral details** did not stick | It has its own **Save**; the checkbox does not save by itself. | *Referral display preferences* |
| *Analytics status* stays at *Incomplete Data* | At least one advertiser whose traffic ran on the referred sites has not had its days moved up. | An Analytics report grouped by Advertiser — [Accounting periods](https://epom.com/ad-server/docs/guides/admin/accounting-periods.md) |
| The page is not in the sidebar | Your admin role lacks *Referral Program Billing*. | **Admin roles & permissions** |

## Reference

| Field or column | Meaning |
|---|---|
| **Upper bound ($)** / **Share (%)** | A bracket: the revenue slice up to the bound, and the commission on that slice. The trailing *and above* row is open-ended. |
| **Apply now** / **Schedule for next month** | Save the left (active, since the 1st of this month) or right (activates on the 1st of next month) table. |
| **Hide referral details** | Referral display preference, saved with its own **Save**. |
| **Referral** / **Referred users** | The referrer and the user they brought in. |
| **Amount** | The commission for the month; recomputed hourly while *Unconfirmed*. |
| **Status** | *Unconfirmed*, *Confirmed*, *Paid*, *Declined*. Only *Unconfirmed* rows are rewritten by the jobs. |
| **Analytics status** | The lowest accounting-period status among the advertisers that ran on the referred sites that month. |
| **Total** / **Confirmed** / **Paid** (footer) | Every row except *Declined* / only *Confirmed* rows / only *Paid* rows — over the current filter. |

| Job | When | What it does |
|---|---|---|
| Current month | Every hour | Regenerates this month's *Unconfirmed* rows from revenue so far |
| Previous month | 01:23 server time, days 1–4 of the month | Regenerates last month's *Unconfirmed* rows |

## Related

- [Billing, ad-server fees and referral billing](https://epom.com/ad-server/docs/guides/admin/finances-and-billing.md)
- [Accounting periods and where the numbers come from](https://epom.com/ad-server/docs/guides/admin/accounting-periods.md)
- [Referral program](https://epom.com/ad-server/docs/guides/collaboration/referral-program.md)