lation scripts
scriptsmembershipdocs
see the scripts
Skip to Content
lation ui
lation interact
lation banking
MigratingAdmin panel and commandsAccountsBills and requestsRegisterLoansConfigurationDevelopersChangelog
lation shops
lation jobs
lation weed
lation chop shop

classics

money laundering
drug sales
coke processing
meth crafting
metal detecting
scuba diving
lation banking

Developers

The lation banking server and client exports with parameters and return values, its events, the server hooks and the open code, with Lua examples.

Every account export takes an account id:

AccountId
PersonalThe player's identifier: citizenid on Qbox and QBCore, identifier on ESX
SocietyThe job or gang name, such as police
Shared and savingsThe account number, such as LS12345678, or the id it was created with
BusinessThe id the resource that opened it chose

Whether a player is connected makes no difference to a personal account: it reads and moves the same either way. PayBill is the one export that needs the player online, and only for a bill sent to a player.

A few rules hold for every export:

  • The account exports wait until the bank has loaded its accounts before answering, so a resource that starts beside the bank gets real answers, not misses.
  • Amounts are whole numbers. Decimals are rounded down, and an amount of zero or less, or above 2000000000, is refused.
  • Exports skip the checks made for players: transfer limits, the offline-transfer setting, the billing list, the limit of 10 open bills on one account and Hooks.canTransact apply only to what players do in the bank. The Bills and Requests switches do apply: CreateBill and PayBill refuse while they are off.
  • The money exports return a refusal code as their third value when they refuse.
  • Money an export moves is written into the history, naming the calling resource as the actor (PayBill names the player), and fires lation_banking:transaction.

Server exports

ExportReturns
GetAccount(id)An account, or nil
GetAccountBalance(id)number, or nil
GetPlayerAccounts(identifier)Every account a player can use but their own
GetAccountMembers(id)The members
GetPlayerAccountNumber(identifier)string, or nil
GetIdentifierByAccountNumber(number)string, or nil
AddAccountMoney(id, amount, note?)boolean, and a code
RemoveAccountMoney(id, amount, note?)boolean, and a code
TransferMoney(fromId, toId, amount, note?)boolean, a message and a code
CreateAccount(data)An account, or nil and an error
DeleteAccount(id)boolean
RenameAccount(id, name)boolean
SetAccountFrozen(id, frozen)boolean
SetAccountOwner(id, identifier)boolean
AddAccountMember(id, identifier, permissions?)boolean
UpdateAccountMember(id, identifier, permissions)boolean
RemoveAccountMember(id, identifier)boolean
ClearAccountMembers(id)boolean
AddTransaction(id, data)boolean
GetTransactions(id, options?)A page of the history
CreateBill(data)A bill id, or nil and an error
PayBill(id, accountId?)boolean, a message and a code
CancelBill(id)boolean
GetBills(id, status?)A player's bills, or an account's
GetLoan(identifier)A loan, or nil
GetPosProducts(accountId)A register's menu
AddPosProduct(accountId, data)A product id, or nil and an error
RemovePosProduct(id)boolean
EnsureSocietyAccounts(name?)boolean, and a code
SetPosBusiness(id, rules?)boolean
SetPosLocation(id, point?)boolean
OpenBank(source, kind?)boolean
RequestPin(source, accountId?)boolean
GetConfig(section?)A copy of the live configuration

Accounts

GetAccount

Server export

local account = exports.lation_banking:GetAccount(id)

Parameters

idstring
Any account id

Returns

table | nil
A copy of the account (below), or nil when there is none, or the id is an offline player the bank has never seen

The account:

{
    id = 'police',
    type = 'society',          -- 'personal', 'savings', 'shared', 'society' or 'business'
    name = 'LSPD',             -- the display name
    number = 'LS88001000',     -- the account number, without spaces
    balance = 18325,
    owner = nil,               -- the owner's identifier; the player's own for a personal account
    frozen = false,            -- frozen by an admin
    members = {
        { identifier = 'ABC12345', name = 'Jane Doe', permissions = { deposit = true, withdraw = true, transfer = true, manage = false } },
    },
}

GetAccountBalance

Server export

local balance = exports.lation_banking:GetAccountBalance(id)

Parameters

idstring
Any account id

Returns

number | nil
The balance, or nil when there is no such account. For an offline player it is read from their character record.
server.lua
local balance = exports.lation_banking:GetAccountBalance('police') or 0

GetPlayerAccounts

Server export

local accounts = exports.lation_banking:GetPlayerAccounts(identifier)

Parameters

identifierstring
The player's identifier

Returns

table
Every account other than their personal one that the player can use: savings, societies, business and shared accounts

