# SHOPS CREATOR

## Forge Shops V2

Advanced shop system for FiveM servers.

Created by **CodeForge**\
Support Discord: <https://discord.gg/UTVssdrXRV>

### Features

* Normal shops with buy and sell modes.
* Reusable item categories through `ItemCategories`.
* Weapon shops with a dedicated NUI, stats, tints, components, license checks and optional 3D preview.
* Illegal shops with configurable police alert chance, delay and cooldown.
* Business shops with duty, management panel, stock, custom prices, employees, NPC income, invoices and worker deliveries.
* Target and non-target interaction modes.
* Proximity-based shop NPC spawning for better performance.
* Model-based shops for vending machines, coffee machines and other props.
* Multiple payment methods per shop.
* Job-restricted shops.
* Server-side validation for purchases, sales, jobs, distance, stock and inventory actions.
* Server-side Discord webhook logging.
* Full translation system in `config/translations.lua`.
* Debug mode with startup hints and structured console logs.
* Open configuration, bridge and hook files for easier server integration.

### Requirements

Required:

* A FiveM server using `cerulean`.
* `oxmysql`.
* ESX or QBCore/QBOX.
* A supported inventory system, or the framework fallback.

Supported framework modes:

* `auto`
* `esx`
* `qb`

Supported inventory aliases:

* `auto`
* `ox` / `ox_inventory`
* `qb` / `qb-inventory` / `qb_inventory`
* `ps` / `ps-inventory` / `ps_inventory`
* `qs` / `qs-inventory` / `qs_inventory` / `quasar`
* `core` / `core_inventory` / `core-inventory`
* `tgiann` / `tgiann-inventory` / `tgiann_inventory`
* `jaksam` / `jaksam_inventory` / `jaksam-inventory`
* `esx` / `esx_default` / `default`

Optional:

* `ox_target` or `qb-target`.
* `forge-notify`.
* `neon-boss` for the external boss menu option.
* Society/banking resources depending on `Config.Business.SocietyMethod`.
* Dispatch resources if you connect illegal shop alerts to your dispatch system.

### Installation

1. Place the folder in your resources directory.

   Recommended path:

   ```cfg
   resources/[forge]/forge-shops
   ```
2. Keep the resource name as `forge-shops`.

   If you rename the resource, update paths that reference the resource name, especially:

   ```lua
   Config.WeaponShop.WeaponImageBase = 'nui://forge-shops/html/public/weapons/'
   ```
3. Make sure your dependencies start before this resource.

   Example `server.cfg`:

   ```cfg
   ensure oxmysql
   ensure es_extended
   # or: ensure qb-core

   ensure ox_inventory
   # optional target:
   ensure ox_target

   ensure forge-shops
   ```
4. Configure your database connection for `oxmysql`.
5. Install the database table.

   By default this is automatic:

   ```lua
   Config.Business.AutoInstallDB = true
   ```

   If you prefer manual installation, run:

   ```sql
   SQL/install.sql
   ```
6. Configure the script in:
   * `config/config.lua`
   * `config/shops.lua`
   * `config/weaponshops.lua`
   * `config/illegalshops.lua`
   * `config/translations.lua`
   * `config/open_server.lua`
   * `config/open_client.lua`
7. Restart the server or restart the resource:

   ```cfg
   restart forge-shops
   ```

### Main Configuration

#### Framework

Set your framework in `config/config.lua`:

```lua
Config.Framework = 'auto'
```

Use `auto` unless you need to force a framework:

```lua
Config.Framework = 'esx'
Config.Framework = 'qb'
```

For ESX, check:

```lua
Config.ESXExport = 'es_extended'
Config.Core = 'esx:getSharedObject'
```

#### Inventory

Set your inventory system:

```lua
Config.Inventory = 'auto'
```

If auto-detection does not match your server, force it:

```lua
Config.Inventory = 'ox'
Config.Inventory = 'qb'
Config.Inventory = 'qs'
```

#### Target Mode

Target disabled:

```lua
Config.UseTarget = { false, 'ox-target', 'target.open_shop' }
```

Target enabled with ox\_target:

```lua
Config.UseTarget = { true, 'ox-target', 'target.open_shop' }
```

Target enabled with qb-target:

```lua
Config.UseTarget = { true, 'qb-target', 'target.open_shop' }
```

