ATY Scripts Logo
ATY Scripts/Dokümanlar/Dealership V2/Introduction

Introduction

🚗 aty_dealershipv2

A fully-featured, player-owned vehicle dealership system for FiveM (ESX / QBCore)
Version 2.0.1 · Author atiysu · Framework-agnostic via aty_lib


📖 Overview

aty_dealershipv2 is an advanced, fully database-driven vehicle dealership resource for FiveM servers. It supports unlimited, fully customisable dealerships that can be either:

  • Self-Served – Managed by server admins only; players can browse and buy freely.
  • Player-Owned – Players can purchase, own, and manage entire dealerships as a business. Owners stock vehicles, set prices, run discounts, issue coupons, deliver ordered stock, and collect revenue to their dealership's balance.

The UI is built with Vue 3 + Vite and communicates over NUI callbacks. All dealership data is persisted in a MariaDB/MySQL database.


✨ Features

Category Feature
Dealerships Unlimited dealerships, each with its own location set
Shop Types self-served (admin-only management) and owned (player-managed)
Purchasing Cash, Bank Card, or Installment (Finance) payments
Finance Configurable interest rate, late fees, maximum months, first-payment requirement
Installments Player installment dashboard, pay monthly or in full, overdue tracking
Coupons Owner/admin creates coupon codes with % discount, expiry time, and usage limit
Discounts Time-limited, usage-capped per-vehicle discounts
Ordering Realistic order delivery mission – spawn truck, hitch trailer, deliver to dealership
Showcase Owners place real vehicles at custom world positions as showroom displays
Test Drive Isolated routing bucket per test drive, timer countdown
Admin Panel Full in-game CRUD for dealerships and the global vehicle catalog
Targets Optional target interaction (works with aty_lib target module)
Exports Rich Lua exports for integration with other resources
Dual-Framework Supports both ESX and QBCore via aty_lib
Customisable UI All colours fully configurable from config.lua without touching source code
Job Restriction Restrict any dealership to a specific job or leave it open to all

📦 Dependencies

Dependency Notes
aty_lib Required – provides framework abstraction, callbacks, SQL helpers, and shared utilities
oxmysql or compatible Required by aty_lib for database queries
ESX or QBCore One framework must be present and started before aty_lib

Note: aty_lib must be started before aty_dealershipv2 in your server.cfg.


🛠️ Installation

Database Setup

Fresh install – run data.sql:

-- Creates the main dealership table and the vehicle_installments table
SOURCE aty_dealershipv2/data.sql

Updating from an older version – run update.sql instead:

-- Creates vehicle_installments if missing and adds the `coupons` column
SOURCE aty_dealershipv2/update.sql

The two tables created are:

Table Purpose
aty_dealership Stores every dealership: locations, vehicles, orders, sales, listings, coupons, balance
vehicle_installments Tracks active finance/installment debt per player

Resource Setup

  1. Copy the aty_dealershipv2 folder into your resources directory (e.g. resources/[aty]/).
  2. Add the following lines to your server.cfg after aty_lib:
ensure aty_lib
ensure aty_dealershipv2
  1. Import the SQL file(s) described above into your database.
  2. Restart your server or use refresh + start aty_dealershipv2.

⚙️ Configuration Reference

All configuration lives in shared/config.lua. Changes here apply to both client and server automatically.


General Settings

