ScriptsM Marketplace

ScriptsM Marketplace

SM Marketplace is a complete player-to-player trading system

Players can browse listings, compare offers, and buy or sell items, vehicles, and properties through one modern marketplace. Sellers can choose their price, add a description, set the listing duration, and take real in-game photos of vehicles and properties.

After a purchase, the system handles the payment and transfers the item, vehicle, or property to the buyer automatically. Server owners can control listing fees, restrict what can be sold, manage marketplace activity, and connect the script to popular frameworks, inventories, garages, and housing systems.

Installation

Download the resource and place SM-MARKETPLACE inside your server resources folder

Import the SQL file

Import:

SM-MARKETPLACE/sm_marketplace.sql

Check dependencies

Required:

oxmysql
screenshot-basic

Supported frameworks:

es_extended
qb-core
qbx_core

Supported inventories:

ox_inventory
qb-inventory
qs-inventory 
ps-inventory
codem-inventory

Supported target systems:

ox_target
qb-target
qtarget

Resource start order

Make sure your resources start in a logical order:

start oxmysql
start screenshot-basic
start [your framework]
start [your inventory]
start [your target]
start SM-MARKETPLACE

Add the resource to server.cfg

ensure SM-MARKETPLACE

Config

All main settings are inside:

SM-MARKETPLACE/config.lua
Config = Config or {}
-- Turn this on if you need extra logs in console while looking for a problem.
Config.Debug = false
-- Language of the marketplace UI. The file must exist in locales/.
Config.Locale = 'en'
 
-- Core integrations used by the marketplace.
-- Keep a value set to 'auto' to detect the running resource automatically,
-- or set it explicitly if more than one compatible resource is installed.
Config.Integrations = {
    -- auto, esx, qbcore, qbox or standalone
    Framework = 'auto',
    -- auto, ox_inventory, qb-inventory, qs-inventory, ps-inventory,
    -- codem-inventory or framework
    Inventory = 'auto',
    -- auto, ox_target, qb-target, qtarget or none
    Target = 'auto',
}
 
-- Seller contact settings shown inside listings.
Config.SellerContact = {
    Phone = {
        -- Show seller phone numbers in listings when they can be found.
        Enabled = true,
        -- If your phone script has its own export for getting numbers, set it here.
        -- This is checked first.
        Export = {
            Resource = '',
            Name = '',
            -- source, license, citizenid, esx_identifier, character or none
            Argument = 'source',
            -- If the export returns a table, put the phone field name here.
            -- Leave empty to auto-detect common field names.
            ReturnField = '',
        },
        -- If phone numbers are stored in your own table, fill it here.
        -- Leave empty to use the built-in fallback checks.
        Database = {
            Table = '',
            OwnerColumn = '',
            PhoneColumn = '',
            -- Which ID should be used to find the owner:
            -- character = character ID, license = player/account ID
            OwnerType = 'character',
        },
    },
}
 
-- How players open the marketplace.
Config.Opening = {
    Tablet = {
        -- Open through the tablet screen instead of opening the UI instantly.
        Enabled = true,
    },
    Command = {
        -- Chat command for opening the marketplace.
        Enabled = true,
        Name = 'market',
        -- tablet or marketplace
        Target = 'tablet',
    },
    Keybind = {
        -- Keybind that opens the marketplace.
        Enabled = true,
        Description = 'Open marketplace',
        -- Any FiveM key name, for example F5, F6, F7 or HOME.
        Key = 'F6',
    },
}
 
-- Who can use the admin panel.
Config.Admin = {
    -- ACE permission for admin access.
    AcePermission = 'sm_marketplace.admin',
    -- Framework groups that should also have admin access.
    FrameworkGroups = {
        admin = true,
        superadmin = true,
        god = true,
    },
}
 
-- Optional Discord webhook for marketplace events.
Config.Discord = {
    Enabled = false,
    Webhook = '',
    Username = 'SM Marketplace',
    AvatarUrl = '',
}
 
-- Main marketplace economy settings.
Config.Marketplace = {
    -- player = one shared marketplace for the whole account.
    -- character = each character has its own separate marketplace.
    OwnerMode = 'character',
    -- Account used when buyers pay for items.
    DefaultBuyAccount = 'bank',
    -- Account where sellers receive their money.
    DefaultSellerPayoutAccount = 'bank',
    Fees = {
        -- Listing fee per hour for each type.
        ByAssetType = {
            item = 21,
            vehicle = 40,
            property = 80,
        },
    },
    ListingHours = {
        -- Allowed listing time range in hours.
        Min = 1,
        Default = 24,
        Max = 120,
    },
}
 
