Skip to content

Exports

External resources can drive the car dealer programmatically via FiveM exports and hook events. All exports are defined in server/exports.lua.

Mutating exports (forceSale, addVehicle) are gated by Config.Integrations.forceSaleAllowList. An empty table allows all resources (open-by-default). Listing specific resource names restricts those exports to only the listed callers (identified via GetInvokingResource). Read-only exports (getCatalog, getShop, getLoans) are always allowed — they leak no money or inventory.

Read-only snapshot of every vehicle the dealer network can sell. Does not require allow-listing.

--- @return table catalog
local catalog = exports['ars_cardealer']:getCatalog()

Returns an array of tables, sorted alphabetically by label:

Field Type Description
model string Vehicle spawn name (unique key)
label string Display name
category string Vehicle category
price number Retail price
stock number Stock count (-1 = unlimited)

Example:

local catalog = exports['ars_cardealer']:getCatalog()
for _, v in ipairs(catalog) do
print(v.model, v.label, v.price)
end

Read-only shop summary. Returns nil if the shop id does not exist. Does not require allow-listing.

--- @param shopId string
--- @return table|nil shop
local shop = exports['ars_cardealer']:getShop('pdm')
Field Type Description
id string Shop identifier
label string Display label
active boolean Whether the shop is active
ownable boolean Whether the shop can be player-owned
productCount number Number of vehicles stocked at this shop
balance number? Shop balance (only if owned)
open boolean? Shop open state (only if owned)

Example:

local shop = exports['ars_cardealer']:getShop('pdm')
if shop then
print(shop.label, shop.balance, shop.open)
end

Sell a vehicle to a player bypassing the in-game UI. Useful for VIP shops, event rewards, quest rewards, or external store menus. Requires allow-listing unless forceSaleAllowList is empty.

--- @param src number Player server ID
--- @param dealerId string Shop identifier
--- @param model string Vehicle spawn name
--- @param opts table Options (all optional)
--- @return table result { ok = true } | { ok = false, reason = '...' }
local res = exports['ars_cardealer']:forceSale(playerSrc, 'pdm', 'sultan', {
paymentType = 'bank',
colorPrimary = { mode = 'palette', index = 0 },
})

Options (opts):

Key Type Description
paymentType string? Payment method (cash, bank, or a custom currency id). Defaults to cash.
colorPrimary table? Primary colour payload.
colorSecondary table? Secondary colour payload.
repSrc number? Salesperson source for commission attribution.
livery number? Livery index applied to the delivered vehicle.
chameleon boolean? Apply chameleon paint.

Failure reasons: not_allowed, invalid_source, not_sold, bad_payment_type, out_of_stock, no_price, and other processSale rejection reasons.

Example:

RegisterCommand('givevip', function(source, args)
local target = tonumber(args[1])
local res = exports['ars_cardealer']:forceSale(target, 'pdm', 'adder', {
paymentType = 'bank',
colorPrimary = { mode = 'palette', index = 111 },
})
if not res.ok then
print('Sale failed:', res.reason)
end
end)

Add or update a vehicle in the master catalog. Lets external resources register models without the admin UI. Requires allow-listing unless forceSaleAllowList is empty.

--- @param model string Vehicle spawn name
--- @param opts table Options (all optional)
--- @return table result { ok = true } | { ok = false, reason = '...' }
local res = exports['ars_cardealer']:addVehicle('sultan', {
label = 'Karin Sultan', category = 'cars', price = 25000, stock = -1,
})

Options (opts):

Key Type Description
label string? Display name
category string? Vehicle category
price number? Retail price
stock number? Stock count (-1 = unlimited)
image string? Image URL
stats table? { speed, accel, handling, braking }

Failure reasons: not_allowed, no_model, exists (model already in the catalog — reported by the create path), not_found (reported by the update path).

Example:

exports['ars_cardealer']:addVehicle('blista', {
label = 'Dinka Blista', category = 'compacts', price = 12000,
})

Query a player’s active loans so external finance UIs can show the same data as the in-game Financing view. Does not require allow-listing.

--- @param src number Player server ID
--- @return table[] loans
local loans = exports['ars_cardealer']:getLoans(playerSrc)

Returns an array of loan rows from ars_cardealer_financing where status = 'active', ordered by financetime ascending.

Example:

local loans = exports['ars_cardealer']:getLoans(targetSrc)
for _, loan in ipairs(loans) do
print(loan.model, loan.plate, loan.payment_amount, loan.payments_remaining)
end

The hook API is toggled by Config.Integrations.Hooks.enabled (default true). External resources register for these events via RegisterNetEvent.

Cancellable. Fires after all validation passes but before money is taken. A listener calls ctx.cancel('reason') to block the sale.

AddEventHandler('ars_cardealer:prePurchase', function(ctx)
if ctx.paymentType == 'cash' and ctx.price > 500000 then
ctx.cancel('luxury_cash_blocked')
end
end)

Context payload:

Field Type Description
dealerId string Shop identifier
customerSrc number Buying player server ID
customerCitizenid string Buying player citizenid
customerName string Buying player name
repSrc number? Salesperson server ID (assisted sale)
repCitizenid string? Salesperson citizenid
model string Vehicle spawn name
plate string Vehicle plate
price number Base price (pre-currency-conversion)
charge number Actual amount deducted (post-conversion)
paymentType string Payment method
financed boolean Whether the purchase is financed
couponCode string? Applied coupon code
cancel(reason) function Call to block the sale with a reason string

Notification only. Fires after the sale fully completes (vehicle delivered, money taken, commission paid). Errors in listeners are caught so they cannot roll back a completed sale.

AddEventHandler('ars_cardealer:postSale', function(ctx)
-- Same payload as prePurchase, minus the cancel function
print(('Sale: %s bought %s for $%s'):format(
ctx.customerName, ctx.model, ctx.charge))
end)

Note: This guide is written by a third party. If you find any incorrect or outdated information, please contact us on Discord so we can update it for you.