Skip to content

Client events

Client events fire on one player’s game: the buyer, the seller, the bidder who was outbid, the robber… They are never broadcast to everyone. Listen to them in client/handlers.lua (the handlers are already there, empty) or from any client script of your own:

AddEventHandler('sl-marketplace:onSaleMade', function(data)
PlaySoundFrontend(-1, 'WAYPOINT_SET', 'HUD_FRONTEND_DEFAULT_SOUNDSET', true)
end)
Event Who receives it Server hook with the same moment
onPurchaseCompleted Buyer OnSaleCompleted
onSaleMade Seller (if online) OnSaleCompleted
onAuctionWon Winner (if online) OnAuctionEnded
onListingCreated Seller OnListingCreated
onListingCancelled Seller OnListingCancelled
onListingBumped Seller OnListingBumped
onBidPlaced Bidder OnBidPlaced
onOutbid Player who was outbid OnBidPlaced
onMailboxClaimed Player collecting OnMailboxClaimed
onMessageReceived Recipient of a chat message OnMessageSent
onRefundStatusChanged Buyer and seller OnRefundRequested / Approved / Rejected
onDeliveryArrived Buyer OnDeliveryCompleted
onDeliveryResult Buyer OnDeliveryCompleted / Failed / Robbed
onDeliveryRobbed Robber OnDeliveryRobbed
onInPersonTradeStarted Buyer and seller —
onInPersonMeetUpdated Buyer and seller OnMeetupStatusChanged
onInPersonTradeCompleted Buyer and seller OnInPersonTradeCompleted
onInPersonTradeCancelled Buyer and seller OnInPersonTradeCancelled
onSkillCheckStarted Player doing the minigame —
onSkillCheckPhase Player doing the minigame —
onSkillCheckFinished Player doing the minigame —

All names start with sl-marketplace:, e.g. sl-marketplace:onSaleMade.

Who: the buyer. When: right after paying (OnSaleCompleted). For courier and in-person purchases settlementPending is true: the item has not arrived yet.

Field Meaning
item, itemLabel, quantity What was bought
price / basePrice Listing price, without extras
grossPaid Total paid
platformFee, deliveryFee, insuranceFee Fees
deliveryMode, listingType, sellerName Details
stage, settlementPending 'committed' / true for courier and in person, 'settled' / false otherwise
listingId Listing ID

Example

AddEventHandler('sl-marketplace:onPurchaseCompleted', function(data)
PlaySoundFrontend(-1, 'PURCHASE', 'HUD_LIQUOR_STORE_SOUNDSET', true)
end)

Test: buy any listing (solo: /markettest listing mailbox fixed bread 50).

Who: the seller, only if online. When: one of their listings is bought.

Field Meaning
buyerName Buyer
item, itemLabel, quantity What was sold
price / basePrice, grossPaid, platformFee, sellerPayout Money
deliveryMode, listingType Details
stage, settlementPending As in onPurchaseCompleted
listingId Listing ID

Test: two players; B buys one of A’s listings while A is online.

Who: the winner, only if online. When: an auction they lead ends (OnAuctionEnded), up to 30 s after the end time.

Field Meaning
item, itemLabel, quantity What they won
winningBid / grossPrice / finalPrice Winning bid
platformFee, sellerPayout Money
sellerName, listingType, deliveryMode, meetupPoint Details
stage 'settled'
listingId Listing ID

Test: /markettest listing mailbox auction bread 100, bid, wait 5 minutes.

Who: the seller. When: their listing has been published.

Fields: listingId, item, itemLabel, itemMetadata, quantity, price, listingType, deliveryMode, featured.

Test: publish any item from the marketplace.

Who: the seller. When: their listing is cancelled, by them or by an admin.

Fields: listingId, item, itemLabel, quantity, price, listingType, cancellationType ('owner' or 'admin').

Test: cancel one of your listings.

Who: the seller. When: they bump a listing.

Fields: listingId, item, itemLabel, cost, bumpedAt.

Test: bump one of your listings.

Who: the bidder. When: their bid is accepted, or proxy bidding bids for them automatically (bidType = 'proxy_auto').

Fields: listingId, item, itemLabel, amount, previousBid, bidType, sellerName.

Test: bid on a test auction.

Who: the player who was leading. When: someone places a higher bid (by hand or by proxy).

Field Meaning
listingId, item, itemLabel The auction
previousBid Their bid, now beaten
newBid The new highest bid
bidderName Who beat them
bidType 'manual' or 'proxy_auto'

Example: sound and screen flash

AddEventHandler('sl-marketplace:onOutbid', function(data)
PlaySoundFrontend(-1, 'LOSER', 'HUD_AWARDS', true)
AnimpostfxPlay('FocusOut', 800, false)
end)

Test: two players bid on the same auction; the first one gets onOutbid when the second bids more.

Who: the player. When: they collect something from their mailbox.

Fields: mailboxId, claimType ('item' or 'money'), amount, item, itemLabel, itemMetadata, quantity, meetupPoint, reason.

Test: collect anything from your mailbox (a won auction always ends up there).

Who: the recipient. When: they receive a message in a listing’s chat.