When target is enabled, it is used for shops, business duty, management, boss menu and worker delivery interactions.

#### Language

Set the active language:

```lua
Config.Locale = 'en'
```

Translations are stored in:

```lua
config/translations.lua
```

Discord webhook texts are configured separately in `config/open_server.lua`.

#### Debug

Enable debug mode while installing or diagnosing:

```lua
Config.Debug = true
```

Disable it in production:

```lua
Config.Debug = false
```

When enabled, the server prints startup hints, including the selected framework, inventory, target system, business status, weapon shop status and Discord logging status.

#### Payment Methods

Global payment methods are configured in:

```lua
Config.PaymentMethods
Config.DefaultPaymentMethods
```

Per-shop payment methods:

```lua
paymentMethods = { 'bank', 'cash' }
```

Examples:

```lua
paymentMethods = { 'cash', 'black_money' }
paymentMethods = { 'bank' }
```

### Adding a Normal Shop

Add normal shops in:

```lua
config/shops.lua
```

Example:

```lua
Shops["Example Shop"] = {
    label        = "shop.example_shop",
    category     = "supermarket",
    sellCategory = "supermarket_sell",
    paymentMethods = { 'bank', 'cash' },

    ped    = { use = true, model = "mp_m_shopkeep_01", coords = vector4(25.0, -1345.0, 28.5, 180.0), useAnimations = true },
    coord  = vector3(25.0, -1345.0, 29.5),
    marker = { use = true, style = 23, r = 51, g = 175, b = 213 },
    blip   = { use = true, style = 52, color = 3, scale = 0.8, text = "blip.example_shop" },
}
```

Then add translations in `config/translations.lua`:

```lua
['shop.example_shop'] = 'Example Shop',
['blip.example_shop'] = 'Example Shop',
```

### Adding Item Categories

Reusable buy categories are in `config/shops.lua`:

```lua
ItemCategories["example_category"] = {
    ["Water"] = {
        itemName  = "water",
        itemImage = "water.png",
        itemPrice = 10,
        special   = false
    },
}
```

Use the category in a shop:

```lua
category = "example_category"
```

### Adding Sell Categories

Sell categories define what a shop buys from players:

```lua
SellCategories["example_sell"] = {
    ["Water"] = {
        itemName  = "water",
        itemImage = "water.png",
        itemPrice = 5
    },
}
```

Use the sell category in a shop:

```lua
sellCategory = "example_sell"
```

### Restricting a Shop by Job

Add `allowedJobs` to the shop:

```lua
allowedJobs = { "police", "ambulance" }
```

Remove `allowedJobs` or leave it empty to allow everyone.

Access is validated server-side.

### Adding a Weapon Shop

Weapon shops are configured in:

```lua
config/weaponshops.lua
```

Example:

```lua
Shops["Ammu-Nation Example"] = {
    label          = "shop.ammu_nation",
    shopType       = 'weapon',
    weaponCategory = { 'handguns', 'melee', 'ammo' },
    requireLicense = true,
    paymentMethods = { 'bank', 'cash' },

    ped    = { use = true, model = "s_m_y_ammucity_01", coords = vector4(22.0, -1107.0, 28.8, 160.0), useAnimations = false },
    coord  = vector3(22.0, -1107.0, 29.8),
    marker = { use = true, style = 23, r = 255, g = 120, b = 30 },
    blip   = { use = true, style = 110, color = 47, scale = 0.85, text = "blip.ammu_nation" },
}
```

Weapon shop settings are in:

```lua
Config.WeaponShop
```

Important options:

* `Enabled`
* `LicenseCheckMode`
* `LicenseItem`
* `LicenseName`
* `GiveMode`
* `StackableWeaponItems`
* `WeaponImageBase`
* `Preview3D`

If `LicenseCheckMode = 'item'`, make sure the license item exists in your inventory.

### Weapon Categories, Components and Tints

Weapon categories are in:

```lua
WeaponCategories
```

Each weapon can define:

* `weaponHash`
* `itemName`
* `image`
* `price`
* `description`
* `tints`
* `stats`
* `components`

Components can define:

* `name`
* `hash`
* `itemName`
* `price`
* `image`
* `slot`

Tint palettes are in:

```lua
WeaponTints
```

### Adding an Illegal Shop

