Documentation

Pepper Dealership

Dealerships for every vehicle type – 3D showroom, test drives, financing, trade-ins, used cars and dealerships run as NPC, job or player business with stock, commission and levels 1–50 for ESX, QBCore and Qbox.

Overview

Pepper Dealership brings dealerships for every vehicle type to your server – cars, motorcycles, commercial vehicles, boats and aircraft. Each dealership is set up individually as an NPC dealership (sells around the clock), a job dealership (staff via the framework job) or a purchasable player dealership with its own owner.

Customers get a 3D showroom: the vehicle stands on the preview spot, the camera orbits it, in-game stats, comparison, paint, custom plates, test drive, financing with real-time payments and trade-in of the old vehicle. Pay cash or by bank, then pick the vehicle up at the pickup spot or find it in the framework garage. A used car lot lets players sell vehicles to each other – the money arrives even if the seller is offline.

Player dealerships keep stock and buy from the manufacturer (delivery or transfer it yourself), set their own prices, hire staff with ranks, wages and commission, make customers offers and grow through levels 1–50 with upgrades, a deal of the week, coupons and a loyalty discount. A catalog tablet (also as an lb-phone app) shows every player all dealerships, deals and a leaderboard.

🧪 Tested on our dev server: Of course we test all scripts continuously on our own dev server “Pepper Scripts”.

Features

  • 6 dealer types (cars, motorcycles, commercial, boats, aviation, mixed), unlimited dealerships, each NPC, job or purchasable
  • Admin menu /dealeradmin with placement mode (aim ray, transparent preview vehicle for parking spots, own position with G), 6 templates, assortment per dealership, set owner
  • Vehicle catalog with 454 vanilla vehicles in 19 categories, image URL, “from level”, import from the framework (qbx_core, QBCore, ESX) with preview
  • 3D showroom: preview vehicle, camera with orbit + views (front, side, rear, top, interior), doors, lights, in-game stats, compare up to 3 vehicles
  • Paint (31 colors, primary + secondary, surcharge per paint type) and custom plates with blocked words and reservation
  • Purchase by cash or bank, handover at the pickup spot (keys, full tank, waypoint) or into the garage, optional contract item (ox_inventory)
  • Test drive with time limit, distance and exit limit, /teststop, return to the salesperson, optional fee and own instance
  • Display vehicles inside the dealership with “View”
  • Financing: 3 plans (6/12/24 payments), 20–90 % down payment, real-time payments from the bank account, late fees, repossession after 3 missed payments, pay off anytime, no penalty while offline
  • Trade-in of the old vehicle (condition + age set the value) and buy-in at the salesperson
  • Used car lot player → player with price, description, duration and payout even to offline sellers
  • “My financing & listings” (/myfinance)
  • Player dealership: 5 ranks with permissions, time clock, wages from the business account, commission, invite/promote/fire
  • Business account with ledger, optionally mirrored into the framework society account
  • Office tablet: stock, own prices (90–130 %), buying via delivery or transfer from the factory, used cars, display, team, account, promotions, settings
  • Offers to customers with a price down to the rank limit and one counter-offer; self-service when nobody is on duty (can be turned off), “call a salesperson”
  • Used stock from trade-ins, buy-ins and repossessions; dealer financing paid into the business account
  • Buy a dealership, hand it over to a player, sell it back to the state; reverts after inactivity
  • Levels 1–50 with 10 titles: vehicle classes and features by level, upgrades (stock, display, staff, buying discount, delivery time)
  • Deal of the week, coupons (percent/amount, uses, expiry) and loyalty discount – capped, never below the buying price
  • Catalog tablet (/dealer, key, optional item) and lb-phone app: all dealerships, assortment, waypoint, test drive appointment/purchase request, leaderboard, own purchases
  • Admin overview: revenue, staff on duty, open payments, forgive/repossess financing, remove listings, correct accounts, plate search
  • Garage script selectable in the config (esx_garage, qb-garages, qbx_garages, jg-advancedgarages, cd_garage, qs-advancedgarages, okokGarage, loaf_garage, framework only or own functions) with garage names per vehicle type, 11 key systems, 7 fuel scripts (ox_fuel, LegacyFuel, cdn-fuel, ps-fuel, qb-fuel, lj-fuel, lc_fuel)
  • Showroom stage with turntable, engine start, light moods, rarity of the day and visitor NPCs
  • Big handover on its own stage: reveal, tour, key handover, photo moment, skippable
  • Price negotiation with a hidden limit, patience and four arguments; one counter-offer on salesperson offers
  • Limited series with serial numbers, special equipment, plate patterns, drops with countdown, reminders and presale
  • Vehicle pass for every car, collector rank with 5 tiers and a tablet collection
  • Live auctions: auction house, weekly schedule, bidding in the hall or by tablet, anti-sniping, player consignments
  • NPC customers for player dealerships with wishes from real stock, passenger on test drives, negotiation, ratings and reputation, with hourly limits for the server economy
  • Dealership events: car launch, open day, sale week, extras and a no-show rule
  • “Today” office page with reputation, revenue, live feed, shortages and a tip
  • 3 Discord webhooks, 15 server exports, German & English, config, locales, bridges and install files open
  • No idle loops (built for 0.00 ms idle)