Each entry has the GetAccount fields plus role (owner, member or boss) and, while the player is online, permissions. For an offline player, a society reached through their job or gang can't be seen; a society they were added to by name still shows.

GetAccountMembers

Server export

local members = exports.lation_banking:GetAccountMembers(id)

Parameters

idstring
A savings, shared, society or business account id

Returns

table
{ identifier, name, permissions } for each member, or an empty table

GetPlayerAccountNumber

Server export

local number = exports.lation_banking:GetPlayerAccountNumber(identifier)

Parameters

identifierstring
The player's identifier

Returns

string | nil
The player's personal account number, without spaces, or nil if the bank has never seen them

GetIdentifierByAccountNumber

Server export

local identifier = exports.lation_banking:GetIdentifierByAccountNumber(number)

Parameters

numberstring
A personal account number. Spaces and dashes are ignored.

Returns

string | nil
The identifier behind it, or nil. Other kinds of account return nil.
server.lua
local identifier = exports.lation_banking:GetIdentifierByAccountNumber('LS 1234 5678')

Money

Refusal codes

AddAccountMoney, RemoveAccountMoney, TransferMoney and PayBill return false and a code as their third value when they refuse. The second value stays what it always was, so scripts that read it keep working; test the third. A code is the last part of the bank's errors.<code> locale key where there is one, and is never translated.

CodeWhat happenedReturned by
invalidAn id that is not a non-empty stringAdd, Remove, Transfer
invalid_amountNot a positive whole amount within the bank's limitAdd, Remove, Transfer
databaseThe bank's accounts did not loadAdd, Remove, Transfer
unknown_accountNo account and no character by that idAdd, Remove, Transfer
recipient_unknownNothing found for the targetTransfer
same_accountThe sender and the target are one accountTransfer
insufficient_fundsThe paying side can't cover itRemove, Transfer, PayBill
frozenThe paying account is frozenRemove, Transfer, PayBill
failedIt did not go through; nothing movedAdd, Transfer, PayBill
bill_settledThe bill is no longer unpaidPayBill
bills_disabled, requests_disabledThat kind is switched offPayBill
no_accessThe account named can't pay this billPayBill
recipient_offlineA player's bill, and the player is offlinePayBill
busyThe player is in the middle of another paymentPayBill
server.lua
local ok, message, code = exports.lation_banking:TransferMoney('police', 'LS12345678', 1000, 'Consulting')
if not ok and code == 'insufficient_funds' then
    -- the police account is short
end

AddAccountMoney

Server export

local ok, _, code = exports.lation_banking:AddAccountMoney(id, amount, note)

Parameters

idstring
Any account id
amountnumber
The amount to add
notestringoptionaldefault nil
The history line's description

Returns

boolean, nil, string
true, or false, nil and a refusal code: unknown_account when there is no such account or character, failed when the framework refused

Credits the account and writes an income line. On a personal account it moves the framework's bank money, online or not. A frozen account still takes money in.

server.lua
exports.lation_banking:AddAccountMoney('police', 2500, 'Impound fee')

RemoveAccountMoney

Server export

local ok, _, code = exports.lation_banking:RemoveAccountMoney(id, amount, note)

Parameters

idstring
Any account id
amountnumber
The amount to take
notestringoptionaldefault nil
The history line's description

Returns

boolean, nil, string
true, or false, nil and a refusal code, moving nothing: insufficient_funds when the balance can't cover it, frozen when the account is frozen

Debits the account and writes an expense line.

server.lua
local ok, _, code = exports.lation_banking:RemoveAccountMoney('mechanic', 900, 'Parts order')
if not ok then
    return -- 'insufficient_funds': the society can't pay for it; 'frozen': an admin froze it
end

TransferMoney

Server export

local ok, message, code = exports.lation_banking:TransferMoney(fromId, toId, amount, note)

Parameters

fromIdstring
The account paying
toIdstring
An account number, account id or player identifier
amountnumber
The amount to send
notestringoptionaldefault nil
Shown on both history lines. Without one, the lines read Transfer to <name> and Transfer from <name>.

Returns

boolean, string, string
true and the bank's message, or false, a message and a refusal code

Moves the money and writes a transfer_out and a transfer_in line under one reference, and tells an online player who received it. Offline recipients are always paid.

On failure the message is invalid, recipient_unknown or same_account when the call is refused before anything is looked up, and the bank's own message in the server's language after that (a frozen sender reads as insufficient funds there). The code says which it was: insufficient_funds, frozen, unknown_account, failed and the rest in the table.

server.lua
local ok, message, code = exports.lation_banking:TransferMoney('police', 'LS12345678', 1000, 'Consulting')
if not ok then print(('transfer refused: %s (%s)'):format(code, message)) end