Illegal shops are configured in:

```lua
config/illegalshops.lua
```

Example:

```lua
Shops["Black Market Example"] = {
    label          = "shop.black_market",
    category       = "black_market",
    sellCategory   = "black_market_sell",
    illegal        = true,
    paymentMethods = { 'cash', 'black_money' },

    coord  = vector3(100.0, 100.0, 30.0),
    marker = { use = true, style = 23, r = 120, g = 0, b = 0 },
    blip   = { use = false, style = 0, color = 0, scale = 0.0, text = "blip.black_market" },
}
```

Police alert settings are in:

```lua
Config.IllegalShops
```

The open server-side hook is:

```lua
IllegalShopPoliceAlert(src, shop, action, coords)
```

You can integrate dispatch systems in:

```lua
config/open_server.lua
```

### Business Shops

Business shops are normal or weapon shops with:

```lua
isBusiness = true
```

Business settings are in:

```lua
Config.Business
```

Main features:

* Worker duty.
* Management panel.
* Stock and restock system.
* Custom item and weapon prices.
* NPC employee hiring and firing.
* NPC salaries.
* Passive NPC income.
* Invoice sales.
* Worker order deliveries.
* Company and worker revenue split.
* External society/banking integration or built-in balance.

Example:

```lua
Shops["My Business Shop"] = {
    label        = "shop.business_store",
    category     = "supermarket",
    sellCategory = "supermarket_sell",

    isBusiness  = true,
    assignedJob = "shopkeeper",
    societyKey  = "society_shopkeeper",
    workerRanks = { 0, 1 },
    ownerRanks  = { 2, 3 },

    dutyPoint = vector4(25.0, -1345.0, 29.49, 180.0),
    adminPanel = {
        targetCoords = vector4(23.0, -1344.0, 29.49, 90.0),
        targetExtent = vector3(1.5, 1.0, 1.5),
    },
    bossMenuPoint = vector4(22.0, -1343.0, 29.49, 90.0),

    ped    = { use = true, model = "CS_Josh", coords = vector4(24.5, -1346.19, 28.5, 266.78), useAnimations = true },
    coord  = vector3(25.3555, -1346.1746, 29.4876),
    marker = { use = true, style = 23, r = 51, g = 175, b = 213 },
    blip   = { use = true, style = 52, color = 2, scale = 0.8, text = "blip.business_store" },
}
```

#### Business Society Money

Use built-in business balance:

```lua
Config.Business.UseBuiltinBalance = true
```

Use external society/banking:

```lua
Config.Business.UseBuiltinBalance = false
Config.Business.SocietyMethod = 'QB'
```

Supported society methods:

* `FORGE`
* `QB`
* `OKOK`
* `ESX`
* `FD`
* `TGG`
* `WASABI`
* `CODEM`
* `JUSTBANKING`

Make sure the required banking/society resource is installed and started.

#### External Boss Menu

To use `neon-boss`:

```lua
Config.Business.UseNeonBossMenu = true
```

Then configure `bossMenuPoint` in each business shop.

### Model-Based Shops

Model shops are configured with:

```lua
Config.ModelScan
Config.ModelShops
```

Example:

```lua
Config.ModelShops = {
    { model = 'prop_vend_soda_01', shop = 'Vending Machines', distance = 1.2, label = 'target.open_vending' },
}
```

The referenced shop should use:

```lua
openByModelOnly = true
```

### Discord Webhook Logs

Discord logs are configured server-side only in:

```lua
config/open_server.lua
```

Do not place webhook URLs in client or shared files.

Enable logs:

```lua
Config.DiscordLogs.Enabled = true
```

Use one default webhook:

```lua
Config.DiscordLogs.DefaultWebhook = 'https://discord.com/api/webhooks/...'
```

Or use a different webhook per category:

```lua
Config.DiscordLogs.Categories.purchases.Webhook = 'https://discord.com/api/webhooks/...'
Config.DiscordLogs.Categories.sells.Webhook = 'https://discord.com/api/webhooks/...'
Config.DiscordLogs.Categories.weapons.Webhook = 'https://discord.com/api/webhooks/...'
Config.DiscordLogs.Categories.business.Webhook = 'https://discord.com/api/webhooks/...'
Config.DiscordLogs.Categories.illegal.Webhook = 'https://discord.com/api/webhooks/...'
```

