The most complete, production-grade shop system for FiveM.
Real-time ox_inventory UI, StateBag sync, dynamic reputation, a fully scripted robbery system with NPC reactions, passive income, analytics, admin tools, shop templates for instant bulk-creation, 80+ blip options, and a fully race-condition-free purchase system β battle-tested on live servers.
Built on ox_core Β· ox_lib Β· ox_inventory Β· ox_target Β· oxmysql
Built by Red Dragon Elite | SerpentsByte
- Overview
- What's New in V2.0.0
- Features
- Dependencies
- Installation
- Configuration
- Shop Templates
- Shop Categories
- Blip System
- Robbery System
- Reputation System
- Analytics
- Admin System
- Commands
- Database
- Localization
- Troubleshooting
- Changelog
- License
RDE Advanced Shop System V2.0.0 is a fully dynamic, in-world shop framework for FiveM servers. Admins can create, edit, and delete shops entirely in-game β no config restarts, no hardcoded locations. Every shop gets its own ox_inventory stash, a spawned NPC clerk, a map blip, and a full set of mechanics including till money, passive income, stock restock, robbery detection, police alerts, and a per-player reputation system.
V2.0.0 adds Shop Templates for instant Ammu-Nation/supermarket/pharmacy setup with a single menu selection, a massively expanded blip library with 80+ icons and 29 colors, and a definitive fix for the multi-purchase race condition that previously caused ox_inventory to throw nil field 'items' errors.
| Feature | Typical Shop Scripts | RDE Advanced Shop System |
|---|---|---|
| Dynamic in-game shop creation | β | β Full CRUD in-game |
| Shop Templates (bulk item presets) | β | β 5 templates, 70+ items |
| ox_inventory UI integration | β or broken | β Fixed & stable |
| StateBag real-time sync | Polling | β Instant |
| Multi-purchase race condition fix | β crashes | β Debounced refresh |
| Robbery system w/ NPC reactions | β | β Hands up, fight back, die |
| Passive till income | β | β Configurable NPC customers |
| Per-player reputation | β | β Affects item prices |
| Auto stock restock | β | β Interval-based |
| Shop analytics | β | β Revenue, purchases, robberies |
| Police alert on robbery | β | β Dispatch + wanted level |
| Multi-language support | β | β EN + DE built-in |
| Blip variety | ~13 options | β 80+ sprites, 29 colors |
The biggest quality-of-life feature in V2. When creating a shop via /createshop, you now get an optional template selection step before the input dialog. Pick a preset and all items are bulk-inserted into your new shop automatically β no more adding 70 weapons one by one.
Five templates ship out of the box:
- π« Ammu-Nation (Complete) β 70 items: all ammo, melee, pistols, SMGs, shotguns, marksman rifles, every attachment, extended clips, drum mags, all scopes, all muzzles, skins, and vests
- πͺ 24/7 Supermarket β snacks, drinks, first aid, cigarettes, phone
- π Pharmacy β bandages, medikit, painkillers, antidote, adrenaline, defibrillator
- β½ Gas Station β drinks, jerrycan, rag, basics
- πΊ Liquor Store β beer, wine, vodka, whiskey, rum, cocktails
Templates are item-presets only β they do NOT spawn shops at fixed locations. You still place the shop wherever you want with /createshop. The template just fills the inventory.
Adding your own template is one Lua block in data/shop_templates.lua. No other files need touching.
From 13 sprites and 10 colors to 80+ sprites and 29 colors. Blips are now grouped into logical categories in the dropdown:
- Shops & Services (gun shop, clothing, pharmacy, bar, casino, nightclub, strip club...)
- Property & Buildings (house, office, warehouse, bunker, hangar, marina, yacht, bank...)
- Crime & Black Market (drugs, cash, weapons deal, weed stash, meth lab, money press...)
- Vehicles (truck, bus, helicopter, boat, sports car, train...)
- Racing & Sports (land race, air race, water race, stunt, tennis, basketball, darts...)
- Generic (star, POI marker, info, business, gift...)
ox_inventory/modules/shops/server.lua:215: attempt to index a nil value (field 'items') β this crash happened when a player dragged multiple items quickly. Root cause: RegisterShop was called inside the buyItem hook, which sets the shop internally to nil during rebuild. Any concurrent purchase hit nil and crashed, closing the UI.
Fix: RegisterShop is no longer called in the buyItem hook at all. ox_inventory manages live stock internally once RegisterShop has been called at startup. We only write DB decrements, till money, and reputation. A debounced refresh (100ms) handles admin-triggered changes like price edits and item additions β never purchases.
You can not open this inventory β this happened because openShopInventory was calling the debounced refreshOxShop (async, 100ms delay) and then immediately firing TriggerClientEvent to open the UI. The client arrived before RegisterShop completed.
Fix: openShopInventory now does a synchronous RegisterShop call inline before triggering the client event. The shop is guaranteed to be registered when the client opens it.
- Create, edit, and delete shops fully in-game via ox_lib UI
- Optional template selection at shop creation β bulk-load 70+ items in one click
- Every shop has its own ox_inventory stash with configurable slots and max weight
- Spawned NPC clerks with selectable ped models, invincibility, freeze, and scenario settings
- Map blips with 80+ configurable sprites, 29 colors, name, and short-range display
- 7 built-in shop categories (General, Weapons, Clothing, Liquor, Electronics, Pharmacy, Custom) each with unique blip defaults and reputation multipliers
- Live price updates after admin edits via debounced
refreshOxShop()
- A percentage of every purchase flows into the shop's cash register (
moneyAccumulationRate) - Configurable max till balance
- Passive income simulates NPC customers even when no players are buying
- Admins can check and empty the till in-game
- Particle effects on till interaction
- Stock depletes in real-time when players purchase items
- Automatic restock on a configurable interval with min/max amounts and a hard cap per item
- Each player has a per-shop reputation score (range: -50 to 100)
- Reputation increases on every purchase and decreases on robbery
- Reputation directly affects item prices β loyal customers get discounts, criminals pay a premium
- Multipliers scale with shop category
- Per-shop tracking of total revenue, total purchases, total robberies, and average transaction value
- Till balance included in analytics view
- Configurable history retention period (days)
- ACE permissions + ox_core group-based admin system
- Admin groups fully configurable: god, owner, admin, superadmin, moderator, mod, staff
- ACE fallback:
rde_shop.admin,rde_orgs.admin,command - Permission cache reset on player spawn
Every shop can be robbed β here's what happens:
Trigger: Player aims a qualifying weapon at the NPC clerk for aimTime seconds while a robbery isn't on cooldown.
NPC Reactions:
- 95% chance the clerk raises their hands and freezes during the timer
- 5% chance the clerk pulls a weapon and fights back
- If the player kills the clerk, the clerk drops money and eventually respawns
- NPC won't flee β they hold their ground or raise their hands
Payout: Scales with the till balance. Money is removed from the till on success.
Police Alert:
- Sends a dispatch alert to configured police jobs (
police,sheriff,state) - Sets the player's wanted level
- Progressive difficulty: more cops nearby = longer aim time + higher fight-back chance
Cooldown: Configurable per-shop cooldown after a successful robbery.
Weapon List (configurable):
WEAPON_PISTOL, WEAPON_PISTOL50, WEAPON_COMBATPISTOL, WEAPON_APPISTOL,
WEAPON_ASSAULTRIFLE, WEAPON_CARBINERIFLE, WEAPON_ADVANCEDRIFLE,
WEAPON_SMG, WEAPON_MICROSMG, WEAPON_PUMPSHOTGUN, WEAPON_SAWNOFFSHOTGUN,
WEAPON_KNIFE, WEAPON_MACHETE, WEAPON_BAT
| Resource | Required | Notes |
|---|---|---|
| oxmysql | β Required | Database layer |
| ox_core | β Required | Player/character framework |
| ox_lib | β Required | UI, callbacks, notifications |
| ox_inventory | β Required | Shop stash + item UI |
| ox_target | β Required | NPC interaction |
cd resources
git clone https://github.com/RedDragonElite/rde_shops.gitensure oxmysql
ensure ox_core
ensure ox_lib
ensure ox_inventory
ensure ox_target
ensure rde_shops
Order matters.
rde_shopsmust start after all its dependencies.
Tables are created automatically on first start. No manual SQL import needed.
Edit config.lua to adjust robbery settings, till rates, restock intervals, reputation thresholds, admin groups, and language. Edit data/shop_templates.lua to add or modify item templates.
restart rde_shops
Then in-game: /createshop β pick a template (or none) β fill in name/ped/blip β done.
Config.DefaultLanguage = 'en' -- 'en' or 'de'
Config.Debug = false -- verbose console logging
Config.TablePrefix = 'rde_' -- database table prefix
Config.AdminGroups = {
'god', 'owner', 'admin', 'superadmin', 'moderator', 'mod', 'staff'
}
Config.AcePermissions = {
'rde_shop.admin',
'rde_orgs.admin',
'command'
}Config.ShopInventory = {
slots = 100,
maxWeight = 100000
}Config.Shops.ped = {
invincible = false,
frozen = true,
blockevents = true,
scenario = 'WORLD_HUMAN_STAND_MOBILE',
deadPedCleanupTime = 20000, -- ms before dead ped is removed
respawnTime = 60000, -- ms before ped respawns after death
}Config.Shops.till = {
moneyAccumulationRate = 0.15, -- 15% of each purchase goes to the till
maxTillMoney = 5000,
enableParticles = true,
passiveIncome = {
enabled = true,
interval = 300, -- every 5 minutes
minAmount = 50,
maxAmount = 250,
},
}Config.Shops.restock = {
enabled = true,
interval = 600, -- every 10 minutes
amountMin = 1,
amountMax = 5,
maxStock = 100,
}Config.Shops.reputation = {
enabled = true,
maxRep = 100,
minRep = -50,
repGainPerPurchase = 1,
repLossPerRobbery = 10,
priceMultiplierMax = 0.9, -- 10% discount at max rep
priceMultiplierMin = 1.5, -- 50% markup at min rep
}Config.Robbery = {
enabled = true,
weaponRequired = true,
aimTime = 5.0, -- seconds to aim before robbery triggers
cooldown = 600, -- seconds between robberies on same shop
npc = {
handsUpChance = 0.95,
fightBackChance = 0.05,
canBeKilled = true,
giveMoneyOnDeath = true,
},
progressive = {
enabled = true,
timeIncreasePerCop = 1.0,
fightBackChanceIncreasePerCop = 0.02,
},
policeNotify = true,
policeJobs = {'police', 'sheriff', 'state'},
minPolice = 0,
dispatchRadius = 300.0,
wantedLevel = 2,
}Templates are defined in data/shop_templates.lua and loaded as a shared script (available on both client and server). They appear in the first step of /createshop as an optional dropdown β selecting "No Template" starts with an empty shop as before.
| Key | Label | Items |
|---|---|---|
ammu_nation |
π« Ammu-Nation (Complete) | 70 β ammo, melee, pistols, SMGs, shotguns, marksman, all attachments |
supermarket_247 |
πͺ 24/7 Supermarket | 13 β food, drinks, first aid, cigarettes, phone |
pharmacy |
π Pharmacy | 7 β bandages, medikit, painkillers, antidote, adrenaline, defib |
gas_station |
β½ Gas Station | 8 β drinks, jerrycan, rag, bandage |
liquor_store |
πΊ Liquor Store | 8 β beer, wine, vodka, whiskey, rum, cocktails |
Open data/shop_templates.lua and add a new block to Config.ShopTemplates:
Config.ShopTemplates['my_black_market'] = {
label = 'π Black Market',
description = 'Off the books.',
category = 'weapons',
pedModel = 'g_m_y_lost_01',
blipSprite = 110,
blipColor = 1,
items = {
{ name = 'WEAPON_ASSAULTRIFLE', price = 18000, quantity = 5, metadata = { registered = false } },
{ name = 'ammo-rifle', price = 25, quantity = 300 },
-- add as many as you want
}
}No other files need changing. The template appears automatically in the next /createshop dialog.
| Category | Default Blip | Rep Multiplier | Notes |
|---|---|---|---|
| πͺ General Store | Sprite 52, Green | 1.0x | |
| π« Weapon Shop | Sprite 110, Red | 1.5x | High robbery severity |
| π Clothing Store | Sprite 73, Blue | 0.8x | |
| πΊ Liquor Store | Sprite 93, Yellow | 1.2x | |
| π± Electronics | Sprite 521, White | 1.3x | |
| π Pharmacy | Sprite 153, Dark | 1.4x | |
| β Custom | Sprite 52, Green | 1.0x |
V2.0.0 ships with 80+ blip sprites and 29 colors available in the /createshop dropdown, grouped by category. A few highlights:
Sprites (selection):
| Icon | Sprite | Label |
|---|---|---|
| π« | 110 | Gun Shop |
| πͺ | 52 | Store / Supermarket |
| π | 153 | Pharmacy |
| πΊ | 93 | Bar |
| β½ | 361 | Gas Station |
| π¦ | 108 | Bank |
| π | 617 | Jeweler |
| π | 51 | Drugs |
| π° | 272 | Cash |
| π | 38 | Race Flag |
| π | 40 | House / Safehouse |
| π’ | 475 | Office |
| π | 500 | Money Press |
Full list in Config.BlipSprites inside config.lua. Reference: FiveM Blip Docs
Colors: White, Red, Green, Blue, Black, Yellow, Light Blue, Purple, Pink, Orange, Brown, Grey, Navy, Cyan, Dark Green, Dark Red, Gold, Royal Blue, Mint, Amber, Indigo, Silver β and more. Full list in Config.BlipColors.
Admin access is verified against ox_core groups listed in Config.AdminGroups, with ACE permission fallback.
Admins can:
- Create, edit, and delete any shop (with optional template selection)
- Manage shop inventory (add/remove items, set prices, drag & drop stock)
- Check and empty any shop's till
- View full shop analytics
- Get a cached permission refresh on every spawn
# server.cfg
add_ace group.admin rde_shop.admin allow
add_principal identifier.steam:110000xxxxxxxx group.admin
| Command | Who | Description |
|---|---|---|
/shop |
Player | Open nearest shop (if in range) |
/shopmanage |
Admin | Open shop management menu |
/createshop |
Admin | Create a new shop (with template selection) |
Tables are created automatically on first start. The system uses Config.TablePrefix (default rde_) for all table names. No manual SQL required.
Built-in English and German support. Switch with Config.DefaultLanguage = 'en' or 'de'.
All locale strings are in Config.Locales β add new languages by copying the en block and translating.
"You can not open this inventory"
Fixed in V2.0.0. openShopInventory now synchronously calls RegisterShop before triggering the client event. If you still see this after updating, ensure you replaced both server.lua and client.lua.
Items crash the shop UI after the first purchase / multi-buy broken
Fixed in V2.0.0. RegisterShop is no longer called inside the buyItem hook. ox_inventory manages live stock internally. Only DB writes happen on purchase now.
Shop inventory won't open at all?
Make sure ox_inventory is fully started before rde_shops. Check F8 for export errors on startup.
Admin permission always returning false?
Verify the player's ox_core group matches an entry in Config.AdminGroups exactly. Restart the resource after any group changes.
Robbery not triggering?
Ensure the player has a qualifying weapon from Config.Robbery.weaponTypes equipped and drawn, and that the shop cooldown has expired.
NPC not spawning / disappearing instantly?
Enable Config.Debug = true for verbose spawn logs. Check deadPedCleanupTime and respawnTime.
Till always showing $0?
Ensure you're on V2.0.0 β getTillMoney was broken in early releases.
Police alert not sending?
Confirm Config.Robbery.policeNotify = true and that the jobs in policeJobs match your server's actual job names.
New Features:
- β
Shop Templates β
/createshopnow has a 3-step flow: template selection β shop data β done. Five built-in templates (Ammu-Nation 70 items, 24/7, Pharmacy, Gas Station, Liquor Store). Templates are defined indata/shop_templates.lua(new shared script). Adding custom templates requires no code changes. - β 80+ Blip Sprites β expanded from 13 to 80+ options, grouped by category (shops, crime, vehicles, property, racing, generic). Full FiveM blip reference coverage for relevant IDs.
- β 29 Blip Colors β expanded from 10 to 29, all official GTA color IDs with descriptive labels.
- β
Template-aware
/createshopβ Ped model, blip sprite/color, and category are pre-filled from the selected template. Admin can override any field. - β
Config.GetTemplateOptions()β helper returns ox_lib-compatible select list, always sorted alphabetically with "No Template" pinned at top.
Critical Fixes:
- β
Multi-purchase race condition (
nil field 'items'crash) βRegisterShopremoved frombuyItemhook entirely. Debounced refresh (100ms) only fires on admin actions. - β
openInventoryrace condition (You can not open this inventory) βopenShopInventorynow performs a synchronousRegisterShopcall inline beforeTriggerClientEvent. Shop is guaranteed registered when client opens it.
Infrastructure:
- β
data/shop_templates.luaadded asshared_scriptinfxmanifest.lua - β
rde_shops:server:applyTemplatecallback β bulkINSERT ... ON DUPLICATE KEY UPDATEwith singlerefreshOxShop()after all items inserted - β
refreshTimersdebounce table β prevents doubleRegisterShopduring rapid admin actions - β
Version bumped to
2.0.0infxmanifest.lua
Critical Fixes:
- Shop inventory now opens correctly β
forceOpenInventoryβOpenInventory - Stable shop IDs replace timestamp spam
- Stock now depletes on purchase
checkAdminPermissioncallback now existsgetTillMoneycallback now existscheckRobberycallback now existscompleteRobberynow returns payout correctlyConfig.Robbery.pedAnimDict/pedAnimNamedefined
Medium Fixes:
- Police alert now sends correct table format
#shopson sparse table βtableCount()- Memory leak on
RegisterShopeliminated SetModelAsNoLongerNeededcalled after ped spawn
Improvements:
refreshOxShop(): live price update after admin edits- StateBag listener for late-join players
ox:playerSpawnedpermission cache reset- NPC raises hands during robbery timer
- Analytics now shows till balance
- Ped cleanup: 20s after death, 60s respawn
###################################################################################
# #
# .:: RED DRAGON ELITE (RDE) - BLACK FLAG SOURCE LICENSE v6.66 ::. #
# #
# PROJECT: RDE ADVANCED SHOP SYSTEM V2.0.0 #
# ARCHITECT: .:: RDE β§ Shin [β³ αα
α±αα
αΎαα αααα
β½] ::. | https://rd-elite.com #
# ORIGIN: https://github.com/RedDragonElite #
# #
# WARNING: THIS CODE IS PROTECTED BY DIGITAL VOODOO AND PURE HATRED FOR LEAKERS #
# #
# [ THE RULES OF THE GAME ] #
# #
# 1. // THE "FUCK GREED" PROTOCOL (FREE USE) #
# You are free to use, edit, and abuse this code on your server. #
# Learn from it. Break it. Fix it. That is the hacker way. #
# Cost: 0.00β¬. If you paid for this, you got scammed by a rat. #
# #
# 2. // THE TEBEX KILL SWITCH (COMMERCIAL SUICIDE) #
# If I find this script on Tebex, Patreon, or in a paid "Premium Pack": #
# > I will DMCA your store into oblivion. #
# > I will publicly shame your community. #
# > I hope your server lag spikes to 9999ms every time you blink. #
# SELLING FREE WORK IS THEFT. AND I AM THE JUDGE. #
# #
# 3. // THE CREDIT OATH #
# Keep this header. If you remove my name, you admit you have no skill. #
# You can add "Edited by [YourName]", but never erase the original creator. #
# Don't be a skid. Respect the architecture. #
# #
# 4. // THE CURSE OF THE COPY-PASTE #
# This code uses StateBags, ox_inventory stashes, and layered callbacks. #
# If you just copy-paste without reading, it WILL break. #
# Don't come crying to my DMs. RTFM or learn to code. #
# #
# -------------------------------------------------------------------------- #
# "We build the future on the graves of paid resources." #
# "REJECT MODERN MEDIOCRITY. EMBRACE RDE SUPERIORITY." #
# -------------------------------------------------------------------------- #
###################################################################################
TL;DR:
- β Free forever β use it, edit it, learn from it
- β Keep the header β credit where it's due
- β Don't sell it β commercial use = instant DMCA
- β Don't be a skid β copy-paste without reading won't work anyway
| π GitHub | RedDragonElite |
| π Website | rd-elite.com |
| π΅ Nostr (RDE) | RedDragonElite |
| π΅ Nostr (Shin) | SerpentsByte |
| π― RDE Props | rde_props |
| πͺ RDE Doors | rde_doors |
| π RDE Car Service | rde_carservice |
When asking for help, always include:
- Full error from server console or txAdmin
- Your
server.cfgresource start order - ox_core / ox_lib / ox_inventory versions in use
"We build the future on the graves of paid resources."
REJECT MODERN MEDIOCRITY. EMBRACE RDE SUPERIORITY.
π Made with π₯ by Red Dragon Elite
