lation scripts
scriptsmembershipdocs
see the scripts
Skip to Content
lation ui
lation interact
lation banking
lation shops
lation jobs
lation weed
lation chop shop

classics

money laundering
Contracts and the warehouseConfigurationDevelopersChangelog
drug sales
coke processing
meth crafting
metal detecting
scuba diving
money laundering

Developers

The money laundering client and server exports, its notification event, the hooks in its open files and the integrations you can edit, with signatures and Lua examples.

Every export is called on exports.lation_laundering. Server exports that act on a player take their server id as source; client exports work on the local player. A player's identifier is the ESX identifier on ESX and the citizenid on Qbox and QBCore.

Client exports

ExportReturns
OpenMenu()Nothing
IsLaundering()boolean
GetData(type?)The local player's record, or one field of it
GetBalance(moneyType)number
PoliceCount()number
GetTimeRemaining()Hours, minutes and seconds

OpenMenu

Client export

exports.lation_laundering:OpenMenu()

Returns

Nothing

Opens the main menu wherever the player is, after CanOpenMenu and the item Config.Start.require asks for. Use it with Config.Start.spawnPed = false to start runs from your own NPC, item or phone app. It waits for the server, so call it from a thread, a command or an event handler.

Contracts start from anywhere. The contract car spawns at the nearest Config.Vehicle.locations entry, and with teleport on the player is put in it there. The car deposit, its refund and the warehouse key are only handled within 15 m of a Config.Start.locations entry, so list the places you open it from there; elsewhere the car is handed out without its deposit, and buying a key does nothing.

client.lua
RegisterCommand('launder', function()
    exports.lation_laundering:OpenMenu()
end, false)

IsLaundering

Client export

local running = exports.lation_laundering:IsLaundering()

Returns

boolean
true while the player has a buyer to meet

It goes false for a moment at the end of each deal, before the next buyer is marked, and stays false once the run stops.

GetData (client)

Client export

local data = exports.lation_laundering:GetData(type)

Parameters

typestringoptionaldefault nil
One field: level, experience, contracts_completed, total_money_cleaned, pending or time_remaining. The whole record when left out.

Returns

table | number
The record from the server, shaped like the server export's, or the value of type. 0 when there is nothing to return.

It asks the server, so call it from a thread.

client.lua
CreateThread(function()
    local level = exports.lation_laundering:GetData('level')
    print(('Laundering level %d'):format(level))
end)

GetBalance

Client export

local amount = exports.lation_laundering:GetBalance(moneyType)

Parameters

moneyTypestring
An item such as markedbills, or an account: cash, bank, or black_money on ESX

Returns

number
What the local player holds, counted the way buyers count it (with Config.QBCore on QBCore and Qbox). 0 when there is nothing.

It asks the server, so call it from a thread.

PoliceCount

Client export

local police = exports.lation_laundering:PoliceCount()

Returns

number
Police in the city, counted as for Config.Police.require: players on duty in Config.Police.jobs on QBCore and Qbox, every player with one of those jobs on ESX

GetTimeRemaining

Client export

local hours, minutes, seconds = exports.lation_laundering:GetTimeRemaining()

Returns

number, number, number
The time left on the local player's wash. 0, 0, 0 when no wash is running or it's done.
client.lua
local h, m, s = exports.lation_laundering:GetTimeRemaining()
if h + m + s > 0 then
    print(('Wash ready in %dh %dm %ds'):format(h, m, s))
end

Server exports

ExportReturns
GetData(source, type?)A player's record, or one field of it
AddData(source, amount, dataType, action)Nothing
CheckLevel(source)Nothing
IsLaundering(source)boolean

GetData

Server export

local data = exports.lation_laundering:GetData(source, type)

Parameters

sourcenumber
The player's server id
typestringoptionaldefault nil
One field of the record. The whole record when left out.

Returns

table | any | nil
The record (below), or the value of type. nil when the player isn't loaded in your framework.

The first time a player is looked up, their row is read from the lation_laundering table, or created at level 1. The record is the cached one, kept in memory until they leave, so treat it as read-only and change it with AddData. At the last level, experience reads as Config.LevelUp.

{
    player_identifier = 'ABC12345', -- once read from the database
    level = 3,
    experience = 42000,           -- XP earned at the current level
    contracts_completed = 318,
    total_money_cleaned = 412750, -- dirty money laundered, lifetime
    pending = 0,                  -- dirty money in the washing machine
    time_remaining = 0,           -- milliseconds left on that wash
}
server.lua
local level = exports.lation_laundering:GetData(source, 'level')
if level and level >= 3 then
    -- unlock something
end

AddData

Server export

exports.lation_laundering:AddData(source, amount, dataType, action)

Parameters

sourcenumber
The player's server id
amountnumber
The amount, 0 or more
dataTypestring
The field: level, experience, contracts_completed or total_money_cleaned
actionstring
'add' to add amount, 'set' to replace the field with it

Returns

Nothing

Changes the cached record. XP is refused at the last level. Adding XP doesn't level the player up on its own: call CheckLevel after it. Nothing is written straight away; the record is saved when the player leaves, when the resource stops and when txAdmin shuts the server down.

