NX CreativeNX CreativeDocs
Scriptsnx_realbanking

Exports

Public exports registered by nx_realbanking, split into server and client.

All server exports live under exports.nx_realbanking:<Name>(). Client exports use the same pattern inside a client-side script.

Server

Integration API

These exports read and move money without a source and without anyone online. Use them for scheduled or automated work: fuel station revenue, faction payroll, funding a faction from a government account.

Each one takes an account reference as its first argument. The same reference format covers all four kinds of account, and it accepts whichever identifier your resource already holds.

ReferenceResolves to
'ACC123456789'A nx_realbanking account (personal, business, savings)
12 or '12'The player on that server id
'player:12'The same, written explicitly
'citizen:ABC123'A framework identifier or citizenid, online or offline
'license:1a2b3c'A raw FiveM identifier (license, steam, discord, fivem, xbl, live)
'char1:1a2b3c'An ESX character identifier
'society:police'A society account, resolved through Config.Societies
'society_police'The shared account name itself
'gov' or 'government'The configured government account

Bare strings are matched in that order, so 'ABC123' works for a citizenid and 'police' works for a job without a prefix. A table form is accepted too: { society = 'police' }, { citizen = 'ABC123' }, { source = 12 }, { government = true }, { account = 'ACC123' }.

Society and government balances are not stored by nx_realbanking. They live in esx_addonaccount on ESX and qb-management or qbx_management on QBCore, and these exports read and write them through whichever one your server runs. The account has to exist there first: paying into a society name that resource has never heard of returns SOCIETY_BACKEND_MISSING rather than writing money nowhere.

On ESX, addon_account_data.money is an integer column. Fractional amounts survive in memory but round when esx_addonaccount saves, so send society accounts whole numbers if the cents matter to you.

Overdraft

Balances stop at zero. A debit that would go below it is refused with INSUFFICIENT_FUNDS and nothing is written.

Society and government accounts can be allowed to go negative, which is what a government account funding factions on a deficit needs. List the account in Config.API.overdraft with the furthest its balance may fall, written as a positive number, or true for no limit. Key it by the shared account name or by the job name.

Config.API = {
    overdraft = {
        ['society_government'] = 250000, -- may fall to -250,000
        ['police']             = 50000,  -- job name works too
        ['society_ambulance']  = true,   -- no limit
    }
}

An account not listed there keeps the hard floor at zero. A debit that is permitted but goes past the configured floor returns OVERDRAFT_LIMIT_EXCEEDED.

Player accounts and personal, business and savings accounts are never taken negative, and no setting changes that.

Overdraft is an ESX feature today. esx_addonaccount lets a shared account hold a negative balance; qb-management refuses at its own API level, so on QBCore a permitted overdraft returns OVERDRAFT_UNSUPPORTED rather than being applied halfway.

These are for your own server-side resources. They skip the checks that exist to constrain a player: no PIN, no ATM proximity, no rate limit, no daily limit and no fee. A frozen or closed account is still refused. Do not wire one straight to a client event without your own authorisation check, or players can call it.

Money-moving exports return a table. On success it carries the new balance and a transaction id. On failure it carries an error code and a readable message, and no money moved.

{ success = true,  balance = 12500.00, txId = 'TX_1756400000_4821' }
{ success = false, error = 'INSUFFICIENT_FUNDS', message = 'Insufficient funds for this transaction' }

Common error codes: ACCOUNT_NOT_FOUND, PLAYER_NOT_FOUND, INVALID_ACCOUNT_REF, INVALID_AMOUNT, INSUFFICIENT_FUNDS, ACCOUNT_FROZEN, ACCOUNT_INACTIVE, CANNOT_TRANSFER_TO_SELF, SOCIETY_NOT_FOUND, SOCIETY_BACKEND_MISSING, OVERDRAFT_LIMIT_EXCEEDED, OVERDRAFT_UNSUPPORTED.

exports.nx_realbanking:GetBalanceserver

Read the current balance of any account.

Parameters

  • refstring|number|table— Account reference.

Returns

