> For the complete documentation index, see [llms.txt](https://mango-5m.gitbook.io/mango5m-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://mango-5m.gitbook.io/mango5m-docs/resources/mango-mdt/configuration/billing-integration.md).

# Billing Integration

Send MDT fines to okokBilling, Codem Billing, esx\_billing, or qb — including the one-line Codem edit.

When an officer issues a fine in the MDT, the fine is recorded in the MDT **and** sent to your billing resource for collection. When the citizen pays it there, the MDT fine flips to **Paid** automatically.

Pick your biller in `config/bridge.lua`:

```lua
Config.Bridge = {
    -- ...
    Billing = 'auto',   -- okokbilling | codem | esx_billing | qb | custom | none
}
```

With `'auto'`, the first running biller wins in this order: `okokbilling` → `codem` → `esx_billing` → `qb`. With `'none'` (or no biller installed), fines are still recorded in the MDT — they're just not collected anywhere.

## At a glance

| Provider      | Config value    | Invoice creation           | Paid sync back to the MDT                     |
| ------------- | --------------- | -------------------------- | --------------------------------------------- |
| okokBilling   | `'okokbilling'` | Automatic                  | ✅ Instant (paid event)                        |
| Codem Billing | `'codem'`       | **One-line edit required** | ✅ Automatic, up to \~1 minute behind (polled) |
| esx\_billing  | `'esx_billing'` | Automatic                  | ✅ Instant (paid event) + poll fallback        |
| qb-management | `'qb'`          | Best effort                | ❌ None — status tags are hidden (see below)   |

**What "paid sync" means:** when the citizen pays the invoice in your billing resource, the MDT fine flips to **Paid** by itself. Some billers announce a payment the moment it happens (an event → instant). Codem fires no such event, so the MDT **checks Codem's records about once a minute** instead — the fine still flips to Paid automatically, just up to \~60 seconds later. Only `qb` genuinely has no way to report payment at all.

## Billers with no paid signal

On a biller that can never report payments (`qb`, or no biller at all), every fine would read **Outstanding forever** — which looks broken even though it isn't. So in that mode the Fines page **automatically hides its payment-status tags**: no Paid/Outstanding/Partially-Paid stamps on tickets or documents, and no status filter chips. (**Void** keeps its stamp — that's an MDT action, not a payment state.)

Everything else keeps working: fines are still issued and billed, and anyone with `fines.manage` can still settle one by hand with **Record Payment** on the citation — amounts and balances stay accurate, only the tags are hidden. No config needed; the page follows the active billing provider automatically.

## Provider setup

{% tabs %}
{% tab title="okokBilling" %}
Works out of the box — the MDT creates invoices through okokBilling automatically and paid invoices sync back. No extra setup.
{% endtab %}

{% tab title="Codem Billing" %}
Codem's core is escrowed and exposes no public "create invoice" API — but its **editable** file ships open. One line fixes that.

Open `codem-billing/editable/server_editable.lua` and add this **at the end of the file** (after the `createBilling` function it defines):

```lua
-- Mango MDT: expose invoice creation (see mango_mdt docs, Billing Integration)
exports('createBilling', createBilling)
```

Then restart `codem-billing` and `mango_mdt`.

Two more Codem requirements:

* **Allowed jobs** — the issuing officer's job (e.g. `police`) must be listed in Codem's own `Config.AllowBillingJobs`, as the **bare job name**, not `society_police`.
* **Paid sync is polled** — Codem fires no event when an invoice is paid, so the MDT checks roughly once a minute. Expect up to \~60 seconds before a paid fine flips to Paid.

{% hint style="danger" %}
If fines never appear in Codem's menu and the console shows `No such export createBilling in resource codem-billing`, the editable line above is missing — a Codem update may also have overwritten it. Re-add it.
{% endhint %}
{% endtab %}

{% tab title="esx\_billing" %}
Works out of the box — the MDT bills through esx\_billing's own export with the society account from `config/fines.lua`:

```lua
Config.Fines = {
    -- ...
    billingAccount = 'society_police',
}
```

Paid fines sync back instantly via esx\_billing's paid event, with a periodic poll as belt-and-braces (covers bills paid while the MDT was restarting).

{% hint style="info" %}
Very old esx\_billing builds predate the `BillPlayerByIdentifier` export. If the console prints `esx_billing BillPlayerByIdentifier export missing`, update esx\_billing — or adapt the call in `bridge/billing/esx_billing.lua`, which is open and editable.
{% endhint %}
{% endtab %}

{% tab title="qb" %}
Best-effort invoice creation through qb-management. **No paid signal exists** — collected fines stay Unpaid in the MDT.
{% endtab %}
{% endtabs %}

## The society account

`Config.Fines.billingAccount` (default `'society_police'`) is where collected money lands. Providers that want a bare job name (Codem) derive it automatically by stripping the `society_` prefix — you configure it once, in one shape.

## If nothing arrives

Console shows this?

```
[Mango:ERROR] Bridge.Billing: no provider active - CreateBill() and every other
call on this bridge returns nil. Set Config.Bridge.Billing in config/bridge.lua.
```

Either `Config.Bridge.Billing` names a provider whose resource isn't running, or `'auto'` found no biller at all. Run `mango_bridges` in the server console to see what was detected. More in Troubleshooting.
