Skip to content

Changelog

Every release of SL-Marketplace, newest first. The format follows Keep a Changelog and the project uses Semantic Versioning.

September 29, 2026

  • Rebuilt the release package from the unchanged 1.16.1 source; no gameplay or database behavior changed.

September 29, 2026

  • Fixed the missing English and Spanish name for the Mono theme in the theme picker.
  • No database changes or migration are required.

v1.16.0 · Per-player languages and preferences

Section titled “v1.16.0 · Per-player languages and preferences”

September 29, 2026

  • All player-facing Lua messages now use each player’s profile language, including notifications, buying and bidding, delivery robberies, prompts, photo uploads and mailbox messages.
  • Added 427 editable English and Spanish strings in locales/en.lua and locales/es.lua. These files are intentionally left unencrypted so server owners can edit them or add languages.
  • Shared messages use Config.DefaultLang, now en. New players see registration in the server’s default language, with missing UI translations falling back to English.
  • Interface themes are saved separately for each character on the current device. Character changes restore that character’s theme and marker colour.
  • Corrected the phone integration documentation: lb-phone is supported out of the box when Config.Phone.Enabled = true.
  • No database changes or migration are required.

September 29, 2026

  • The README now describes every feature, including courier robberies and the timing minigame: who can rob, what each party gets and how to tune it.
  • Step-by-step installation: downloading from the Cfx Portal, the escrow licence requirement, getting a free Imgbb key and the admin permission.
  • New sections: commands and keys, configuration map, what you can edit, and FAQ and troubleshooting.
  • DOCUMENTATION adds robbery outcomes and the full list of server hooks and client events.
  • Removed claims that were not accurate: there is no built-in phone app.
  • No code or database changes: no migration is needed.

September 29, 2026

  • The release checklist records that 1.15.0 was published after its encrypted build was tested on a live server.
  • Removed the links to an old third-party repository from the version list.
  • No code or database changes: no migration is needed.

v1.15.0 · Interface redesign and the robbery minigame

Section titled “v1.15.0 · Interface redesign and the robbery minigame”

September 29, 2026

This is the biggest release since the resource was created: the interface has been rewritten from scratch and robbing a delivery is no longer a waiting game.

  • The Discord webhook moves to a server-only convar. Set set sl_marketplace_discord_webhook "YOUR_URL" in server.cfg and remove the old Config.Discord.Webhook field from your shared configuration. The resource no longer reads that field. Keep Config.Discord.Enabled = true to enable logs; use set, never setr or sets, for the URL.
  • Config.Gameplay.NPCDelivery.ExtractionTime no longer exists. Forcing the trunk used to mean holding a key for six seconds; it is now an aiming minigame that lasts as long as the player takes, so a fixed number of milliseconds stopped meaning anything. It is replaced by ExtractionAttempts (how many attempts there are) and ExtractionMinSeconds (the minimum the server validates). Anyone who updates while keeping their config.lua will not see any error: the old setting is simply ignored, so it has to be reviewed by hand.
  • StopSpeedThreshold is also gone, as already noted in 1.14.3.
  • All documentation is available in English (*.md) and Spanish (*.es.md). DOCUMENTACION.md is now DOCUMENTATION.md.
  • A seller’s storefront banner now scrolls with the content and the avatar sits over it without being clipped; the close button stays fixed in the corner.
  • Vue 3.4.38, Lucide 0.462.0 and the fonts are bundled locally, with their licences. Starting the interface no longer needs the JavaScript CDNs or Google Fonts; photos and external icons still use their services.
  • Complete visual redesign, component-based and with one view per file: catalogue, product page, publish, messaging, profile, mailbox, alerts, follows, favourites, my listings and admin panel.
  • app.js is split into domain modules under store/, with a test suite that makes sure the template does not use bindings that setup() does not return — the bug that made flash sales invisible without a single error in the console.
  • Notifications now look like phone notifications, are grouped when repeated and use the theme colour. The HUD icon and the notifications share a column, so the third notification no longer covers the icon.
  • Eleven more notifications change from a sentence to fields, so the item, the amount and who sent it can be read without rereading the whole sentence.
  • A JavaScript error no longer leaves the player unable to play, and a broken icon or photo no longer takes the interface down with it.
  • Markers are a ring rather than a disc: they mark the spot without covering it, pulse slowly and light up as you approach. They take the colour of the theme the player has selected.
  • The “press E to…” prompt is our own, not GTA’s little grey box, so it also follows the theme. It is pinned to the entity it refers to —the courier, the person you are meeting, the trunk— and shrinks with distance.
  • With that, the last 3D text drawn with GTA natives is gone.
  • New minigame: a ring that goes round once and a segment you have to hit. Three phases, each faster, narrower and with a different key, so you cannot just mash a single one. It is fully configured in Config.SkillCheck.

  • Failing has a cost: there are three attempts per van and per player, and once all three are used the lock breaks for that player. Only failing the timing uses up an attempt; getting shot or the van driving off does not.

  • Taking damage interrupts the attempt. Before, only shooting yourself interrupted it, so you could take a whole burst of fire with the minigame spinning away calmly.

  • The thief stands still with an animation of tampering with something, instead of opening a van with their arms hanging down.

  • Fixed: with the courier held at gunpoint you could press E and receive the order anyway, keeping both the stolen package and the purchased one. A courier who is being held no longer delivers anything, and the server checks this even when a third party is the one holding them.

  • Three new events for integrations: sl-marketplace:onSkillCheckStarted, onSkillCheckPhase and onSkillCheckFinished.

  • New theme: Mono. White neon on pure black, the only one without a brand colour. The markers and the “press E” prompt in the world follow it like the others, so they turn white too.

  • Notifications for a followed seller can be turned off without unfollowing them, from the follows view. Requires sql/migrate_1.15.sql.
  • The per-player, per-delivery limit on robbery requests no longer resets when the token expires; once it is used up, the previous token is invalidated too.
  • Intimidation checks the model and health of the registered courier.
  • Bundles could not be published with ox_inventory.
  • The mailbox treated a bundle as a single item, and NPC delivery did not carry its contents.
  • Modals were invisible in game.
  • The admin panel did not open.
  • Instant delivery promised a mailbox it does not use.