Field Meaning
listingId Listing of the conversation
conversationKey Conversation ID
fromIdentifier, partnerIdentifier Sender and the other side of the chat
messageId Message ID
messageKind Kind of message
preview Short preview of the text

Example: phone-style notification when the marketplace is closed

AddEventHandler('sl-marketplace:onMessageReceived', function(data)
exports['okokNotify']:Alert('Marketplace', data.preview, 4000, 'info')
end)

Test: two players; B writes to A from one of A’s listings.

Who: buyer and seller (each gets their own role). When: a refund is requested, approved, forced or rejected.

Field Meaning
refundId, historyId, listingId IDs
role 'buyer' or 'seller'
status 'pending', 'approved', 'forced' or 'rejected'
item, itemLabel, amount What and how much
reason / note Buyer’s reason or seller’s note

Test: two players; B requests a refund on a purchase from A, A approves or rejects it.

Who: the buyer. When: the courier van hands them the item. Does not fire if the van was robbed or failed.

Fields: deliveryId, item, itemLabel, quantity, sellerName, listingId, deliveryMode, stage.

Test: /markettest listing npc fixed bread 50, buy it and wait for the van.

Who: the buyer. When: a courier delivery ends, whatever the outcome. Use this one if you want a single handler for every case.

Field Meaning
deliveryId, listingId IDs
result 'delivered', 'stolen' or 'failed'
item, itemLabel, quantity, sellerName The order
deliveryMode, stage Details
reason Why it failed (only failed)
refundAmount Refunded, when there was a refund
thiefName Who robbed it (only stolen)

Example

AddEventHandler('sl-marketplace:onDeliveryResult', function(data)
if data.result == 'stolen' then
exports['okokNotify']:Alert('Courier', data.thiefName .. ' robbed your package!', 6000, 'error')
end
end)

Test: as onDeliveryArrived for delivered; destroy the van for failed; have another player rob it for stolen.

Who: the robber. When: they rob a courier van (OnDeliveryRobbed).

Fields: deliveryId, item, itemLabel, itemMetadata, quantity, value, trigger ('cargo_stolen' or 'driver_killed'), listingId, stage.

Test: two players; one buys with courier delivery, the other robs the van.

Who: buyer and seller. When: an in-person trade is created, and again when a player reconnects with a trade still open (rehydrated = true).

Field Meaning
tradeId (also id) Trade ID
role 'buyer' or 'seller'
counterpart, partnerIdentifier The other player
itemLabel, quantity, price, listingId The deal
meetStatus State of the meeting point
rehydrated true when restored after reconnecting

Test: two players online; B buys one of A’s listings with the in person mode.

Who: buyer and seller. When: the meeting point is proposed, accepted, declined, cancelled or expires.

Fields: tradeId (also id), meetStatus, meetProposedBy, meetProposedCoords, meetProposedAt, meetWindowEndsAt, meetCoords.

Test: in an in-person trade, propose a location from the chat and accept it with the other player.

Who: buyer and seller. When: both confirm the exchange face to face.

Fields: tradeId, role, item (nil for barter), itemLabel, quantity (nil for barter), price (0 for barter), isBarter, tradeKind, barter, platformFee, sellerPayout, listingId, stage.

Test: complete an in-person trade.

Who: buyer and seller. When: the trade is cancelled or times out.

Fields: tradeId (also id), reason, partnerIdentifier.

Test: cancel an in-person trade from the chat.

The ring the robber has to time to force a van’s cargo hold. Three phases, each faster and on a different key (configured in Config.SkillCheck). context is currently always 'deliveryRobbery'.

When: the ring appears, before the first phase.

Fields: context, deliveryId, phases (how many phases).

When: each phase resolves.

Field Meaning
context, deliveryId What is being attempted
phase Phase that just resolved (1, 2, 3…)
phases Total phases
key Key the phase asked for ('E', 'Q', 'R', 'F')
result 'hit' or 'miss'

When: the minigame ends, however it ends. Always after the last onSkillCheckPhase.

Field Meaning
context, deliveryId What was attempted
result 'passed' (all phases), 'failed' (a phase missed) or 'cancelled' (walked off, shot, or the van left)
passed true only for 'passed'
cleared Phases cleared before it ended
phases Total phases

Example: your own sounds instead of the built-in ones

Set Config.SkillCheck.Sounds = false and play your own:

AddEventHandler('sl-marketplace:onSkillCheckPhase', function(data)
if data.result == 'hit' then
PlaySoundFrontend(-1, 'CONFIRM_BEEP', 'HUD_MINI_GAME_SOUNDSET', true)
else
PlaySoundFrontend(-1, 'ERROR', 'HUD_FRONTEND_DEFAULT_SOUNDSET', true)
end
end)
AddEventHandler('sl-marketplace:onSkillCheckFinished', function(data)
if data.result == 'failed' then
-- a botched attempt makes noise: alert police from the SERVER, not from here
TriggerServerEvent('your_dispatch:suspicious', 'Noise at a courier van')
end
end)

Test the three: two players; one buys with courier delivery, the other intercepts the van, threatens the driver and starts forcing the cargo hold. Fail one run on purpose to see miss and failed.