-- Anything added here cannot be listed on the marketplace.
Config.Blacklist = {
    Items = {
        -- money = true,
        -- black_money = true,
    },
    Vehicles = {
        -- Plate or model name/hash, for example:
        -- police = true,
        -- ['POLICE1'] = true,
    },
    Properties = {
        -- property id/name
    },
}
 
-- Which category opens first in the catalog.
Config.UI = {
    DefaultCategory = 'items',
}
 
-- Storage settings and storage locations.
Config.Storage = {
    -- How close players must be to use storage.
    InteractDistance = 2.0,
    MarkerDrawDistance = 20.0,
    Prompt = '[E] Open storage',
    Interaction = {
        -- auto: use target if available, otherwise use text prompts.
        -- You can also force: target, framework or gta.
        Mode = 'auto',
        TargetIcon = 'fas fa-box-archive',
        TargetLabel = 'Open storage',
    },
    Blip = {
        -- Map blip settings for storage.
        Enabled = true,
        Sprite = 478,
        Color = 2,
        Scale = 0.8,
        Label = 'Marketplace Storage',
    },
    Marker = {
        -- 3D marker settings for storage.
        Enabled = true,
        Type = 1,
        Size = { x = 1.0, y = 1.0, z = 0.55 },
        Color = { r = 155, g = 185, b = 255, a = 170 },
        Bob = false,
        FaceCamera = false,
    },
    Locations = {
        -- Add as many storage locations as you want.
        {
            label = 'Marketplace Storage',
            coords = vector3(62.87, 124.68, 79.19),
        },
        {
            label = 'Marketplace Storage',
            coords = vector3(-439.71, 6143.81, 31.48),
        },
    },
}
 
-- Connect the marketplace to your vehicle and property scripts.
Config.Bridges = {
    Vehicles = {
        -- Use auto to let the script detect your vehicle system automatically.
        Active = 'auto',
        Adapters = {
            -- Presets for common vehicle ownership scripts.
            esx_owned_vehicles = {
                resource = 'es_extended',
                tables = { 'owned_vehicles', 'owner_vehicles' },
                ownerColumn = 'owner',
                ownerType = 'esx_identifier',
                plateColumn = 'plate',
                vehicleDataColumn = 'vehicle',
                label = 'ESX Owned Vehicles',
            },
            qb_player_vehicles = {
                resource = 'qb-core',
                table = 'player_vehicles',
                ownerColumn = 'citizenid',
                ownerType = 'citizenid',
                plateColumn = 'plate',
                modelColumn = 'vehicle',
                vehicleDataColumn = 'mods',
                label = 'QBCore Player Vehicles',
            },
            qbox_player_vehicles = {
                resource = 'qbx_vehicles',
                table = 'player_vehicles',
                ownerColumn = 'citizenid',
                ownerType = 'citizenid',
                plateColumn = 'plate',
                modelColumn = 'vehicle',
                vehicleDataColumn = 'mods',
                label = 'Qbox Player Vehicles',
            },
            qs_advancedgarages = {
                resource = 'qs-advancedgarages',
                table = 'player_vehicles',
                ownerColumn = 'citizenid',
                ownerType = 'citizenid',
                plateColumn = 'plate',
                modelColumn = 'vehicle',
                vehicleDataColumn = 'mods',
                label = 'QS Advanced Garages',
            },
            cd_garage = {
                resource = 'cd_garage',
                table = 'owned_vehicles',
                ownerColumn = 'owner',
                ownerType = 'identifier',
                plateColumn = 'plate',
                vehicleDataColumn = 'vehicle',
                label = 'CD Garage',
            },
            okok_garage = {
                resource = 'okokGarage',
                table = 'owned_vehicles',
                ownerColumn = 'owner',
                ownerType = 'identifier',
                plateColumn = 'plate',
                vehicleDataColumn = 'vehicle',
                label = 'OkOk Garage',
            },
            jg_advancedgarages = {
                resource = 'jg-advancedgarages',
                table = 'player_vehicles',
                ownerColumn = 'citizenid',
                ownerType = 'citizenid',
                plateColumn = 'plate',
                modelColumn = 'vehicle',
                vehicleDataColumn = 'mods',
                label = 'JG Advanced Garages',
            },
        },
    },
    Housing = {
        -- Use auto to let the script detect your property system automatically.
        Active = 'esx_property',
        Adapters = {
            -- Presets for common housing/property scripts.
            esx_property = {
                resource = 'esx_property',
                table = 'esx_properties',
                ownerColumn = 'owner',
                ownerType = 'esx_identifier',
                propertyIdColumn = 'id',
                ownershipExport = 'GetMarketplacePlayerProperties',
                transferExport = 'SetMarketplacePropertyOwner',
                label = 'ESX Property',
            },
            qb_houses = {
                resource = 'qb-houses',
                table = 'player_houses',
                ownerColumn = 'citizenid',
                ownerType = 'citizenid',
                propertyIdColumn = 'house',
                resetColumns = {
                    keyholders = '[]',
                },
                label = 'QB Houses',
            },
            qbox_properties = {
                resource = 'qbx_properties',
                table = 'properties',
                ownerColumn = 'owner',
                ownerType = 'citizenid',
                propertyIdColumn = 'id',
                resetColumns = {
                    keyholders = '{}',
                },
                label = 'Qbox Properties',
            },
            ps_housing = {
                resource = 'ps-housing',
                table = 'properties',
                ownerColumn = 'owner_citizenid',
                ownerType = 'citizenid',
                propertyIdColumn = 'property_id',
                resetColumns = {
                    has_access = '[]',
                    keyholders = '[]',
                },
                label = 'PS Housing',
            },
            qs_housing = {
                resource = 'qs-housing',
                tables = { 'player_houses', 'qs_player_houses', 'houselocations' },
                ownerColumn = 'citizenid',
                ownerType = 'citizenid',
                propertyIdColumn = 'house',
                resetColumns = {
                    keyholders = '[]',
                },
                label = 'QS Housing',
            },
            vms_housing = {
                resource = 'vms_housing',
                table = 'houses',
                ownerColumn = 'owner',
                ownerType = 'identifier',
                propertyIdColumn = 'id',
                resetColumns = {
                    keys = '[]',
                },
                label = 'VMS Housing',
            },
            rtx_housing = {
                resource = 'rtx_housing',
                table = 'rtx_housing',
                ownerColumn = 'owner',
                ownerType = 'identifier',
                propertyIdColumn = 'id',
                resetColumns = {
                    keyholders = '[]',
                },
                label = 'RTX Housing',
            },
            bcs_housing = {
                resource = 'bcs_housing',
                table = 'properties',
                ownerColumn = 'owner',
                ownerType = 'citizenid',
                propertyIdColumn = 'identifier',
                resetColumns = {
                    keyholders = '[]',
                    permissions = '[]',
                },
                label = 'BCS Housing',
            },
            loaf_housing = {
                resource = 'loaf_housing',
                table = 'loaf_properties',
                ownerColumn = 'owner',
                ownerType = 'identifier',
                propertyIdColumn = 'id',
                resetColumns = {
                    keys = '[]',
                },
                label = 'Loaf Housing',
            },
            origen_housing = {
                resource = 'origen_housing',
                table = 'origen_houses',
                ownerColumn = 'owner',
                ownerType = 'identifier',
                propertyIdColumn = 'id',
                resetColumns = {
                    keys = '[]',
                },
                label = 'Origen Housing',
            },
        },
    },
}
 