Requirements

Requirement Version
FiveM server build ≥ 7290
OneSync required
Framework ESX, QBCore or Qbox
Database MySQL 8 or MariaDB ≥ 10.6

Dependencies

  • ox_lib
  • oxmysql
  • optional ox_target or qb-target – otherwise a “[E] …” prompt
  • a garage script (choose it in the config) – optionally a key and a fuel script (detected automatically)
  • optional ox_inventory – contract and tablet item
  • optional lb-phone – own app “Pepper Dealership”

Installation

  1. Copy the folder to resources/[pepper]/pepper_dealership – do not rename it.
  2. Add to your server.cfg after the framework, oxmysql and ox_lib:
ensure pepper_dealership
  1. Admin permission: add_ace group.admin pepper_dealership.admin allow (or a group from Config.AdminGroups).
  2. The resource creates its tables on start. You only need install/pepper_dealership.sql if your database user may not create tables.
  3. Adjust config/config.lua (language, garage, purchase, financing …), webhooks in config/server.lua.
  4. Start the server, open /dealeradmin in game, take a template (e.g. Premium Deluxe Motorsport) or create your own dealership and set the points in placement mode.
  5. Choose your garage: in config/config.lua set Config.Garage.System to your garage script and put the names of your garages (car, boat, aircraft) from your garage script's config into Config.Garage.Garages. On start the server console shows system, table and garages (“Garage: …”) and warns if the script is not running or its columns are missing.
Config.Garage.System Garage script
esx_garage ESX Legacy garage
qb-garages QBCore garages
qbx_garages Qbox garages
jg-advancedgarages JG Advanced Garages
cd_garage Codesign Garage
qs-advancedgarages Quasar Advanced Garages
okokGarage okokGarage
loaf_garage Loaf Garage
framework no garage script (framework table only)
custom own functions Config.Garage.Add/Remove/Transfer/OwnerOf
auto detects the running script itself

Optional:

  • Tablet item: Config.Tablet.Item = 'dealer_tablet' and an ox_inventory item with server = { export = 'pepper_dealership.dealer_tablet' }.
  • lb-phone: if lb-phone runs, the app appears automatically (Config.Tablet.LbPhone).

Configuration

File Content
config/config.lua The essentials: language, framework, commands, garage, keys, showroom, purchase, plates, test drive, licence, police, financing, trade-in, used cars, auctions
config/advanced.lua Fine-tuning: dealer types, categories, blips, keys, camera, distances, timings, models, events. Values from config.lua take priority
config/ranks.lua Ranks with permissions, wage, commission, discount; player dealership (price range, stock, offers), wholesale, ownership
config/progression.lua Level curve, XP, unlocks, upgrades, discount cap, promotions, loyalty, requests, tablet
config/dealers.lua Templates (check coordinates in game)
config/vehicles.lua Catalog for the first fill (maintained in game afterwards)
config/colors.lua Paint colors
config/server.lua Webhooks, admin ACE, allowed image hosts (never sent to clients)

Dealerships, catalog, assortments, stock, prices and promotions live in the database and are maintained in game.

Permissions

Who Permission
Admin ACE pepper_dealership.admin or Config.AdminGroups – admin menu, all dealerships, promotions for NPC dealerships too
Staff (job/purchasable) Ranks from config/ranks.lua: sell, display, used, stock, prices, staff, account, promo, upgrades, settings
Job dealership Rank from the job grade (mapping per dealership in the admin menu)

Creating a dealership

  1. /dealeradmin → take a template or New dealership: name, dealer type, operating mode (NPC/job/purchasable), job or price.
  2. Tab Points → Set points one by one: salesperson, preview spot, pickup spots, test drive start; optionally trade-in zone, display and used car spots; for job/purchasable also office, time clock and delivery point. In placement mode: aim, E set, G own position or own vehicle, mouse wheel rotate, Page up/down height, X skip, Z back, ESC finish.
  3. Tab Assortment: choose categories, hide single models.
  4. Save – blip, salesperson and display vehicles appear for everyone right away.