You can also store webhook URLs in `server.cfg` using convars:

```cfg
set forge_shops_purchases_webhook "https://discord.com/api/webhooks/..."
```

Then point the category to that convar:

```lua
Config.DiscordLogs.Categories.purchases.Convar = 'forge_shops_purchases_webhook'
```

Default categories:

* `purchases`
* `sells`
* `weapons`
* `business`
* `illegal`

Default log actions:

* `item_purchase`
* `item_sell`
* `weapon_purchase`
* `accessory_purchase`
* `invoice_sale`
* `worker_sale`
* `worker_weapon_sale`
* `business_management`
* `illegal_alert`

### Translations

All player-facing and admin-facing text is in:

```lua
config/translations.lua
```

Set the active language in:

```lua
Config.Locale = 'en'
```

To add a language:

1. Copy the English language table.
2. Rename it to your locale code, for example `es`.
3. Translate the values, not the keys.
4. Set `Config.Locale` to your locale code.

Do not translate:

* Event names.
* Export names.
* Function names.
* Item names.
* Weapon hashes.
* Job names.
* Permission names.
* Internal identifiers.

Discord log texts are intentionally configured in `config/open_server.lua`.

### Images

Item images use:

```lua
Config.ItemImageBaseURL
Config.ItemImageExtension
```

Examples:

```lua
Config.ItemImageBaseURL = 'nui://ox_inventory/web/images/'
Config.ItemImageBaseURL = 'nui://qb-inventory/html/images/'
Config.ItemImageBaseURL = 'public/items/'
```

Weapon images use:

```lua
Config.WeaponShop.WeaponImageBase
Config.WeaponShop.WeaponImageExt
```

Image filenames must match the configured item or weapon image names.

### Editable Integration Files

These files are intended for configuration and integration:

* `config/config.lua`
* `config/translations.lua`
* `config/shops.lua`
* `config/weaponshops.lua`
* `config/illegalshops.lua`
* `config/bridge_client.lua`
* `config/bridge_server.lua`
* `config/open_client.lua`
* `config/open_server.lua`

Use `config/open_server.lua` for protected server-side hooks such as:

* Inventory carry checks.
* Discord webhook configuration.
* Illegal shop police alerts.

### Troubleshooting

#### The shop does not open

* Check that your framework is started before `forge-shops`.
* Check `Config.Framework`.
* Check that your inventory resource is started.
* Check `Config.Inventory`.
* If using target, check `Config.UseTarget` and make sure `ox_target` or `qb-target` is started.
* Check `allowedJobs` on the shop.
* Check that the player is close enough to the configured coordinates.

#### Items are not added or removed

* Check that the item exists in your inventory system.
* Check `Config.Inventory`.
* Enable `Config.Debug = true` and read the server console.
* Check inventory weight/capacity rules.

#### Weapon purchases fail

* Check `Config.WeaponShop.Enabled`.
* Check `Config.WeaponShop.GiveMode`.
* If using `GiveMode = 'item'`, make sure weapon items exist in your inventory.
* If using licenses, make sure the configured license item or framework license exists.
* Check that weapon components and ammo item names match your inventory.

#### Business money does not update

* Check `Config.Business.Enabled`.
* Check `Config.Business.UseBuiltinBalance`.
* If using external society money, check `Config.Business.SocietyMethod`.
* Make sure the society/banking resource required by your selected method is started.
* Make sure the shop has a valid `societyKey`.

#### NPCs appear only nearby

Shop NPCs are spawned by proximity for performance.

Adjust:

```lua
Config.PedSpawnRadius = 50
```

Higher values keep NPCs spawned from farther away, but may cost more performance on servers with many shops.

#### Images are missing

* Check `Config.ItemImageBaseURL`.
* Check `Config.WeaponShop.WeaponImageBase`.
* Check that filenames include the configured extension.
* If you renamed the resource, update NUI paths that contain `forge-shops`.

#### Text is missing or shows a translation key

* Check `config/translations.lua`.
* Make sure the key exists in the active language.
* English is used as fallback when possible.

### Support

For support, updates and questions, join:

<https://discord.gg/UTVssdrXRV>


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://codeforge.gitbook.io/codeforge/sleek-series/shops-creator.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
