Skip to content

Fine collectionGame

Collect offense files’ fines and medical care in game: the modes (direct debit, invoices, custom), supported scripts and the custom mode.

On this page06
  1. Choose the mode
  2. How it works
  3. Medical care
  4. Compatibility
  5. Custom mode
  6. Troubleshooting

The fine stays managed in SuperMDT: amount, status, who, when. Fine collection adds an in-game payment channel: when an offense file is closed, its amount is debited or invoiced to the character, and paying in game marks the fine paid in the MDT, without an officer having to record it.

In Settings › Game › Integrations › Fine collection, pick the Collection mode (administrators, or a rank with Delegated administration › Set up the game):

Mode What happens in game Offline character
None (default) Nothing. An officer records the payment by hand. —
Direct debit The amount is taken from the character’s bank (never below zero). Waits for their login.
esx_billing invoice An ESX invoice; once paid, it goes to the company account. Invoiced anyway.
okokBilling invoice Experimental An okokBilling invoice. Waits for their login.
qb-phone invoice An invoice in the qb-phone phone (QBCore). Invoiced anyway.
Custom Your billing script, or billing_ui / qs-billing (see below). Depends on the script.

Under the setting, SuperMDT lists the modes usable on this server (based on what the bridge detected) and warns you if the chosen mode isn’t.

  1. An officer closes an offense file that has unpaid fines, for a citizen who is a game character.
  2. SuperMDT sends a single invoice (or a single debit) for this file. Never two: the ID is kept by the bridge, even after a restart.
  3. The file shows the In-game collection: being sent, waiting for the character to log in, invoice sent (awaiting payment), paid in game, or failed with the reason.
  4. On payment in game, the fine becomes paid on its own: the file’s history notes “Fine of … paid in game”, the audit log “The system received from the game the fine payment of …” (Unpaid → Paid). With direct debit it’s immediate: the money leaves when the fine is sent, and the fine is paid right away. In invoice mode, the bridge listens to the script’s payment event (esx_billing, qb-phone, billing_ui) or reads the invoice again every 60 s (okokBilling, qs-billing, CustomBilling.isPaid).

The Mark paid button stays on the file for the other cases: a fine settled outside the game, a script that doesn’t report payments, or an uncertain result checked in game.

As long as the invoice hasn’t left, it follows the record (a fine settled or cancelled by hand changes the amount or cancels the sending). Once sent, it no longer changes: cancelling the fine in the MDT doesn’t remove the invoice in game. A later payment is logged, but the cancelled fine stays cancelled.

Switching the mode back to None pauses collections that haven’t left yet; they start again if you turn a mode back on.

On the file, Retry the collection sends a failed collection again (for example after “insufficient funds”). You need the Records & fines › Retry a collection permission (members and up by default, only shown in the matrix when the game integration is on); without it, the button stays visible but locked, with the hint “Restricted: Records & fines › Retry a collection”. An uncertain result is never retried on its own: check in game, and mark the fine paid by hand if needed (Records & fines › Mark a fine paid). See Permissions.

The same engine also collects the medical department’s care, with the same modes (direct debit, esx_billing, okokBilling, qb-phone, custom, so billing_ui and qs-billing too). The debt stays in the MDT: the medical visit is Paid or Unpaid (Medical records).

Settings › Game: care billing, one medical department at a time
  • The setting. In Settings › Game › Integrations, Care billing section, each department with medical records has its own mode (None by default). It can differ from the fines mode. The change is logged.
  • The trigger: the signature. The bill is sent when the visit is signed (Sign now when creating it, or Sign later), for a patient who is a game character. An unsigned visit is never billed. One bill per visit, never two, even after a bridge restart.
  • The label in game is “Medical care no. 12 — EMS” (visit number, department short name). The money goes to the company account of the first job linked to the medical department (“ambulance”).
  • A payment detected in game marks the visit Paid on its own, on behalf of the system: the visit’s history notes that the system received the care bill payment from the game, and so does the audit log (without medical content).
  • Until the bill is sent, it follows the visit: a changed amount changes the bill; Mark as paid, a deletion or an edit that removes the signature cancel it. Once sent, it no longer changes.
  • The status shows on the visit, under In-game bill: being sent, waiting for the character to connect, bill sent, paid in game, failed with the reason, or cancelled.
  • Retry. After a failure (insufficient funds…), Retry the bill sends it again. You need Medical records › Retry a care bill (members and up by default, shown in the matrix when the game integration is on); without it, the button is locked. An uncertain result is never retried: check in game.