Buying, test drive, financing

At the salesperson open the showroom: pick a vehicle, paint and plate, handover and payment. Test drive starts right away; /teststop ends it. With Finance you choose plan and down payment – payments are taken from the bank account automatically, the overview is at /myfinance. For a trade-in park the old vehicle in the trade-in zone and select it in the showroom.

Licence, deposit and police

Driving licence: Test drives and purchases need the matching licence. Set your licence script in Config.License.System:

Setting For
'esx_license' ESX with esx_license – also esx_dmvschool, okokDrivingSchool (ESX) and most ESX driving schools
'qb' QBCore/Qbox licences (metadata.licences) – qb-drivingschool, qb-cityhall, okokDrivingSchool (QB)
'bcs_licensemanager' BCS License Manager
'item' Licence as an inventory item – bl_idcard, um-idcard, qbx_idcard, ox_inventory cards
'custom' your own check via Config.License.Check
'auto' detects BCS → esx_license (ESX) → QBCore/Qbox
false no check

Config.License.Classes sets which class a vehicle needs (car, motorcycle, truck, boat, air), Config.License.Names how the licence is called in your script. Boats and aircraft are unchecked by default. TestDrive/Purchase turn the check off separately, OnError decides what happens when the lookup fails.

Deposit: A test drive takes a deposit (Config.TestDrive.Deposit, share of the vehicle price with minimum and maximum). It is returned when the vehicle comes back, minus any damage.

Theft: Driving further than MaxDistance triggers a warning. Without turning back within Theft.WarnSeconds the vehicle counts as stolen: the dealership keeps the deposit (player dealership: into the account), the police get an alert with the position (renewed every AlertEverySeconds), and after TrackMinutes the dealership recovers the vehicle. No test drive for Theft.CooldownMinutes afterwards. Alerts go through Config.Police.Dispatch (Pepper Emergency pepper_dispatch, ps-dispatch, cd_dispatch, qs-dispatch, rcore_dispatch, core_dispatch) or, without a dispatch script, built in as a notification with blip to every player with a job from Config.Police.Jobs. With Theft.Enabled = false the drive simply ends at the limit as before.

Selling a vehicle to a player

With /sellcar a player sells their own vehicle directly to another player. Both stand at the vehicle, the seller picks vehicle, buyer (player ID) and price, the buyer sees condition, price and registration fee and accepts or declines. Afterwards the vehicle is in the buyer's garage, the keys change and the vehicle passport counts one more previous owner. Financed, listed, rented and occupied vehicles cannot be sold. Settings in Config.Handover (distance, price limits, fee, payment methods, offer time).

Player dealership

  • Buy at the salesperson of a purchasable dealership (one per character). The owner finds the office inside.
  • Time clock: only staff who are clocked in sell and earn wages and commission.
  • Stock: new cars only come from stock. Buy at 70 % (delivery) or cheaper via transfer from the factory – waypoint, hand it in at the delivery point with E, damage is repaired from the account.
  • Offer to customers: in the showroom “Make an offer” → choose a nearby customer, set the discount, send. The customer sees it with payment, financing, trade-in and coupon and accepts.
  • Self-service: when nobody is on duty, customers buy themselves (can be turned off in the office, as can financing and trade-in in self-service).

Levels, upgrades and promotions

Player dealerships earn XP for sales, transfers, purchases after a test drive and paid-off dealer financing. Levels 1–50 (about 80–100 hours of business) unlock vehicle classes (e.g. sports from 15, super from 30) and features: coupons from 5, deal of the week from 8, dealer financing from 10, long terms from 20, “featured” in the catalog from 25. With money from the business account the owner upgrades stock, display, staff, buying discount and delivery time. All discounts together are capped at 25 % (Config.Pricing) and a player dealership never sells below the buying price. NPC dealerships have no level limits.

Showroom stage and handover

The optional Handover stage point in the admin menu enables the big handover. Without it pickup works as usual. Timing, keys and cover are in Config.Reveal, the stage in Config.Showroom.

Negotiation

In NPC dealerships and self-service, players can negotiate for up to 3 rounds. Owners can turn this off in the office. Staff cannot negotiate at their own dealership. Values are in Config.Negotiation. A negotiated price is valid for 5 minutes and one purchase; the discount cap and purchase cost remain limits.

Limited series

Admins create series in the admin menu under Series. The price is fixed. Player dealerships only sell series that list them; the price minus the series cost goes to the account and stock stays untouched. Equipment values are GTA numbers. Config.Series and Config.Collectors control presale, limits, points and ranks.

Auctions

