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

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.

All settings live in config.lua at the root of the resource. It ships unescrowed, along with strings.lua (every line of text), logs.lua (Discord webhooks), the framework bridge and the two functions.lua files. The sections below follow the file from top to bottom.

config.lua is read when the resource starts, so restart lation_laundering after a change. Times are written with the file's own Seconds, Minutes and Hours (1000, 60000 and 3600000 milliseconds).

Debug and update check

OptionDefaultWhat it does
Config.DebugfalsePrints the server's step-by-step log lines in the console, and outlines the target zones on qb-target and qtarget. Leave it off on a live server.
Config.VersionChecktrueChecks for a newer release on start and prints a notice in the server console when there is one.

Interfaces

OptionDefaultWhat it does
Config.Menu'ox_lib'The menus: 'lation_ui', 'ox_lib', 'esx' (ESX's context menu) or 'qb' (qb-menu).
Config.Target'none'How players interact: 'ox_target', 'qb-target', 'qtarget', 'custom' or 'none' for text prompts. With lation interact, use 'ox_target'. 'custom' is written in client/functions.lua; see developers.
Config.Progress'ox_lib'The progress bars: 'lation_ui', 'ox_lib', 'qbcore' or 'custom'. A custom one must play the animation and attach the prop it's given.
Config.Notify'ox_lib'The notifications: 'lation_ui', 'ox_lib', 'esx', 'qb', 'okok' (okokNotify), 'sd-notify', 'wasabi_notify' or 'custom'. Where the system shows a title, it's Money Laundering.
Config.InteractKey38The key for text prompts, as a control id (38 is E). Only used with Config.Target = 'none'. The prompts say "E" in their text, so change Strings.TextUI with it.

With Config.Menu = 'esx', the menu's Warehouse row does nothing, so players can't buy the warehouse key from it. Use another menu if players need the warehouse.

The alerts (a buyer turning a player down, the key purchase confirm, a finished wash) and the amount dialogs at the washer and the counters always use ox_lib.

Text prompts

The system that draws the text prompts isn't in config.lua. It's the first setting in client/functions.lua:

client/functions.lua
-- Options: 'lation_ui', 'ox_lib', 'jg-textui', 'okokTextUI', 'qbcore' & 'custom'
local textui = 'lation_ui'

The default needs lation_ui running. Without it, set 'ox_lib'. A prompt shows when the player is on foot within 2 m of the launderer, a buyer, the warehouse door, the washing machine or a money counter.

Phone

OptionDefaultWhat it does
Config.Phone'none'Where the player hears that a wash is done: 'qb-phone', 'npwd', 'qs-smartphone', 'qs-smartphonepro', 'lb-phone', 'gksphone', 'yseries' or 'custom'. 'none' shows an alert on screen.

Most phones get a mail from Warehouse, subject Money Status: "Your money is now done & ready to be picked up." npwd gets a text and gksphone a message. The text is Strings.Phone.

Start

The launderer, where players open the menu.

config.lua
Config.Start = {
    spawnPed = true,
    randomizeSpawn = false,
    require = false,
    item = { name = 'water', quantity = 1, remove = false },
    render = 75,
    model = 'g_m_importexport_01',
    locations = {
        vec4(138.6853, 270.6841, 109.9740, 73.0269),
    }
}
OptionDefaultWhat it does
spawnPedtrueSpawns a launderer at the locations. Set false to have none and open the menu your own way with the OpenMenu export.
randomizeSpawnfalsePuts one launderer at a location picked at random each time the resource starts, instead of one at every location.
requirefalseRequires an item to open the menu. Without it, the player is told "I don't think you're ready..".
item.name'water'The required item.
item.quantity1How many they must carry.
item.removefalseTakes one of the item each time the menu opens.
render75Meters from a location at which its launderer appears.
model'g_m_importexport_01'The launderer's ped model.
locationsone locationWhere launderers stand, as vec4.

The server checks that a player is within 15 m of one of these locations before it takes the car deposit, refunds it or sells the warehouse key. If you open the menu elsewhere with the export, add those places here too.

Police

config.lua
Config.Police = {
    jobs = { 'police', 'sheriff' },
    require = false,
    count = 3,
    warehouseAccess = true,
    enableDispatch = false,
    dispatchSystem = 'none'
}
OptionDefaultWhat it does
jobs{ 'police', 'sheriff' }The police jobs: counted for require, let into the warehouse, and, for the dispatch systems that take a job list, sent the calls.
requirefalseRequires police in the city to start each contract. Doesn't apply to the warehouse.
count3How many. On QBCore and Qbox only players on duty count; on ESX, every player with one of the jobs.
warehouseAccesstrueLets police into the warehouse without a key or the level. They still need the level to wash and count while Config.Warehouse.requireLvl is on.
enableDispatchfalseSends a dispatch call when a buyer turns a player down. Needs Config.Reject.enable.
dispatchSystem'none''cd_dispatch', 'ps-dispatch', 'qs-dispatch', 'core_dispatch', 'rcore_dispatch', 'aty_dispatch', 'linden_outlawalert' or 'custom'.

The call is "10-911 Suspicious Activity" at the player's position and street. A 'custom' dispatch is written in PoliceDispatch in client/functions.lua.

Items

config.lua
Config.Items = {
    key = 'warehouse_key',
    uncountedMoney = 'uncounted_money'
}
OptionDefaultWhat it does
key'warehouse_key'The item that opens the warehouse.
uncountedMoney'uncounted_money'The item a finished wash gives, counted into cash at a money counter.

The dirty money isn't set here: each level names its own in dirtyMoney.

QBCore dirty money

How markedbills and cashrolls are read on QBCore and Qbox. Other items, and every item on ESX, count as $1 each.

config.lua
Config.QBCore = {
    metadata = true,
    countTotal = true,
    takeAll = false,
    hardValues = false,
    items = {
        ['markedbills'] = 500,
    }
}
OptionDefaultWhat it does
metadatatrueCounts each bag at the worth stored on it, as QBCore's markedbills carry. false counts each as $1. On Qbox, set false if your dirty money is markedbills.
countTotaltrueAdds up every bag the player carries. false counts only the first one found, so players wash one bag at a time.
takeAllfalseWith metadata on, a buyer offers to take everything the player carries instead of an amount in the level's range.
hardValuesfalseIgnores any stored worth and counts each item at the value in items.
items{ ['markedbills'] = 500 }The value of each item for hardValues.

With metadata on, a bag worth more than a deal is swapped for one holding the rest. With hardValues, whole items are taken until the deal is covered, and nothing comes back.

The server refuses a contract whose clean payout is over the level's top amount raised by its negotiate multiplier. With takeAll, a large bag goes over that and the deal pays nothing.

Contract car

config.lua
Config.Vehicle = {
    spawn = true,
    teleport = true,
    fuel = 85.0,
    models = { 'baller3', 'fugitive' },
    random = true,
    requireDeposit = true,
    depositPrice = 500,
    returnDeposit = true,
    depositReturn = 250,
    account = 'cash',
    locations = {
        vec4(125.9180, 278.1013, 109.9004, 249.8953),
    }
}
OptionDefaultWhat it does
spawntrueGives players a car when they start a run and have none out.
teleporttruePuts the player in its driver's seat.
fuel85.0Its fuel, through LegacyFuel, cdn-fuel, ps-fuel, lj-fuel, okokGasStation or nd_fuel when running, and its fuel state bag. Keep the .0.
models{ 'baller3', 'fugitive' }The car models.
randomtruePicks a model at random. false always uses the first.
requireDeposittrueCharges a deposit for the car.
depositPrice500The deposit.
returnDeposittrueRefunds part of it when the player picks Return Vehicle at the launderer.
depositReturn250The refund.
account'cash'The account for the deposit and refund: 'cash' or 'bank'.
locationsone locationWhere cars spawn, as vec4. The one nearest the player is used, so give each launderer location one.

Keys are given through wasabi_carlock, okokGarage, qb-vehiclekeys, qs-vehiclekeys, cd_garage, vehicles_keys, t1ger_keys or Renewed-Vehiclekeys, whichever runs. Others go in GiveKeys in client/functions.lua.

Rejections

config.lua
Config.Reject = {
    enable = true,
    continue = true
}
OptionDefaultWhat it does
enabletrueLets buyers turn players down, by each level's rejectChance.
continuetrueMarks the next buyer after a rejection or a lost negotiation. false ends the run.

Warehouse

config.lua
Config.Warehouse = {
    unlockAt = 5,
    allowContracts = false,
    requireLvl = true,
    requirePurchase = true,
    price = 2500,
    account = 'cash',
    showBlip = true,
    enterAt = vec4(1142.6859, -986.6674, 45.9059, 96.6889),
    exitAt = vec4(1138.0872, -3199.1570, -39.6657, 181.2139),
    rotate = 180,
    isMLO = false,
    duration = 1 * Hours + 25 * Minutes + 30 * Seconds,
    -- washer, counters, limits: below
    disable = { 200, 36 },
    convertTo = 'cash'
}
OptionDefaultWhat it does
unlockAt5The level that opens the warehouse: the key in the menu, the blip, and by default entry and use. Its level's dirtyMoney is what the washer takes.
allowContractsfalseLets players keep running contracts once they reach unlockAt. Off, buyers refuse them and the menu drops New Contract.
requireLvltrueRequires unlockAt to enter, wash, pick up and count. false lets anyone with a key in, though only players who have reached unlockAt can buy keys.
requirePurchasetrueCharges for the key. false gives it free from the menu.
price2500The key's price.
account'cash'The account it's paid from: 'cash' or 'bank'.
showBliptrueMarks the door with the warehouse blip, for players at unlockAt and anyone who buys a key.
enterAtvec4(1142.6859, -986.6674, 45.9059, 96.6889)The door outside, where players enter and come back out.
exitAtvec4(1138.0872, -3199.1570, -39.6657, 181.2139)Where players arrive inside, and the way out.
rotate180Degrees added to the heading when a player arrives on either side, so they face the right way.
isMLOfalseSet true when the warehouse is an MLO players walk into: the door and way out points are dropped.
duration1 * Hours + 25 * Minutes + 30 * SecondsHow long a wash takes. It counts while the player is on the server and is saved when they leave or the server restarts.
disable{ 200, 36 }Controls turned off while counting, as control ids: 200 is Esc, 36 is Left Ctrl.
convertTo'cash'Where counted money goes: 'cash' or 'bank'.

The default warehouse is the counterfeit cash factory interior, which bob74_ipl fills with its machines. To use another place, move enterAt, exitAt, the washer and the counters.

Washer and counters

config.lua
washer = {
    coords = vec3(1122.4, -3193.5, -40.35),
    size = vec3(1.7, 4.35, 2.1),
    rotation = 0,
    debug = false,
},
counters = {
    [1] = {
        coords = vec3(1116.0024, -3194.9362, -40.5910),
        size = vec3(3.2, 1.0, 1.8),
        rotation = 0,
        radius = 0.35,
        offset = vec3(0.6327, 0.0385, -0.8101),
        heading = 88.88,
        debug = false
    },
    [2] = {
        coords = vec3(1116.0164, -3196.2717, -40.5917),
        size = vec3(3.2, 1.0, 1.8),
        rotation = 0,
        radius = 0.35,
        offset = vec3(0.5997, 0.0329, -0.8074),
        heading = 88.88,
        debug = false
    },
},
OptionDefaultWhat it does
washer.coordsvec3(1122.4, -3193.5, -40.35)The washing machine players use.
washer.sizevec3(1.7, 4.35, 2.1)The zone around it, for text prompts.
washer.rotation0The zone's rotation, for text prompts.
washer.debugfalseDraws the zone, for text prompts.
counterstwo countersThe money counters, one entry each. Add more in the same shape; this makes counters in the interior usable and doesn't place any.
coordsThe money counter.
size, rotation, debugIts zone, for text prompts.
radius0.35Its target zone's radius.
offsetWhere the chair goes and the player sits, from coords.
heading88.88The way the player faces while counting.

Limits

config.lua
limits = {
    washing = { min = 500, max = 25000 },
    counting = { min = 0, max = 15000, interval = 2500 }
},
OptionDefaultWhat it does
limits.washing.min500The least dirty money one wash takes.
limits.washing.max25000The most. Contract amounts are set per level instead.
limits.counting.min0The least a player can count at a sitting.
limits.counting.max15000The most.
limits.counting.interval2500Money per counting animation, about 18 seconds each: $10,000 plays it 4 times.

Levels

config.lua
Config.Levels = {
    [1] = { dirtyMoney = 'markedbills', taxRate = 25, clean = { min = 500, max = 1000 }, addXP = 1000, negotiateChance = 60, multiplier = 25, rejectChance = 20 },
    [2] = { dirtyMoney = 'markedbills', taxRate = 20, clean = { min = 750, max = 1500 }, addXP = 500, negotiateChance = 70, multiplier = 50, rejectChance = 15 },
    [3] = { dirtyMoney = 'markedbills', taxRate = 15, clean = { min = 1000, max = 2000 }, addXP = 250, negotiateChance = 80, multiplier = 75, rejectChance = 10 },
    [4] = { dirtyMoney = 'markedbills', taxRate = 10, clean = { min = 1500, max = 3000 }, addXP = 125, negotiateChance = 90, multiplier = 100, rejectChance = 5 },
    [5] = { dirtyMoney = 'markedbills', taxRate = 5, clean = { min = 2000, max = 10000 }, addXP = 1, negotiateChance = 95, multiplier = 125, rejectChance = 0 },
}

Config.LevelUp = 100000
Config.AllowNegotiations = true

The file spreads each level over several lines with notes; the values are these.

FieldWhat it does
dirtyMoneyThe dirty money buyers take at this level: an item such as markedbills, or on ESX the black_money account.
taxRateThe percent kept from every deal and wash.
clean.min, clean.maxThe range a buyer's offer is drawn from, in dirty money.
addXPXP for each contract and each warehouse wash.
negotiateChancePercent chance a buyer agrees to a higher offer.
multiplierPercent a successful negotiation adds to the offer.
rejectChancePercent chance a buyer turns the player down. Needs Config.Reject.enable.

Levels are numbered from 1 with no gaps; add or remove them freely. The last one is the top: it earns no more XP. A level's clean, negotiateChance, multiplier and rejectChance matter only while it can run contracts, so not at unlockAt and above unless allowContracts is on.

OptionDefaultWhat it does
Config.LevelUp100000XP from one level to the next. The leftover carries over. To speed up or slow down a level, change its addXP.
Config.AllowNegotiationstrueShows the Negotiate menu when a player carries more than the offer.

Blips

config.lua
Config.Blips = {
    start = { enabled = true, sprite = 47, color = 0, scale = 0.8, label = 'Money Laundering' },
    contracts = { sprite = 500, color = 2, scale = 0.8, label = 'Money Contract' },
    warehouse = { sprite = 473, color = 17, scale = 0.8, label = 'Warehouse' }
}
OptionDefaultWhat it does
start.enabledtrueMarks each launderer.
contractssprite 500, color 2The buyer's blip, shown for every contract.
warehousesprite 473, color 17The door's blip; turn it off with Config.Warehouse.showBlip.
sprite, color, scale, labelThe blip's icon, color, size and name.

Animations

config.lua
Config.Animations = {
    accept = {
        label = 'Making deal..',
        duration = 5000,
        position = 'bottom',
        useWhileDead = false,
        canCancel = true,
        disable = { move = true, car = true, combat = true },
        anim = { dict = 'missfam4', clip = 'base' },
        prop = { model = `p_amb_clipboard_01`, bone = 36029, pos = vec3(0.160, 0.080, 0.100), rot = vec3(-130.00, -50.00, 0.00) }
    },
    negotiate = {
        label = 'Negotiating..',
        duration = 6000,
        position = 'bottom',
        useWhileDead = false,
        canCancel = true,
        disable = { move = true, car = true, combat = true },
        anim = { dict = 'misscarsteal4@actor', clip = 'actor_berating_loop' },
        prop = { }
    },
    wash = {
        duration = 1500,
        anim = { dict = 'missfbi_s4mop', clip = 'put_down_bucket' }
    },
    count = {
        anim = { dict = 'anim@amb@business@cfm@cfm_counting_notes@', clip = 'note_counting_counter' },
        props = {
            chair = 'v_corp_cd_chair',
            briefcase = 'prop_cash_case_02',
            cash = 'bkr_prop_money_sorted_01',
            cashWrapped = 'bkr_prop_money_wrapped_01'
        }
    }
}
OptionWhat it does
acceptThe progress bar for making a deal: label, duration in milliseconds, position (ox_lib only), useWhileDead, canCancel, the controls it disables, the anim and the prop in hand.
negotiateThe progress bar for negotiating, in the same shape.
washThe animation at the washing machine and how long it plays.
countThe counting animation and its props: the chair and briefcase placed at the counter, and the loose and wrapped cash in hand.

Buyer locations and models

OptionDefaultWhat it does
Config.Locations77 locationsWhere buyers wait, as vec4, across Los Santos. Each contract picks one at random. The deal is refused more than 15 m from it.
Config.Models84 ped modelsThe buyers' ped models, picked at random for each contract.

Logs

Discord webhooks, in logs.lua. The file is loaded on the server only, so players never receive your webhook URLs.

logs.lua
Logs.Name = 'Laundering Logs'
Logs.Image = 'https://i.imgur.com/ILTkWBh.png'
Logs.Footer = 'https://i.imgur.com/ILTkWBh.png'

Logs.Types = {
    levelUp = { enabled = false, webhook = '' },
    contracts = { enabled = false, webhook = '' },
    warehouse = { enabled = false, webhook = '' },
    counting = { enabled = false, webhook = '' },
    negotiate = { enabled = false, webhook = '' },
    rejected = { enabled = false, webhook = '' },
    warehouseKey = { enabled = false, webhook = '' }
}
OptionWhat it does
Logs.Name, Logs.Image, Logs.FooterThe webhook's name, its avatar, and the icon by the footer's date.
levelUpA player reaching a new level.
contractsA finished contract: dirty money in and clean cash out.
warehouseA wash picked up: dirty money in and uncounted money out.
countingMoney counted into cash.
negotiateA negotiation, from and to, and whether the buyer agreed.
rejectedA buyer turning a player down.
warehouseKeyA warehouse key bought, and its price.

Each log names the player, their server id and their identifier. Set enabled = true and paste the webhook URL to turn one on. The levelUp log currently posts whenever it has a webhook, enabled or not.

Text

Every line players read is in strings.lua, in English, grouped by where it shows. Edit it to reword or translate.

TableHolds
Strings.NotifyNotifications, including the time left on a wash
Strings.TargetsTarget option names, labels, icons and distances
Strings.TextUIText prompt labels and icons
Strings.AlertThe buyers' refusals and the key purchase confirm
Strings.InputsThe washing and counting amount dialogs
Strings.MenuThe main, negotiate and final offer menus, and the experience bar's colors
Strings.PhoneThe message sent when a wash is done
Strings.LogsDiscord log titles, colors and lines

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

Last updated November 11, 2026

Contracts and the warehouse

How players open the money laundering menu, take contracts to buyers around the city, negotiate, level up, and wash and count money at the warehouse, with the default numbers.

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.

On this page

Debug and update checkInterfacesText promptsPhoneStartPoliceItemsQBCore dirty moneyContract carRejectionsWarehouseWasher and countersLimitsLevelsBlipsAnimationsBuyer locations and modelsLogsText
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