August 20, 2026

  • Critical: server/devtools.lua was declared in fxmanifest.lua but excluded from the distribution ZIP, so the resource did not start cleanly on a fresh install. The file is part of the package again and stays inert unless Config.Debug is true and the caller is an administrator.
  • Diagnostic traces of the photo flow (39 in Lua, 9 in the interface) no longer write to the console: they sit behind Config.Debug on the server and client, and behind PHOTO_DEBUG in the interface.
  • The tests/ folder is excluded from the commercial package, just like html/tests/.
  • RELEASE_CHECKLIST.md documents that git archive produces an empty ZIP without an error if it is run outside the repository root, and adds a step to verify the package contents.

August 20, 2026

  • The server chooses the courier and van models and the client can no longer spawn different ones.
  • A delivery’s entity record is immutable; it validates the model, the driver-vehicle link and proximity to the origin, and rejects net IDs reused by another delivery.
  • Delivery and network IDs are normalised strictly: NaN, decimals, negatives and values outside the 16-bit range are discarded.
  • Pickup requires a living courier with the expected model at a real distance from the buyer; reporting a lost delivery requires the vehicle to be destroyed and verified.
  • Robbery checks the vehicle model and bounds the extraction window from above, in addition to the existing minimum.
  • New dedicated rate limits: deliverySpawn, deliveryClaim and deliveryRobbery.
  • Trunk extraction no longer depends on StopSpeedThreshold (removed): it can start while moving, but still requires proximity.
  • Added the tests/security.test.js suite covering these guarantees.

August 7, 2026

  • NPC deliveries validate network entities, proximity, timings and failure reasons on the server; a delivery can no longer be robbed or settled from any position.
  • Bids use conditional claims to avoid balance/state races; proxy bids, cancellations and mailbox claims have extra limits and validations.
  • Refunds, administrative cancellations and barter operations avoid double resolution; monetary counteroffers now reserve the buyer’s money when accepted.
  • Malformed input, out-of-range quantities/prices and bulk actions without a rate limit are rejected.
  • The admin panel permission uses the explicit ACE marketplace.admin, and the interface no longer stays empty if the user is not authorised.

August 7, 2026

  • Imgbb/Imgur credentials are no longer stored in config.lua, which is shared with clients.
  • Photo uploads read the credentials from server-only convars.
  • Added setup instructions for sl_marketplace_imgbb_key and sl_marketplace_imgur_client_id.

v1.14.0 · Barter state machine + counteroffer

Section titled “v1.14.0 · Barter state machine + counteroffer”