Config = {
    Target          = false,       -- true = use ox_target/qtarget zones, false = proximity markers
    RealisticOrder  = true,        -- true = order delivery requires driving the truck
    OrderCooldown   = 1,           -- minutes between orders (per dealership)
    DefaultStock    = 1,           -- fallback stock when not specified
    MaxListings     = 5,           -- max showcase vehicle listings per dealership
    TestTime        = 60,          -- test-drive time limit in seconds
Key Type Description
Target boolean Enable ox_target-style zone interactions instead of proximity DrawText3D
RealisticOrder boolean Requires the owner to drive a delivery truck to restock vehicles
OrderCooldown number Minutes before another order can be placed on the same shop
DefaultStock number Stock assigned to a vehicle if none is specified
MaxListings number Maximum number of showcase listings per dealership
TestTime number Seconds a player gets for a test drive

Order Pickup Locations – the array of vector4 coordinates where delivery trucks spawn:

OrderPickupLocation = {
    vector4(1204.3624, -3099.4116, 5.8572, 0.0),
    -- add more pickup points as needed
},
OrderTruckModel   = "phantom",   -- GTA model name for the delivery truck
OrderTrailerModel = "tr4",       -- GTA model name for the trailer

Finance Settings

PaymentInterval           = 24,    -- hours between installment payments (24 = daily)
MaxInstallmentMonths      = 24,    -- maximum months a player can spread payments over
MaxActiveInstallments     = 3,     -- max concurrent installment contracts per player

FinanceInterest           = 0.05,  -- 5% interest added to the total financed price
FinanceLateFee            = 0.02,  -- 2% compounding fee per overdue interval
FinanceCheckFullPrice     = true,  -- player must have full vehicle price in bank to finance
FinanceFirstPaymentRequired = true, -- first monthly payment is deducted immediately on purchase
Key Description
PaymentInterval Use 12 = every 12 h, 24 = daily, 168 = weekly, 720 = monthly
FinanceInterest Multiplied onto selling price → total financed amount
FinanceLateFee Applied per each missed interval, compounding on the remaining balance
FinanceCheckFullPrice Safety check – prevents players from taking finance they cannot theoretically repay
FinanceFirstPaymentRequired Deducts the first monthly instalment at the moment of purchase

UI Theme

Every colour used in the NUI can be overridden without touching Vue source code:

UI = {
    PrimaryColor          = "#69ffec",  -- Main accent / highlight colour
    PrimaryColorDark      = "#3f998e",  -- Darker shade of accent
    BackgroundPrimary     = "#0c0e12",  -- Main panel background
    BackgroundSecondary   = "#2c2f3a",  -- Card / secondary panel colour
    TextPrimary           = "#ffffff",
    TextSecondary         = "#999999",
    ButtonPrimaryStart    = "#69ffec",  -- Gradient start for primary buttons
    ButtonPrimaryEnd      = "#3f998e",  -- Gradient end for primary buttons
    StatusSuccess         = "#1f8a43",
    StatusWarning         = "#d78024",
    StatusError           = "#eb3333",
    StatusDanger          = "#d03737",
},

Interaction Zones

Controls the radius and visibility distance for each interaction point:

Interactions = {
    ZoneRadius       = 4.0,   -- radius of the main shop / ped zone
    ZoneDistance     = 4.0,   -- draw distance for the zone prompt
    ManageRadius     = 2.0,   -- boss management dashboard zone
    ManageDistance   = 2.0,
    PurchaseRadius   = 2.0,   -- "purchase this dealership" zone
    PurchaseDistance = 2.0,
    ShowcaseRadius   = 2.0,   -- around showcase-listed vehicles
    ShowcaseDistance = 2.0,
},

Vehicle Stats

Controls how vehicle performance data is fetched and displayed:

VehicleStats = {
    AWD_Threshold = 0.3,              -- acceleration value above which drivetrain reads "AWD"
    Normalization = {
        Speed        = { 100, 180 },  -- km/h min/max for bar chart
        Acceleration = { 0.1, 0.4 },
        Handling     = { 20, 45 },
        Braking      = { 0.0, 1.0 },
        Traction     = { 1, 3 },
    }
},

Callbacks & Hooks

OnVehiclePurchase

Called server-side every time a vehicle is successfully purchased:

OnVehiclePurchase = function(source, model, plate, price, method)
    -- source  = player server ID
    -- model   = vehicle model string
    -- plate   = generated license plate
    -- price   = final price after discounts/coupons
    -- method  = "cash" | "bank" | "finance"
    
    -- Example: award XP, log to Discord, grant keys, etc.
    print(string.format("Player %s bought %s (%s) for $%s via %s", source, model, plate, price, method))
end

🏪 Dealership Types

Type Description
self-served No owner. All vehicles are permanently in stock. Admins manage everything through the admin panel. Ideal for government/public dealerships.
owned Can be purchased by a player. The owner manages stock, orders, listings, prices, discounts, coupons, and the dealership's balance.

🛡️ Admin Panel Guide

Opening the Admin Panel

Use the in-game command (default: dealershipadmin):

/dealershipadmin

This command is restricted to the permission levels defined in:

Config.AdminPermissions = { "god", "admin", "superadmin" }

For QBCore, these are QBCore permission levels. For ESX, these map to ESX account ranks.


Creating a Dealership

  1. Run /dealershipadmin to open the admin panel.
  2. Click the Create (➕) button in the top-right.
  3. Fill in the creation form:
Field Description
Name Unique identifier for the dealership (no spaces recommended)
Price Cost for a player to purchase this dealership (set 0 if not for sale)
Blip ID GTA map blip sprite ID (see blip sprites reference)
Job all for everyone, or a job name (e.g. mechanic) to restrict access
Ped Model Model name for the salesperson NPC (default: ig_siemonyetarian)
Type owned or self-served
Locations Click each button and confirm placement in the world
Categories Select which vehicle categories appear in this dealership's stock
  1. Locations – You must set all 8 points:
Location Purpose
Dashboard Where the boss management menu is accessed (marker)
Dealership Position of the map blip
Purchase Zone where players can buy the dealership itself
Ped Where the salesperson NPC spawns
Preview Where vehicles are shown in the shopping camera
Spawn Where the purchased vehicle appears after buying
Test Where the vehicle spawns for a test drive
Order Point Where the delivery truck arrives after an order
  1. Click Create to save. The dealership appears on all connected clients immediately.

Editing a Dealership

  1. Open the admin panel.
  2. Find the dealership in the list and click the Edit (⚙️) icon.
  3. Modify any fields and re-set any locations as needed.
  4. Click Update.

All connected clients receive the updated dealership data in real time.


Deleting a Dealership

  1. Open the admin panel.
  2. Click the Delete icon next to the dealership.
  3. Confirm in the popup.

This permanently removes the dealership and all its data from the database.


Managing the Vehicle Catalog

The global vehicle catalog (shared/catalog.lua) defines every vehicle available to any dealership. Admins can manage it in-game:

  1. Open /dealershipadmin.
  2. Click Edit Vehicles (pencil icon).
  3. Select the vehicle you want to modify from the dropdown.
  4. Edit its Name, Label, Model, Price, and Category.
  5. Alternatively click Delete to remove it from the catalog entirely.

To add a new vehicle to the catalog, use the addVehicleToCatalog server callback or manually add it to shared/catalog.lua.

Changes to the catalog are saved directly to shared/catalog.lua and broadcast to all clients.


👤 Player Guide

Browsing Vehicles

  1. Approach the dealership NPC on the map (look for the blip icon).
  2. Press [E] when the prompt appears to open the shop menu.
  3. Use the search bar to filter by vehicle name.
  4. Use the category tabs at the top to filter by type (Cars, Bikes, Boats, etc.).
  5. Click any vehicle to select it – a live 3D preview will spawn at the preview point.
    • Scroll to rotate the 3D preview model.
    • Pinch / scroll wheel to zoom.
  6. View the vehicle's Technical Specifications panel:
    • Max Speed, Acceleration, Braking, Traction, Seats, Drivetrain

Test Drive

  1. Select a vehicle in the shop menu.
  2. Click Test Drive.
  3. The vehicle spawns at the test drive location. You have Config.TestTime seconds (default 60 s) before it is automatically returned.
  4. Exit the vehicle at any time to end the test drive early.

Test drives are isolated in a routing bucket – other players cannot see or interact with the test drive vehicle.


Purchasing a Vehicle

  1. Select a vehicle in the shop menu.
  2. Choose your primary colour and secondary colour using the colour pickers.
  3. (Optional) Enter a coupon code and click Apply to receive a discount.
  4. Choose your payment method:
Method Requirements
Pay with Card (Bank) Must have sufficient bank balance
Pay with Cash Must have sufficient cash on hand
Pay with Installments (Finance) See finance conditions below
  1. If using Finance:
    • Select the number of months (1 – MaxInstallmentMonths).
    • The UI shows the monthly payment and total amount with interest.
    • If FinanceCheckFullPrice = true, you need the full vehicle price in your bank.
    • If FinanceFirstPaymentRequired = true, the first instalment is deducted immediately.
  2. Confirm the purchase. The vehicle spawns at the dealership spawn point with:
    • Your chosen colours applied.
    • Your vehicle keys granted (via aty_lib key export).
    • A full fuel tank (100%).
    • A unique license plate.

Using Coupons

  1. In the purchase panel, locate the Coupon Code input.
  2. Type the code provided by the dealership owner and click Apply.
  3. If valid, the discount percentage is shown and the total price is reduced.
  4. Coupons can expire or have a usage limit – if either is exceeded, the code is rejected.

Installment Payments

  1. Use the command /installments (default) to open your Installments Dashboard.
  2. All active finance contracts are listed, showing:
    • Vehicle name and plate
    • Total debt / remaining balance
    • Monthly payment amount
    • Next payment due date
    • Overdue status
  3. Click Make Payment to pay one monthly instalment.
  4. Click Pay in Full to clear the entire remaining balance in one go.

Late Fees: If a payment is missed, a FinanceLateFee percentage is compounded onto the remaining balance for each overdue interval.


💼 Dealership Owner (Boss) Guide

Accessing the Boss Menu

  1. Go to your dealership's Dashboard marker (the location you set when creating it).
  2. Press [E] when the prompt appears.
  3. The Boss Menu opens, with tabs for: Dashboard, Stock, Orders, Sales, Vehicle Listing, Coupons.

Dashboard

Displays a real-time overview:

  • Account Balance – money in the dealership's safe.
  • Vehicles in Stock – total units across all models.
  • Listed Vehicles – number of active showcase listings.
  • Total Sales – revenue broken down by Day / Week / Month / Year.

Stock Management & Ordering

Navigate to the Stock tab:

  • All vehicles in your dealership's catalog are listed with their current stock levels.
  • For each vehicle you can:
    • Edit Price – set your own selling price (independent of the catalog base price).
    • Order Vehicle – place a restock order (see below).
    • Set Discount – configure a time-limited sale.
    • Remove Discount – cancel an active discount.

Order Delivery Mission

When RealisticOrder = true (default):

  1. In the Stock tab, click Order Vehicle for the model you want.
  2. Enter the quantity and confirm. The order cost is deducted from your bank immediately.
  3. You receive a notification when the delivery truck has arrived.
  4. Travel to the truck blip on your map. Get into the Phantom truck.
  5. A new blip directs you to the docks to pick up the trailer – drive there and attach the trailer.
  6. A final blip shows your dealership's order point. Drive the truck+trailer there.
  7. Press [E] at the delivery marker to complete the delivery.
  8. The ordered vehicles are added to your stock automatically.

Only one active order can be in progress at a time per dealership.


Vehicle Listings (Showcase)

The Vehicle Listing tab lets you place physical showcase vehicles in the world:

  1. Click Create Listing.
  2. Select the vehicle from your catalog.
  3. Choose a colour.
  4. The location selector opens in-world – aim at the ground where you want the car placed and confirm.
  5. The vehicle spawns, frozen in place. Players who walk up to it see stats and price information.

Maximum listings per dealership: Config.MaxListings (default 5).

To remove a listing:

  1. Open the Vehicle Listing tab.
  2. Click Delete Listing next to the entry and confirm.

Discounts

  1. Go to the Stock tab.
  2. Click Set Discount on a vehicle.
  3. Configure:
    • Percentage % – how much off (e.g. 20 = 20% discount)
    • Duration (hours) – how long the discount is active
    • Usage Limit – maximum times the discount can be applied before it expires
  4. Click Apply. The discounted price is calculated automatically at checkout.
  5. Click Remove Discount to end it early.

Coupons

  1. Go to the Coupons tab.
  2. Click Create Coupon.
  3. Fill in:
    • Code – unique alphanumeric code players will type at checkout
    • Percentage % – discount value
    • Duration (hours) – expiry window
    • Usage Limit – max redemptions
  4. Share the code with your customers. When a player redeems it, the usage count decrements.
  5. Delete expired or unwanted coupons at any time.

Sales History

The Sales tab shows a chronological log of every vehicle sold:

Column Description
Vehicle Model name
Price Amount charged
Payment Type cash / bank / finance
Date Timestamp of the sale

Treasury (Deposit / Withdraw)

The Dashboard tab contains the dealership's Account Balance with two actions:

  • Deposit – move money from your bank into the dealership safe.
  • Withdraw – move money from the dealership safe to your bank.

Revenue from vehicle sales is automatically added to the dealership balance.
When customers pay installments, each payment also flows to the dealership balance.


📡 Exports API

These Lua exports are available to other resources:

-- Open the main shop UI for the closest dealership
exports["aty_dealershipv2"]:openDealership()

-- Open the player's installments dashboard
exports["aty_dealershipv2"]:openInstallments()

-- Returns a table of all shops (same structure as DB rows, decoded)
local shops = exports["aty_dealershipv2"]:getShops()

-- Returns data for a single shop by name
local shop = exports["aty_dealershipv2"]:getShopData("LuxuryCars")

-- Returns all active installments for the local player
local installments = exports["aty_dealershipv2"]:getPlayerInstallments()

-- Returns a single installment by its database ID
local inst = exports["aty_dealershipv2"]:getInstallmentById(5)

-- Returns the vehicle list (with stock > 0) for a shop
local vehicles = exports["aty_dealershipv2"]:getDealershipVehicles("LuxuryCars")

💻 Commands Reference

Command Permission Description
/dealershipadmin Admin (god / admin / superadmin) Opens the admin management panel
/directsale (Reserved / configurable)
/installments Any player Opens the installment payment dashboard

Command names can be changed in config.lua:

Commands = {
    Admin       = "dealershipadmin",
    DirectSale  = "directsale",
    Installments = "installments",
},

📚 Catalog (shared/catalog.lua)

The catalog is a Lua table where each key is the vehicle's internal identifier:

Catalog = {
    ["adder"] = {
        name     = "Adder",           -- short display name
        label    = "Truffade",        -- manufacturer / brand
        model    = "adder",           -- GTA spawn model name
        price    = 1000000,           -- base purchase price in $
        category = "Super",           -- category string (used to filter per dealership)
    },
    -- ...
}

The catalog file is written/saved by the admin panel. You can also edit it manually – just restart the resource afterwards.


🌐 Locale / Translations

Language strings are in shared/locale.lua. The active locale is set at the top:

Locale = 'en'

To add a new language, duplicate the ["en"] block and change the key:

Locales = {
    ["en"] = { ... },
    ["tr"] = {
        ['no_vehicles_for_sale'] = "Bu galeride satılık araç yok",
        -- ... all keys
    }
}

Then set Locale = 'tr' at the top of the file.


📁 File Structure

aty_dealershipv2/
├── client/
│   └── client.lua          # All client-side logic (UI control, camera, preview, zones)
├── server/
│   ├── server.lua          # All server callbacks (purchasing, orders, installments, etc.)
│   └── admin.lua           # Admin commands, dealership CRUD, catalog management
├── shared/
│   ├── config.lua          # ⬅ Main configuration file
│   ├── catalog.lua         # Global vehicle catalog (read/written by admin panel)
│   └── locale.lua          # Localisation strings
├── web/                    # Vue 3 + Vite NUI source
│   └── src/
│       ├── components/     # ShopMenu, BossMenu, AdminMenu, Installments, Showcase…
│       ├── stores/         # Pinia state management
│       └── utils/          # fetchNui helper
├── ui/                     # Compiled NUI output (served by FiveM)
├── data.sql                # Fresh install database schema
├── update.sql              # Incremental migration for existing installs
└── fxmanifest.lua          # Resource manifest

🔧 Troubleshooting

Dealership NPC / Blip not appearing

  • Ensure the resource started without errors (server console).
  • Check that the database import was successful and at least one row exists in aty_dealership.
  • Verify aty_lib is started before aty_dealershipv2.

UI opens but vehicles don't load

  • The shared/catalog.lua may be empty or malformed. Check the file for syntax errors.
  • Confirm the dealership has vehicles assigned (categories were selected when creating it).

"aty_lib" not found error

  • Ensure aty_lib is downloaded and listed in server.cfg before this resource.

Finance / installments not working

  • Confirm the vehicle_installments table exists. Run update.sql if upgrading.
  • Check Config.PaymentInterval is set correctly.

Order delivery mission doesn't trigger

  • Ensure Config.RealisticOrder = true.
  • Check that OrderTruckModel and OrderTrailerModel are valid GTA V model names on your server.
  • Verify the OrderPickupLocation coordinates are reachable and not inside an interior.

Admin command not working

  • Confirm the player's ESX grade / QBCore permission matches one of the Config.AdminPermissions values.
  • Check the console for any errors when starting the resource.

📄 License

This resource is the intellectual property of atiysu. Redistribution, resale, or public release without explicit permission is prohibited. For support or licensing inquiries, contact the author directly.


Made with ❤️ by atiysu

ATY Scripts LogoATY SCRIPTS

QBCore & ESX için yüksek optimizasyonlu FiveM scriptleri üretiyoruz. Maksimum performans, hassas kod, sıfır gecikme.

Topluluğa Katıl

Partner

Tebex resmi partneri. Güvenli ödeme ve Cfx.re Keymaster entegrasyonu.

Yasal

Rockstar Games, Cfx.re, FiveM veya Take-Two Interactive ile bağlantılı değildir. Satın alımlar Tebex Hizmet Şartları'na tabidir.

© 2026 ATY SCRIPTS. Tüm hakları saklıdır.