Under Auction house admins set the lot spot and auctioneer at their position, plan dates and add lots. Config.Auction.Schedule creates weekly dates; a date without lots is dropped. Money is only taken when the lot is sold, plus the buyer premium. If the top bidder is offline or cannot pay, the next bid wins and they are blocked for that auction. With Remote = false bidding only works in the hall.

NPC customers and reputation

Customers only come to player dealerships with a salesperson on duty and the Customer area point set. Serve them in the office under Customers. A sale creates real money, so MaxRevenuePerHour and MaxPerPlayerHour in config/customers.lua apply. Customer types, names and the reputation window are there too.

Events

Staff with the promotions right plan events in the office, between 15 minutes and 3 days ahead. If nobody is on duty at the start, the event fails: cost lost, reputation −0.5. Types and extras are in Config.Events.

Catalog tablet and phone

/dealer (bindable key) shows every player all dealerships with status (open, staff on duty, self-service, closed), assortment, stock, deal of the week, waypoint, test drive appointment and purchase request, the leaderboard and own purchases. Staff also see their dealership’s requests. With lb-phone the same view is an app.

Commands

Command Who Purpose
/dealeradmin Admin Admin menu
/dealer everyone Catalog tablet
/myfinance everyone My financing & listings
/teststop everyone End test drive or transfer
/sellcar everyone Sell your own vehicle to a player next to you

All commands can be renamed or disabled in the config.

Webhooks

In config/server.lua:

Webhook Content
admin Dealerships created/changed/deleted, owner, catalog, actions from the admin overview
business Purchases, ownership changes, player-to-player sales, stolen test drives, repossessions, used cars, level-ups
security Suspicious activity

Exports

Server

exports.pepper_dealership:getDealers()                 -- all dealerships (public view)
exports.pepper_dealership:getDealer(id)
exports.pepper_dealership:getVehicle(model)            -- catalog entry
exports.pepper_dealership:getVehiclePrice(model)
exports.pepper_dealership:getCatalog()
exports.pepper_dealership:isFinanced(plate)            -- for garage/trade scripts: do not sell/transfer
exports.pepper_dealership:getFinance(plate)
exports.pepper_dealership:isListed(plate)              -- listed on the used car lot
exports.pepper_dealership:getRank(src, dealerId)       -- rank in a player dealership or nil
exports.pepper_dealership:getDuty(src)                 -- dealership ID on duty or nil
exports.pepper_dealership:getBalance(dealerId)
exports.pepper_dealership:addBalance(dealerId, amount, note)
exports.pepper_dealership:getStock(dealerId, model)
exports.pepper_dealership:getLevel(dealerId)
exports.pepper_dealership:addXp(dealerId, amount)

Server events – for police computers, insurance, logs. Server side only, receive them with AddEventHandler (not RegisterNetEvent):

AddEventHandler('pepper_dealership:vehiclePurchased', function(e) end)    -- source, identifier, dealerId, model, plate, price, financed, delivery, used
AddEventHandler('pepper_dealership:ownerChanged', function(e) end)        -- plate, model, from, to, source, price, via ('handover' | 'listing' | 'auction')
AddEventHandler('pepper_dealership:vehicleSoldToDealer', function(e) end) -- source, identifier, dealerId, model, plate, price
AddEventHandler('pepper_dealership:vehicleRepossessed', function(e) end)  -- plate, model, identifier, dealerId
AddEventHandler('pepper_dealership:testDriveStolen', function(e) end)     -- source, identifier, dealerId, model, plate, coords

Framework integration

The bridges in bridge/ (open) detect ESX, QBCore and Qbox automatically (Config.Framework = 'auto'). Money runs through the framework, bought vehicles through the garage bridge (bridge/server/garage.lua, own functions with Config.Garage.System = 'custom'), keys through bridge/*/keys.lua, fuel through bridge/client/fuel.lua.

Troubleshooting

Problem Solution
Bought vehicle missing in the garage Config.Garage.System = your garage script? Garage names in Config.Garage.Garages correct? The console on start (“Garage: …”) shows both
No keys after buying Key script running? Otherwise Config.Keys.Mode = 'custom' with your own functions
Preview vehicle missing in the showroom Set the preview spot again in the admin menu; check the model in the catalog (“Check model”)
Customer cannot buy at a player dealership A salesperson is on duty (buy via offer) or self-service is off
Vehicle class missing at a player dealership Level too low – see office → Level or config/progression.lua
App missing in lb-phone Config.Tablet.LbPhone = true? The app registers again after an lb-phone restart; F8 with Config.Debug = true shows the reason

Changelog

See CHANGELOG.md in the download.

Support

Discord → ticket (category “Script Support”), link your purchase with /verify first.


Found a mistake? Report it on Discord.