How Integrations Work#
Nothing inside Shops Creator is written against one framework or one inventory. Every third-party resource is reached through a small bridge file, and the right bridge is picked at start-up by looking at which resources are already running. The bridges are not encrypted, so they can be read and adapted.
Layer | Supported | Without it |
|---|---|---|
Framework |
| Required. Qbox reuses the QBCore bridge. |
Inventory |
| Standalone mode: no item list in the creator and a console warning on every start. Not for a live server. |
Target |
| Players press |
Societies |
| Revenue sharing with a job account does nothing. |
Gangs | Framework gangs (QBCore / Qbox) · | Gang restrictions are skipped. |
Progress bars · HUD |
|
|
3D text · text UI |
| Built-in 3D text and |
Log screenshots |
| Logs are sent without a screenshot. |
Database |
| Required. |
Frameworks#
The framework is detected from the resource that is running and loaded from custom/esx/ or custom/qb/. Each bridge answers the same questions — who is this player, what job and grade do they have, how much money is in an account, add or remove an item — so the rest of the script never has to know which framework it is on.
ESX | QBCore | Qbox | |
|---|---|---|---|
Identifier |
|
|
|
Admins | Groups | Permissions | Same as QBCore |
| Cash account |
|
|
| Black money account |
|
|
Gangs |
| Built in | Built in |
If you renamed your framework resource, add its new folder name to the frameworks table at the top of config/main.lua:
local frameworks = {
['es_extended'] = 'esx',
['qb-core'] = 'qb',
['qbx_core'] = 'qb',
['my-core'] = 'qb', -- a renamed QBCore
}Inventories#
The inventory bridge does two jobs: it builds the item list the creator offers — names, labels and pictures — and it reads the player's inventory when they sell items or deposit stock. Pictures come straight from your inventory's own image folder, so every item already has its icon.
Inventory | Pictures read from |
|---|---|
|
|
| The |
|
|
|
|
|
|
|
|
|
|
If your images live somewhere else, change the path at the top of the matching file in server/custom/inventory/. A renamed inventory is added to the inventories table in config/main.lua, exactly like a framework.
Adding another inventory#
Copy the closest file in server/custom/inventory/ — qb.lua for a QBCore-style inventory, ox.lua for an ox-style one — rename it, change the guard at the top and the image path, and add your resource to the inventories table in config/main.lua:
-- server/custom/inventory/my_inventory.lua
if Config.Inventory ~= 'my_inventory' then
return
end
sv_inventory.imagePath = 'nui://my_inventory/html/images/'
function sv_inventory:formatItemList()
local itemList = sfr:getItemList()
for _, v in pairs(itemList) do
v.image = self.imagePath .. (v.image or 'default.png')
end
return itemList
endTargets and Interaction#
With Config.UseTarget = false — the default — players walk into the shop's zone and get a 3D prompt on the shopkeeper: Press [E] to access the shop, Press [E] to sell items on a sell shop, and Press [E] to access the boss menu on an owned shop's management point.
With Config.UseTarget = true, the same points become target zones on ox_target or qb-target, whichever is running:
-- config/main.lua
Config.UseTarget = true
Config.TargetWidth = 5.0 -- interaction zone width
Config.TargetHeight = 5.0 -- interaction zone heightThe zones are only created while a player is inside the shop's area, so hundreds of shops cost nothing to players far away. While a shop is closed by its opening hours, the prompt is replaced by a countdown — Opens in 2h 15m — and the shopkeeper leaves until opening time.
Societies and Gangs#
A shop can send a percentage of every sale to one or more job accounts — the police account gets 10% of the Ammu-Nation, the city 5% of everything. On a sell shop it works the other way: the listed societies fund their share of what is paid to the player, and the sale is refused if a society cannot afford it.
Framework | Society backends, in order |
|---|---|
ESX |
|
QBCore / Qbox |
|
The backends live in server/custom/society/. To use another banking resource, fill in the three functions — addMoney, getMoney and removeMoney — in a copy of the closest file.
Gang restrictions read QBCore and Qbox gangs natively. On ESX they need qs-gangs; without it, a shop locked to a gang is open to everybody.
Payment Methods#
Payment methods are your framework's accounts. Two lists in config/main.lua decide which ones exist:
-- What a shop accepts until the creator picks something else for it
Config.DefaultMoneyType = {
{ label = 'Money', value = 'money' },
{ label = 'Bank', value = 'bank' },
}
-- Every method the creator may choose from
Config.CreatorMoneyTypes = {
{ label = 'Money', value = 'money' },
{ label = 'Bank', value = 'bank' },
{ label = 'Black Money', value = 'black_money' },
}value is the account name your framework understands. On QBCore, money is translated to cash automatically. Each store then picks which of these it accepts in the creator, and the server refuses a payment in any method the shop does not accept.
Notifications, Text and Progress#
Every message the script shows goes through one function, Notification, in custom/client.lua. By default it uses the script's own toasts, styled like its windows. Commented-out examples for qs-interface and ox_lib sit in the same function — uncomment the one you want, or call your own notification resource there.
-- custom/client.lua
function Notification(msg, type)
-- exports['qs-interface']:AddNotify(msg, 'Inform', 5000, 'fas fa-file')
-- lib.notify({ title = 'Shops', description = msg, type = type })
SendReactMessage('notification', { msg = msg, type = type })
endThe same file holds the 3D text (qs-textui when it is running), the progress bar (qs-interface, otherwise ox_lib) and ToggleHud, which hides the radar and the qs-interface HUD while a shop or menu is open. Add your own HUD's export inside ToggleHud to hide it too.
Discord Logs#
Everything that matters is posted to Discord as an embed with the player's name, server id and identifiers (Steam, Discord, license). Paste one webhook per category in server/webhooks.lua; a category left empty is simply not sent.
-- server/webhooks.lua
_G['webhook'] = {
creator = '', -- shops created, updated and deleted
bossmenu = '', -- shops bought and sold by players
checkout = '', -- every purchase in a store
sell = '', -- every sale to a sell shop
templates = '', -- templates created, deleted and imported
bossmenu_operations = '', -- employees, permissions, stock, money, promotions
}
_G['fivemanage'] = {
webhook = '', -- a Fivemanage token, to attach screenshots
}Languages#
41 translations ship in locales/: Arabic, Bulgarian, Bengali, Catalan, Czech, Danish, German, Greek, English, Spanish, Estonian, Persian, Finnish, French, Hebrew, Hindi, Croatian, Hungarian, Indonesian, Italian, Japanese, Korean, Lithuanian, Latvian, Malay, Dutch, Norwegian, Polish, Portuguese, Romanian, Russian, Slovak, Slovenian, Swedish, Swahili, Thai, Turkish, Ukrainian, Urdu, Vietnamese and Chinese.
Set the code in config/main.lua:
Config.Locale = 'es'To add another language, copy locales/en.json to locales/<code>.json, translate the texts and set Config.Locale to that code. The same file translates the interface, the in-game prompts and the Discord logs.
How prices look is a separate, visual setting — Config.Intl uses the browser's number formatting, so pt-BR with BRL shows R$ 1.000 and de-DE with EUR shows 1.000 €.



