This section lists all available commands and exports included in the script. You'll find client-side and server-side functions designed to help developers integrate, extend, or interact with billing from their own scripts.
Quasar Billing registers two in-game commands and three console commands. The in-game ones respect permissions; the console ones exist for the cases where you cannot get into the game to fix something.
Command
Where
Description
/billing
In game
Opens the interface. Bound to F7 by default; the name and the key are both set in config/shared/config.lua.
/billingadmin
In game
Reopens the admin access screen once the server already has an admin. It grants nothing by itself.
qs-billing:checkadmin <id>
Console
Reports which of the four access routes is shut for that player, and why. Run this before opening a ticket.
qs-billing:grantadmin <id>
Console
Grants in-game admin access to a connected player.
qs-billing:dbreset confirm
Console
Drops this resource's tables, re-runs migrations and re-seeds. Debug mode only.
dbreset deletes every invoice, payment and setting belonging to billing, and there is no undo. It refuses to run with debug off, precisely so it can never fire on a live server. It touches no other resource's data.
Sixteen server exports. These are how another resource drives billing — a fine from your MDT, a fee from your garage, a rent charge from your housing script, or a check on whether somebody owes money before you let them collect a car.
CreateInvoice
lua
local reference, err = exports['qs-billing']:CreateInvoice({
target = source, -- server id, OR an identifier string for an offline player
society = 'police', -- omit for a private invoice, billed by a person
category = 'fine',
lines = {
{ label = 'Speeding', price = 500, quantity = 1 },
{ label = 'No insurance', price = 250 },
},
dueHours = 72,
notes = 'Highway 1, radar 4',
metadata = { mdtFineId = 812 },
})
ifnot reference thenprint('billing refused it:', err) -- err is a locale key, e.g. error.no_linesend
The export most integrations need. It returns the invoice reference string, or nil plus an error key when the server refuses it.
Field
What it does
target
Who pays. A server id for an online player, or an identifier string to bill somebody offline.
lines
At least one. Each takes label and price, optionally quantity, discount and taxRate.
society
Lines are re-priced on the server, so a total you send is ignored. Invoices made this way also skip the approval queue — an integration is not an employee, so it is not held against a grade's limit.
IsServiceBlocked and HasOverdue
lua
-- In your garage, before handing a car back:if exports['qs-billing']:IsServiceBlocked(identifier, 'garage') thenreturn Notify(source, 'Unpaid fines. Settle them before collecting a vehicle.')
end-- Or the blunt version, for anything overdue at all:if exports['qs-billing']:HasOverdue(identifier) then ... end
Both return a boolean. IsServiceBlocked answers for a named service; the names are free text, and whatever you typed into a collection stage is what you check for here.
Nothing enforces itself. Billing keeps the list — your resource decides what being blocked means. Add housing to a stage and never ask about it, and nothing happens to anybody's house.
GetOutstandingTotal
lua
local owed = exports['qs-billing']:GetOutstandingTotal(identifier) --> number-- Make a consequence proportional instead of binaryif owed > 5000then
ApplyCreditFreeze(identifier)
end
Returns everything still owed by that identifier across pending, partial and overdue invoices, as a plain number. Useful when you want a threshold rather than a yes or no.
GetInvoice and GetPlayerInvoices
lua
-- One invoice, lines includedlocal invoice = exports['qs-billing']:GetInvoice('INV-4K7P92')
-- A player's invoices; scope defaults to 'received'local list = exports['qs-billing']:GetPlayerInvoices(identifier, {
scope = 'received',
status = 'overdue',
})
Read-only lookups. GetInvoice takes a reference and returns the whole invoice with its line items; GetPlayerInvoices takes an identifier and an optional filter table.
PayInvoice, CancelInvoice and RefundInvoice
lua
-- Charge a player for an invoice. account is 'bank' or 'cash'
exports['qs-billing']:PayInvoice(payerSource, reference, 'bank')
-- Withdraw an invoice. Any partial payment is refunded
exports['qs-billing']:CancelInvoice(reference, 'Issued in error')
-- Pay a settled invoice back in full, from the company account
exports['qs-billing']:RefundInvoice(source, reference, 'Goodwill')
The three write operations on an existing invoice. RefundInvoice only works on invoices that were paid in full, and the company account has to be able to cover it.
Creates a template that issues a fresh invoice on a schedule — rent, insurance, a retainer. Returns the schedule id, or nil plus an error key.
Permission checks
lua
exports['qs-billing']:IsAdmin(source) --> boolean, across all four routes
exports['qs-billing']:CanIssue(source) --> may that job and grade bill at all
exports['qs-billing']:CanPlayerBill(source) --> the fuller check the UI itself uses
Three levels of the same question. CanIssue asks only about the job and grade; CanPlayerBill is what the interface uses, and also weighs duty status and the feature switches.
GetSetting and GetFramework
lua
-- Any live setting, by dotted pathlocal hours = exports['qs-billing']:GetSetting('billing.dueHours', 72)
-- The bridge table billing talks to your framework throughlocal Framework = exports['qs-billing']:GetFramework()
Because settings live in the database and change without a restart, GetSetting always returns the current value — do not cache it on your side.
Notify
lua
exports['qs-billing']:Notify(source, {
type = 'success',
title = 'Invoice paid',
description = 'INV-4K7P92 has been settled.',
})
Sends a notification through whatever notification system the server is running, so your message looks like every other message on the server rather than like billing's.
The four ways to control the window. IsUiOpen is worth checking before you open something of your own over the top of it.
OpenInvoice
lua
exports['qs-billing']:OpenInvoice('INV-4K7P92')
Opens the interface straight onto one document, skipping the list. Use it when your script already knows which invoice the player cares about.
GetPlayerData
lua
local data = exports['qs-billing']:GetPlayerData()
Returns billing's normalised view of the local player — identity, job, grade and duty — in the same shape on every framework. Handy if you want one code path instead of one per framework.
The language the server is running, and the whole dictionary behind it — already merged over English, so every key is present whatever the translation left out. This is how the phone app puts every string in the player's language without shipping a second copy of the locales to fall behind the first, and it is there for your own scripts to do the same.
Notify
lua
exports['qs-billing']:Notify({
type = 'success',
title = 'Invoice paid',
})
The client-side twin of the server export. Works whether or not the interface is open — the page is always loaded, it simply has no focus.
Every export that can refuse returns a locale key, not a sentence: error.no_lines, error.amount_too_high, error.invalid_interval.
That is deliberate — it means the same failure reads in the player's own language, in all seven of them. Log the key for yourself; do not show it raw to a player.
The company it is billed for, and the account the money lands in. Omit it for a private invoice.
metadata
Anything you want handed back when the invoice is settled. This is how an MDT closes its own fine.
dueHours
Optional. Falls back to the server's configured default.