# 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 1. [Overview](#overview) 2. [Architecture](#architecture) 3. [Prerequisites](#prerequisites) 4. [Part 1: Discord Bot Setup](#part-1-discord-bot-setup) 5. [Part 2: Discord Roles Configuration](#part-2-discord-roles-configuration) 6. [Part 3: LuckPerms Groups & Permissions](#part-3-luckperms-groups-permissions) 7. [Part 4: LuckPerms Discord Integration](#part-4-luckperms-discord-integration) 8. [Part 5: Paymenter Webhook Configuration](#part-5-paymenter-webhook-configuration) 9. [Testing & Verification](#testing-verification) 10. [Troubleshooting](#troubleshooting) --- ## 🎯 OVERVIEW ### What This Guide Does This guide sets up **fully automated subscription management**: 1. User purchases subscription in Paymenter 2. Paymenter sends webhook to Discord bot 3. Discord bot assigns appropriate role to user 4. LuckPerms detects Discord role and syncs to in-game rank 5. 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 1. **Paymenter** (billing.firefrostgaming.com) - Billing system 2. **Discord Server** - Community hub 3. **Discord Bot** - Automation middleman 4. **LuckPerms** - Permission management (all 13 game servers) 5. **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:** 1. Go to https://discord.com/developers/applications 2. Click **New Application** 3. Name: "Firefrost Subscription Manager" 4. Click **Create** ### Task 2: Configure Bot Settings 1. In the application, go to **Bot** tab (left sidebar) 2. Click **Add Bot** → **Yes, do it!** 3. Under **Privileged Gateway Intents**, enable: - ✅ **Server Members Intent** (REQUIRED - bot needs to assign roles) - ✅ **Message Content Intent** (REQUIRED - bot needs to read webhook data) 4. Click **Save Changes** ### Task 3: Get Bot Token 1. Under **Bot** tab, find **Token** section 2. Click **Reset Token** (confirm if asked) 3. Click **Copy** to copy the token 4. **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 1. Go to **OAuth2** tab → **URL Generator** (left sidebar) 2. Under **Scopes**, select: - ✅ `bot` - ✅ `applications.commands` 3. Under **Bot Permissions**, select: - ✅ **Manage Roles** (REQUIRED - assigns subscriber roles) - ✅ **Send Messages** (for welcome DMs) - ✅ **Read Message History** (optional) - ✅ **Use Slash Commands** (future-proofing) 4. Scroll down and **Copy** the generated URL 5. Open the URL in a new browser tab 6. Select **Firefrost Gaming** server from dropdown 7. Click **Authorize** 8. 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) 1. Open Discord 2. Go to **User Settings** (gear icon) 3. Go to **Advanced** (left sidebar) 4. Enable **Developer Mode** ✅ 5. Close settings 6. Right-click your **Firefrost Gaming** server icon 7. Click **Copy Server ID** 8. **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:** ```bash ssh root@63.143.34.217 ``` **Install Node.js (if not already installed):** ```bash # 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:** ```bash mkdir -p /opt/firefrost-discord-bot cd /opt/firefrost-discord-bot ``` **Create package.json:** ```bash 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:** ```bash npm install ``` **Create bot.js file:** ```bash 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:** ```bash nano bot.js ``` **Find these lines:** ```javascript const DISCORD_TOKEN = 'YOUR_BOT_TOKEN_HERE'; const GUILD_ID = 'YOUR_GUILD_ID_HERE'; ``` **Replace with:** ```javascript 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:** ```bash 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:** ```bash # 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:** ```bash 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:** 1. Go to https://dash.cloudflare.com 2. Select **firefrostgaming.com** domain 3. Go to **DNS** → **Records** 4. Click **Add record** 5. 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 6. Click **Save** **Wait 1-2 minutes for DNS to propagate.** **Verify DNS is working:** ```bash # 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:** ```bash 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:** ```bash ln -s /etc/nginx/sites-available/discord-webhook /etc/nginx/sites-enabled/ nginx -t systemctl reload nginx ``` **Get SSL certificate:** ```bash certbot --nginx -d webhook.firefrostgaming.com ``` **Test the webhook endpoint:** ```bash curl https://webhook.firefrostgaming.com/health ``` **Should return:** ```json {"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:** ```bash 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:** 1. Create Discord roles (Part 2) 2. Update bot code with role IDs 3. Configure LuckPerms 4. Test the complete flow --- ## 👥 PART 2: DISCORD ROLES CONFIGURATION ### Step 1: Create Discord Roles (Holly's Task) **In your Discord server:** 1. Right-click server icon → **Server Settings** 2. Click **Roles** 3. 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:** 1. Right-click the role in Server Settings → Roles 2. Click **Copy ID** (if you don't see this, enable Developer Mode in Discord settings) 3. 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:** ```bash ssh root@63.143.34.217 nano /opt/firefrost-discord-bot/bot.js ``` **Find the `PRODUCT_ROLE_MAP` section and replace it:** ```javascript 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:** ```bash 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: `@⚡ Sovereign` only --- ## ⚙️ 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):** 1. Go to https://panel.firefrostgaming.com 2. Click on any server (doesn't matter which - they all share the MySQL database) 3. Click **Console** tab 4. 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:** 1. Go to Pterodactyl Panel 2. Open console for a different server 3. Run `/lp listgroups` 4. 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:** ```conf # Discord integration discord-integration { enabled = false } ``` **Change to:** ```conf 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:** 1. Open each server's console 2. Click **Restart** 3. Wait for server to come back online **Repeat for all 13 servers.** ### Step 3: Test Discord → LuckPerms Sync **Manual test:** 1. Go to Discord 2. Manually assign yourself `The Awakened` role (right-click your name → Roles) 3. Join a Minecraft server 4. Run `/lp user YourUsername info` 5. Should show you're in the `awakened` group **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`** ```nginx 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:** ```bash ln -s /etc/nginx/sites-available/discord-bot-webhook /etc/nginx/sites-enabled/ nginx -t systemctl reload nginx ``` **Get SSL certificate:** ```bash 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:** 1. Go to **Settings** → **Webhooks** 2. Click **Add Webhook** 3. Configure: - **URL:** `https://webhook.firefrostgaming.com/webhook/paymenter` - **Events:** - ✅ `subscription.created` - ✅ `payment.completed` - ✅ `subscription.cancelled` - ✅ `subscription.expired` - **Payload Format:** JSON 4. Click **Save** ### Step 3: Test Webhook **Create a test purchase in Paymenter (use test mode if available).** **Watch Discord bot logs:** ```bash 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:** 1. **Create test user in Discord** 2. **Purchase Awakened tier ($1) in Paymenter** 3. **Verify webhook fires** (check Discord bot logs) 4. **Verify Discord role assigned** (check Discord - user should have "The Awakened" role) 5. **Join Minecraft server** 6. **Run `/lp user TestUser info`** - Should show `awakened` group 7. **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:** 1. Upgrade test user to Fire Elemental ($5/mo) in Paymenter 2. Verify Discord role changes (old role removed, new role added) 3. Join Minecraft server 4. Run `/lp user TestUser info` - Should show `fire_elemental` group 5. 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:** 1. Cancel test user's subscription in Paymenter 2. Verify Discord role removed 3. Join Minecraft server 4. Run `/lp user TestUser info` - Should show `wanderer` or default group 5. 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:** 1. **Webhook logs:** `journalctl -u firefrost-discord-bot -f` - Are webhooks being received? 2. **Paymenter webhook config:** Is webhook URL correct? 3. **Discord bot permissions:** Does bot have "Manage Roles" permission? 4. **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:** 1. **LuckPerms config:** Is Discord integration enabled? 2. **Role IDs:** Are Discord role IDs correct in luckperms.conf? 3. **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:** 1. **Whitelist status:** Is whitelist enabled on server? 2. **LuckPerms sync:** Run `/whitelist add Username` manually as test 3. **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:** 1. **Bot running:** `systemctl status firefrost-discord-bot` 2. **Bot logs:** `journalctl -u firefrost-discord-bot -f` for errors 3. **Nginx proxy:** Is Nginx running and proxying correctly? **Solution:** - Restart Discord bot - Check bot code for syntax errors - Test webhook manually with curl: ```bash 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 ```bash # 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 ```bash # View user's groups /lp user info # Manually add user to group /lp user parent add # Remove user from group /lp user parent remove # View group permissions /lp group 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