> For the complete documentation index, see [llms.txt](https://codeforge.gitbook.io/codeforge/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://codeforge.gitbook.io/codeforge/sleek-series/shops-creator.md).

# 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>