Managing accounts

CreateAccount

Server export

local account, err = exports.lation_banking:CreateAccount(data)

Parameters

data.idstringoptionaldefault a new account number
Up to 50 characters. Prefix it with your resource name for a business account.
data.typestringoptionaldefault 'shared'
'society', 'shared', 'savings' or 'business'
data.namestring
The display name, up to 40 characters
data.ownerstringoptional
The owner's identifier. Required for savings, ignored for a society.
data.balancenumberoptionaldefault 0
The opening balance

Returns

table | nil, string
The account as GetAccount returns it, or nil and invalid, invalid_name, exists or database

A player may hold one savings account. The shared-account limit per player doesn't apply here, and business accounts never count against it.

server.lua
local account, err = exports.lation_banking:CreateAccount({ id = 'myshop:12', type = 'business', name = 'Bean Machine', owner = ownerIdentifier })
if not account then print(('could not open the account: %s'):format(err)) end

DeleteAccount

Server export

local ok = exports.lation_banking:DeleteAccount(id)

Parameters

idstring
A savings, shared, society or business account id

Returns

boolean

Removes the account and its members.

DeleteAccount does not pay the balance out anywhere. Move it first with TransferMoney or RemoveAccountMoney.

RenameAccount

Server export

local ok = exports.lation_banking:RenameAccount(id, name)

Parameters

idstring
The account
namestring
The new display name, up to 40 characters

Returns

boolean

The id never changes. A society's name is set back to its job's label on the next start.

SetAccountFrozen

Server export

local ok = exports.lation_banking:SetAccountFrozen(id, frozen)

Parameters

idstring
The account; personal accounts can't be frozen
frozenboolean
true to freeze, false to thaw

Returns

boolean

A frozen account takes money in but refuses withdrawals, transfers out and bill payments.

SetAccountOwner

Server export

local ok = exports.lation_banking:SetAccountOwner(id, identifier)

Parameters

idstring
A shared or business account
identifierstring | nil
The new owner. A business account may be given nil while it is between owners; a shared account may not.

Returns

boolean
false for any other kind of account

A member who becomes the owner stops being a member.

AddAccountMember

Server export

local ok = exports.lation_banking:AddAccountMember(id, identifier, permissions)

Parameters

idstring
The account
identifierstring
The player to add, online or not
permissionstableoptionaldefault { deposit = true, withdraw = true, transfer = true, manage = false }
Any key left out takes its default

Returns

boolean
false when the player is already a member or the owner

manage only means something on a shared account; on society and business accounts members never manage. A player added to a society who isn't one of its bosses uses these permissions.

server.lua
exports.lation_banking:AddAccountMember('police', identifier, { deposit = true, withdraw = false, transfer = false })

UpdateAccountMember

Server export

local ok = exports.lation_banking:UpdateAccountMember(id, identifier, permissions)

Parameters

idstring
The account
identifierstring
A member
permissionstable
{ deposit, withdraw, transfer, manage }. Keys left out go back to their defaults, so pass all four.

Returns

boolean
false when the player is not a member

RemoveAccountMember

Server export

local ok = exports.lation_banking:RemoveAccountMember(id, identifier)

Parameters

idstring
The account
identifierstring
A member

Returns

boolean
false when the player is not a member

ClearAccountMembers

Server export

local ok = exports.lation_banking:ClearAccountMembers(id)

Parameters

idstring
The account

Returns

boolean

Removes every member at once, for a business whose staff were all let go.

History

AddTransaction

Server export

local ok = exports.lation_banking:AddTransaction(id, data)

Parameters

idstring
Any account id
data.typestring
deposit, withdraw, transfer_in, transfer_out, income or expense
data.amountnumber
The amount moved
data.notestringoptionaldefault nil
The description, up to 255 characters
data.counterpartystringoptionaldefault nil
The other side's name
data.counterpartyAccountstringoptionaldefault nil
The other side's account number
data.actorstringoptionaldefault the calling resource
Who made the move, shown in the admin ledger
data.referencestringoptionaldefault nil
Up to 40 characters

Returns

boolean
false for an unknown type or a bad amount

Writes a history line without moving money, for a script that moves the money itself and wants a clear line in the history. When framework tracking already wrote the same move on a personal account in the last 5 seconds (same amount, same direction), that line is filled in instead of a second one being added.

server.lua
-- the money already left through the framework; give the line its reason
exports.lation_banking:AddTransaction(identifier, { type = 'expense', amount = 400, note = 'Rent · Alta Street 12', counterparty = 'Alta Street Realty' })

GetTransactions

Server export

