LCK Billing
Install and configure the billing system, connect supported banking providers, create a custom adapter, and integrate trusted resources through server exports.
Installation
Checklist
- Back up the database.
- Import
sql/install.sqlusing the same database configured for the framework. - Start
oxmysqlormysql-asyncbeforelck-billing. - Set
Config.DatabaseandConfig.Framework. - Configure allowed jobs and exact society account names.
- Configure and verify the banking adapter.
- Keep Discord webhook values only in
config/server.lua. - Add trusted external resources explicitly.
- Add
ensure lck-billingafter the framework, SQL, and active banking resource. - Restart and check for the
Readymessage.
Recommended start order
ensure oxmysql
ensure es_extended
ensure esx_addonaccount
ensure lck-billing
For QBCore, replace the framework and banking entries with the installed QBCore resources. The resource deliberately has no hard dependency on optional targets, inventories, notification libraries, or banks.
To uninstall, stop the resource, back up financial records, and import sql/uninstall.sql.
Configuration
All configured amounts use euros. The server converts them to integer cents before storing or processing them.
Invoice modes
Config.PersonalInvoicesenables player invoices without a society, sets the maximum amount, and controls nearby or offline recipients.Config.AllowedJobsdefines society accounts, grade limits, custom-reason permission, andinvoicePresetsentries withnameandvalue.
Payment settings
Config.Autopay.AfterDays controls when unpaid invoices are automatically charged.
Config.VAT.SocietiesReceiveVAT decides whether VAT goes to the issuer or Config.VAT.TreasuryAccount.
Config.Commission pays a percentage of a society invoice to the employee who issued it.
All payment splits are calculated on the server and written to payment metadata.
Restricted menus
Config.Access.InspectPlayerJobs and Config.Access.CityInvoicesJobs map job names to minimum grades:
Config.Access = {
InspectPlayerJobs = { police = 0 },
CityInvoicesJobs = { police = 3 }
}
Discord logs
Enable ServerConfig.Logging.Discord and set ServerConfig.Logging.Webhook in config/server.lua. This server-only file is never sent to clients.
Banking integrations
The built-in society integrations are:
Renewed-Banking
Uses getAccountMoney, addAccountMoney, and removeAccountMoney.
qs-banking
Uses GetAccountBalance, AddMoney, and RemoveMoney.
okokBanking
Uses the okokbanking_societies table with conditional parameterized updates.
esx_addonaccount
Uses the shared-account event API and addon_account_data.
loaf_banking
Uses the explicit export mapping configured in Config.LoafBanking.
Player balances always use the active ESX or QBCore framework bridge. Config.Banking = 'auto' prefers Renewed-Banking, qs-banking, configured loaf_banking, okokBanking, esx_addonaccount, then framework-only player accounts.
Account names
Renewed-Banking and qs-banking use job account names such as police. The adapters safely remove a leading society_, so configurations such as society_police continue to work.
loaf_banking
There is no public loaf_banking API in the official Loaf Scripts documentation. Set the three names in Config.LoafBanking.Exports from your installed resource's server documentation.
If its balance export returns a table, set BalanceField. If mutation exports return no value on success, set MutationReturnsBoolean = false only after verifying that behavior. The adapter logs a warning and remains unavailable while its mapping is incomplete.
Before release, test player debit, society credit, employee commission, VAT routing, insufficient funds, and database rollback against the exact banking version installed.
Custom banking
Editable adapter
Set Config.Banking = 'custom' and implement or configure custom/server/custom_banking.lua. Every normalized method must return either a useful value or false, 'error_code'. Never return true before the bank confirms a mutation.
Runtime registration
Add the registering resource to Config.TrustedResources, then register every required function:
local ok, errorCode = exports['lck-billing']:RegisterBankingAdapter('my-bank', {
IsAvailable = function()
return GetResourceState('my-bank') == 'started'
end,
GetPlayerBalance = function(source, account)
return exports['my-bank']:GetBalance(source, account)
end,
RemovePlayerMoney = function(source, account, amount, reason)
return exports['my-bank']:Remove(source, account, amount, reason)
end,
AddPlayerMoney = function(source, account, amount, reason)
return exports['my-bank']:Add(source, account, amount, reason)
end,
GetSocietyBalance = function(account)
return exports['my-bank']:GetBusinessBalance(account)
end,
AddSocietyMoney = function(account, amount, reason)
return exports['my-bank']:AddBusinessMoney(account, amount, reason)
end,
RemoveSocietyMoney = function(account, amount, reason)
return exports['my-bank']:RemoveBusinessMoney(account, amount, reason)
end,
AccountExists = function(account)
return exports['my-bank']:BusinessExists(account)
end,
ResolveSocietyAccount = function(job)
return 'society_' .. job
end
})
The export names above demonstrate the adapter shape. They are not a claim about a third-party banking API.
Export mapping
Config.CustomBanking can map basic player and society exports. This method cannot adapt unusual argument ordering, callbacks, events, multi-currency accounts, or complex return values. Use the editable or runtime adapter for those systems.
Exports
Sensitive exports require the invoking resource to be listed in Config.TrustedResources.
local ok, invoiceId = exports['lck-billing']:CreateInvoice(data)
local ok, invoice = exports['lck-billing']:GetInvoice(invoiceId)
local ok, page = exports['lck-billing']:GetPlayerInvoices(identifier, filters)
local ok, page = exports['lck-billing']:GetSocietyInvoices(accountName, filters)
local ok, invoice = exports['lck-billing']:PayInvoice(invoiceId, payerSource, 'bank')
local ok, invoice = exports['lck-billing']:PayInvoiceReference(reference, payerSource, 'bank')
local ok, summary = exports['lck-billing']:PayAllInvoices(payerSource, 'bank')
local ok, invoice = exports['lck-billing']:CancelInvoice(invoiceId, actorSource)
local ok, cents = exports['lck-billing']:GetUnpaidInvoiceTotal(identifier)
local ok, count = exports['lck-billing']:GetPendingInvoiceCount(identifier)
Trusted society invoice
local ok, invoiceId = exports['lck-billing']:CreateInvoice({
senderSource = source,
recipientSource = targetSource,
invoiceMode = 'society',
societyAccount = 'society_mechanic',
reason = 'Vehicle recovery',
amount = 500
})
Client export
exports['lck-billing']:OpenBilling('personal')
Need help connecting your bank?
Join the LCKSCRIPTS Discord for configuration help and guidance for your installed banking version.
Join Discord ↗