number|nil
local balance = exports.nx_realbanking:GetBalance('society:police')
local personal = exports.nx_realbanking:GetBalance('citizen:ABC123')
exports.nx_realbanking:AddMoneyserver

Credit an account. The reason is stored on the transaction and shown in the player's bank app.

Parameters

  • refstring|number|table— Account reference.
  • amountnumber— Positive amount. Rounded to two decimals.
  • reasonstring|nil— Stored on the transaction. Trimmed to 140 characters.
  • metadatatable|nil— Extra data kept alongside the reason.

Returns

table { success, balance, txId, accountId, error, message }
-- Fuel station revenue into a society account
local result = exports.nx_realbanking:AddMoney(
    'society:mechanic', 1250.00, 'Fuel station revenue'
)

if not result.success then
    print('Payout failed: ' .. result.error)
end
exports.nx_realbanking:RemoveMoneyserver

Debit an account. Stops at zero unless the account is listed in Config.API.overdraft.

Parameters

  • refstring|number|table— Account reference.
  • amountnumber— Positive amount. Rounded to two decimals.
  • reasonstring|nil— Stored on the transaction.
  • metadatatable|nil— Extra data kept alongside the reason.

Returns

table { success, balance, txId, accountId, error, message }
local result = exports.nx_realbanking:RemoveMoney(
    'citizen:ABC123', 150.00, 'Union dues'
)
exports.nx_realbanking:Transferserver

Move money between any two accounts, in any combination. Debits the source first and puts the money back if the credit fails.

Parameters

  • fromRefstring|number|table— Source account reference.
  • toRefstring|number|table— Target account reference.
  • amountnumber— Positive amount.
  • reasonstring|nil— Stored on both sides of the transfer.
  • metadatatable|nil— Extra data kept alongside the reason.

Returns

table { success, fromBalance, toBalance, txId, error, message }
-- Monthly funding from the government to a faction
local result = exports.nx_realbanking:Transfer(
    'gov', 'society:ambulance', 50000.00, 'Q3 department funding'
)

-- Faction payroll to an individual, online or not
exports.nx_realbanking:Transfer(
    'society:police', 'citizen:ABC123', 2500.00, 'Weekly salary'
)
exports.nx_realbanking:CanAffordserver

Check whether an account holds at least the given amount.

Parameters

  • refstring|number|table— Account reference.
  • amountnumber— Amount to test against.

Returns

boolean
if exports.nx_realbanking:CanAfford('society:police', payrollTotal) then
    runPayroll()
end
exports.nx_realbanking:GetAccountserver

Read one account's details, including its live balance and whether the owner is online.

Parameters

  • refstring|number|table— Account reference.

Returns

table|nil { kind, accountId, citizenId, society, name, accountType, balance, frozen, active, online, source }
local account = exports.nx_realbanking:GetAccount('ACC123456789')
if account and not account.frozen then
    print(account.name, account.balance)
end
exports.nx_realbanking:GetAccountsserver

List every nx_realbanking account a player owns. The one linked to their framework bank balance is flagged and reports the live value rather than a cached copy.

Parameters

  • refstring|number|table— Reference to a player.

Returns

table Array of { accountId, accountType, name, balance, linked, frozen, active }
for _, account in ipairs(exports.nx_realbanking:GetAccounts('citizen:ABC123')) do
    print(account.accountId, account.accountType, account.balance)
end
exports.nx_realbanking:GetTransactionsserver

Read recent transactions for an account, newest first, with the stored reason attached as description.

Parameters

  • refstring|number|table— Account reference.
  • limitnumber|nil— Defaults to 20. Capped at 100.

Returns

table Array of transaction rows
local rows = exports.nx_realbanking:GetTransactions('ACC123456789', 10)
for _, tx in ipairs(rows) do
    print(tx.transaction_type, tx.amount, tx.description)
end
exports.nx_realbanking:ResolveAccountserver

Resolve a reference without moving money. Use it on resource start to check that the account names in your own config are real.

Parameters

  • refstring|number|table— Account reference.

