Skip to main content
The plugin makes an outbound TLS connection to ItemShop and receives paid orders in real time. You do not open a port on the game server. If it was offline, outstanding deliveries are replayed after reconnecting.

Requirements

  • Java 17 or newer
  • Paper/Spigot 1.19+, Folia, BungeeCord, or Velocity 3.x
  • a server created in the ItemShop panel
  • write access to plugins/ItemShop/ for configuration and the fulfilment journal

Install from the panel

1

Download the correct JAR

Open Plugin in the shop panel and download the universal ItemShop-1.0.0.jar. Put it in one platform’s plugins/ directory; do not install both a platform-specific JAR and the universal JAR.
2

Generate configuration

Select a server, click Generate plugin key, then download config.yml. The panel creates a shop-bound plugin key with the minimum orders:write capability.
3

Start the plugin

Put the file at plugins/ItemShop/config.yml and start the server. /itemshop shows connection status and /itemshop reload safely reloads configuration.
apiKey is a secret shown once. Do not publish or commit config.yml, and do not paste it into support tickets. Do not delete fulfillment-journal.json: without it an interrupted delivery cannot be reconciled safely.

Configuration format

The panel generator emits every field used by the plugin:
config.yml
Production apiUrl must use https://. A separate API domain works only if the same origin serves the Socket.IO /plugin namespace.

Fulfilment safety

1

Push and atomic claim

Every connected instance may see order:deliver, but exactly one wins the atomic order:claim. The others do not execute commands.
2

Durable journal before commands

Before the first command, the plugin writes and fsyncs EXECUTING. After the last command it writes AWAITING_ACK, while commands themselves run on the platform’s required thread.
3

Acknowledge or review

After a restart, AWAITING_ACK can be acknowledged without running commands again. A recovered EXECUTING state is ambiguous, so automatic replay is blocked and the owner must choose complete or retry after checking the game server.
Arbitrary console commands cannot provide strict exactly-once semantics. In the ambiguous crash window, the system chooses safe at-most-once behaviour and asks for an explicit decision instead of risking a duplicate grant.

Test before selling

  1. Create a product with a harmless test command.
  2. Place a 100%-discount order so no payment provider is involved.
  3. Check /itemshop, server logs, and the paidprocessingcompleted transition.
  4. Repeat with the player offline, after the player joins, and after restarting the plugin before delivery.
  5. Separately run a real provider sandbox test: checkout → signed webhook → delivery → ACK.

Troubleshooting

Check the exact camelCase names: apiUrl, apiKey, and serverId. The key starts with isk_, the server ID is 24 hex characters, and apiUrl must not end in /api/v2.
Generate a new key from Plugin. It must have type plugin, capability orders:write, be active, and be bound to the shop that owns serverId.
Check nickname spelling, the online-player requirement, and blockedServers. Joining or switching modes pulls outstanding deliveries after joinDeliveryDelaySeconds.
The plugin recovered EXECUTING after a crash, so at least one command may have run. Check the player’s/server’s state first, then choose complete or retry in the panel.
Use /itemshop reload or a full restart. Do not use the platform-wide Minecraft /reload, which can leave libraries and listeners in an inconsistent state.
See the plugin fulfilment protocol for event and state details.