Events
Every event, when it fires, whether it can be cancelled, and what is mutable on it.
All ZyAuctions events are synchronous and fire on the main server thread, so the Bukkit API is safe to use in a handler.
The naming tells you which half of an action you are in. Present tense — ListingCreateEvent,
ListingPurchaseEvent — fires before the action and can be cancelled. Past tense —
ListingSoldEvent, ListingExpiredEvent — fires after, when the money and items have
already moved, and cannot be cancelled.
Every event except ListingCreateEvent and CollectibleClaimEvent extends ListingEvent,
which provides listing() — an immutable snapshot taken when the event was constructed.
ListingCreateEvent
Fires after validation but before the seller is charged and the listing is stored.
| Cancellable | Yes |
| On cancel | No listing is created, nothing is charged, the seller keeps their item and is told the listing was refused. |
| Method | |
|---|---|
Player seller() | Who is creating it. |
ListingRequest request() | What they are selling and how. |
double listingFee() | What they are about to pay. |
void listingFee(double) | Change it. Negative values are treated as zero. |
@EventHandler
public void onCreate(ListingCreateEvent event) {
if (event.request().item().getType() == Material.DIAMOND_BLOCK) {
event.listingFee(event.listingFee() * 3); // premium listing fee
}
}You cannot change the item or the price here — ListingRequest is immutable. Cancel the
event and create your own listing if you need to alter what is being sold.
ListingPurchaseEvent
Fires before a fixed-price listing changes hands, before any money moves.
| Cancellable | Yes |
| On cancel | The listing stays on sale, the buyer's balance is untouched. |
| Method | |
|---|---|
Player buyer() | Who is buying. |
double price() / price(double) | What the buyer pays. Values at or below zero are clamped to a penny. |
double salesTax() / salesTax(double) | What is withheld from the seller's payout. Negative values are treated as zero, and it is capped at the price. |
Listing listing() | What is being bought. |
@EventHandler
public void onPurchase(ListingPurchaseEvent event) {
if (event.buyer().hasPermission("myplugin.discount")) {
event.price(event.price() * 0.9);
}
}Note that lowering price() lowers what the buyer pays but not what the seller receives —
sellerReceived is price − salesTax, so a discount comes out of the seller's pocket
unless you lower the tax too.
ListingBidEvent
Fires before a bid is accepted, before any money moves.
| Cancellable | Yes |
| On cancel | The current top bid stands, the bidder's balance is untouched. |
| Method | |
|---|---|
Player bidder() | Who is bidding. |
double amount() / amount(double) | The bid. |
double previousBid() | The bid this one is beating, or the starting bid if it is the first. |
The plugin still enforces Listing.minimumBid() after your handler runs, so raising
amount() always works and lowering it below the minimum makes the bid fail with
BID_TOO_LOW.
ListingCancelEvent
Fires before a listing is withdrawn.
| Cancellable | Yes |
| On cancel | The listing stays on sale. |
| Method | |
|---|---|
Optional<UUID> actor() | Who is withdrawing it; empty for console and automated removals. |
boolean administrative() | Whether this is a staff removal rather than the seller's own withdrawal. |
@EventHandler
public void onCancel(ListingCancelEvent event) {
if (event.administrative()) {
auditLog.record(event.actor().orElse(null), event.listing().id());
}
}ListingSoldEvent
Fires after a listing has sold and the money has moved. Covers both routes: a fixed-price purchase, and an auction that ended with at least one bid.
| Cancellable | No — the transaction is already done. |
| Method | |
|---|---|
UUID buyer() | Who now owns the item. |
double price() | What the buyer paid. |
double sellerReceived() | What the seller was credited, after tax. |
boolean wonAtAuction() | true for an auction ending, false for a fixed-price purchase. |
This is the event to build a sale history on.
ListingExpiredEvent
Fires after a listing has run out of time without selling and the item has been placed in
its seller's collection bin. An auction that ended with bids fires ListingSoldEvent
instead.
| Cancellable | No — the item has already moved. |
| Method | |
|---|---|
Collectible collectible() | The bin entry now holding the returned item. |
CollectibleClaimEvent
Fires before an item is handed over from a collection bin.
| Cancellable | Yes |
| On cancel | The entry stays in the bin. |
| Method | |
|---|---|
Player player() | Who is claiming. |
Collectible collectible() | What they are claiming. |
When a player claims their whole bin at once this fires separately for each entry, so
cancelling affects only that one — and claimAll stops at the first refusal.
Registering
Nothing unusual:
getServer().getPluginManager().registerEvents(new MyListener(), this);Use ignoreCancelled = true unless you specifically want to see events another plugin has
already vetoed, and pick the lowest priority that does what you need. If you are only
observing — logging, statistics, webhooks — use EventPriority.MONITOR and do not change
anything.
Stability
Events are API. A field name is as much of a contract as a method signature, and renaming one is a breaking change. If an event gains information it will gain a method, not change an existing one.