Returns

table { success, kind, accountId, citizenId, society, name, online, source, error }
local resolved = exports.nx_realbanking:ResolveAccount('society:fuel')
if not resolved.success then
    print('Configured account is not usable: ' .. resolved.error)
else
    print(resolved.kind, resolved.name)  -- "society", "Fuel"
end

Invoices

exports.nx_realbanking:CreateInvoiceserver

Insert a new invoice into the database and return its reference id.

Parameters

  • datatable— Invoice payload. Required: senderIdentifier, receiverIdentifier, amount, label. Optional: senderName, receiverName, type ("society" | "freelance" | "personal", default "personal"), senderJob, senderJobLabel, govAccount, societyAccount.

Returns

boolean success, string|nil refIdOrError
local ok, refId = exports.nx_realbanking:CreateInvoice({
    senderIdentifier = 'char1:abc',
    senderName = 'John Smith',
    receiverIdentifier = 'char1:xyz',
    receiverName = 'Jane Doe',
    type = 'personal',
    amount = 250.00,
    label = 'Ride share'
})
exports.nx_realbanking:GetInvoiceserver

Look up an invoice by numeric id or reference id.

Parameters

  • invoiceRefstring|number— Numeric invoice id or reference id (e.g. "INV-ABC123").

Returns

table|nil
local invoice = exports.nx_realbanking:GetInvoice('INV-ABC123')
exports.nx_realbanking:GetInvoiceByRefserver

Fetch a single invoice row by its reference id.

Parameters

  • refIdstring— Reference id returned from CreateInvoice.

Returns

table|nil
local invoice = exports.nx_realbanking:GetInvoiceByRef('INV-ABC123')
if invoice then
    print(invoice.amount, invoice.status)
end
exports.nx_realbanking:GetPlayerInvoicesserver

List invoices received by a given player, newest first.

Parameters

  • identifierstring— Player identifier (framework-specific: ESX identifier or QB citizenid).
  • status?string— Filter: 'pending' | 'paid' | 'cancelled' | 'overdue'. Omit for all.

Returns

