Quasar Framework (qs-core) gives every character one wallet that every script on your FiveM server shares: the cash an ESX script pays out is the cash a QBCore script charges, and the bank balance a Quasar Framework job fills is the one an ESX Legacy shop reads. On top of that wallet you get paychecks by job grade, a full FiveM banking script (qs-banking) with bank branches, ATMs, account numbers, transfers and history, and society and boss funds through the esx_society and qb-management compatibility bridges.
Part | Resource | Folder |
|---|---|---|
Money accounts, paychecks, money commands and exports |
|
|
Bank branches, ATMs, transfers, history |
|
|
ESX society accounts |
|
|
QBCore job and gang funds |
|
|
Money accounts#
Every character has three accounts:
Account | Key | Starting balance | Where players see it | Used for |
|---|---|---|---|---|
Cash |
| $500 | HUD, | Shops, |
Bank |
| $5,000 | HUD, | Paychecks, transfers, the vehicle dealership, police fines. |
Black money |
| $0 | The drug dealer | Dirty money: dealer sales from the drug economy pay into it. |
Cash and bank are the money ESX and QBCore scripts work with: ESX's money account and QBCore's cash are Quasar Framework's cash, and bank is bank everywhere. A paycheck paid by Quasar Framework is in xPlayer.getAccount('bank') and in Player.PlayerData.money.bank straight away.
Black money is an account of its own: banks and ATMs only handle cash and bank, and admins move it with /addmoney and /removemoney (see below).
Starting money#
New characters get the balances of Config.Accounts in qs-core/shared/config.lua:
Config.Accounts = {
cash = 500,
bank = 5000,
black_money = 0,
}Changing the numbers affects characters created afterwards; existing characters keep their balances. This is the only place that sets starting money — Config.StartingAccountMoney in es_extended is not used.
Where money comes from and where it goes#
Every change of cash, bank or black money carries a reason, which you see in your logs and in the qs:server:moneyChange event.
What happens | Account | Amount | Reason |
|---|---|---|---|
Paycheck | + bank | Salary of your job grade |
|
Selling job goods (miner, lumberjack, fisher) | + cash | Per item sold |
|
Delivery job: each package, end-of-shift bonus | + cash | Per stop / bonus |
|
Delivery van deposit (taken, then returned) | − / + cash | $100 |
|
Medic stabilises a downed patient | + cash (medic) | $250 |
|
Drug sales to a dealer | + black money | Per sale |
|
| cash, player to player | Any |
|
Shop purchase | − cash | Price × amount |
|
Vehicle dealership | − bank, or cash if the bank is short | Vehicle price |
|
Hospital treatment | − cash | $250 |
|
Police fine | − bank | $1 – $50,000 |
|
Bank deposit / withdrawal | cash ↔ bank | Any |
|
Bank transfer | − bank (sender), + bank (recipient) | Amount (+ fee for the sender) |
|
Admin command or admin menu | Any | Any |
|
One more option shapes the economy: Config.Death.loseCashOnDeath in qs-core/shared/config.lua (default false). Set it to true and players lose all their cash when they respawn at the hospital.
Money commands#
Command | Who | What it does |
|---|---|---|
| Everyone | Shows your cash and bank balance. |
| Everyone | Gives cash to the nearest player within 3 m. Both players get a notification. |
| Admins ( | Adds money to |
| Admins ( | Removes money. Nothing happens if the player does not have that much. |
<account> is the Quasar Framework key: cash, bank or black_money (not ESX's money). From the server console or txAdmin the same commands work without the slash, for example addmoney 1 bank 10000. Admins can also add, remove or set any account from the admin menu (F6) — see Administration.
To keep a record in Discord, set the webhooks in qs-core/shared/config.lua:
Option | Default | What it logs |
|---|---|---|
|
| Every |
|
| Every |
Money from your own scripts#
local core = exports['qs-core']
local cash = core:GetMoney(source, 'cash')
-- pay 250 into the bank, tagged for your logs
core:AddMoney(source, 'bank', 250, 'myscript:reward')
-- charge 100 cash; false when the player cannot afford it
if core:RemoveMoney(source, 'cash', 100, 'myscript:fee') then
-- paid
end
-- set an exact balance
core:SetMoney(source, 'bank', 10000)local xPlayer = ESX.GetPlayerFromId(source)
xPlayer.addMoney(250) -- cash
xPlayer.addAccountMoney('bank', 250)
xPlayer.removeAccountMoney('bank', 100)
local bank = xPlayer.getAccount('bank').moneylocal Player = QBCore.Functions.GetPlayer(source)
Player.Functions.AddMoney('bank', 250, 'reward')
Player.Functions.RemoveMoney('cash', 100, 'fee')
local cash = Player.Functions.GetMoney('cash')Server export | Parameters | Returns |
|---|---|---|
|
| Balance (number). |
|
|
|
|
|
|
|
|
|
Every AddMoney and RemoveMoney fires the server event qs:server:moneyChange — the easiest way to build a money log:
AddEventHandler('qs:server:moneyChange', function(source, account, kind, amount, reason)
-- kind is 'add' or 'remove'
print(('[money] %s %s $%s %s (%s)'):format(source, kind, amount, account, reason or '-'))
end)SetMoney changes the balance without firing it.
Driving the economy from your own scripts? The player object (
exports['qs-core']:GetPlayer(source)withgetMoney,addMoney,removeMoney,setMoney), every money export and every event are listed in Commands and Exports.
Paychecks#
Every 30 minutes, everyone online with a character loaded receives the salary of their job grade in their bank, with the notification Paycheck received: $500. The timer is shared: everyone is paid at the same moment. A grade with salary 0 is not paid.
Option | Default | What it does |
|---|---|---|
|
| Turns paychecks on or off. |
|
| Time between paychecks, in milliseconds. |
Both are in qs-core/shared/config.lua and are read when qs-core starts.
Salaries by job and grade#
Job | Grade | Rank | Salary |
|---|---|---|---|
| 0 | Freelancer | $200 |
| 0 | Recruit | $500 |
| 1 | Officer | $750 |
| 2 | Sergeant | $1,000 |
| 3 | Chief (boss) | $2,000 |
| 0 | Trainee | $500 |
| 1 | Paramedic | $800 |
| 2 | Doctor | $1,200 |
| 3 | Chief (boss) | $2,000 |
| 0 | Hunter | $200 |
| 0 | Driver | $200 |
| 0 | Miner | $175 |
| 0 | Lumberjack | $175 |
| 0 | Fisherman | $150 |
Players without a job are unemployed and still receive $200 as Freelancer. Set that salary to 0 to stop paying the unemployed.
Salaries live in qs-core/shared/jobs.lua:
['police'] = {
label = 'Police',
grades = {
[0] = { name = 'recruit', label = 'Recruit', salary = 500 },
[1] = { name = 'officer', label = 'Officer', salary = 750 },
[2] = { name = 'sergeant', label = 'Sergeant', salary = 1000 },
[3] = { name = 'boss', label = 'Chief', salary = 2000, isBoss = true },
},
},Banking#
qs-banking (in [addons]) is the FiveM banking script of Quasar Framework: 8 bank branches with tellers, every ATM on the map, personal account numbers, deposits, withdrawals, transfers to online and offline players and a transaction history. The balances it shows are the same cash and bank used by every ESX, QBCore and Quasar Framework script.
Bank branches and ATMs#
Each branch has a green Bank blip on the map and a teller. Walk up to the counter: within about 2.4 m you see Press E to use the bank; press E. ATMs need no blip — every ATM prop in the world works: stand within 1.6 m to see Press E to use the ATM.
# | Branch | Coordinates |
|---|---|---|
1 | Legion Square |
|
2 | Rockford Hills |
|
3 | Great Ocean Highway |
|
4 | Paleto Bay |
|
5 | Alta, Hawick Avenue |
|
6 | Burton |
|
7 | Route 68, Harmony |
|
8 | Pacific Standard, Vinewood |
|
What you can do | Bank branch | ATM |
|---|---|---|
See your bank balance, cash and account number | Yes | Yes |
Deposit cash | Yes | Yes |
Withdraw cash | Yes | Yes |
Transfer to another account | Yes | — |
Transaction history | Yes | Yes |
The HUD hides while the bank is open. Amount fields have quick buttons ($100, $500, $1,000, $5,000, $25,000) and MAX.
Account numbers#
Every character gets one account number the first time they open a bank or an ATM: QS followed by 9 digits, for example QS482910375. It never changes. Click the balance card to copy it (Account number copied) and share it to receive transfers.
Deposit and withdraw#
Deposit moves cash into the bank. You need that much cash (You don't have that much cash).
Withdraw moves money from the bank into your cash. You need that much in the bank (Insufficient funds).
Amounts are whole dollars above 0. You see Deposited $500 or Withdrew $500, and the balances update at once.
Transfers#
Get the recipient's account number
They find it on the balance card of any bank or ATM and can copy it with one click.
Open a bank branch
Transfers are made at a branch (ATMs do not have the Transfer tab). Choose Transfer.
Enter the number and the amount
Paste the account number (spaces are ignored), type the amount and confirm.
Done
You see Transferred $1000. If the recipient is online, the money is in their bank at once and they see You received $1000. If they are offline, it is added to their bank and waiting for them at their next login.
Rule | What happens |
|---|---|
The account number does not exist | That account does not exist |
It is your own account | You cannot transfer to yourself |
Your bank does not cover the amount plus the fee | Insufficient funds |
Transfer fee |
|
Example with Config.TransferFee = 0.02 (2%): sending $10,000 costs the sender $10,200 and the recipient receives $10,000.
History#
The History tab lists your 25 newest operations (Config.HistoryLimit), newest first. Each one is stored with its amount, your bank balance after it, a label and the date.
Type | Sign | Label |
|---|---|---|
| + | Cash deposit |
| − | Cash withdrawal |
| + | Transfer from |
| − | Transfer to |
The sender's transfer_out shows the amount sent; the fee is not a separate line. For a transfer received while offline, the balance column of that line shows 0.
Limits#
Limit | Value |
|---|---|
Amounts | Whole dollars above 0 (decimals are rounded down). |
Deposits and withdrawals | One every 0.6 seconds per player. |
Transfers | One every 1.2 seconds per player. |
Maximum per operation | None — up to your balance. |
Going below zero | Not possible. |
History shown | 25 newest operations ( |
Banking configuration#
All options are in qs-banking/config.lua.
Option | Default | What it does |
|---|---|---|
|
| Control that opens a bank or an ATM. |
|
| ATM reach in metres. Bank branches use this + 0.8 m. |
|
| Fee charged to the sender, as a fraction of the amount ( |
|
| How many history lines are shown. |
|
| Props that work as ATMs. |
| 8 branches |
|
|
| Blip of every branch. |
To add a branch, stand where the teller should be, run /coords and add a line to Config.Banks:
Config.Banks = {
-- ...existing branches...
{ coords = vec4(0.0, 0.0, 0.0, 0.0), ped = 'U_M_M_BankMan', scenario = 'WORLD_HUMAN_CLIPBOARD' }, -- paste the vec4 from /coords
}Then restart qs-banking.
Events and callbacks for integrators#
qs-banking has no commands and no exports. Phone banking apps, tablets and logs can use these:
qs-banking:data (server callback)
Returns the calling player's { cash, bank, account, history } and creates their account number if they do not have one yet.
-- client side
exports['qs-core']:TriggerCallback('qs-banking:data', function(data)
print(data.account, data.bank, #data.history)
end)qs-banking:server:deposit / qs-banking:server:withdraw (net events)
TriggerServerEvent('qs-banking:server:deposit', amount) and TriggerServerEvent('qs-banking:server:withdraw', amount). The server applies every rule above (balance, whole amounts, rate limit), logs the operation and notifies the player.
qs-banking:server:transfer (net event)
TriggerServerEvent('qs-banking:server:transfer', accountNumber, amount). Same checks, fee and history as a transfer made at a branch, so a phone app can offer transfers too.
qs-banking:client:update (client event)
Sent to the player with { cash, bank, history } after each of their operations, and to the recipient of a transfer.
Money log reasons
Bank operations fire qs:server:moneyChange with the reasons bank-deposit, bank-withdraw and bank-transfer.
Database tables
bank_accounts (citizenid, account_number) and bank_transactions (citizenid, type, amount, balance, label, created) are created by the Quasar Framework SQL file.
SELECT account_number FROM bank_accounts WHERE citizenid = 'QSABC123';Integrating a phone or a tablet? The
qs-corecallbacks (TriggerCallback) and money exports are documented in Commands and Exports.
Society and boss funds#
Many ESX and QBCore scripts keep a shared balance per job or gang — the money of the police department, a mechanic shop or a gang. Quasar Framework ships two compatibility resources in [bridge] that answer exactly like the originals, so those scripts work unmodified:
Bridge | For | Database table | Holds |
|---|---|---|---|
| ESX scripts |
| One balance per society account name. |
| QBCore scripts |
| One balance per job ( |
Both create their table on start and save every change.
Export / callback | What it does |
|---|---|
| Balance of that account. |
| Adds a whole amount above 0. |
| Removes it; the balance never goes below 0. No return value. |
| The registered society. |
Callbacks | Same data through |
Event | Registers a society, as ESX job scripts do on start. |
exports['esx_society']:addMoney('society_police', 500)
local balance = exports['esx_society']:getSocietyMoney('society_police')Export | What it does |
|---|---|
| Balance of a job. |
| Adds; returns |
| Removes; |
| Balance of a gang. |
| Adds to a gang. |
| Removes from a gang; |
exports['qb-management']:AddMoney('police', 500)
if exports['qb-management']:RemoveMoney('police', 200) then
-- paid from the police fund
endFrequently asked questions#
I did not get a paycheck.
Paychecks arrive every 30 minutes for everyone online at that moment, into the bank. Check that your job grade has a salary above 0 in qs-core/shared/jobs.lua (jobs created by ESX or QBCore scripts start at 0) and that Config.Paycheck.enabled is true.
A transfer says "That account does not exist".
The number is wrong, or the recipient has never opened a bank or ATM — account numbers are created on the first visit. Ask them to open one and send you the QS… number from their balance card.
Can I send money to someone who is offline?
Yes. Bank transfers to offline characters are added to their bank and waiting for them at their next login.
How do I give a player money as an admin?
/addmoney <id> <account> <amount>, for example /addmoney 3 bank 25000, or the Money action of the admin menu (F6).
How do I add a fee to bank transfers?
Set Config.TransferFee in qs-banking/config.lua, for example 0.02 for 2%. The sender pays it on top of the amount.
Can players pay at shops by card?
Yes. Set Config.PayAccount = 'bank' in qs-coreshops/config.lua and every shop charges the bank instead of cash.
Do ESX and QBCore scripts see the same money?
Yes for cash and bank: there is one wallet. xPlayer.getMoney(), xPlayer.getAccount('bank'), Player.Functions.GetMoney('cash') and exports['qs-core']:GetMoney() all read the same balances.