-- Optional vehicle naming and preview image settings.
Config.VehiclePresentation = {
    -- Add vehicle brand to the title when possible.
    UseMakeInTitle = true,
    -- Optional image URL template. Example: "https://.../%s.png"
    ImageUrlTemplate = '',
}
 
-- Vehicle photo settings used when creating vehicle listings.
Config.VehiclePhoto = {
    Enabled = true,
    -- Screenshot resource name, usually screenshot-basic.
    Resource = 'screenshot-basic',
    FreezeVehicleDuringCapture = true,
    HideHudDuringCapture = true,
    Marker = {
        -- Marker shown at vehicle photo spots.
        Enabled = true,
        Type = 36,
        Size = { x = 1.8, y = 1.8, z = 0.8 },
        Color = { r = 190, g = 190, b = 190, a = 170 },
        Bob = false,
        FaceCamera = true,
    },
    Locations = {
        -- Places where players can take vehicle photos.
        {
            label = 'Marketplace Photo Spot',
            coords = vector3(-45.15, -1114.05, 26),
            heading = 71.0,
        },
    },
}
 
-- Property photo settings used when creating property listings.
Config.PropertyPhoto = {
    Enabled = true,
    Resource = 'screenshot-basic',
    HideHudDuringCapture = true,
    FirstPerson = true,
}
 
-- Internal payload sent from Lua to the UI.
function Config:GetClientPayload()
    return {
        marketplace = {
            fees = self.Marketplace.Fees,
            price = {
                min = 1,
                max = 1000000000,
            },
            listingHours = {
                min = self.Marketplace.ListingHours.Min,
                default = self.Marketplace.ListingHours.Default,
                max = self.Marketplace.ListingHours.Max,
            },
        },
        ui = {
            defaultCategory = self.UI.DefaultCategory,
            defaultSort = 'newest',
            locale = self.Locale,
            messages = Locales and (Locales[self.Locale] or Locales.en) or {},
        },
        images = {
            maxUploadImages = 4,
            uploadQueue = {
                Concurrency = 2,
                RetryAttempts = 2,
                RetryDelayMs = 350,
            },
        },
    }
end