table[]
local pending = exports.nx_realbanking:GetPlayerInvoices('char1:abc', 'pending')
print(('%d pending invoice(s)'):format(#pending))
exports.nx_realbanking:GetSentInvoicesserver

List invoices a player has sent.

Parameters

  • identifierstring— Player identifier of the sender.
  • status?string— Filter: 'pending' | 'paid' | 'cancelled' | 'overdue'. Omit for all.

Returns

table[]
local sent = exports.nx_realbanking:GetSentInvoices('char1:abc', 'pending')
exports.nx_realbanking:GetSocietyInvoicesserver

List invoices issued under a given society or job.

Parameters

  • jobstring— Job name (matches Config.Societies key).
  • status?string— Filter: 'pending' | 'paid' | 'cancelled' | 'overdue'. Omit for all.

Returns

table[]
local policeInvoices = exports.nx_realbanking:GetSocietyInvoices('police', 'pending')
exports.nx_realbanking:PayInvoiceserver

Pay an invoice on behalf of the given source. Funds are pulled from the player's default account and distributed to society / commission / VAT destinations.

Parameters

  • refIdstring— Reference id of the invoice to pay.
  • sourcenumber— Server id of the paying player.

Returns

boolean success, string|nil error
local ok, err = exports.nx_realbanking:PayInvoice('INV-ABC123', source)
if not ok then
    print('Payment failed:', err)
end
exports.nx_realbanking:CancelInvoiceserver

Cancel a pending invoice. Bypasses the player-level cancel checks. Intended for admin or system flows.

Parameters

  • refIdstring— Reference id of the invoice to cancel.
  • reason?string— Optional reason recorded in the audit log.

Returns

boolean success, string|nil error
local ok, err = exports.nx_realbanking:CancelInvoice('INV-ABC123', 'duplicate')
exports.nx_realbanking:GetPendingInvoiceCountserver

Count a player's pending invoices in either direction.

Parameters

  • identifierstring— Player identifier.
  • direction?'received' | 'sent'— Direction to count. Defaults to 'received'.

Returns

number
local count = exports.nx_realbanking:GetPendingInvoiceCount('char1:abc', 'received')

Credit cards

exports.nx_realbanking:ChargeCreditCardserver

Charge an amount against a credit card. Supply one of cardId, cardNumber, or citizenId to resolve the card.

Parameters

  • payloadtable— Fields: amount (number, required), cardId | cardNumber | citizenId (one required), merchant (string, optional), transactionType (string, optional).

Returns

table { success: boolean, error?: string, ... }
local result = exports.nx_realbanking:ChargeCreditCard({
    citizenId = 'char1:abc',
    amount = 1200,
    merchant = 'Ammu-Nation',
    transactionType = 'purchase'
})

if not result.success then
    print('Charge failed:', result.error)
end
exports.nx_realbanking:ApplyCreditCardserver

Run the credit-application flow for a player. Assesses score, checks tier eligibility, and either issues a card or returns a rejection reason.

Parameters

  • sourcenumber— Server id of the applying player.
  • requestedTier?string— One of 'standard', 'gold', 'black'. Omit to auto-assign the highest eligible tier from Config.Credit.tierPriority.

Returns

table { success: boolean, error?: string, card?: table, tier?: string, score?: number, ... }
local result = exports.nx_realbanking:ApplyCreditCard(source, 'gold')
if result.success then
    print('Issued', result.tier, 'card #', result.card.number)
else
    print('Rejected:', result.error)
end

The Online* exports below mirror the bank UI actions with the ATM distance check removed, so another server resource such as a laptop or phone banking app can run them for a player who is nowhere near an ATM. Every other guard still runs: rate limiting, account access, ownership, status, and balance validation. These are server-only, so a client cannot reach them directly. Pass the player's own source, and call them only once your resource has authenticated that player's session.

Each returns a table shaped { success = boolean, error = string|nil } plus whatever fields the underlying action produces.

Remote banking

exports.nx_realbanking:OnlineTransferserver

Move money between two accounts without requiring ATM proximity.

Parameters

  • sourcenumber— Server id of the player making the transfer.
  • datatable— Fields: fromAccountId (or fromAccount), toAccountId (or toAccount), amount (number). Optional: description (string), stored on both transactions and shown in the bank app history.

Returns

table { success: boolean, error?: string, ... }
local result = exports.nx_realbanking:OnlineTransfer(source, {
    fromAccountId = 'ACC-1001',
    toAccountId = 'ACC-2002',
    amount = 500.00,
    description = 'Rent'
})
exports.nx_realbanking:OnlineCreateAccountserver

Open a new account for the calling player without requiring ATM proximity.

Parameters

  • sourcenumber— Server id of the player opening the account.
  • datatable— Fields: accountType ('personal' | 'business' | 'savings'), pin (4-digit numeric string). Optional: accountName (string).

Returns

table { success: boolean, error?: string, ... }
local result = exports.nx_realbanking:OnlineCreateAccount(source, {
    accountType = 'savings',
    accountName = 'Rainy day',
    pin = '4821'
})
exports.nx_realbanking:OnlineCloseAccountserver

Close an account the calling player owns, without requiring ATM proximity.

Parameters

  • sourcenumber— Server id of the requesting player.
  • datatable— Fields: accountId (string).

Returns

table { success: boolean, error?: string, ... }
local result = exports.nx_realbanking:OnlineCloseAccount(source, {
    accountId = 'ACC-1001'
})
exports.nx_realbanking:OnlineAddMemberserver

Add a member to a shared account without requiring ATM proximity.

Parameters

  • sourcenumber— Server id of the account owner or manager.
  • datatable— Fields: accountId (string), and citizenId (string) or targetSource (number) to identify the new member. Optional: role (string), permissions (table), limits (table).

Returns

table { success: boolean, error?: string, ... }
local result = exports.nx_realbanking:OnlineAddMember(source, {
    accountId = 'ACC-1001',
    citizenId = 'char1:xyz',
    role = 'teller'
})
exports.nx_realbanking:OnlineTransferOwnershipserver

Hand ownership of an account to another citizen, without requiring ATM proximity.

Parameters

  • sourcenumber— Server id of the current owner.
  • datatable— Fields: accountId (string), citizenId (string) of the new owner.

Returns

table { success: boolean, error?: string, ... }
local result = exports.nx_realbanking:OnlineTransferOwnership(source, {
    accountId = 'ACC-1001',
    citizenId = 'char1:xyz'
})
exports.nx_realbanking:OnlineApplyCreditCardserver

Rate-limited credit application without ATM proximity. Use this instead of ApplyCreditCard when the caller is a remote banking surface.

Parameters

  • sourcenumber— Server id of the applying player.
  • datatable— Optional. Field: requestedTier ('standard' | 'gold' | 'black'). Omit to auto-assign the highest eligible tier.

Returns

table { success: boolean, error?: string, card?: table, tier?: string, score?: number, ... }
local result = exports.nx_realbanking:OnlineApplyCreditCard(source, {
    requestedTier = 'gold'
})

The logging exports below let your own resource write into the same Discord channels the bank uses, so a shop purchase or a heist payout lands in the same audit trail as a withdrawal.

Logging

exports.nx_realbanking:LogBankEventserver

Record an event in the bank's Discord log. Routing, formatting and delivery follow whatever the server owner configured for that category.

Parameters

  • entrytable— Fields: event (string, snake_case key), category ('transactions' | 'security' | 'invoices' | 'credit' | 'accounts' | 'admin'), severity ('info' | 'success' | 'warning' | 'critical'). Identify the player with source, or citizenId when they are offline. Optional: playerName, headline, summary, digest, fields (array of { name, value, inline }), footer.

Returns

table { success: boolean, error?: string }
local result = exports.nx_realbanking:LogBankEvent({
    event     = 'shop_purchase',
    category  = 'transactions',
    severity  = 'info',
    source    = source,
    headline  = 'Ammunation purchase',
    summary   = 'Bought a weapon licence',
    fields    = { { name = 'Merchant', value = 'Ammunation', inline = true } }
})

if not result.success then
    print('Not logged:', result.error) -- e.g. CATEGORY_DISABLED
end

Text you pass is escaped before it reaches Discord, so a player name containing formatting or a link cannot forge content in the log.

Returns CATEGORY_DISABLED when the server owner has that category switched off or has set no webhook for it. That is a normal outcome, not an error to retry.

exports.nx_realbanking:GetLogStatusserver

Current delivery state, for an admin command or a health check.

Returns

table { queues: table[], disabled: string[] }
local status = exports.nx_realbanking:GetLogStatus()

for _, q in ipairs(status.queues) do
    print(('%s: %d waiting, %d dropped'):format(q.category, q.pending, q.dropped))
end

disabled lists webhooks that Discord rejected, usually because the URL was deleted or its token regenerated. Those are switched off until the resource restarts and are reported in the server console.

Client

exports.nx_realbanking:IsAtATMclient

Returns true while the player is within detection range of a known ATM prop.

Returns

boolean
if exports.nx_realbanking:IsAtATM() then
    -- Custom interaction prompt
end
exports.nx_realbanking:GetNearestATMclient

Returns the current ATM context, or nil if none is in range.

Returns

{ entity: number, coords: vector3, distance: number, hash: number } | nil
local atm = exports.nx_realbanking:GetNearestATM()
if atm and atm.distance < 1.5 then
    print('Standing at ATM', atm.entity)
end
exports.nx_realbanking:IsInteractingclient

Returns true while the ATM session is active (camera engaged, NUI open).

Returns

boolean
if exports.nx_realbanking:IsInteracting() then
    -- Suppress your own UI while banking
end
exports.nx_realbanking:GetSessionclient

Returns the current client-side session descriptor, or nil when idle.

Returns

table | nil
local session = exports.nx_realbanking:GetSession()
if session then
    print('Session id:', session.id)
end
NX Docs