April 19, 2026

  • A proposal goes through: proposed → (countered)* → accepted → in-window → completed/cancelled
  • The seller can send a counteroffer from the chat asking for different items; the original proposal is marked Countered and the offered items go back to the buyer
  • The buyer can accept the counteroffer (locking the requested items in escrow), reject it or cancel their original proposal
  • Accepting the barter does not swap the items instantly: it creates an in-person trade that requires a physical meeting (same UX as a person purchase)
  • When both are in proximity and confirm, the items + money are finally exchanged
  • Every event (proposal, counteroffer, accepted, cancelled, rejected) is recorded in the chat thread as a system row
  • marketplace:counterTrade — the seller posts a counteroffer stating which items they want in return
  • marketplace:cancelProposal — the sender withdraws their open proposal (escrow refund)
  • marketplace:rejectProposal — the recipient rejects it (escrow refund)
  • marketplace:acceptTrade — rewritten: creates a marketplace_trades row with trade_kind='barter' and a snapshot of the offer, and starts the meeting window
  • Run sql/migrate_1.14.sql → extends the message’s trade_status (countered, cancelled, expired, completed) and adds counter_of_message_id, wanted_items, trade_id; and adds trade_kind + barter_offer to marketplace_trades
  • Barters already accepted in v1.13 still complete with the traditional exchange; the new flow only applies to proposals created from v1.14 on

April 19, 2026

🤝 In-person trades no longer trigger blips/prompts automatically

Section titled “🤝 In-person trades no longer trigger blips/prompts automatically”
  • After buying with person, the chat with the seller opens as before, but there is no blip or prompt
  • Either party sends a meetup proposal from the chat (current position or a point on the map)
  • The other party Accepts / Declines the proposal from the chat
  • Only once accepted are the blip + proximity prompt enabled; a time window also opens (10 min by default)
  • If nobody gets there in time, the meetup expires and returns to the “chat-only” state — it can be proposed again
  • Either party can cancel a proposal or an active meetup at any time
  • Every event (propose/accept/cancel/decline/expire) is recorded in the chat thread as a system row
Config.InPersonTrade = {
...
MeetRequestTimeoutSeconds = 300, -- proposal expires without an answer
MeetWindowSeconds = 600 -- 10 min to meet after accepting
}
  • Run sql/migrate_1.13.sql → adds meet_status, meet_proposed_by, meet_proposed_coords, meet_proposed_at, meet_window_ends_at to marketplace_trades
  • Existing trades move to meet_status='none' → a meetup can be proposed from the chat

April 13, 2026

🚚 The buyer chooses how to receive, the seller marks their preferred modes

Section titled “🚚 The buyer chooses how to receive, the seller marks their preferred modes”
  • In fixed/dutch/bundle listings the seller marks preferred delivery modes (multiple checkboxes)
  • The buyer can always choose any mode when buying, from a unified modal
  • If they choose a NON-preferred mode → they pay an extra (Config.DeliveryBuyerFee) that goes entirely to the seller
  • Auctions/barter/reverse keep a single mode set by the seller (there is no active buyer when they close)
Config.DeliveryBuyerFee = {
mailbox = 0, meetup = 100, npc = 0, person = 300
}
  • Run sql/migrate_1.10.sql → adds delivery_modes_allowed VARCHAR(60) to marketplace_listings
  • Legacy listings (NULL) keep working in single-mode
  • Unified purchase modal with a 4-mode radio + a visual “preferred” / “+$X” chip
  • The total to pay is calculated live (price + mode extra + NPC cost + insurance)
  • Meetup is disabled if the listing has no point configured

v1.9.0 · Vehicles, weapons, icons and custom toasts

Section titled “v1.9.0 · Vehicles, weapons, icons and custom toasts”

April 13, 2026

  • Inventory.GetList now includes the player’s vehicles from owned_vehicles
  • Listing a vehicle changes owner to 'marketplace' (escrow), preserving all props/tuning
  • On cancel/expiry → it is returned to the seller; on sale → it is transferred to the buyer
  • Vehicles only support fixed/auction/blind/dutch, with mailbox/meetup/person delivery (NPC delivery blocked)
  • item_metadata stores the vehicle’s plate + model for deferred delivery
  • Weapons from getLoadout() are listed with ammo and components
  • Listing does p.removeWeapon; claiming from the mailbox restores it with ammo and components
  • Automatic label: Pistol (120 ammo)
  • (ox_inventory already handles weapons as items, so no extra layer is needed)

🖼️ Item icons (fallback without a photo)

Section titled “🖼️ Item icons (fallback without a photo)”
  • Config.ItemIcons.UrlPatterns with %s (name) and %c (category) support
  • Prioritises nui://ox_inventory/web/images/ (self-contained, ~2000 free icons)
  • Falls back to nui://marketplace/html/images/ for custom items
  • On-error cascade: if the first pattern fails, it tries the next one
  • Specific fallbacks for vehicle and weapon (_vehicle.png / _weapon.png in the local folder)
  • Zero external dependencies — everything is served from FiveM assets

🔔 Custom toasts (no more ESX notify under the UI)