local page = exports.lation_banking:GetTransactions(id, options)

Parameters

idstring
Any account id
options.pagenumberoptionaldefault 1
The page to read
options.perPagenumberoptionaldefault 25
Rows per page, up to 500
options.filters.typestableoptional
A list of types
options.filters.searchstringoptional
Matches the note, counterparty, actor and reference
options.filters.dateFromstringoptional
YYYY-MM-DD
options.filters.dateTostringoptional
YYYY-MM-DD

Returns

table
transactions, pagination and summary (below)

The page:

{
    transactions = {           -- newest first
        {
            id = 4512,
            type = 'income',
            amount = 2500,
            balanceAfter = 18325,
            note = 'Impound fee',
            counterparty = nil,
            counterpartyAccount = nil, -- formatted, 'LS 1234 5678'
            actor = 'my_impound',      -- the player, or the resource that called an export
            reference = nil,
            createdAt = 1730000000,    -- unix seconds
        },
    },
    pagination = { page = 1, perPage = 25, total = 120, totalPages = 5 },
    summary = { income = 52000, expense = 31000, net = 21000 }, -- across every matching row
}
server.lua
local page = exports.lation_banking:GetTransactions('police', {
    perPage = 10,
    filters = { types = { 'income' }, dateFrom = os.date('%Y-%m-%d', os.time() - 7 * 86400) }
})
print(('police took in %d this week'):format(page.summary.income))

Bills

CreateBill

Server export

local billId, err = exports.lation_banking:CreateBill(data)

Parameters

data.targetstring
Who pays: a player's identifier or account number, or a society, shared or business account by id or number. Not a savings account.
data.amountnumber
The amount owed
data.notestringoptionaldefault nil
What it is for, up to 255 characters
data.accountstringoptionaldefault nil
Where the money goes: a society, shared or business id, or a player identifier. Leave it out for a fine that leaves the economy.
data.issuerstringoptionaldefault the account's name, or the calling resource
The name shown on the bill
data.issuerIdstringoptionaldefault nil
The identifier of the player who wrote it. They are told when it is paid or declined, and can cancel it.
data.duenumberoptionaldefault now plus Days until due
The due date in unix seconds

Returns

number | nil, string
The bill's id, or nil and invalid, bills_disabled, recipient_unknown, same_account, invalid_amount or database

A bill from this export needs no society on the billing list and carries no employee cut. While Config > Bills > Bills is off it is refused with bills_disabled, since nobody could see or pay it.

  • Sent to a player, they are told when it arrives and can decline it only while Players can decline bills is on.
  • Sent to an account (business to business), everyone who may send money from that account sees it under the account's name and pays it from that account. It can always be declined and is never collected automatically. same_account means target and account are the same account.
server.lua
-- a fine for a player
local billId, err = exports.lation_banking:CreateBill({ target = citizenid, amount = 1500, note = 'Speeding', account = 'police' })

-- one business billing another: the mechanics bill the police for a fleet service
local billId, err = exports.lation_banking:CreateBill({ target = 'police', amount = 3200, note = 'Fleet service', account = 'mechanic' })

PayBill

Server export

local ok, reason = exports.lation_banking:PayBill(id, accountId)

Parameters

idnumber
The bill's id
accountIdstringoptionaldefault the player's personal account
An account the player may transfer from. For a bill sent to an account, that account or nothing.

Returns

boolean, string, string
true and the bank's message, or false, a message and a refusal code

Pays an unpaid bill.

  • A player's bill is paid on their behalf, from accountId or their personal account. The player must be online.
  • A bill sent to an account is paid from that account, with nobody online.

The message is a code for a refusal made before paying is tried (bill_settled, bills_disabled, requests_disabled, no_access, frozen, recipient_offline or busy) and the bank's own message after that; the third value is always the code.

server.lua
-- the police pay the fleet service they were billed
local ok, message, code = exports.lation_banking:PayBill(billId)
if not ok and code == 'insufficient_funds' then print('the police account is short') end

CancelBill

Server export

local ok = exports.lation_banking:CancelBill(id)

Parameters

idnumber
The bill's id

Returns

boolean
false when it is not unpaid

Cancels an unpaid bill. Nothing is collected, and when it belongs to a repeating series, the series ends.

GetBills

Server export

local bills = exports.lation_banking:GetBills(id, status)

Parameters

idstring
The player who owes them, or an account id for what was billed to that account
statusstringoptionaldefault nil
unpaid, paid, declined, cancelled or expired; all of them when left out

Returns

table
The newest 100 bills and requests (below)

A bill:

{
    id = 812,
    kind = 'bill',          -- 'bill' or 'request'
    amount = 1500,
    note = 'Speeding',
    status = 'unpaid',
    reference = '3FA9C2D1-0B7E',
    issuer = 'LSPD',        -- the name on the bill
    issuerId = nil,         -- the player who wrote it
    accountId = 'police',   -- where the money goes; nil for a fine
    target = 'ABC12345',    -- who pays: a player's identifier, or an account id
    createdAt = 1730000000,
    dueAt = 1730604800,
    paidAt = nil,
    commission = 0,         -- the employee cut, in percent
    sale = nil,             -- a register's ticket: { lines, subtotal, tax, taxRate, taxAccount?, note? }
    scheduleId = nil,       -- the repeating series it belongs to
    repeatDays = nil,
}

Loans

GetLoan

Server export

local loan = exports.lation_banking:GetLoan(identifier)

Parameters

identifierstring
The player

Returns

table | nil
The player's active or defaulted loan, or nil
{
    id = 31,
    identifier = 'ABC12345',
    name = 'Jane Doe',
    principal = 10000,     -- borrowed
    interest = 10,         -- percent
    total = 11000,         -- to repay
    remaining = 7856,
    paid = 3144,
    installment = 1572,    -- per day
    termDays = 7,
    nextDue = 1730086400,  -- unix seconds
    missed = 0,
    status = 'active',     -- 'active' or 'defaulted'
    createdAt = 1729900000,
    closedAt = nil,
}

Register

GetPosProducts

Server export

local products = exports.lation_banking:GetPosProducts(accountId)

Parameters

accountIdstring
The business's society id

Returns

table
The menu in order: { id, category, label, price, item } each. A price of 0 means on the menu but not for sale.

AddPosProduct

Server export

local productId, err = exports.lation_banking:AddPosProduct(accountId, data)

Parameters

accountIdstring
The business's society id
data.labelstring
The product name, up to 40 characters
data.pricenumber
Above zero
data.categorystringoptionaldefault nil
Up to 30 characters
data.itemstringoptionaldefault nil
An inventory item name, for the tile's picture

Returns

number | nil, string
The product id, or nil and invalid, limit (300 products) or database

A register only sells from the menu of a society listed under Config > POS > Businesses. Open registers refresh at once.

server.lua
exports.lation_banking:AddPosProduct('burgershot', { label = 'Bleeder', price = 12, category = 'Burgers', item = 'burger' })

RemovePosProduct

Server export

local ok = exports.lation_banking:RemovePosProduct(id)

Parameters

idnumber
The product id

Returns

boolean

Societies and registers

For a resource that runs jobs or businesses of its own, such as lation jobs: society accounts on demand, and register entries under Config > POS that it keeps itself.

EnsureSocietyAccounts

Server export

local ok, reason = exports.lation_banking:EnsureSocietyAccounts(name)

Parameters

namestringoptionaldefault nil
A job or gang name, to ask about that one

Returns

boolean, string
true, or false and societies_disabled, gangs_disabled, unknown_group, invalid or database

