Added Task 7: Set Up DNS (Cloudflare) before Nginx configuration. Michael needs to: 1. Add A record: webhook.firefrostgaming.com → 63.143.34.217 2. Set to DNS only (proxy OFF) 3. Verify DNS propagation with dig Renumbered subsequent tasks (Nginx is now Task 8, Holly prep is Task 9). Chronicler #40
38 KiB
Firefrost Gaming - Subscription Automation Guide
Version: 1.0
Date: March 23, 2026
Author: Chronicler #40
Audience: Holly (Lead Builder) + Michael (for Discord bot setup)
Purpose: Automate subscriber tier assignment from Paymenter purchase to in-game ranks
📋 TABLE OF CONTENTS
- Overview
- Architecture
- Prerequisites
- Part 1: Discord Bot Setup
- Part 2: Discord Roles Configuration
- Part 3: LuckPerms Groups & Permissions
- Part 4: LuckPerms Discord Integration
- Part 5: Paymenter Webhook Configuration
- Testing & Verification
- Troubleshooting
🎯 OVERVIEW
What This Guide Does
This guide sets up fully automated subscription management:
- User purchases subscription in Paymenter
- Paymenter sends webhook to Discord bot
- Discord bot assigns appropriate role to user
- LuckPerms detects Discord role and syncs to in-game rank
- Player automatically gets correct permissions on all 13 servers
No manual work required after setup.
The Flow
User Subscribes ($1-$499)
↓
Paymenter (billing.firefrostgaming.com)
↓
Webhook fires (new purchase detected)
↓
Discord Bot receives webhook
↓
Bot assigns Discord role (The Awakened, Fire Elemental, etc.)
↓
LuckPerms syncs Discord role → In-game group
↓
Player gets permissions on all 13 servers instantly
↓
Player can join servers, claim chunks, set homes (based on tier)
Time Estimate
- Discord Bot Setup: 1-2 hours (Michael + Holly)
- Discord Roles: 30 minutes (Holly)
- LuckPerms Configuration: 2-3 hours (Holly, across all 13 servers)
- Paymenter Webhooks: 1 hour (Michael + Holly testing)
Total: 4-6 hours
🏗️ ARCHITECTURE
Components
- Paymenter (billing.firefrostgaming.com) - Billing system
- Discord Server - Community hub
- Discord Bot - Automation middleman
- LuckPerms - Permission management (all 13 game servers)
- MySQL Database - Shared permission storage
Why This Design?
Why not direct Paymenter → LuckPerms?
- Discord is the community hub - subscribers want Discord access too
- Discord roles provide social status and channel access
- Discord bot can handle complex logic (upgrades, downgrades, cancellations)
- Easier to troubleshoot (can see Discord roles visually)
Why LuckPerms syncs FROM Discord?
- Industry standard approach
- Discord becomes "source of truth" for subscriber status
- If someone loses subscriber role in Discord, they automatically lose in-game perks
- Prevents desync between Discord and game servers
✅ PREREQUISITES
Before You Start
Complete these first:
- Server-Side Mod Deployment Guide completed on ALL 13 servers
- LuckPerms installed and connected to MySQL on all servers
- Michael has created MySQL database and provided credentials
- You have admin access to Firefrost Gaming Discord server
- You have access to Paymenter admin panel
What You'll Need
From Michael:
- Discord bot token (Michael will create this)
- Paymenter admin credentials
- MySQL database credentials (already provided for LuckPerms)
Access Required:
- Discord server admin permissions
- Pterodactyl panel access (to restart servers)
- SSH access to game servers (for testing)
🤖 PART 1: DISCORD BOT SETUP
🔧 MICHAEL'S PRE-SETUP (Complete BEFORE Holly Starts)
STOP: Michael must complete this entire section BEFORE handing the guide to Holly.
Task 1: Create Discord Application & Bot
Michael's steps:
- Go to https://discord.com/developers/applications
- Click New Application
- Name: "Firefrost Subscription Manager"
- Click Create
Task 2: Configure Bot Settings
- In the application, go to Bot tab (left sidebar)
- Click Add Bot → Yes, do it!
- Under Privileged Gateway Intents, enable:
- ✅ Server Members Intent (REQUIRED - bot needs to assign roles)
- ✅ Message Content Intent (REQUIRED - bot needs to read webhook data)
- Click Save Changes
Task 3: Get Bot Token
- Under Bot tab, find Token section
- Click Reset Token (confirm if asked)
- Click Copy to copy the token
- SAVE THIS TOKEN SECURELY - you'll give it to Holly later
The token looks like:
MTxxxxxxxxxxxxxxxxxxxxxx.xxxxxx.xxxxxxxxxxxxxxxxxxxxxxxxxxx
⚠️ NEVER share this token publicly or commit it to git!
Task 4: Invite Bot to Discord Server
- Go to OAuth2 tab → URL Generator (left sidebar)
- Under Scopes, select:
- ✅
bot - ✅
applications.commands
- ✅
- Under Bot Permissions, select:
- ✅ Manage Roles (REQUIRED - assigns subscriber roles)
- ✅ Send Messages (for welcome DMs)
- ✅ Read Message History (optional)
- ✅ Use Slash Commands (future-proofing)
- Scroll down and Copy the generated URL
- Open the URL in a new browser tab
- Select Firefrost Gaming server from dropdown
- Click Authorize
- Complete the CAPTCHA
The bot should now appear in your Discord server's member list (offline status is normal - it's not running yet).
Task 5: Get Discord Server ID (Guild ID)
- Open Discord
- Go to User Settings (gear icon)
- Go to Advanced (left sidebar)
- Enable Developer Mode ✅
- Close settings
- Right-click your Firefrost Gaming server icon
- Click Copy Server ID
- Save this ID - you'll give it to Holly
The ID looks like:
123456789012345678
Task 6: Deploy Bot Code on Command Center
SSH to Command Center:
ssh root@63.143.34.217
Install Node.js (if not already installed):
# Check if Node.js is installed
node --version
# If not installed or version < 18, install Node.js 20:
curl -fsSL https://deb.nodesource.com/setup_20.x | bash -
apt-get install -y nodejs
# Verify
node --version # Should show v20.x.x
npm --version # Should show 10.x.x
Create bot directory:
mkdir -p /opt/firefrost-discord-bot
cd /opt/firefrost-discord-bot
Create package.json:
cat > package.json << 'EOF'
{
"name": "firefrost-discord-bot",
"version": "1.0.0",
"description": "Firefrost Gaming subscription automation bot",
"main": "bot.js",
"scripts": {
"start": "node bot.js"
},
"dependencies": {
"discord.js": "^14.14.1",
"express": "^4.18.2",
"body-parser": "^1.20.2"
}
}
EOF
Install dependencies:
npm install
Create bot.js file:
cat > bot.js << 'EOF'
// Firefrost Gaming - Discord Subscription Bot
// Handles Paymenter webhooks and assigns Discord roles
const { Client, GatewayIntentBits } = require('discord.js');
const express = require('express');
const bodyParser = require('body-parser');
// Configuration - REPLACE THESE VALUES
const DISCORD_TOKEN = 'YOUR_BOT_TOKEN_HERE';
const GUILD_ID = 'YOUR_GUILD_ID_HERE';
// Product ID to Role ID mapping (from Paymenter)
// Holly will fill these in after creating Discord roles
const PRODUCT_ROLE_MAP = {
'2': 'AWAKENED_ROLE_ID',
'3': 'FIRE_ELEMENTAL_ROLE_ID',
'4': 'FROST_ELEMENTAL_ROLE_ID',
'5': 'FIRE_KNIGHT_ROLE_ID',
'6': 'FROST_KNIGHT_ROLE_ID',
'7': 'FIRE_MASTER_ROLE_ID',
'8': 'FROST_MASTER_ROLE_ID',
'9': 'FIRE_LEGEND_ROLE_ID',
'10': 'FROST_LEGEND_ROLE_ID',
'11': 'SOVEREIGN_ROLE_ID'
};
// Initialize Discord client
const client = new Client({
intents: [
GatewayIntentBits.Guilds,
GatewayIntentBits.GuildMembers
]
});
// Initialize Express for webhook receiver
const app = express();
app.use(bodyParser.json());
// Discord bot ready event
client.once('ready', () => {
console.log(`✅ Bot logged in as ${client.user.tag}`);
console.log(`🔗 Connected to ${client.guilds.cache.size} server(s)`);
});
// Webhook endpoint - Paymenter sends POST here
app.post('/webhook/paymenter', async (req, res) => {
try {
console.log('📬 Received webhook from Paymenter');
console.log('Payload:', JSON.stringify(req.body, null, 2));
const { event, product_id, user_email, discord_id } = req.body;
// Validate webhook
if (!event || !product_id) {
console.error('❌ Invalid webhook data - missing event or product_id');
return res.status(400).json({ error: 'Missing required fields' });
}
if (!discord_id) {
console.error('⚠️ No discord_id provided - cannot assign role');
return res.status(400).json({ error: 'Missing discord_id' });
}
console.log(`📦 Event: ${event}, Product: ${product_id}, Discord ID: ${discord_id}`);
// Get Discord guild
const guild = client.guilds.cache.get(GUILD_ID);
if (!guild) {
console.error('❌ Guild not found');
return res.status(500).json({ error: 'Guild not found' });
}
// Get member
const member = await guild.members.fetch(discord_id);
if (!member) {
console.error('❌ Member not found in Discord server');
return res.status(404).json({ error: 'Member not found' });
}
// Get role ID for this product
const roleId = PRODUCT_ROLE_MAP[product_id];
if (!roleId || roleId.includes('ROLE_ID')) {
console.error(`❌ No role mapped for product ${product_id} (or role ID not configured)`);
return res.status(400).json({ error: 'Unknown product or role not configured' });
}
// Handle event
if (event === 'subscription.created' || event === 'payment.completed') {
// Add role
await member.roles.add(roleId);
console.log(`✅ Added role ${roleId} to ${member.user.tag}`);
// Send welcome DM
try {
await member.send(`🎉 Welcome to Firefrost Gaming! Your subscription is now active. Check out the server - your perks are ready!`);
console.log(`📨 Sent welcome DM to ${member.user.tag}`);
} catch (err) {
console.log('⚠️ Could not send DM (user has DMs disabled)');
}
} else if (event === 'subscription.cancelled' || event === 'subscription.expired') {
// Remove role
await member.roles.remove(roleId);
console.log(`❌ Removed role ${roleId} from ${member.user.tag}`);
} else {
console.log(`⚠️ Unknown event type: ${event}`);
}
res.status(200).json({ success: true });
} catch (error) {
console.error('❌ Webhook processing error:', error);
res.status(500).json({ error: 'Internal server error', details: error.message });
}
});
// Health check endpoint
app.get('/health', (req, res) => {
res.status(200).json({
status: 'healthy',
bot: client.user ? client.user.tag : 'disconnected',
uptime: process.uptime()
});
});
// Start Express server
const PORT = 3100;
app.listen(PORT, () => {
console.log(`🌐 Webhook server listening on port ${PORT}`);
console.log(`📍 Webhook URL: http://localhost:${PORT}/webhook/paymenter`);
});
// Start Discord bot
client.login(DISCORD_TOKEN);
EOF
Edit bot.js and add your credentials:
nano bot.js
Find these lines:
const DISCORD_TOKEN = 'YOUR_BOT_TOKEN_HERE';
const GUILD_ID = 'YOUR_GUILD_ID_HERE';
Replace with:
const DISCORD_TOKEN = 'MTxxxx...'; // Your actual bot token from Task 3
const GUILD_ID = '123456789012345678'; // Your actual server ID from Task 5
Save and exit (Ctrl+X, Y, Enter)
Create systemd service:
cat > /etc/systemd/system/firefrost-discord-bot.service << 'EOF'
[Unit]
Description=Firefrost Gaming Discord Bot
After=network.target
[Service]
Type=simple
User=root
WorkingDirectory=/opt/firefrost-discord-bot
ExecStart=/usr/bin/node /opt/firefrost-discord-bot/bot.js
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target
EOF
Enable and start the bot:
# Reload systemd
systemctl daemon-reload
# Enable auto-start on boot
systemctl enable firefrost-discord-bot
# Start the bot
systemctl start firefrost-discord-bot
# Check status
systemctl status firefrost-discord-bot
You should see:
● firefrost-discord-bot.service - Firefrost Gaming Discord Bot
Loaded: loaded
Active: active (running)
View logs to confirm it's working:
journalctl -u firefrost-discord-bot -f
You should see:
✅ Bot logged in as Firefrost Subscription Manager#1234
🔗 Connected to 1 server(s)
🌐 Webhook server listening on port 3100
If you see errors about invalid token:
- Double-check you copied the token correctly
- Make sure there are no extra spaces
- Verify the token hasn't been reset/revoked
Press Ctrl+C to exit log view when done.
Task 7: Set Up DNS (Cloudflare)
Before setting up Nginx, add DNS record:
- Go to https://dash.cloudflare.com
- Select firefrostgaming.com domain
- Go to DNS → Records
- Click Add record
- Configure:
- Type: A
- Name: webhook
- IPv4 address: 63.143.34.217 (Command Center IP)
- Proxy status: 🟠 DNS only (turn OFF the orange cloud)
- TTL: Auto
- Click Save
Wait 1-2 minutes for DNS to propagate.
Verify DNS is working:
# Test DNS resolution
dig webhook.firefrostgaming.com
# Should show:
# webhook.firefrostgaming.com. 300 IN A 63.143.34.217
Task 8: Set Up Nginx Reverse Proxy
Still on Command Center, configure Nginx:
cat > /etc/nginx/sites-available/discord-webhook << 'EOF'
server {
listen 80;
server_name webhook.firefrostgaming.com;
location / {
proxy_pass http://localhost:3100;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_cache_bypass $http_upgrade;
}
}
EOF
Enable the site:
ln -s /etc/nginx/sites-available/discord-webhook /etc/nginx/sites-enabled/
nginx -t
systemctl reload nginx
Get SSL certificate:
certbot --nginx -d webhook.firefrostgaming.com
Test the webhook endpoint:
curl https://webhook.firefrostgaming.com/health
Should return:
{"status":"healthy","bot":"Firefrost Subscription Manager#1234","uptime":123.456}
Task 9: Prepare Information for Holly
Create a file with all the info Holly needs:
cat > /root/holly-bot-credentials.txt << EOF
Firefrost Discord Bot - Credentials for Holly
Bot Name: Firefrost Subscription Manager
Bot Token: $(grep "const DISCORD_TOKEN" /opt/firefrost-discord-bot/bot.js | cut -d"'" -f2)
Guild ID: $(grep "const GUILD_ID" /opt/firefrost-discord-bot/bot.js | cut -d"'" -f2)
Webhook URL: https://webhook.firefrostgaming.com/webhook/paymenter
Bot is installed on: Command Center (63.143.34.217)
Bot directory: /opt/firefrost-discord-bot/
Service name: firefrost-discord-bot
Commands for Holly:
- View logs: journalctl -u firefrost-discord-bot -f
- Restart bot: systemctl restart firefrost-discord-bot
- Edit bot code: nano /opt/firefrost-discord-bot/bot.js
Next Steps:
1. Holly creates Discord roles (Part 2 of guide)
2. Holly gets role IDs and updates bot.js PRODUCT_ROLE_MAP
3. Holly restarts bot: systemctl restart firefrost-discord-bot
4. Test webhook flow
---
Generated: $(date)
EOF
cat /root/holly-bot-credentials.txt
Save this output - you'll give it to Holly.
✅ MICHAEL'S PRE-SETUP COMPLETE
Checklist before handing to Holly:
- Discord bot created and invited to server
- Bot token saved securely
- Guild ID recorded
- Node.js installed on Command Center
- Bot code deployed to /opt/firefrost-discord-bot/
- Bot service running successfully
- Nginx reverse proxy configured
- SSL certificate obtained
- Webhook endpoint accessible at https://webhook.firefrostgaming.com
- Credentials file created for Holly
If all checked, proceed to Part 2 and hand the guide to Holly.
👥 HOLLY'S TASKS START HERE
At this point, Michael has:
- ✅ Created the Discord bot application
- ✅ Deployed bot code to Command Center
- ✅ Set up Nginx reverse proxy
- ✅ Bot is running and accessible at https://webhook.firefrostgaming.com
Holly, you now need to:
- Create Discord roles (Part 2)
- Update bot code with role IDs
- Configure LuckPerms
- Test the complete flow
👥 PART 2: DISCORD ROLES CONFIGURATION
Step 1: Create Discord Roles (Holly's Task)
In your Discord server:
- Right-click server icon → Server Settings
- Click Roles
- Click Create Role for each tier
Create these roles (in order, top to bottom):
Role 1: Sovereign (Founder)
- Name:
⚡ Sovereign - Color:
#FFD600(Amber Gold) - Permissions: (default member permissions)
- Display separately: ✅ Yes
- Mentionable: ✅ Yes
Role 2: Fire Legend
- Name:
🔥 Fire Legend - Color:
#FF3D00(Deep Orange/Red) - Permissions: (default member permissions)
- Display separately: ✅ Yes
Role 3: Frost Legend
- Name:
❄️ Frost Legend - Color:
#00E5FF(Electric Cyan) - Permissions: (default member permissions)
- Display separately: ✅ Yes
Role 4: Fire Master
- Name:
🔥 Fire Master - Color:
#FF3D00 - Permissions: (default member permissions)
- Display separately: ✅ Yes
Role 5: Frost Master
- Name:
❄️ Frost Master - Color:
#00E5FF - Permissions: (default member permissions)
- Display separately: ✅ Yes
Role 6: Fire Knight
- Name:
🔥 Fire Knight - Color:
#FF3D00 - Permissions: (default member permissions)
- Display separately: ✅ Yes
Role 7: Frost Knight
- Name:
❄️ Frost Knight - Color:
#00E5FF - Permissions: (default member permissions)
- Display separately: ✅ Yes
Role 8: Fire Elemental
- Name:
🔥 Fire Elemental - Color:
#FF3D00 - Permissions: (default member permissions)
- Display separately: ✅ Yes
Role 9: Frost Elemental
- Name:
❄️ Frost Elemental - Color:
#00E5FF - Permissions: (default member permissions)
- Display separately: ✅ Yes
Role 10: The Awakened
- Name:
The Awakened - Color:
#FFFFFF(White) - Permissions: (default member permissions)
- Display separately: ✅ Yes
Role 11: Wanderer (Free)
- Name:
Wanderer - Color:
#99AAB5(Gray) - Permissions: Read messages only (restrict Send Messages in channels)
- Display separately: No
Step 2: Get Role IDs
For each role you just created:
- Right-click the role in Server Settings → Roles
- Click Copy ID (if you don't see this, enable Developer Mode in Discord settings)
- Paste the ID somewhere - you'll need them
Create a mapping:
The Awakened: 123456789012345678
Fire Elemental: 234567890123456789
Frost Elemental: 345678901234567890
Fire Knight: 456789012345678901
Frost Knight: 567890123456789012
Fire Master: 678901234567890123
Frost Master: 789012345678901234
Fire Legend: 890123456789012345
Frost Legend: 901234567890123456
Sovereign: 012345678901234567
Step 3: Update Bot Code with Role IDs (Michael's Task)
Holly: After you create all the Discord roles and copy their IDs (from Step 2), give the list to Michael. He'll update the bot code.
Michael: Holly will give you a list like this:
The Awakened: 123456789012345678
Fire Elemental: 234567890123456789
Frost Elemental: 345678901234567890
Fire Knight: 456789012345678901
Frost Knight: 567890123456789012
Fire Master: 678901234567890123
Frost Master: 789012345678901234
Fire Legend: 890123456789012345
Frost Legend: 901234567890123456
Sovereign: 012345678901234567
SSH to Command Center and edit the bot code:
ssh root@63.143.34.217
nano /opt/firefrost-discord-bot/bot.js
Find the PRODUCT_ROLE_MAP section and replace it:
const PRODUCT_ROLE_MAP = {
'2': '123456789012345678', // The Awakened (use Holly's actual ID)
'3': '234567890123456789', // Fire Elemental
'4': '345678901234567890', // Frost Elemental
'5': '456789012345678901', // Fire Knight
'6': '567890123456789012', // Frost Knight
'7': '678901234567890123', // Fire Master
'8': '789012345678901234', // Frost Master
'9': '890123456789012345', // Fire Legend
'10': '901234567890123456', // Frost Legend
'11': '012345678901234567' // Sovereign
};
Save and exit (Ctrl+X, Y, Enter)
Restart the bot:
systemctl restart firefrost-discord-bot
# Verify it restarted successfully
systemctl status firefrost-discord-bot
# Check logs to confirm no errors
journalctl -u firefrost-discord-bot -f
You should see:
✅ Bot logged in as Firefrost Subscription Manager#1234
🌐 Webhook server listening on port 3100
Now hand back to Holly for Part 3.
Step 4: Configure Channel Permissions
Create private channels for Fire/Frost paths:
Fire Path Channels
#🔥-fire-general- Only visible to Fire Elemental+ roles#🔥-fire-builds- Only visible to Fire Elemental+ roles#🔥-fire-strategy- Only visible to Fire Elemental+ roles
Permissions:
- Deny:
@everyone- View Channel - Allow:
@🔥 Fire Elemental,@🔥 Fire Knight,@🔥 Fire Master,@🔥 Fire Legend,@⚡ Sovereign
Frost Path Channels
#❄️-frost-general- Only visible to Frost Elemental+ roles#❄️-frost-builds- Only visible to Frost Elemental+ roles#❄️-frost-strategy- Only visible to Frost Elemental+ roles
Permissions:
- Deny:
@everyone- View Channel - Allow:
@❄️ Frost Elemental,@❄️ Frost Knight,@❄️ Frost Master,@❄️ Frost Legend,@⚡ Sovereign
The Nexus (Sovereign Only)
#⚡-the-nexus- Only visible to Sovereign
Permissions:
- Deny:
@everyone- View Channel - Allow:
@⚡ Sovereignonly
⚙️ PART 3: LUCKPERMS GROUPS & PERMISSIONS
This is the longest section - you'll configure 11 groups across 13 servers.
Step 1: Create LuckPerms Groups
Access ONE game server's console first (we'll sync to others after):
- Go to https://panel.firefrostgaming.com
- Click on any server (doesn't matter which - they all share the MySQL database)
- Click Console tab
- Make sure server is running (start it if stopped)
Then run these commands in the console:
Create Wanderer Group (Free Tier)
/lp creategroup wanderer
/lp group wanderer setweight 10
/lp group wanderer meta setprefix "&7[Wanderer] "
/lp group wanderer meta setsuffix ""
Create Awakened Group ($1 Tier)
/lp creategroup awakened
/lp group awakened parent add wanderer
/lp group awakened setweight 20
/lp group awakened meta setprefix "&f[The Awakened] "
# Permissions
/lp group awakened permission set ftbessentials.home.set true
/lp group awakened permission set ftbessentials.home.teleport true
/lp group awakened meta setmeta max-homes 1
Create Fire Elemental Group ($5/mo)
/lp creategroup fire_elemental
/lp group fire_elemental parent add awakened
/lp group fire_elemental setweight 30
/lp group fire_elemental meta setprefix "&c[🔥 Fire Elemental] "
# Permissions
/lp group fire_elemental meta setmeta max-homes 5
/lp group fire_elemental permission set ftbchunks.claim true
/lp group fire_elemental meta setmeta max-claimed-chunks 25
/lp group fire_elemental permission set ftbessentials.rtp true
/lp group fire_elemental meta setmeta rtp-cooldown 3600
Create Frost Elemental Group ($5/mo)
/lp creategroup frost_elemental
/lp group frost_elemental parent add awakened
/lp group frost_elemental setweight 30
/lp group frost_elemental meta setprefix "&b[❄️ Frost Elemental] "
# Permissions (same as Fire Elemental)
/lp group frost_elemental meta setmeta max-homes 5
/lp group frost_elemental permission set ftbchunks.claim true
/lp group frost_elemental meta setmeta max-claimed-chunks 25
/lp group frost_elemental permission set ftbessentials.rtp true
/lp group frost_elemental meta setmeta rtp-cooldown 3600
Create Fire Knight Group ($10/mo)
/lp creategroup fire_knight
/lp group fire_knight parent add fire_elemental
/lp group fire_knight setweight 40
/lp group fire_knight meta setprefix "&c[🔥 Fire Knight] "
# Permissions
/lp group fire_knight meta setmeta max-homes 10
/lp group fire_knight meta setmeta max-claimed-chunks 49
/lp group fire_knight meta setmeta max-force-loaded-chunks 4
/lp group fire_knight meta setmeta rtp-cooldown 1800
Create Frost Knight Group ($10/mo)
/lp creategroup frost_knight
/lp group frost_knight parent add frost_elemental
/lp group frost_knight setweight 40
/lp group frost_knight meta setprefix "&b[❄️ Frost Knight] "
# Permissions (same as Fire Knight)
/lp group frost_knight meta setmeta max-homes 10
/lp group frost_knight meta setmeta max-claimed-chunks 49
/lp group frost_knight meta setmeta max-force-loaded-chunks 4
/lp group frost_knight meta setmeta rtp-cooldown 1800
Create Fire Master Group ($15/mo)
/lp creategroup fire_master
/lp group fire_master parent add fire_knight
/lp group fire_master setweight 50
/lp group fire_master meta setprefix "&c[🔥 Fire Master] "
# Permissions
/lp group fire_master meta setmeta max-homes 20
/lp group fire_master meta setmeta max-claimed-chunks 100
/lp group fire_master meta setmeta max-force-loaded-chunks 9
/lp group fire_master meta setmeta rtp-cooldown 900
Create Frost Master Group ($15/mo)
/lp creategroup frost_master
/lp group frost_master parent add frost_knight
/lp group frost_master setweight 50
/lp group frost_master meta setprefix "&b[❄️ Frost Master] "
# Permissions
/lp group frost_master meta setmeta max-homes 20
/lp group frost_master meta setmeta max-claimed-chunks 100
/lp group frost_master meta setmeta max-force-loaded-chunks 9
/lp group frost_master meta setmeta rtp-cooldown 900
Create Fire Legend Group ($20/mo)
/lp creategroup fire_legend
/lp group fire_legend parent add fire_master
/lp group fire_legend setweight 60
/lp group fire_legend meta setprefix "&c[🔥 Fire Legend] "
# Permissions
/lp group fire_legend meta setmeta max-homes 35
/lp group fire_legend meta setmeta max-claimed-chunks 121
/lp group fire_legend meta setmeta max-force-loaded-chunks 16
/lp group fire_legend meta setmeta rtp-cooldown 600
Create Frost Legend Group ($20/mo)
/lp creategroup frost_legend
/lp group frost_legend parent add frost_master
/lp group frost_legend setweight 60
/lp group frost_legend meta setprefix "&b[❄️ Frost Legend] "
# Permissions
/lp group frost_legend meta setmeta max-homes 35
/lp group frost_legend meta setmeta max-claimed-chunks 121
/lp group frost_legend meta setmeta max-force-loaded-chunks 16
/lp group frost_legend meta setmeta rtp-cooldown 600
Create Sovereign (Founder) Group ($499 Lifetime)
/lp creategroup sovereign
/lp group sovereign parent add awakened
/lp group sovereign setweight 100
/lp group sovereign meta setprefix "&6[⚡ Founder] "
# Permissions (maximum everything)
/lp group sovereign meta setmeta max-homes 50
/lp group sovereign meta setmeta max-claimed-chunks 225
/lp group sovereign meta setmeta max-force-loaded-chunks 81
/lp group sovereign permission set ftbessentials.rtp true
# No rtp cooldown for Sovereign
Step 2: Verify Groups Created
/lp listgroups
You should see all 11 groups listed.
Step 3: Sync to All Other Servers
Because all servers connect to the SAME MySQL database, the groups are already synced!
To verify on another server:
- Go to Pterodactyl Panel
- Open console for a different server
- Run
/lp listgroups - Should show the same 11 groups
If groups don't appear:
- Check that server's LuckPerms config points to the MySQL database
- Restart the server
🔗 PART 4: LUCKPERMS DISCORD INTEGRATION
This connects Discord roles to LuckPerms groups.
Step 1: Enable Discord Integration in LuckPerms
On EVERY server, edit /config/luckperms/luckperms.conf:
Find the section:
# Discord integration
discord-integration {
enabled = false
}
Change to:
discord-integration {
enabled = true
# Role to group mappings
role-mappings {
# Format: "discord-role-id" = "luckperms-group"
"123456789012345678" = "awakened" # The Awakened
"234567890123456789" = "fire_elemental" # Fire Elemental
"345678901234567890" = "frost_elemental" # Frost Elemental
"456789012345678901" = "fire_knight" # Fire Knight
"567890123456789012" = "frost_knight" # Frost Knight
"678901234567890123" = "fire_master" # Fire Master
"789012345678901234" = "frost_master" # Frost Master
"890123456789012345" = "fire_legend" # Fire Legend
"901234567890123456" = "frost_legend" # Frost Legend
"012345678901234567" = "sovereign" # Sovereign
}
}
Replace role IDs with the ACTUAL role IDs you copied in Part 2.
Save the file.
Step 2: Restart All Servers
Via Pterodactyl Panel:
- Open each server's console
- Click Restart
- Wait for server to come back online
Repeat for all 13 servers.
Step 3: Test Discord → LuckPerms Sync
Manual test:
- Go to Discord
- Manually assign yourself
The Awakenedrole (right-click your name → Roles) - Join a Minecraft server
- Run
/lp user YourUsername info - Should show you're in the
awakenedgroup
If it doesn't work:
- Check LuckPerms config for typos in role IDs
- Check that Discord integration is enabled
- Restart the server
🪝 PART 5: PAYMENTER WEBHOOK CONFIGURATION
This connects Paymenter to the Discord bot.
Step 1: Set Up Nginx Proxy (Michael's Task)
On Command Center (where Discord bot runs):
Create file: /etc/nginx/sites-available/discord-bot-webhook
server {
listen 80;
server_name webhook.firefrostgaming.com;
location / {
proxy_pass http://localhost:3100;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
Enable the site:
ln -s /etc/nginx/sites-available/discord-bot-webhook /etc/nginx/sites-enabled/
nginx -t
systemctl reload nginx
Get SSL certificate:
certbot --nginx -d webhook.firefrostgaming.com
Now the webhook endpoint is:
https://webhook.firefrostgaming.com/webhook/paymenter
Step 2: Configure Paymenter Webhooks (Michael + Holly)
In Paymenter admin panel:
- Go to Settings → Webhooks
- Click Add Webhook
- Configure:
- URL:
https://webhook.firefrostgaming.com/webhook/paymenter - Events:
- ✅
subscription.created - ✅
payment.completed - ✅
subscription.cancelled - ✅
subscription.expired
- ✅
- Payload Format: JSON
- URL:
- Click Save
Step 3: Test Webhook
Create a test purchase in Paymenter (use test mode if available).
Watch Discord bot logs:
journalctl -u firefrost-discord-bot -f
You should see:
📬 Received webhook from Paymenter
📦 Event: subscription.created, Product: 2, User: 123456789012345678
✅ Added role 123456789012345678 to TestUser#1234
If it works, the user should now have The Awakened role in Discord.
If it doesn't work:
- Check webhook URL is correct
- Check Paymenter is sending the correct payload format
- Check Discord bot logs for errors
✅ TESTING & VERIFICATION
End-to-End Test
Complete flow test:
- Create test user in Discord
- Purchase Awakened tier ($1) in Paymenter
- Verify webhook fires (check Discord bot logs)
- Verify Discord role assigned (check Discord - user should have "The Awakened" role)
- Join Minecraft server
- Run
/lp user TestUser info- Should showawakenedgroup - Test permissions:
/sethome test- Should work (1 home allowed)/sethome test2- Should FAIL (only 1 home for Awakened)- Try claiming chunks - Should FAIL (Awakened has 0 chunk claims)
- Try
/rtp- Should FAIL (Awakened has no /rtp access)
If all these work correctly, the automation is functioning!
Upgrade Test
Test tier upgrade:
- Upgrade test user to Fire Elemental ($5/mo) in Paymenter
- Verify Discord role changes (old role removed, new role added)
- Join Minecraft server
- Run
/lp user TestUser info- Should showfire_elementalgroup - Test new permissions:
/sethome- Should work (5 homes allowed)- Claim chunks - Should work (25 chunks allowed)
/rtp- Should work (60 minute cooldown)
Cancellation Test
Test subscription cancellation:
- Cancel test user's subscription in Paymenter
- Verify Discord role removed
- Join Minecraft server
- Run
/lp user TestUser info- Should showwandereror default group - Test permissions:
/sethome- Should FAIL (no subscription)- Try joining server - Should be DENIED (whitelist = Awakened+ only)
🔧 TROUBLESHOOTING
Discord Role Not Assigned After Purchase
Symptoms: User purchases subscription but doesn't get Discord role.
Check:
- Webhook logs:
journalctl -u firefrost-discord-bot -f- Are webhooks being received?
- Paymenter webhook config: Is webhook URL correct?
- Discord bot permissions: Does bot have "Manage Roles" permission?
- Role position: Bot's role must be ABOVE subscriber roles in Discord role hierarchy
Solution:
- Move bot's role to the top of the role list in Discord Server Settings
- Restart Discord bot:
systemctl restart firefrost-discord-bot
LuckPerms Not Syncing Discord Roles
Symptoms: User has Discord role but no in-game permissions.
Check:
- LuckPerms config: Is Discord integration enabled?
- Role IDs: Are Discord role IDs correct in luckperms.conf?
- Server restart: Did you restart server after config change?
Solution:
- Double-check role IDs match (right-click role in Discord → Copy ID)
- Ensure luckperms.conf has correct mapping
- Restart all game servers
User Can't Join Server After Subscribing
Symptoms: User purchased subscription, has Discord role, but can't join server.
Check:
- Whitelist status: Is whitelist enabled on server?
- LuckPerms sync: Run
/whitelist add Usernamemanually as test - Server online: Is server actually running?
Solution:
- Ensure LuckPerms-based whitelist is configured (see Server-Side Mod Deployment Guide)
- Check server console for "User not whitelisted" messages
- Manually add to whitelist temporarily while debugging
Webhook Endpoint Returns 500 Error
Symptoms: Paymenter shows webhook failed with 500 error.
Check:
- Bot running:
systemctl status firefrost-discord-bot - Bot logs:
journalctl -u firefrost-discord-bot -ffor errors - Nginx proxy: Is Nginx running and proxying correctly?
Solution:
- Restart Discord bot
- Check bot code for syntax errors
- Test webhook manually with curl:
curl -X POST https://webhook.firefrostgaming.com/webhook/paymenter \ -H "Content-Type: application/json" \ -d '{"event":"subscription.created","product_id":"2","discord_id":"YOUR_DISCORD_ID"}'
📚 REFERENCE
Quick Command Reference
Discord Bot Management
# Start bot
systemctl start firefrost-discord-bot
# Stop bot
systemctl stop firefrost-discord-bot
# Restart bot
systemctl restart firefrost-discord-bot
# View logs
journalctl -u firefrost-discord-bot -f
# Check status
systemctl status firefrost-discord-bot
LuckPerms Commands
# View user's groups
/lp user <username> info
# Manually add user to group
/lp user <username> parent add <groupname>
# Remove user from group
/lp user <username> parent remove <groupname>
# View group permissions
/lp group <groupname> permission info
# List all groups
/lp listgroups
Subscriber Tier → Discord Role → LuckPerms Group Mapping
| Tier | Price | Discord Role | LuckPerms Group |
|---|---|---|---|
| Wanderer | Free | Wanderer |
wanderer |
| Awakened | $1 | The Awakened |
awakened |
| Fire Elemental | $5/mo | 🔥 Fire Elemental |
fire_elemental |
| Frost Elemental | $5/mo | ❄️ Frost Elemental |
frost_elemental |
| Fire Knight | $10/mo | 🔥 Fire Knight |
fire_knight |
| Frost Knight | $10/mo | ❄️ Frost Knight |
frost_knight |
| Fire Master | $15/mo | 🔥 Fire Master |
fire_master |
| Frost Master | $15/mo | ❄️ Frost Master |
frost_master |
| Fire Legend | $20/mo | 🔥 Fire Legend |
fire_legend |
| Frost Legend | $20/mo | ❄️ Frost Legend |
frost_legend |
| Sovereign | $499 | ⚡ Sovereign |
sovereign |
File Locations Quick Reference
Command Center (63.143.34.217)
└── /opt/firefrost-discord-bot/
├── bot.js
├── package.json
└── node_modules/
Game Servers (TX1/NC1)
└── /config/luckperms/
└── luckperms.conf (Discord integration config)
Nginx
└── /etc/nginx/sites-available/
└── discord-bot-webhook
End of Subscription Automation Guide
You've now completed the full automation setup! Users can subscribe in Paymenter and automatically get:
- Discord role assignment
- In-game rank sync
- Correct permissions on all 13 servers
- Channel access based on Fire/Frost path
Fire + Frost + Foundation = Where Love Builds Legacy 🔥❄️
Document Version: 1.0
Last Updated: March 23, 2026
Maintained By: Firefrost Gaming Infrastructure Team