Skip to content

TrapDrugPhone

QBCore NUI Economy

Trap line handset for FiveM: encrypted phone UI, buyer messaging, meet-and-sell flow, police risk scaling, leaderboard, USB charger / battery loop, optional DrugPhone Manager tablet (trapadmin_tablet), and runtime overrides in data/trap_runtime.json.

At a glance

qb-core + oxmysql · No root config.lua — defaults in shared/trap_defaults.lua, live data in data/*.json (Manager writes trap_runtime.json) · resource fxmanifest name TrapDrugPhone — keep your ensure folder name consistent with that

Buy license — Tebex · Support Discord · TrapDrugPhone — YouTube · YouTube @XVisonMods

Still stuck after Dependencies / Notes? Open a ticket in Discord with your ensure order and any client / server error lines.

Preview

Showcase · TrapDrugPhone

Direct link: youtu.be/4v0Z9eoQCpQ

Framework support

Supported. Add all items below to qb-core/shared/items.lua and/or ox_inventory as listed on this page.

TrapDrugPhone ships for qb-core. ESX servers should use scripts documented on the ESX page instead.

Coming soon on the broader docs site — this resource targets QBCore today.

Features

  • Usable trap handsets (Config.Phone.PhoneVariants in shared/phone_variants.lua) + usb_charger + trapadmin_tablet
  • NUI phone shell (html/), shop clerk (client/phone_shop.lua / server/shop_ped.lua), meet scene (client/meet_scene.lua)
  • Negotiation / conversation server modules, police job count → risk (Config.Police), sale dispatch for configured jobs
  • Leaderboard file (Config.LeaderboardFile, default trapdrugphone_leaderboard.json) + optional DB helper (server/leaderboard_db.lua)
  • DrugPhone Manager saves data/trap_runtime.json (shop coords, drugs, contacts, extraction time, battery knobs, etc.)

Dependencies

  • qb-core (required)
  • oxmysql (required — server/main.lua load order includes @oxmysql/lib/MySQL.lua)

Common stacks also run qb-inventory or ox_inventory; the script picks an image host on startup via server/inventory_bridge.lua. Tune Config.ItemImageBase in shared/trap_defaults.lua if your inventory path differs.

Permissions (ACE)

The permission string is exactly:

trapdrugphone.admin

It is referenced in shared/trap_defaults.lua as Config.AdminAce = 'trapdrugphone.admin' and in the trapadmin_tablet item description. Players need this ACE to use DrugPhone Manager from the tablet item.

Copy-paste — server.cfg (or your ACE / permissions resource) — pick one pattern; change group.admin or the identifier to match how you run permissions:

# DrugPhone Manager — full access (same string as Config.AdminAce)
add_ace group.admin trapdrugphone.admin allow

Copy-paste — grant by FiveM identifier (replace with a real license / discord / fivem id):

add_ace identifier.license:0000000000000000000000000000000000000000 trapdrugphone.admin allow

Copy-paste — grant by QB permission group (if you use qb-core permission groups that map to ACE):

add_ace qbcore.god trapdrugphone.admin allow
add_ace qbcore.admin trapdrugphone.admin allow

Restart the server (or refresh ACEs) after editing.

Inventory items

Merge these into your framework items file. Restart qb-core after editing items.lua, then restart TrapDrugPhone. For ox_inventory, restart ox_inventory (or the server) after editing data/items.lua.

Images (qb-inventory)

Filenames below (trap_phone.png, usbcharger.png, tablet.png) must exist under your inventory images folder or change every ['image'] to match your pack.

qb-core — qb-core/shared/items.lua

Handset variants (item names match shared/phone_variants.lua):

['scrlt_iphone17_01'] = { ['name'] = 'scrlt_iphone17_01', ['label'] = 'iPhone 17 Black', ['weight'] = 200, ['type'] = 'item', ['image'] = 'trap_phone.png', ['unique'] = false, ['useable'] = true, ['shouldClose'] = true, ['combinable'] = nil, ['description'] = 'Trap line handset.' },
['scrlt_iphone17_02'] = { ['name'] = 'scrlt_iphone17_02', ['label'] = 'iPhone 17 White', ['weight'] = 200, ['type'] = 'item', ['image'] = 'trap_phone.png', ['unique'] = false, ['useable'] = true, ['shouldClose'] = true, ['combinable'] = nil, ['description'] = 'Trap line handset.' },
['scrlt_iphone17_03'] = { ['name'] = 'scrlt_iphone17_03', ['label'] = 'iPhone 17 Steel Gray', ['weight'] = 200, ['type'] = 'item', ['image'] = 'trap_phone.png', ['unique'] = false, ['useable'] = true, ['shouldClose'] = true, ['combinable'] = nil, ['description'] = 'Trap line handset.' },
['scrlt_iphone17_04'] = { ['name'] = 'scrlt_iphone17_04', ['label'] = 'iPhone 17 Green', ['weight'] = 200, ['type'] = 'item', ['image'] = 'trap_phone.png', ['unique'] = false, ['useable'] = true, ['shouldClose'] = true, ['combinable'] = nil, ['description'] = 'Trap line handset.' },
['scrlt_iphone17_05'] = { ['name'] = 'scrlt_iphone17_05', ['label'] = 'iPhone 17 Purple', ['weight'] = 200, ['type'] = 'item', ['image'] = 'trap_phone.png', ['unique'] = false, ['useable'] = true, ['shouldClose'] = true, ['combinable'] = nil, ['description'] = 'Trap line handset.' },
['scrlt_iphone17_06'] = { ['name'] = 'scrlt_iphone17_06', ['label'] = 'iPhone 17 Light Blue', ['weight'] = 200, ['type'] = 'item', ['image'] = 'trap_phone.png', ['unique'] = false, ['useable'] = true, ['shouldClose'] = true, ['combinable'] = nil, ['description'] = 'Trap line handset.' },
['scrlt_iphone17pro_01'] = { ['name'] = 'scrlt_iphone17pro_01', ['label'] = 'iPhone 17 Pro Black', ['weight'] = 200, ['type'] = 'item', ['image'] = 'trap_phone.png', ['unique'] = false, ['useable'] = true, ['shouldClose'] = true, ['combinable'] = nil, ['description'] = 'Trap line handset.' },
['scrlt_iphone17pro_02'] = { ['name'] = 'scrlt_iphone17pro_02', ['label'] = 'iPhone 17 Pro White', ['weight'] = 200, ['type'] = 'item', ['image'] = 'trap_phone.png', ['unique'] = false, ['useable'] = true, ['shouldClose'] = true, ['combinable'] = nil, ['description'] = 'Trap line handset.' },
['scrlt_iphone17pro_03'] = { ['name'] = 'scrlt_iphone17pro_03', ['label'] = 'iPhone 17 Pro Gray', ['weight'] = 200, ['type'] = 'item', ['image'] = 'trap_phone.png', ['unique'] = false, ['useable'] = true, ['shouldClose'] = true, ['combinable'] = nil, ['description'] = 'Trap line handset.' },
['scrlt_iphone17pro_04'] = { ['name'] = 'scrlt_iphone17pro_04', ['label'] = 'iPhone 17 Pro Dark Blue', ['weight'] = 200, ['type'] = 'item', ['image'] = 'trap_phone.png', ['unique'] = false, ['useable'] = true, ['shouldClose'] = true, ['combinable'] = nil, ['description'] = 'Trap line handset.' },
['scrlt_iphone17pro_05'] = { ['name'] = 'scrlt_iphone17pro_05', ['label'] = 'iPhone 17 Pro Orange', ['weight'] = 200, ['type'] = 'item', ['image'] = 'trap_phone.png', ['unique'] = false, ['useable'] = true, ['shouldClose'] = true, ['combinable'] = nil, ['description'] = 'Trap line handset.' },
['scrlt_iphone17air_01'] = { ['name'] = 'scrlt_iphone17air_01', ['label'] = 'iPhone 17 Air Black', ['weight'] = 200, ['type'] = 'item', ['image'] = 'trap_phone.png', ['unique'] = false, ['useable'] = true, ['shouldClose'] = true, ['combinable'] = nil, ['description'] = 'Trap line handset.' },
['scrlt_iphone17air_02'] = { ['name'] = 'scrlt_iphone17air_02', ['label'] = 'iPhone 17 Air White', ['weight'] = 200, ['type'] = 'item', ['image'] = 'trap_phone.png', ['unique'] = false, ['useable'] = true, ['shouldClose'] = true, ['combinable'] = nil, ['description'] = 'Trap line handset.' },
['scrlt_iphone17air_03'] = { ['name'] = 'scrlt_iphone17air_03', ['label'] = 'iPhone 17 Air Light Gold', ['weight'] = 200, ['type'] = 'item', ['image'] = 'trap_phone.png', ['unique'] = false, ['useable'] = true, ['shouldClose'] = true, ['combinable'] = nil, ['description'] = 'Trap line handset.' },
['scrlt_iphone17air_04'] = { ['name'] = 'scrlt_iphone17air_04', ['label'] = 'iPhone 17 Air Light Blue', ['weight'] = 200, ['type'] = 'item', ['image'] = 'trap_phone.png', ['unique'] = false, ['useable'] = true, ['shouldClose'] = true, ['combinable'] = nil, ['description'] = 'Trap line handset.' },
['scrlt_ifruit17_01'] = { ['name'] = 'scrlt_ifruit17_01', ['label'] = 'iFruit 17 Black', ['weight'] = 200, ['type'] = 'item', ['image'] = 'trap_phone.png', ['unique'] = false, ['useable'] = true, ['shouldClose'] = true, ['combinable'] = nil, ['description'] = 'Trap line handset.' },
['scrlt_ifruit17_02'] = { ['name'] = 'scrlt_ifruit17_02', ['label'] = 'iFruit 17 White', ['weight'] = 200, ['type'] = 'item', ['image'] = 'trap_phone.png', ['unique'] = false, ['useable'] = true, ['shouldClose'] = true, ['combinable'] = nil, ['description'] = 'Trap line handset.' },
['scrlt_ifruit17_03'] = { ['name'] = 'scrlt_ifruit17_03', ['label'] = 'iFruit 17 Steel Gray', ['weight'] = 200, ['type'] = 'item', ['image'] = 'trap_phone.png', ['unique'] = false, ['useable'] = true, ['shouldClose'] = true, ['combinable'] = nil, ['description'] = 'Trap line handset.' },
['scrlt_ifruit17_04'] = { ['name'] = 'scrlt_ifruit17_04', ['label'] = 'iFruit 17 Green', ['weight'] = 200, ['type'] = 'item', ['image'] = 'trap_phone.png', ['unique'] = false, ['useable'] = true, ['shouldClose'] = true, ['combinable'] = nil, ['description'] = 'Trap line handset.' },
['scrlt_ifruit17_05'] = { ['name'] = 'scrlt_ifruit17_05', ['label'] = 'iFruit 17 Purple', ['weight'] = 200, ['type'] = 'item', ['image'] = 'trap_phone.png', ['unique'] = false, ['useable'] = true, ['shouldClose'] = true, ['combinable'] = nil, ['description'] = 'Trap line handset.' },
['scrlt_ifruit17_06'] = { ['name'] = 'scrlt_ifruit17_06', ['label'] = 'iFruit 17 Light Blue', ['weight'] = 200, ['type'] = 'item', ['image'] = 'trap_phone.png', ['unique'] = false, ['useable'] = true, ['shouldClose'] = true, ['combinable'] = nil, ['description'] = 'Trap line handset.' },
['scrlt_ifruit17pro_01'] = { ['name'] = 'scrlt_ifruit17pro_01', ['label'] = 'iFruit 17 Pro Black', ['weight'] = 200, ['type'] = 'item', ['image'] = 'trap_phone.png', ['unique'] = false, ['useable'] = true, ['shouldClose'] = true, ['combinable'] = nil, ['description'] = 'Trap line handset.' },
['scrlt_ifruit17pro_02'] = { ['name'] = 'scrlt_ifruit17pro_02', ['label'] = 'iFruit 17 Pro White', ['weight'] = 200, ['type'] = 'item', ['image'] = 'trap_phone.png', ['unique'] = false, ['useable'] = true, ['shouldClose'] = true, ['combinable'] = nil, ['description'] = 'Trap line handset.' },
['scrlt_ifruit17pro_03'] = { ['name'] = 'scrlt_ifruit17pro_03', ['label'] = 'iFruit 17 Pro Gray', ['weight'] = 200, ['type'] = 'item', ['image'] = 'trap_phone.png', ['unique'] = false, ['useable'] = true, ['shouldClose'] = true, ['combinable'] = nil, ['description'] = 'Trap line handset.' },
['scrlt_ifruit17pro_04'] = { ['name'] = 'scrlt_ifruit17pro_04', ['label'] = 'iFruit 17 Pro Dark Blue', ['weight'] = 200, ['type'] = 'item', ['image'] = 'trap_phone.png', ['unique'] = false, ['useable'] = true, ['shouldClose'] = true, ['combinable'] = nil, ['description'] = 'Trap line handset.' },
['scrlt_ifruit17pro_05'] = { ['name'] = 'scrlt_ifruit17pro_05', ['label'] = 'iFruit 17 Pro Orange', ['weight'] = 200, ['type'] = 'item', ['image'] = 'trap_phone.png', ['unique'] = false, ['useable'] = true, ['shouldClose'] = true, ['combinable'] = nil, ['description'] = 'Trap line handset.' },
['scrlt_ifruit17air_01'] = { ['name'] = 'scrlt_ifruit17air_01', ['label'] = 'iFruit 17 Air Black', ['weight'] = 200, ['type'] = 'item', ['image'] = 'trap_phone.png', ['unique'] = false, ['useable'] = true, ['shouldClose'] = true, ['combinable'] = nil, ['description'] = 'Trap line handset.' },
['scrlt_ifruit17air_02'] = { ['name'] = 'scrlt_ifruit17air_02', ['label'] = 'iFruit 17 Air White', ['weight'] = 200, ['type'] = 'item', ['image'] = 'trap_phone.png', ['unique'] = false, ['useable'] = true, ['shouldClose'] = true, ['combinable'] = nil, ['description'] = 'Trap line handset.' },
['scrlt_ifruit17air_03'] = { ['name'] = 'scrlt_ifruit17air_03', ['label'] = 'iFruit 17 Air Light Gold', ['weight'] = 200, ['type'] = 'item', ['image'] = 'trap_phone.png', ['unique'] = false, ['useable'] = true, ['shouldClose'] = true, ['combinable'] = nil, ['description'] = 'Trap line handset.' },
['scrlt_ifruit17air_04'] = { ['name'] = 'scrlt_ifruit17air_04', ['label'] = 'iFruit 17 Air Light Blue', ['weight'] = 200, ['type'] = 'item', ['image'] = 'trap_phone.png', ['unique'] = false, ['useable'] = true, ['shouldClose'] = true, ['combinable'] = nil, ['description'] = 'Trap line handset.' },

Charger and DrugPhone Manager tablet (ACE: trapdrugphone.admin in tablet description — grant that ACE from Permissions (ACE) above):

['usb_charger'] = {
    ['name'] = 'usb_charger',
    ['label'] = 'USB Charger',
    ['weight'] = 80,
    ['type'] = 'item',
    ['image'] = 'usbcharger.png',
    ['unique'] = false,
    ['useable'] = true,
    ['shouldClose'] = true,
    ['combinable'] = nil,
    ['description'] = 'Powers the trap phone while carried. Can burn out.',
},

['trapadmin_tablet'] = {
    ['name'] = 'trapadmin_tablet',
    ['label'] = 'DrugPhone Manager',
    ['weight'] = 500,
    ['type'] = 'item',
    ['image'] = 'tablet.png',
    ['unique'] = false,
    ['useable'] = true,
    ['shouldClose'] = true,
    ['combinable'] = nil,
    ['description'] = 'Trap line admin tablet. ACE: trapdrugphone.admin',
},

ox_inventory — ox_inventory/data/items.lua

Add icons under your inventory web/images (or your configured path) with filenames matching what you use in item metadata if applicable. Item names must match shared/phone_variants.lua.

['usb_charger'] = {
    label = 'USB Charger',
    weight = 80,
    stack = false,
    close = true,
    description = 'Powers the trap phone while carried. Can burn out.',
},

['trapadmin_tablet'] = {
    label = 'DrugPhone Manager',
    weight = 500,
    stack = false,
    close = true,
    description = 'Trap line admin tablet. ACE: trapdrugphone.admin',
},

['scrlt_iphone17_01'] = { label = 'iPhone 17 Black', weight = 200, stack = false, close = true, description = 'Trap line handset.' },
['scrlt_iphone17_02'] = { label = 'iPhone 17 White', weight = 200, stack = false, close = true, description = 'Trap line handset.' },
['scrlt_iphone17_03'] = { label = 'iPhone 17 Steel Gray', weight = 200, stack = false, close = true, description = 'Trap line handset.' },
['scrlt_iphone17_04'] = { label = 'iPhone 17 Green', weight = 200, stack = false, close = true, description = 'Trap line handset.' },
['scrlt_iphone17_05'] = { label = 'iPhone 17 Purple', weight = 200, stack = false, close = true, description = 'Trap line handset.' },
['scrlt_iphone17_06'] = { label = 'iPhone 17 Light Blue', weight = 200, stack = false, close = true, description = 'Trap line handset.' },
['scrlt_iphone17pro_01'] = { label = 'iPhone 17 Pro Black', weight = 200, stack = false, close = true, description = 'Trap line handset.' },
['scrlt_iphone17pro_02'] = { label = 'iPhone 17 Pro White', weight = 200, stack = false, close = true, description = 'Trap line handset.' },
['scrlt_iphone17pro_03'] = { label = 'iPhone 17 Pro Gray', weight = 200, stack = false, close = true, description = 'Trap line handset.' },
['scrlt_iphone17pro_04'] = { label = 'iPhone 17 Pro Dark Blue', weight = 200, stack = false, close = true, description = 'Trap line handset.' },
['scrlt_iphone17pro_05'] = { label = 'iPhone 17 Pro Orange', weight = 200, stack = false, close = true, description = 'Trap line handset.' },
['scrlt_iphone17air_01'] = { label = 'iPhone 17 Air Black', weight = 200, stack = false, close = true, description = 'Trap line handset.' },
['scrlt_iphone17air_02'] = { label = 'iPhone 17 Air White', weight = 200, stack = false, close = true, description = 'Trap line handset.' },
['scrlt_iphone17air_03'] = { label = 'iPhone 17 Air Light Gold', weight = 200, stack = false, close = true, description = 'Trap line handset.' },
['scrlt_iphone17air_04'] = { label = 'iPhone 17 Air Light Blue', weight = 200, stack = false, close = true, description = 'Trap line handset.' },
['scrlt_ifruit17_01'] = { label = 'iFruit 17 Black', weight = 200, stack = false, close = true, description = 'Trap line handset.' },
['scrlt_ifruit17_02'] = { label = 'iFruit 17 White', weight = 200, stack = false, close = true, description = 'Trap line handset.' },
['scrlt_ifruit17_03'] = { label = 'iFruit 17 Steel Gray', weight = 200, stack = false, close = true, description = 'Trap line handset.' },
['scrlt_ifruit17_04'] = { label = 'iFruit 17 Green', weight = 200, stack = false, close = true, description = 'Trap line handset.' },
['scrlt_ifruit17_05'] = { label = 'iFruit 17 Purple', weight = 200, stack = false, close = true, description = 'Trap line handset.' },
['scrlt_ifruit17_06'] = { label = 'iFruit 17 Light Blue', weight = 200, stack = false, close = true, description = 'Trap line handset.' },
['scrlt_ifruit17pro_01'] = { label = 'iFruit 17 Pro Black', weight = 200, stack = false, close = true, description = 'Trap line handset.' },
['scrlt_ifruit17pro_02'] = { label = 'iFruit 17 Pro White', weight = 200, stack = false, close = true, description = 'Trap line handset.' },
['scrlt_ifruit17pro_03'] = { label = 'iFruit 17 Pro Gray', weight = 200, stack = false, close = true, description = 'Trap line handset.' },
['scrlt_ifruit17pro_04'] = { label = 'iFruit 17 Pro Dark Blue', weight = 200, stack = false, close = true, description = 'Trap line handset.' },
['scrlt_ifruit17pro_05'] = { label = 'iFruit 17 Pro Orange', weight = 200, stack = false, close = true, description = 'Trap line handset.' },
['scrlt_ifruit17air_01'] = { label = 'iFruit 17 Air Black', weight = 200, stack = false, close = true, description = 'Trap line handset.' },
['scrlt_ifruit17air_02'] = { label = 'iFruit 17 Air White', weight = 200, stack = false, close = true, description = 'Trap line handset.' },
['scrlt_ifruit17air_03'] = { label = 'iFruit 17 Air Light Gold', weight = 200, stack = false, close = true, description = 'Trap line handset.' },
['scrlt_ifruit17air_04'] = { label = 'iFruit 17 Air Light Blue', weight = 200, stack = false, close = true, description = 'Trap line handset.' },

Installation

Steps

  1. Place the resource folder under resources/[...]/ (name it the same as in server.cfg, e.g. TrapDrugPhone).
  2. Add Permissions (ACE) and Inventory items from this page (qb and/or ox).
  3. Start the resource.

Notes

  • Version 1.0.0 in fxmanifest.lua.