FiveM Docs
Addons

esx_clotheshop

esx_clotheshop adds 14 clothing stores to ESX Legacy. Configure prices, per-piece charging and saved outfits, and learn the server callback and its checks.

esx_clotheshop places clothing stores around the map where players change their outfit through the esx_skin menu and pay with cash. After paying, players can optionally save the outfit to their wardrobe (the property datastore used by esx_property).

Overview

FactValue
Resourceesx_clotheshop
SideClient + server
Dependenciesesx_lib, es_extended, esx_skin (plus oxmysql)
Optionalesx_datastore with a property datastore for saved outfits
DatabaseNone of its own

In-game flow

  1. Walk into a store marker and press E.
  2. Change clothing in the restricted skin menu (t-shirt, torso, decals, arms, pants, shoes, bags, chain, helmet, glasses, watches).
  3. Confirm the purchase. The server charges cash and saves the new skin through esx_skin.
  4. If a property datastore exists, choose whether to save the outfit and type a name.

If the player cancels, leaves the marker or cannot pay, the previous skin is restored.

Installation

There is no SQL file. Make sure the dependencies start first:

server.cfg
ensure esx_skin
ensure esx_datastore
ensure esx_clotheshop

To enable saved outfits, create the per-player datastore once:

INSERT INTO `datastore` (`name`, `label`, `shared`) VALUES ('property', 'Property', 0);

Configuration

KeyDefaultDescription
Config.LocaleGetConvar('esx:locale', 'en')Locale used for texts.
Config.Price250Price of a purchase (or of each changed piece).
Config.ChargePerPiecefalseCharge Config.Price per changed item in Config.SkinProps instead of a flat price.
Config.ShopDistance3.0Max distance in meters from a shop that the server accepts for a purchase.
Config.PurchaseSessionDuration60000Time in ms after paying during which the outfit can be saved.
Config.MaxOutfits20Max outfits in the dressing list. New saves are ignored when full.
Config.MaxOutfitLabelLength40Outfit names are trimmed to this length. Control characters are removed.
Config.DrawDistance10.0Marker draw distance.
Config.MarkerSize{ x = 1.5, y = 1.5, z = 1.0 }Marker size. x is also the interaction radius.
Config.MarkerColor{ r = 102, g = 102, b = 204 }Marker color (alpha is fixed at 100).
Config.MarkerType1Marker type.
Config.Shops14 vector3 positionsStore locations. Each also gets a blip (sprite 73, color 47).
Config.SkinProps{ 'tshirt', 'torso', 'decals', 'arms', 'pants', 'shoes', 'bags', 'chain', 'helmet', 'glasses', 'watches' }Items compared for per-piece pricing (<name>_1 and <name>_2).
config.lua
-- Charge 150 per changed piece, minimum 150
Config.Price = 150
Config.ChargePerPiece = true

Server callbacks and events

esx_clotheshop:buyClothes (callback)

Triggered by the client with (newSkin, oldSkin). Returns bought, failure where failure is 'not_enough_money' or 'save_failed'.

Server-side safeguards:

  • The player must be within Config.ShopDistance of a shop.
  • newSkin is validated with exports.esx_skin:ValidateSkin.
  • The price is calculated against the skin stored on the server (exports.esx_skin:GetSkin), not the oldSkin sent by the client.
  • The money operation is wrapped in beginAccountOperation/endAccountOperation and refunded if esx_skin:SaveSkin fails.
  • Only one purchase per identifier can run at a time.

esx_clotheshop:checkPropertyDataStore (callback)

Returns true when the player has a property datastore. The client uses it to decide whether to show the save prompt.

esx_clotheshop:saveOutfit (net event)

TriggerServerEvent('esx_clotheshop:saveOutfit', label, skin)

Client-triggerable

This event can be fired by any client. It is safe by design: it only works within Config.PurchaseSessionDuration after a successful purchase, ignores the skin argument and stores the skin that was actually paid for, sanitizes the label and respects Config.MaxOutfits.

Saved outfits are appended to dressing in the player's property datastore as { label = string, skin = table }.

Integration tips

  • esx_property reads the same dressing list, so outfits bought here show up in property wardrobes.
  • To read outfits from your own resource on the server:
server/main.lua
TriggerEvent('esx_datastore:getDataStore', 'property', xPlayer.getIdentifier(), function(store)
    local outfits = store and store.get('dressing') or {}

    for i, outfit in ipairs(outfits) do
        print(i, outfit.label)
    end
end)
  • Payment uses the cash account (xPlayer.removeMoney). Edit server/main.lua if you want bank payments.

Common issues

  • Purchase always fails with a "save failed" message: the server distance check uses Config.ShopDistance (3.0). If you moved a shop marker, update the Config.Shops entry, not just the visual marker.
  • Outfit not saved: the property datastore is missing, the 60 second window expired, or the player already has Config.MaxOutfits outfits.
  • Skin resets after buying: esx_skin failed to save the skin. Check the server console; the purchase is refunded in that case.

Frequently asked questions

Independent documentation

esx-fivem.com is a community project and is not affiliated with the ESX Framework team. Facts on this page were checked against the upstream source. Official resources: docs.esx-framework.org and github.com/esx-framework.
Edit on GitHub

Last updated on

On this page