Does what the bank does on its own start: every job the framework knows gets its society account, and every gang while Config > Accounts > Gang accounts too is on. Safe to call any time; nothing is ever closed, and an account outlives the job it was opened for.

  • Without a name it returns true, or false, 'societies_disabled' while Config > Accounts > Society accounts is off, when the bank opens none.
  • With a name it says whether that account exists afterwards: true (one opened before society accounts went off still counts), or false and societies_disabled, gangs_disabled (a gang, with gang accounts off) or unknown_group (a name the framework doesn't know).

Call it after adding a job while the server runs. The bank also does this on its own when lation_jobs:jobCreated or lation_jobs:jobDeleted fires, and on QBCore when qb-core's AddJob or AddGang adds one.

server.lua
local ok, reason = exports.lation_banking:EnsureSocietyAccounts('tequilala')
if not ok then print(('no society account for tequilala: %s'):format(reason)) end

SetPosBusiness

Server export

local ok = exports.lation_banking:SetPosBusiness(id, rules)

Parameters

idstring
The society: a job or gang name
rules.taxnumber | falseoptional
Its own sales tax in percent; false for the section's
rules.accountstring | falseoptional
The society its tax is paid into; false for the section's
rules.lockedbooleanoptional
true keeps the menu to the admin: its bosses can't edit it at the register

Returns

boolean
true once saved, or when nothing needed changing; false for a bad argument or a failed save

Lists the society under Config > POS > Businesses, as an admin adding it would, so it gets a register; pass nil instead of rules to take it off. Its menu is kept either way.

It merges: only the fields you pass change, so the tax, tax account and menu setting an admin chose stay when you leave them out, and a resource that lists its businesses on every start never resets them. A new entry starts on the section's tax and account, with the menu open to its bosses. Any other key, such as a label, is ignored.

server.lua
exports.lation_banking:SetPosBusiness('burgershot', {})  -- give Burger Shot a register
exports.lation_banking:SetPosBusiness('burgershot', nil) -- and take it away

SetPosLocation

Server export

local ok = exports.lation_banking:SetPosLocation(id, point)

Parameters

idstring
An id of your own, prefixed with your resource name
point.labelstring
The point's name, up to 40 characters
point.coordstable
{ x, y, z, w }
point.businessstringoptionaldefault ''
The society whose staff see Open register there; empty for any business

Returns

boolean
true once saved

Places a register point under Config > POS > Registers, replacing the one that id already holds; pass nil instead of point to remove it. The points an admin placed from the panel carry no id and are not yours to change. The 50-point limit counts every point.

server.lua
exports.lation_banking:SetPosLocation('myjobs:14', { label = 'Counter', business = 'burgershot', coords = { x = -1194.2, y = -893.5, z = 13.9, w = 305.0 } })

Players

OpenBank

Server export

local sent = exports.lation_banking:OpenBank(source, kind)

Parameters

sourcenumber
The player's server id
kindstringoptionaldefault 'bank'
bank, atm, bill, pos or admin

Returns

boolean
true once the request is sent; false for admin and a player who is not an admin

The usual checks still apply when it opens, such as Hooks.canOpen, the PIN at an ATM, and having a register for pos.

server.lua
exports.lation_banking:OpenBank(source, 'atm')

RequestPin

Server export

local passed = exports.lation_banking:RequestPin(source, accountId)

Parameters

sourcenumber
The player's server id
accountIdstringoptionaldefault nil
A shared or business account; the player's own PIN when left out

Returns

boolean
Whether the player entered the right PIN

Puts something of your own behind the bank's PIN. The player sees the PIN pad and the call waits for the answer, which is decided on the server.

  • Returns true straight away when Config > ATMs > Ask for a PIN is off or the account has no PIN, so you can always call it and let the server's setting decide.
  • Returns false when the player cancels, runs out of tries, already has the bank open, or leaves, and for an unknown accountId.
  • Three misses lock the account out for 15 minutes, as at an ATM.
server.lua
if exports.lation_banking:RequestPin(source) then
    OpenTheSafe(source)
end

Settings

GetConfig

Server export

local section = exports.lation_banking:GetConfig(name)

Parameters

namestringoptionaldefault nil
general, currency, amounts, banks, blip, atm, accounts, transfers, transactions, bills, requests, pos, savings or loans

Returns

table | nil
A copy of that section, nested by the keys on the configuration page, or every section when left out. nil for an unknown section or logs.

Coordinates come back as { x, y, z, w } tables. Logging is never returned, so the webhook stays on the server.

server.lua
local atm = exports.lation_banking:GetConfig('atm')
print(atm.pin) -- false

Business accounts

A business account holds money for your resource: a player-owned shop, a garage, anything with a till that is not a job. Your resource opens it, names its owner and staff, and moves its money; the bank keeps the balance, the number, the PIN and the history, and players see it under Business accounts.

server.lua
local id = ('myshop:%s'):format(shopId)

exports.lation_banking:CreateAccount({ id = id, type = 'business', name = 'Bean Machine', owner = ownerIdentifier })
exports.lation_banking:AddAccountMember(id, employeeIdentifier, { deposit = true, withdraw = false, transfer = false })

-- a sale at your till
exports.lation_banking:AddAccountMoney(id, 250, 'Order #1042')

-- the shop changes hands, or nobody owns it for now
exports.lation_banking:SetAccountOwner(id, newOwnerIdentifier)
exports.lation_banking:SetAccountOwner(id, nil)

The owner can deposit, withdraw and transfer; members can do what you allowed. Nothing about the account is managed from the bank: players can't rename it, change its members or close it. Business accounts don't count against the shared account limit.

To keep your own copy of the balance in step, listen for lation_banking:transaction and skip the moves your resource made itself.

Client exports

openBank, openATM, openPos and closeBank

Client export

exports.lation_banking:openBank(account) -- the full bank, on that account
exports.lation_banking:openATM()   -- the ATM view
exports.lation_banking:openPos()   -- the register
exports.lation_banking:closeBank() -- closes whichever is open

They go through the server's checks, as a branch or an ATM does. openBank takes an optional account id: the bank opens on that account when the player can use it, and on their own otherwise; lation jobs' Open in bank uses it. openPos is what the ox_inventory item's client.export calls.

isOpen

Client export

local open = exports.lation_banking:isOpen()

Returns

boolean
Whether the bank, an ATM, a card or the admin panel is open

requestPin (client)

Client export

local passed = exports.lation_banking:requestPin(accountId)

Parameters

accountIdstringoptionaldefault nil
A shared or business account; the player's own PIN when left out

Returns

boolean
The server's answer, as RequestPin gives it
client.lua
if exports.lation_banking:requestPin() then
    OpenLocker()
end

Events

lation_banking:transaction

Server event

AddEventHandler('lation_banking:transaction', function(tx) end)

Fields of tx

accountIdstring
The account the line is on
typestring
deposit, withdraw, transfer_in, transfer_out, income or expense
amountnumber
Always positive
balanceAfternumber | nil
The balance after the move, when known
notestring | nil
The description
counterpartystring | nil
The other side's name
counterpartyAccountstring | nil
The other side's account number
actorIdentifierstring | nil
The player behind it, when a player acted
actorNamestring | nil
That player's name, or the resource that called an export
referencestring | nil
Shared by both lines of a transfer, and by every line a bill payment writes

A local server event fired for every line the bank writes: player actions, exports, the compatibility exports, other scripts' tracked moves, interest, imports and admin adjustments. A report that fills in a line framework tracking already wrote does not fire it again.

server.lua
AddEventHandler('lation_banking:transaction', function(tx)
    if tx.accountId ~= myAccountId then return end
    if tx.actorName == GetCurrentResourceName() then return end -- our own move
    print(('%s %d, balance now %s'):format(tx.type, tx.amount, tx.balanceAfter))
end)

lation_banking:configUpdated

Server event

AddEventHandler('lation_banking:configUpdated', function(section) end)

Parameters

sectionstring | nil
The section an admin saved, such as atm; nil once the stored configuration is first loaded on start

A local server event fired after a section is saved and applied. Read the new values with GetConfig.

server.lua
AddEventHandler('lation_banking:configUpdated', function(section)
    if section == 'currency' then
        local currency = exports.lation_banking:GetConfig('currency')
        print(('the bank now writes money with %s'):format(currency.symbol))
    end
end)

On the client, lation_banking:configUpdated fires with no arguments when a section the client holds (General, Currency, Quick amounts, Branches, Map blip, ATMs or POS) changed.

Compatibility events

The events the old banks used still work; see Migrating.

EventSideWhat lation banking does
Renewed-Banking:client:openBankUIClientOpens the bank, or the ATM view with { atm = true }
Renewed-Banking:client:sendNotificationClientShows the message as a notification
okokBanking:OpenATMClientOpens the ATM view
okokBanking:AddNewTransactionServer, localWrites both sides of a transfer another script made

Hooks

server/utils/hooks.lua ships open. Edit the functions in place.

canOpen

Hook

function Hooks.canOpen(source, kind)

Parameters

sourcenumber
The player
kindstring
bank, atm, bill, pos (a cashier's register), pos_charge (the card a customer pays a sale on) or pin (a RequestPin card)

Returns

boolean, string
false and an optional message to refuse

Called before the bank opens. The admin panel does not pass through it.

server/utils/hooks.lua
-- ATMs only for players with a bank card (ox_inventory)
function Hooks.canOpen(source, kind)
    if kind == 'atm' and exports.ox_inventory:Search(source, 'count', 'bank_card') < 1 then
        return false, 'You need your bank card'
    end
    return true
end

canTransact

Hook

function Hooks.canTransact(data)

Parameters

data.sourcenumber
The player
data.actionstring
deposit, withdraw, transfer, bill or pos
data.accountIdstring
For deposit and withdraw, the account; for transfer, the sender; for bill, the paying account (cash when a sale is paid in cash); for pos, the business ringing the sale
data.amountnumber
The amount
data.targetstring | nil
For transfer, the recipient; for bill, the account the bill pays into; for pos, the customer, or the account the sale is billed to

Returns

boolean, string
false and an optional message to refuse

Called before a player's deposit, withdrawal, transfer, bill payment or sale, while nothing has moved yet. For a sale the bill does not exist yet, which makes this the place to refuse one whose goods the customer could not carry. Exports, the compatibility exports, loans and ongoing payments do not call it.

server/utils/hooks.lua
function Hooks.canTransact(data)
    if data.action == 'withdraw' and data.amount > 50000 then
        return false, 'Withdrawals over $50,000 need a manager'
    end
    return true
end

onTransaction

Hook

function Hooks.onTransaction(transaction)

Parameters

transactiontable
The same fields as lation_banking:transaction

Called after every line is written, just before the event fires.

onAccountChange

Hook

function Hooks.onAccountChange(data)

Parameters

data.actionstring
created, deleted, memberAdded, memberUpdated or memberRemoved
data.accountIdstring
The account
data.sourcenumber
The player who did it
data.identifierstring | nil
The member, for the member actions

Called when a player opens or closes a shared or savings account, or adds, changes or removes a member, including leaving on their own. Changes made through exports do not call it.

server/utils/hooks.lua
function Hooks.onAccountChange(data)
    if data.action == 'memberAdded' then
        print(('%s was given access to %s'):format(data.identifier, data.accountId))
    end
end

ongoingPayments

Hook

function Hooks.ongoingPayments(source, identifier)

Parameters

sourcenumber
The player
identifierstring
Their identifier

Returns

table
A list of entries (below), drawn under the bills

What the player owes other resources, listed under their bills. Called when the Bills page opens, while bills are on, and cached for 30 seconds, so keep it quick. Up to 20 rows are shown, and an error in it is printed to the console instead of breaking the page.

FieldTypeDefaultDescription
idstringrequiredStable and unique, such as finance:7XD863HX
labelstringrequiredThe headline
notestringnilThe second line
amountnumbernilThe next payment, shown on the right
remainingnumbernilStill owed in all, shown under the amount
dueAtnumbernilUnix seconds; shown as a date, red once past
progresstablenil{ paid = 1, total = 12 } draws a meter
iconstringnilA name from the bank's icon set, such as car or receipt
warningbooleanfalseMarks the row as having a problem
payablebooleanfalseShows a Pay button; needs pay
payfunctionnilpay(source) moves the money itself and returns success, message?
reasonstringthe labelWhat the history line is called once paid

pay runs under the player's lock, like every money action, and not at an ATM. Its money leaves through the framework, so with tracking on the line it writes is renamed to reason.

server/utils/hooks.lua
function Hooks.ongoingPayments(source, identifier)
    local list = {}

    -- ...keep the jg-dealerships block that ships here...

    list[#list + 1] = {
        id = 'rent:' .. identifier,
        label = 'Apartment rent',
        note = 'Alta Street 12',
        amount = 400,
        dueAt = os.time() + 3 * 86400,
        icon = 'receipt',
        payable = true,
        pay = function(src) return PayRent(src) end
    }
    return list
end

Open code

These files ship unescrowed, for you to edit:

FileWhat it holds
bridge/server.lua, bridge/client.luaFramework access: players, money, jobs, gangs, HasSocietyAccess, usable items. Add a framework where it says Add custom framework here.
server/utils/hooks.luaThe hooks above
server/utils/perms.luaIsAdmin, who may open /bankadmin
server/utils/logging.luaLogging to Discord or Fivemanage, and the logging defaults
server/database/queries.lua, schema.sql, migrations.luaEvery SQL statement, the tables and the schema updates
client/utils/interact.luaInteraction systems, with a custom slot
client/utils/notify.luaNotification systems, with a custom slot
client/utils/peds.luaHow branch peds are spawned
locales/*.jsonEvery string

Still stuck? Ask in our Discord: the people who write the scripts answer.

Last updated November 10, 2026

Configuration

Every lation banking option with its default and limits, edited in game under /bankadmin > Config, since the resource has no config file.

Changelog

Every lation banking release, newest first, with what it added, changed and fixed.

On this page

Server exportsAccountsGetAccountGetAccountBalanceGetPlayerAccountsGetAccountMembersGetPlayerAccountNumberGetIdentifierByAccountNumberMoneyRefusal codesAddAccountMoneyRemoveAccountMoneyTransferMoneyManaging accountsCreateAccountDeleteAccountRenameAccountSetAccountFrozenSetAccountOwnerAddAccountMemberUpdateAccountMemberRemoveAccountMemberClearAccountMembersHistoryAddTransactionGetTransactionsBillsCreateBillPayBillCancelBillGetBillsLoansGetLoanRegisterGetPosProductsAddPosProductRemovePosProductSocieties and registersEnsureSocietyAccountsSetPosBusinessSetPosLocationPlayersOpenBankRequestPinSettingsGetConfigBusiness accountsClient exportsopenBank, openATM, openPos and closeBankisOpenrequestPin (client)Eventslation_banking:transactionlation_banking:configUpdatedCompatibility eventsHookscanOpencanTransactonTransactiononAccountChangeongoingPaymentsOpen code
lation scripts

FiveM scripts for Qbox, QBCore and ESX servers, made to look and work like one product.

store

  • all scripts
  • membership
  • classics

help

  • docs
  • discord
  • email support

legal

  • terms
  • refunds
  • privacy
© 2026 Lation Labslationscripts.com
  • home
  • scripts
  • membership
  • docs