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
/dealeradminwith 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
- Copy the folder to
resources/[pepper]/pepper_dealership– do not rename it. - Add to your
server.cfgafter the framework, oxmysql and ox_lib:
ensure pepper_dealership
- Admin permission:
add_ace group.admin pepper_dealership.admin allow(or a group fromConfig.AdminGroups). - The resource creates its tables on start. You only need
install/pepper_dealership.sqlif your database user may not create tables. - Adjust
config/config.lua(language, garage, purchase, financing …), webhooks inconfig/server.lua. - Start the server, open
/dealeradminin game, take a template (e.g. Premium Deluxe Motorsport) or create your own dealership and set the points in placement mode. - Choose your garage: in
config/config.luasetConfig.Garage.Systemto your garage script and put the names of your garages (car, boat, aircraft) from your garage script's config intoConfig.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 withserver = { 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
/dealeradmin→ take a template or New dealership: name, dealer type, operating mode (NPC/job/purchasable), job or price.- 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.
- Tab Assortment: choose categories, hide single models.
- 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.