Section titled “🔔 Custom toasts (no more ESX notify under the UI)”
  • notify(msg, ok) helper on the client: if the marketplace is open it uses the internal NUI toast; if it is closed it falls back to ESX
  • Fixes the bug where ESX notifications were hidden behind the interface
  • The marketplace_listings table already had item_metadata; no SQL migration is needed
  • If you use a fork with this column renamed, adjust it in createListing

April 12, 2026

  • No blips by default (stealth): ShowBlipToBuyer=false and ShowBlipToWorld=false
  • Buyers/interceptors have to find the courier physically on the map
  • Intimidation: aim a weapon at the NPC within 5m → “E” prompt → the NPC stops the vehicle and raises their hands
  • Configurable success rate (55% by default) when intimidating
  • If intimidation fails, the NPC tries to flee
  • Config.OnDeliveryRobbed hook so servers can connect a police alert
  • The NPC’s network IDs are broadcast to every client so they can intercept
  • New delivery_mode = 'person' for listings
  • When buying, the buyer chooses a meeting point (predefined meetup or free waypoint)
  • marketplace_trades table with bilateral buyer_accepted + seller_accepted
  • Both see a blip of the point + a notification
  • Proximity scan: when both are within 3m of the point → “E — Start trade” prompt
  • Bilateral modal: each sees the other’s status, and both must press “Confirm my part”
  • Atomic transfer when both accept (item → buyer, money → seller)
  • Cancellation on timeout (2h default), on abandonment, or manually
  • Refunds no longer duplicate items: applyRefund now removes the item from the buyer before returning it to the seller. If the buyer is offline or does not have the item, the refund is rejected automatically (unless an admin forces it)
  • Fixed bundle refunds so that all items in the bundle are processed
  • Config.Gameplay.NPCDelivery.ShowBlipToBuyer / ShowBlipToWorld
  • Config.Gameplay.NPCDelivery.IntimidationEnabled / IntimidationDistance / RobSuccessRate / PoliceAlertOnRob
  • Config.InPersonTrade.* (Enabled, ProximityMeters, LocationRadiusMeters, TimeoutMinutes, AllowCustomLocation)
  • Config.OnDeliveryRobbed(thiefSrc, deliveryId, value) hook function

April 12, 2026

  • Expanded storefronts: the public profile becomes a complete shop
    • Header banner (URL configurable per seller)
    • Long description (up to 1500 chars)
    • Pinned listings (up to 3) that appear at the top with a gold border
    • Tabs: Active / Sold / Ratings / About (long description)
    • Shows recent sales history + top ratings
    • Quick link from your own profile to view “my storefront”
  • Pin/unpin listings with a button in the seller’s own shop
  • Complete refund system:
    • Configurable window (7 days by default)
    • “Request refund” button in the history for eligible purchases
    • Request modal with a required reason (min 10 chars)
    • Section in the history for the seller with pending refunds
    • The seller approves (→ item returns, money returns) or rejects with a note
    • Auto-approval after a configurable timeout (72h default)
    • Admin panel with a refund queue and a force button
  • New columns in marketplace_users: banner_url, long_description, pinned_listings
  • New table marketplace_refunds with full tracking
  • Config.Storefront.Enabled / MaxPinned / LongDescriptionMaxLen
  • Config.Refunds.Enabled / WindowDays / AutoApproveAfterHours / ServerFeeRefunded

April 12, 2026

  • New listing_type barter: exchanging items without money (or with a monetary component)
  • The seller specifies wants_items (items they accept in return) or checks wants_any
  • offered_items column in marketplace_messages for barter proposals
  • trade_status column (open/accepted/rejected/withdrawn) in messages
  • “Propose barter” modal with an inventory item selector + optional money
  • Proposed items are locked in escrow until accepted/rejected/expired
  • On acceptance: atomic two-way transfer
  • When a proposal is accepted: all the others are auto-rejected and refunded
  • On expiry: the poster’s item returns to the mailbox + refund of all proposals
  • “Accept barter” button in the chat (only visible to the barter’s poster)
  • Config.Barter.Enabled / AllowMoneyComponent / MaxItemsPerProposal / DurationMinutes

April 12, 2026

  • Dutch auctions (dutch): the price starts high and drops automatically
    • Columns dutch_floor, dutch_step_percent, dutch_interval_min
    • Current price calculated live (client + server)
    • The UI shows a countdown to the next drop
    • Range validations: step 5-25%, floor >= 10% of the starting price
  • Reverse auctions (reverse): the buyer posts what they are looking for
    • The buyer deposits the maximum price in escrow
    • Sellers send offers through the chat with offer_amount
    • “Accept offer” button in the chat for the buyer
    • On acceptance: item transfer, payout with fee, refund of the difference
    • If it expires without acceptance: the deposit is returned automatically
  • New config: Config.Auctions.Dutch, Config.Auctions.Reverse (toggles)

