Skip to main content

Using Billing

Open and navigate​

Default controlPurpose
F7Toggle the billing dashboard
/billingOpen Overview
/createinvoiceOpen Create Invoice
/payreferenceOpen Pay by Reference
/inspectcitizenOpen admin inspection; lookups require admin permission

Commands and the keybind are configurable in config/client/config.lua. Opening commands do not switch an already-open dashboard to another modal; use its navigation or close it first. Escape closes the current modal first, then closes the panel on the next press; the Close control also exits the UI.

Views​

  • Overview: Personal unpaid, overdue, paid, and total-due statistics, plus the latest 12 records from the invoice buckets available to the player. The unpaid count includes overdue invoices.
  • Personal: Received and sent tabs, status filters, selectable invoice rows, and details. Sent records also include society invoices personally issued by the employee.
  • Society: Received/sent invoices and balance for the player's own job, when the management grade is met. This is not a selector for every society.
  • Admin: Search by reference, author/receiver name, or author/receiver identifier. An empty search loads the latest invoices. The inspection modal supports citizen name/identifier lookup and society browsing.
  • Invoice receipt: Using a physical invoice opens a paper-style view showing issuer, receiver, reference, status, dates, reason, VAT, and total.

Inspection results paginate the already-fetched records in groups of eight; ordinary lists render their fetched result set without server-side pagination. These are not unlimited history browsers. Personal/society buckets and identifier inspection are limited to 200 rows each, admin invoice search requests 100 rows, and dashboard statistics use up to 500 received rows. Citizen type-ahead begins after two typed characters in the UI; the directory returns up to 25 matches by default. Use narrower admin searches for older records.

Create an invoice​

  1. Open Create Invoice.
  2. Choose personal issuance or your society when your job's sending grade allows it. Eligible employees default to society issuance.
  3. Select a nearby player or a configured society target. Society targets require a banking backend and membership in the receive allow-list.
  4. Choose a category and preset reason, or enter a custom reason and amount. Presets fill fields but do not lock them.
  5. Review the amount and VAT, then send. The server resolves the personal target from its server ID and rechecks distance.

Amounts must be positive and within the UI ceiling. The UI limits reasons to 200 characters. Identical issuer/receiver identifiers are rejected. VAT is stored by the server; see the rounding note if the creation preview differs from the resulting invoice.

Online personal recipients are notified and offered an item copy if configured; eligible online members of a billed society are notified instead for society recipients. Item delivery is best-effort and is not queued for offline recipients.

Payments and overdue invoices​

Personal payments​

Select a received invoice, choose Pay, and confirm bank or cash. To pay another character's invoice, open Pay by Reference, enter its reference, review it, then pay from your own account. The original billed identifier remains on the invoice; third-party payment does not transfer ownership of the debt.

Holding an invoice item permits opening its record, but the receipt's Pay button is shown only for the billed party. A third party can copy the reference, close the receipt, and use Pay by Reference instead.

Society payments​

A society receiver's invoice is paid from that society's account, not from the acting employee's wallet. The server permits an administrator or a member of that same job meeting its management grade. Use the Society view for ordinary society settlement. The Pay by Reference modal currently uses the player's displayed personal balance for its affordability check even for society references; the normal society confirmation path avoids that UI mismatch.

Where funds go​

  • A personal issuer receives the payout in their bank, even if the payer chose cash.
  • A society issuer receives the payout in its configured society backend, with the configured pre-VAT employee share allocated to the stored issuing employee's bank.
  • Optional VAT routing attempts to send the stored VAT to Config.SocietyToReceiveVAT. If that transfer fails, VAT remains part of the issuer payout.
  • Employee share and VAT-routing settings are evaluated when paid, not permanently captured at invoice creation.
  • When Wasabi Banking is the active backend, Config.LogTransactionsToBanking mirrors payment-related statement entries. It does not make Wasabi Banking own the framework's personal cash/bank operations.

Offline personal credits and automatic debits use the built-in framework adapters: offline-player APIs for QBCore/QBOX and users.accounts SQL for ESX. Validate the offline APIs and saved balances for your deployed framework version.

Provider failures

Settlement is not a cross-resource atomic money transaction. Debits, credits, and invoice status writes occur separately, and the current settlement path does not roll back every failed recipient credit. Keep provider accounts available, verify all payout destinations during installation, and reconcile balances and records if a payment reports provider/SQL errors. Do not assume a success notification proves every downstream credit was saved.

Overdue collection​