On the bridge side, nothing more to set: the fine command carries source: "care" (the Custom mode receives fine.source in CustomBilling.issue and the supermdt:fineIssued event), and the bridge’s hello announces the care modes (careModes) to hook their payment events.

Tested in game tried in game on a real server. Verified in code written from the script’s source code or native API, covered by the bridge’s tests, not tried in game yet. Experimental from the publisher’s public documentation, never tried: check it on your server before relying on it.

Debit works on all three frameworks, with the character connected. The bank decides the history line and the credit to the service’s account:

Framework Bank Status Line for the player Amount paid to the service’s account
ESX, QBCore, Qbox Renewed-Banking Verified in code Yes Yes
QBCore qb-banking Verified in code Yes Yes (job account)
ESX esx_addonaccount (+ esx_banking, sd-phone) Verified in code With esx_banking or sd-phone Yes (society_ + job)
ESX, QBCore, Qbox okokBanking, qs-banking, snipe-banking, tgg-banking Experimental Yes Yes
ESX, QBCore, Qbox fd_banking Experimental No Yes
ESX, QBCore, Qbox No recognized bank Verified in code No No

Qbox has no native invoices: direct debit does the same as qbx_police’s /fine command.

Framework Script Mode Status Good to know
ESX esx_billing esx_billing invoice Verified in code Offline possible. Paid to the society_ account of the first linked job: a job must be linked to the service. Amount capped by esx_billing (100,000 by default). Can’t be declined (esx_billing has no decline). When the bridge starts, an invoice paid while it was stopped is found and marked paid.
ESX, QBCore okokBilling okokBilling invoice Experimental Connected character. Payment detected by re-reading the invoice every 60 s.
QBCore qb-phone qb-phone invoice Tested in game Offline possible, can’t be declined if the phone_invoices table has the candecline column (otherwise supermdt status warns that the player may be able to decline it; fix: ALTER TABLE phone_invoices ADD COLUMN candecline INT(1) NOT NULL DEFAULT 1). A declined invoice stays invoiced in SuperMDT. A database error is a clear failure that can be retried. When the bridge starts, an invoice paid while it was stopped is marked paid. Useless if the server uses another phone (lb-phone, qs-smartphone…): nobody would read the invoice.
ESX, QBCore billing_ui (jaksam) Custom Experimental Built in: used in Custom mode as long as custom.lua isn’t completed. Offline possible. A job must be linked.
ESX, QBCore qs-billing (Quasar) Custom Experimental Built in, after billing_ui. Connected character. Payment detected by re-reading the invoice. Needs oxmysql.
ESX, QBCore codem-billing, RxBilling, tgg-billing Custom, to complete Not supported No adapter provided: their public API doesn’t allow invoicing without a connected issuing player, or knowing an invoice is paid. Detected and reported. Usable through Custom mode if you complete custom.lua.

Custom mode plugs in any billing script (CodeM, RxBilling, tgg-billing, an lb-phone app, a homemade script) through a bridge file: integrations/billing/custom.lua.

  1. Open integrations/billing/custom.lua.
  2. Complete CustomBilling.issue(fine, done): create the invoice in your script, then call done with its result.
  3. If your script doesn’t report payments, also complete CustomBilling.isPaid(reference): the bridge asks it every 60 s.
  4. Set CustomBilling.configured = true.
  5. ensure supermdt-bridge, then pick Custom in SuperMDT.

A payment can also be reported from any resource with exports['supermdt-bridge']:markFinePaid(fineRef). The supermdt:fineIssued server event fires for every invoice, in every mode.

Priority order in Custom mode: your completed custom.lua, then billing_ui, then qs-billing. Without any of the three, collection fails with “custom mode not configured”.

What you see Cause What to do
“billing resource missing on the server” Mode chosen without its script (esx_billing, okokBilling, qb-phone) supermdt status (“Fines” line); change mode.
“custom mode not configured” custom.lua not completed, and neither billing_ui nor qs-billing Complete the file, CustomBilling.configured = true, ensure supermdt-bridge.
“Waiting for the character to log in” Direct debit, okokBilling or qs-billing: character offline It leaves at their next login.
“insufficient funds” Balance too low at debit time Retry the collection later.
“uncertain result” Server stopped during collection, or invoice not found after creation Check in game; mark paid by hand if needed.
“the billing script refused” (esx_billing) Amount above esx_billing’s cap Raise esx_billing’s Config.MaxBillAmount.