April 12, 2026

  • New delivery mode npc: an NPC in a vehicle takes the package to the buyer
  • Automatic ped + vehicle spawn from the nearest meetup
  • The NPC drives to the destination with GTA V AI
  • Optional interception system: if Config.Gameplay.NPCDelivery.Interceptable=true, other players see a red blip at the origin and can rob the NPC
  • Only listings worth >= MinValueForIntercept generate shared blips
  • Optional insurance (+10%): if the package is stolen, the seller is paid 80% of the price
  • Payout to the seller only when the delivery is confirmed (not on purchase)
  • Robbery detection through the NPC’s death or the vehicle’s destruction
  • Auto-retry if the vehicle gets stuck
  • Private buyer blip always visible to track their package
  • Automatic 15 min timeout that cancels the delivery and refunds
  • marketplace_deliveries table with a full history
  • Config.Gameplay.NPCDelivery.Enabled
  • Config.Gameplay.NPCDelivery.Cost ($500 per shipment)
  • Config.Gameplay.NPCDelivery.Interceptable (toggle for non-PvP servers)
  • Config.Gameplay.NPCDelivery.MinValueForIntercept
  • Config.Gameplay.NPCDelivery.InsuranceCost / InsurancePayout
  • Config.Gameplay.NPCDelivery.MaxDistance, Speed, DeliveryTimeout
  • Config.Gameplay.NPCDelivery.Models.Peds / Vehicles

April 12, 2026

  • Flash sales with a temporary discount (10-70%) and configurable duration (10-120 min)
  • Pulsing red badge and a visible countdown on cards
  • Struck-through price with the discount applied
  • Bundles: pack up to 8 inventory items into one listing
  • UI builder to create bundles with an inventory selector
  • Multiple delivery when buying a bundle
  • Config.Gameplay.NPCDelivery placeholder for v1.4

April 12, 2026

  • Blind auctions: bids hidden until the end
  • eBay-style proxy bidding: automatically raises your bid up to your maximum
  • Config.Auctions.Blind.Enabled and Config.Auctions.ProxyBidding.Enabled

April 12, 2026

  • Follow sellers with notifications of new listings
  • Wishlist / item alerts with an optional maximum price
  • Automatic verified seller badge (50 sales + 4.5★ + 10 ratings)
  • Report system with configurable reasons
  • Clickable public profile with active listings
  • UI overhaul: sidebar, design tokens, Lucide icons, command palette (Ctrl+K)
  • Skeleton loaders, toasts with icons, improved empty states

April 12, 2026

  • Direct sales and auctions with automatic anti-snipe
  • Buy Now on auctions with a refund to the bidder
  • Bump for expired/active listings (costs money)
  • Featured listings with a gold border and ordering priority
  • Seller profiles with a unique shop name, bio and avatar colour
  • 1-5 star ratings + a comment after each purchase
  • Automatic reputation (+1 per sale, +1 per 5★)
  • Item categories with icons
  • Rarities (common → legendary) with a forced minimum price
  • Multiple photos per listing (up to 4) with a free in-game camera
  • Photo upload to Imgur through its API
  • Buyer↔seller chat/offers per listing with an inbox
  • Favourites / watchlist with bid notifications
  • Real-time push notifications with toasts by type
  • Sounds on key events (outbid, sale, purchase)
  • Physical “meetup” delivery at 4 map points with a blip + route
  • Mailbox for items and money with claiming
  • Filterable transaction history (sales/purchases/all)
  • Historical price statistics when choosing an item to sell
  • Advanced filters: search, category, rarity, price range, sorting
  • Pagination with total listings and pages
  • Admin panel with list/cancel/ban
  • ACE permissions group.admin + manual identifiers
  • /marketadmin command to open in admin mode
  • Discord webhooks configurable per event
  • Rate limiting (sliding window) per action and player
  • Auto-cleanup of old listings and mailbox entries (1h cron)
  • Vue 3 UI via CDN (no build step) with ES/EN i18n
  • Confirmation modal replacing the browser’s confirm()
  • Photo gallery with keyboard navigation
  • Empty states with large icons per section
  • Auto-detected ox_inventory support
  • lb-phone / qb-phone integration stub
  • 8 SQL tables with appropriate indexes and foreign keys
  • ESX/ox inventory abstraction in server/inventory.lua
  • Discord webhook module isolated in server/discord.lua
  • Free camera module isolated in client/camera.lua