Real-time webstore integration for Paper and Folia servers. Syncs purchases from Tebex, CraftingStore, MineStoreCMS and McSets, then broadcasts donations in-game, posts Discord embeds, tracks goals and exposes 40+ PlaceholderAPI placeholders.
Overview
BlockyDonations polls your webstore on a configurable interval and processes new purchases automatically. When a donation is detected it fires a configurable multi-line chat broadcast with optional player-head rendering, triggers a GG Wave reaction window, sends a Discord embed and updates all leaderboard and goal state.
Storage is handled by SQLite, MySQL or MariaDB - choose what fits your infrastructure. All polling and Discord requests run asynchronously so the main thread is never blocked. Folia threaded schedulers are detected and used automatically. Multi-server clustering is supported via database-backed leader election.
Supported Providers
- Tebex
- CraftingStore
- MineStoreCMS
- McSets
Optional Integrations
- PlaceholderAPI - required for all
%bd_*%placeholders - Floodgate - suppresses heads for Bedrock players
- Chat Plugins - ChatControl, ZelChat, AdvancedChat compatibility
No restart needed. Run /bd reload after editing config.yml to apply changes immediately.
Installation
- Download BlockyDonations from BuiltByBit
- Place the JAR in your
plugins/folder - Start or restart the server - default files generate automatically
- Edit
plugins/BlockyDonations/config.ymlwith your store credentials - Run
/bd reloador restart again to activate
PlaceholderAPI required: Install PlaceholderAPI separately for %bd_*% placeholders to work in scoreboards, holograms and NPCs.
Configuration
Store Provider
store:
provider: "tebex" # tebex | craftingstore | minestorecms | mcsets
tebex:
secret-key: "YOUR_TEBEX_SECRET_KEY_HERE"
craftingstore:
api-token: "YOUR_CRAFTINGSTORE_TOKEN_HERE"
mcsets:
api-key: "ss_YOUR_API_KEY_HERE"
base-url: "https://app.mcsets.com/api/v1/setstore"
minestorecms:
secret-key: "YOUR_MINESTORECMS_SECRET_KEY_HERE"
store-url: "https://store.yourserver.com"
Database
BlockyDonations can use SQLite (local file) or MySQL/MariaDB (external). MySQL enables multi-server clustering with automatic leader election.
database:
type: "sqlite" # sqlite | mysql | mariadb
sqlite:
file: "donations.db"
mysql:
host: "127.0.0.1"
port: 3306
database: "blockydonations"
username: "root"
password: "change-me"
use-ssl: false
parameters: "useUnicode=true&characterEncoding=utf8&serverTimezone=UTC"
Sync Settings
sync:
interval: 120 # seconds between syncs (min 30)
fetch-limit: 50 # max purchases per sync cycle
Broadcast Message
The broadcast is a YAML list - each entry is one chat line sent together. Player head rows ({player_head_1} through {player_head_8}) render the player's face texture alongside the text. All messages support full MiniMessage syntax including gradients, colors, hover effects and click events.
broadcast:
enabled: true
message:
- ' '
- '{player_head_1} <#FF8800>✦ <gradient:#FF8800:#FFD700><bold>New Donation!</bold></gradient>'
- '{player_head_2}'
- '{player_head_3} <white>Player: <#FFD700>{player}'
- '{player_head_4} <white>Package: <#00BBFF>{package}'
- '{player_head_5} <white>Amount: <#49FF00>{amount_formatted}'
- '{player_head_6}'
- '{player_head_7} <click:open_url:"https://store.servername.com"><hover:show_text:"<gold>Click to Open!"><#FFD700>Visit our store!</hover></click>'
- '{player_head_8} <white>Write <#FFD700>"GG" <white>in chat to celebrate! <#FF3232>❤'
- ' '
sound:
enabled: true
type: "ENTITY_PLAYER_LEVELUP"
volume: 1.0
pitch: 1.0
head-render-type: "helm" # helm (with hat) | avatar (raw face)
Broadcast Placeholders
{player} Player name
{package} Package / product name
{amount} Raw amount (e.g. 9.99)
{amount_formatted} Amount with symbol (e.g. $9.99)
{currency} ISO currency code
{currency_symbol} Symbol (e.g. $)
{provider} Store provider name
{store_name} Store display name
{store_url} Store URL
{store_url_encoded} URL-encoded (use in open_url tags)
{player_head_1..8} Full 8-pixel row (top=1, bottom=8)
{player_head} Row 1 only (compact)
{player_face_url} mc-heads.net avatar URL
{skin_minotar_avatar} Minotar avatar URL
{skin_minotar_helm} Minotar with hat
{skin_starlight_archer} StarlightSkins archer pose
Commands
Base command: /blockydonations - aliases: /bd, /blockydon, /d, /donations
Permissions
| Node | Default | Description |
|---|---|---|
| blockydonations.* | op | All BlockyDonations permissions. |
| blockydonations.admin | op | All admin commands: reload, sync, test, status, update. |
| blockydonations.command.reload | op | Use /bd reload. |
| blockydonations.command.sync | op | Use /bd sync. |
| blockydonations.command.test | op | Use /bd test. |
| blockydonations.command.status | op | Use /bd status. |
| blockydonations.command.top | true | Use /bd top - open to all players by default. |
| blockydonations.command.stats | op | Use /bd stats. |
| blockydonations.command.goals | op | Use /bd goals. |
| blockydonations.command.sales | op | Use /bd sales. |
| blockydonations.command.update | op | Use /bd update. |
PlaceholderAPI
All placeholders require PlaceholderAPI to be installed. Every placeholder starts with %bd_.
Store Info
%bd_store_name% Store display name
%bd_store_url% Store URL
%bd_store_currency% Currency code (e.g. USD)
%bd_store_currency_symbol% Currency symbol (e.g. $)
%bd_store_provider% Provider name (e.g. tebex)
Latest Donation
%bd_latest_player% Donor username
%bd_latest_package% Package name
%bd_latest_amount% Raw amount
%bd_latest_amount_formatted% Amount with symbol
%bd_latest_currency% Currency code
Revenue
%bd_revenue_total% Total revenue (raw)
%bd_revenue_monthly% Monthly revenue (raw)
%bd_revenue_total_formatted% Total with symbol
%bd_revenue_monthly_formatted% Monthly with symbol
Leaderboards
Replace alltime with monthly or recent. Replace 1 with any rank from 1 to 10.
%bd_top_alltime_1% Rank 1 player name
%bd_top_alltime_1_amount% Raw amount
%bd_top_alltime_1_formatted% Amount with symbol
%bd_top_alltime_1_uuid% Player UUID
%bd_top_alltime_1_skin% Minotar head URL
%bd_top_alltime_1_skin_helm% Helmet render URL
%bd_top_alltime_1_skin_avatar% Avatar render URL
%bd_top_alltime_1_skin_bust% Bust render URL
%bd_top_alltime_1_skin_body% Full body render URL
Player Statistics
%bd_player_total% Total donated (raw)
%bd_player_monthly% Monthly total (raw)
%bd_player_recent% Recent total (configurable days)
%bd_player_total_formatted% Total with symbol
%bd_player_monthly_formatted% Monthly with symbol
%bd_player_recent_formatted% Recent with symbol
%bd_player_rank_alltime% Player's all-time leaderboard rank
Goals
%bd_goal_name% Goal name
%bd_goal_current% Current progress (raw)
%bd_goal_target% Target amount (raw)
%bd_goal_target_formatted% Target with symbol
%bd_goal_percent% Completion percentage
%bd_goal_remaining% Amount remaining
%bd_goal_bar% Visual progress bar
%bd_goal_completed% true / false
%bd_goal_completions% Total times goal reached
Sales
%bd_sale_name% Active sale name
%bd_sale_discount% Discount percentage
%bd_sale_active% true / false
Broadcast
All broadcast text supports full MiniMessage syntax including gradients, hover events and click events. Player head rows use Minotar to sample the face texture and render it as Unicode characters across consecutive chat lines.
Head Render Type
broadcast:
head-render-type: "helm" # helm (with hat layer) | avatar (raw face only)
Skin Render URLs
Use these in Discord embeds or custom messages:
{skin_minotar_avatar} Minotar avatar
{skin_minotar_helm} Minotar with hat
{skin_minotar_bust} Minotar bust
{skin_minotar_body} Minotar full body
{skin_starlight_archer} StarlightSkins archer pose
{skin_starlight_bust} StarlightSkins bust
{skin_starlight_chibi} StarlightSkins chibi
Chat Reactions (GG Wave)
A reaction window opens for all players after each donation. Players type reaction words (like "GG") to celebrate. Reactions can be styled with rainbow, gradient, or solid colors.
Basic Configuration
chat-reactions:
enabled: true
listener-priority: "LOWEST" # HIGHEST | HIGH | NORMAL | LOW | LOWEST
window-seconds: 15
min-amount: 2 # Minimum donation to trigger the wave (0 = no minimum)
chance: 50 # 0-100 chance for wave to activate
match-anywhere: true # false = exact match, true = word appears anywhere
case-sensitive: false
words:
- "gg"
- "ggs"
- "thank you"
- "thanks"
- "w"
- "pog"
- "poggers"
Text Formatting
chat-reactions:
format: "rainbow" # rainbow | gradient | solid | solidrainbow
rainbow:
gradient: "#FF0000:#FF9A00:#FFF200:#00D26A:#8B00FF"
gradient-smoothness: 8 # 2-32 (higher = smoother)
solid-color: "#FFD700"
solid-rainbow-colors:
- "#FF0000"
- "#FF7700"
- "#FFFF00"
- "#00FF00"
- "#00FFFF"
- "#0077FF"
decorations:
bold: true
italic: false
underline: false
Rewards
Execute commands when players type reaction words. Use {player} placeholder.
chat-reactions:
rewards:
enabled: true
commands:
- "[CONSOLE] eco give {player} 100"
run-once-per-wave: false # true = player gets rewards only once per wave
chance: 25 # 0-100 chance to run when reaction word is typed
Sounds
chat-reactions:
sounds:
wave-start:
enabled: true
type: "item.goat_horn.sound.0"
volume: 1.0
pitch: 1.0
category: "MASTER"
Regex Patterns
Match messages using Java regex for advanced customization. Patterns are tested before the word list.
chat-reactions:
patterns:
- pattern: "(?i)^g+$" # Match one or more 'g's (case insensitive)
replace-with: "GG"
color: "gradient"
sound:
type: "entity.player_levelup"
volume: 1.0
pitch: 1.2
broadcast: true
Discord Webhook
Setup
- Open Discord server settings, go to Integrations, then Webhooks.
- Create a new webhook, choose a channel, copy the URL.
- Create a separate webhook for goals (optional).
- Paste URLs into
discord.yml. - Run
/bd reload.
Donation Embed
discord:
enabled: false
webhook-url: "https://discord.com/api/webhooks/YOUR_WEBHOOK_ID/YOUR_WEBHOOK_TOKEN"
donation-embed:
title: "New Donation! 🎉"
description: "**{player}** donated **{currency_symbol}{amount}** for **{package}**!\nThank you for supporting the server! ❤️"
color: "#36CC00"
footer: "Server Goal: {goal_percent}% / 100% {goal_bar}"
timestamp:
enabled: true
author:
enabled: true # Shows donator's head and name
image:
provider: "starlight" # minotar | starlight | none
placement: "image" # thumbnail | image | description | none
minotar:
type: "helm" # avatar | helm | bust | body | skin
size: 128
starlight:
type: "random" # archer | bust | chibi | portrait | default | etc
branding-images:
- url: "https://leafstudios.dev/images/logo_small.png"
placement: "thumbnail"
Goal Reached Embed
Sent to a separate webhook channel when the server reaches its monthly goal.
discord:
goal-embed:
enabled: true
title: "🎉 Goal Reached! 🎉"
description: "Thanks to **{latest_donator}** and everyone who donated.\n\nWe've reached our goal of **{goal_target_formatted}**!\nThis is completion #**{goal_completions}**. Y'all are amazing! ❤️\n\nAll-time top donor: **{top_donator}** ({top_donator_amount})"
color: "#FFD700"
footer: "Server Goal: 100% 🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩"
timestamp:
enabled: true
Discord sends are queued and dispatched at most once per second to avoid rate limits.
Leaderboards
Three leaderboard types are maintained independently:
- alltime - total donations since install
- monthly - current calendar month, resets on the 1st
- recent - past N days, configured via
leaderboard.recent-days
leaderboard:
size: 10 # Show top 10 players
recent-days: 7 # "recent" leaderboard looks back 7 days
Use /bd top to display a leaderboard in-game, or reference values in holograms and scoreboards via PlaceholderAPI placeholders.
Goals
Auto-fetched from your store. BlockyDonations automatically detects and uses goals configured in your store provider (Tebex, CraftingStore, MineStoreCMS, McSets). If a goal is set in your store, it will be synchronized automatically — no manual config needed.
Set a monetary target for your community to reach each month. When the goal is completed, BlockyDonations fires an in-game announcement and sends a dedicated Discord embed.
goals:
track-completions: true # Track how many times goal was reached
announce-in-chat: true # Show in-game announcement when goal reached
progress-bar-length: 25
progress-bar-style: "pipes" # blocks | pipes | custom
progress-bar-filled: "█"
progress-bar-empty: "█"
progress-bar-color-filled: "<green><b>"
progress-bar-color-empty: "<gray><b>"
Effects
Visual and audio effects that fire for all online players when a donation is detected.
Fireworks
effects:
firework:
enabled: true
type: BALL_LARGE # BALL | BALL_LARGE | BURST | CREEPER | STAR
power: 1 # 0-4 (higher = longer fuse / goes higher)
flicker: true
trail: true
colors:
- ORANGE
- YELLOW
fade-colors: [] # Leave empty to use same as colors
Lightning & Title
effects:
lightning:
enabled: false
damaging: false # Visual only (true = deals damage)
title:
enabled: false
title: "<gradient:#FF8800:#FFD700><bold>✦ New Donation! ✦</bold></gradient>"
subtitle: "<#FFD700>{player} <white>donated <#49FF00>{amount_formatted}</white>!"
fade-in: 10 # ticks (20 = 1 second)
stay: 60
fade-out: 20