server.lua
exports.lation_laundering:AddData(source, 5000, 'experience', 'add')
exports.lation_laundering:CheckLevel(source)

CheckLevel

Server export

exports.lation_laundering:CheckLevel(source)

Parameters

sourcenumber
The player's server id

Returns

Nothing

Moves the player up a level for every Config.LevelUp of XP they hold, keeps the leftover, and sends the levelUp log. Does nothing at the last level. The player isn't told, and the warehouse blip waits for their next login or a key.

IsLaundering (server)

Server export

local running = exports.lation_laundering:IsLaundering(source)

Parameters

sourcenumber
The player's server id

Returns

boolean
The player's client IsLaundering

It asks the player's client and waits for the answer, so call it from a thread or an event handler.

Events

lation_laundering:Notify

Client event

TriggerClientEvent('lation_laundering:Notify', source, message, type)

Parameters

messagestring
The text
typestring
success, error, warning or inform, as your notification system reads them

Send it from the server to show a notification through Config.Notify, under the script's Money Laundering title where the system shows one.

server.lua
TriggerClientEvent('lation_laundering:Notify', source, 'The launderer wants a word', 'inform')

Hooks

Hooks are plain functions in the files that ship open. Edit them in place.

Client hooks

In client/functions.lua.

HookCalledDefault
CanOpenMenu()Before the main menu opens, at the launderer or through OpenMenuRefuses dead players
CanBuyKey()When a player picks Warehouse in the menu, before the confirmAllows everyone
CanEnterWarehouse()When a player uses the warehouse doorThe key, police and level checks
StartedLaundering()After each contract is assigned, so once per buyerEmpty
StoppedLaundering()When a run is stopped with Stop Contracts, or ends because the dirty money ran outEmpty
EnteredWarehouse()After a player is taken insideEmpty
ExitedWarehouse()After a player is taken back outEmpty
StartedCounting()When counting startsLocks ox_inventory, qb-inventory or qs-inventory
StoppedCounting()When counting endsUnlocks them

CanOpenMenu

Client hook

CanOpenMenu = function() end

Returns

boolean
false to keep the menu closed

Tell the player why when you refuse, with ShowNotification(message, 'error').

CanBuyKey

Client hook

CanBuyKey = function() end

Returns

boolean
false to refuse the key

The file's example keeps keys to gang members, with a placeholder that lets everyone through:

client/functions.lua
CanBuyKey = function()
    local inGang = true -- replace with your gang script's check
    if not inGang then
        ShowNotification('You must be a gang member to purchase this', 'error')
        return false
    end
    return true
end

CanEnterWarehouse

Client hook

CanEnterWarehouse = function() end

Returns

boolean
false to keep the player out

The default is the warehouse's whole entry check: the player needs Config.Items.key and, with Config.Warehouse.requireLvl, the unlock level; police jobs need neither while Config.Police.warehouseAccess is on. A refused player is told "You are not authorized to enter". Add your own conditions before its return, and keep the rest unless you mean to replace it.

Server hooks

In server/functions.lua. Both run before the money moves.

HookCalled withWhen
TaxPaid(source, amount, type)The tax kept, and 'contracts' or 'warehouse'At every deal, and when a wash is picked up
MoneyLaundered(source, amount, type)The clean cash paid for a deal, or the uncounted money a wash gives, and 'contracts' or 'warehouse'The same moments
server/functions.lua
function TaxPaid(source, amount, type)
    -- the tax goes to a job's account in lation banking
    exports.lation_banking:AddAccountMoney('government', amount, 'Laundering tax')
end

Integrations

Each system the config lets you pick is a function in client/functions.lua, with a branch to fill in for 'custom':

To changeEdit
Notifications (Config.Notify = 'custom')ShowNotification(message, type)
Progress bars (Config.Progress = 'custom')ProgressBar(data), which returns true when it completes
Text promptsThe textui setting at the top, and ShowTextUI(text, icon) and HideTextUI(label)
A target (Config.Target = 'custom')AddCircleZone, AddTargetEntity, RemoveCircleZone and RemoveTargetEntity
Dispatch (Config.Police.dispatchSystem = 'custom')PoliceDispatch(dispatch), given coords and street
Phone (Config.Phone = 'custom')SendPhoneMessage(), and the lation_laundering:phoneMessage handler in server/functions.lua
Fuel and keys for the contract carSetFuel(vehicle) and GiveKeys(vehicle)
Item checks on the clientHasItem(item, amount) and ItemCount(item)

Frameworks live in bridge/client.lua and bridge/server.lua: each function has a branch marked for a custom framework.

config.lua
strings.lua
logs.lua
client.lua
server.lua
functions.lua
functions.lua

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

Last updated November 11, 2026

Configuration

Every option in money laundering's config.lua with its default value, plus the text prompt setting, the Discord logs in logs.lua and the text in strings.lua.

Changelog

Every money laundering release, newest first, with what it added, changed and fixed.

On this page

Client exportsOpenMenuIsLaunderingGetData (client)GetBalancePoliceCountGetTimeRemainingServer exportsGetDataAddDataCheckLevelIsLaundering (server)Eventslation_laundering:NotifyHooksClient hooksCanOpenMenuCanBuyKeyCanEnterWarehouseServer hooksIntegrations
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