Once a stored deadline passes, read APIs display an unpaid invoice as overdue even before the background sweep updates it. The sweep starts after about 10 seconds, then runs every Config.OverdueCheckInterval seconds (minimum 15), examining up to 25 oldest eligible records per pass.

  • Automatic collection off (default): Expired unpaid rows are marked overdue; they remain manually payable.
  • Automatic collection on: Personal invoices are collected from the billed character's bank, online or offline; society receivers use the society account. Failed collections remain overdue and are retried by subsequent sweeps.

This is not an interest/late-fee system. It does not change the stored total when the deadline passes. Because each batch selects the oldest eligible rows, a backlog of uncollectable invoices can delay later rows; do not interpret the interval as a guaranteed settlement deadline for every invoice.

Cancel, delete, and clear​

Cancellation​

The server allows the issuer, the stored issuing employee, an authorized manager of the issuing society, or an administrator to cancel an unpaid invoice. Cancellation changes status and does not refund a paid invoice.

The current database mutation only cancels rows stored as unpaid. A persisted overdue row can show a Cancel action in the UI but the update returns false. In addition, the UI's society Cancel visibility follows management access and does not cover every stored-employee permission supported by the server export. Use the export contract when integrating cancellation; do not assume UI visibility and server eligibility are identical.

Admin deletion and clearing​

Administrators can delete a single invoice from its details or inspect a citizen/society and use Clear all.

Permanent record deletion

Deletion is not payment, cancellation, or refund. These actions remove database records without restoring money. Clear all is dispatched directly from the inspection button; it does not have the individual delete confirmation modal. Back up records and verify the selected identifier before using it.

Clear removes rows where the identifier is the author or receiver. Inspection also lists rows where it is only invoicer_identifier, so clearing an employee does not necessarily remove every society-issued record visible in their inspection results. It removes matching rows across statuses, not only unpaid invoices. Existing physical items pointing to deleted records will no longer open an invoice.

Debug commands​

Only registered with Config.Debug = true:

CommandPurpose and restriction
/openbilling <view> <modal>Local UI opening helper. Views: overview, personal, society, admin; optional modals: create, payref, inspect. The command itself is unrestricted while debugging, but admin data callbacks remain permission-checked.
/billing_smokeServer-side smoke helper registered with ox_lib's restricted = 'group.admin'. This command restriction is distinct from Config.AdminAce. Run from an authorized in-game staging character.

The smoke helper tries creation, reads the result/list, attempts a real cash payment, checks paid status, and deletes its test invoice. Self-invoicing is intentionally rejected, so it falls back to a synthetic issuer. It can consume player funds and create an item copy. It is not a complete public API or money-integrity test: it does not test client exports or CancelInvoice, and it does not prove the synthetic issuer received money. Do not run it as a harmless production health check. Disable debug mode after testing.

Troubleshooting​

SymptomCheck
Blank UICorrect resource folder name; ui/build/index.html and assets deployed; client/F8 errors; framework payload and ox_lib callbacks working.
No nearby targetsAnother loaded character must be within Config.CreateInvoiceDistance; the UI cannot bill your own personal identifier.
No society issuanceCorrect raw job name, send-grade entry, grade level, and working society banking backend. Preset job lists do not grant issuance rights.
Society view lockedCheck the separate management-grade map, not only the sending map. No duty flag is used by these checks.
Society payment hangs/failsChosen backend started first, accounts exist, and its exports are compatible. ESX requires both society and shared-account callback handlers; use BankingIntegration = 'none' if you intentionally have no society system.
No item / unusable itemCorrect selected inventory, item registration, metadata, available capacity, and the framework API required by its usable-item bridge. Look for [wasabi_billing][item] warnings.
Item has no Pay buttonThe viewer must be the billed party and the invoice must be payable. For another character's personal invoice, use Pay by Reference.
Admin lookup deniedGrant wsbbilling to the actual player's ACE principal or confirm the supported framework admin permission.
Citizen search SQL errorCheck PlayersTable/IdentifierColumn, and whether character names use charinfo or firstname/lastname. These overrides are not global money-schema switches.
Existing okokBilling UI event does nothingThe client compatibility flag is not supplied by server config; see Migration.
No Discord logEnable the logger and fill the relevant bucket URL; an empty bucket string does not fall back to default.
Invoice cancellation fails after expiryA persisted overdue status is not cancellable by the current database update.
Unexpected historical receiver typeReview the society list used at first startup and the migration backfill behavior.

Report the resource version, selected framework/banking/inventory providers, exact action and invoice reference, and relevant client/server errors when requesting support. Keep webhook URLs and private player data out of public logs or screenshots.