Provision and manage Docker containers from Catalyst directly through Paymenter, with a matching dark theme that auto-syncs colors.
A full-featured server extension that lets Paymenter automatically provision and manage Docker containers through Catalyst. Includes a complete Paymenter theme (Catalyst Obsidian) with live color sync from the Catalyst panel.
| Component | Description |
|---|---|
| Server Extension | Catalyst.php — full server lifecycle (create, suspend, unsuspend, terminate, upgrade) |
| SSO Provider | SsoService.php — self-contained OAuth2/OIDC, no Passport needed |
| Migration | 6 database tables for templates, nodes, nests, mappings, users, sync logs |
| Server Status Widget | Live CPU/RAM/disk stats, connection info, status indicator |
| Theme | Dark Obsidian theme with full color sync from Catalyst panel |
- Full server lifecycle — create, suspend, unsuspend, terminate, upgrade servers automatically
- Auto-sync — templates, nodes, and nests synced from Catalyst on product config load
- Smart node selection — auto-picks the best node by available resources; or manual mode
- User provisioning — 3 modes: auto (random password), auto+email, manual
- Dynamic template variables — egg/template variables appear as configurable product options
- Docker image variants — select image variants (Java 8/11/17/21, etc.) at product config
- Auto port assignment — set primary port to
0for next free allocation from node pool - Network modes — Bridge (port mapping via allocations) or MC-VLAN (direct IP)
- Server auto-recovery —
ensureServerExists()verifies, relinks, or recreates missing servers - Customer dashboard — live CPU/RAM/disk widgets, connection info, "Open Catalyst Panel" button
- Test Connection — verifies health endpoint + permissions for nodes, templates, servers, users, roles
- Separate backend/frontend URLs —
host= API URL,frontend_url= user-facing panel URL
- Dark Obsidian design — DM Sans + Outfit fonts, glassmorphism cards
- Live color sync — all 26 Catalyst theme colors synced via
catalyst-sync.js - CSS variable system — uses
--color-primary,--color-card,--color-surface2/3,--color-neutraletc. so every element adapts when colors change - Custom pages — home (visual builder), products (index/show/checkout), services (index/show), login, navigation
- Responsive — works across all breakpoints with inline styles (no Tailwind build dependency)
- Paymenter installed and running
- Catalyst panel installed and running with an admin API key
- Log into your Catalyst panel as admin
- Go to API Keys
- Create a new key named
Paymenter Integration - Copy the generated key
Copy into your Paymenter installation:
extensions/Servers/Catalyst/
├── Catalyst.php ← Main extension class (1,745 lines)
├── SsoService.php ← OAuth2/OIDC provider (no Passport)
├── database/migrations/
│ └── 2026_04_17_000001_create_catalyst_tables.php ← 6 tables
├── resources/views/
│ └── server-status.blade.php ← Live server status widget
└── README.md
Register with Paymenter:
cd /path/to/paymenter
php artisan clear-compiled
composer dump-autoload -o- Go to Admin Panel → Extensions → Servers
- Find Catalyst in the list
- Click Install (runs migration, creates 6 tables, generates SSO credentials)
- Click Enable
| Setting | Description | Default |
|---|---|---|
| Catalyst Backend URL | API URL (e.g. http://localhost:3000) |
— |
| Catalyst Frontend URL | User-facing panel URL (e.g. http://localhost:5173) |
Same as backend |
| Admin API Key | Catalyst admin API key | — |
| Verify SSL Certificate | Disable for self-signed certs | Checked |
| API Timeout (seconds) | Request timeout | 30 |
| Auto-sync Templates & Nodes | Sync when configuring products | Checked |
| Default User Role ID | Role for newly created Catalyst users | Empty |
| User Creation Mode | auto / auto_email / manual |
auto |
| Auto-start after install | Start server after installation | Unchecked |
After saving, 3 SSO fields appear (auto-generated): Client ID, Client Secret, Discovery URL.
Click Test Connection to verify API access and permissions.
- Go to Products → Create Product
- Set general info (name, pricing, billing cycle)
- Under Server Settings, select Catalyst
- Configure:
| Field | Description |
|---|---|
| Node Selection | Auto (best fit) or Manual |
| Node | Specific node (only in manual mode) |
| Location | Deployment region |
| Filter by Nest | Filter template categories |
| Template | Catalyst template (auto-populated from sync) |
| Memory | RAM in MiB (min 512) |
| CPU Cores | Cores (min 0.5, cast to int for Catalyst) |
| Disk Space | Disk in MiB (min 1024) |
| Backup Storage | Backup allocation MiB |
| Database Slots | Databases allowed |
| Primary Port | Main port (0 = auto-assign from node allocations) |
| Network Mode | Port Mapping (Bridge) or Direct IP (MC-VLAN) |
| Server Name Prefix | Use {user}, {product}, {id} placeholders |
Template-specific variables (e.g. MC_VERSION, IMAGE_VARIANT) appear automatically after selecting a template.
Copy the theme into Paymenter:
themes/catalyst/
├── theme.php ← Theme config (53 settings)
├── vite.config.js
├── css/
│ ├── app.css ← Custom overrides
│ └── easymde.css
├── js/
│ ├── app.js ← Entry point
│ ├── catalyst-sync.js ← Color sync from Catalyst panel (17.7KB)
│ └── easymde-entry.js
├── public/catalyst/ ← Built assets (run `npm run build`)
│ ├── manifest.json
│ └── assets/
└── views/
├── layouts/
│ ├── app.blade.php ← App shell
│ └── colors.blade.php ← CSS variable fallbacks + sync trigger
├── components/
│ ├── button/ ← primary, secondary, save, danger
│ ├── form/input.blade.php
│ └── navigation/index.blade.php ← Responsive nav with mobile slide-over
├── auth/login.blade.php
├── home.blade.php ← Visual builder with 5 sections
├── products/
│ ├── index.blade.php ← Category sidebar, product grid
│ ├── show.blade.php ← Resources + What's Included cards
│ └── checkout.blade.php ← Two-column layout with sticky sidebar
└── services/
├── index.blade.php ← Stats row, service cards with server details
├── show.blade.php ← Server details, billing, actions, status tabs
└── partials/
└── billing-agreement.blade.php
Build the theme assets:
cd themes/catalyst
npm install
npm run buildActivate the theme in Admin Panel → Settings → Theme → Catalyst.
- Customer places order → Paymenter calls
createServer() ensureCatalystUser()— finds or creates Catalyst user account- Fetches template defaults, merges with product config into environment variables
selectNode()— auto-picks best node (most free memory) or uses configured nodeautoAssignPorts()(if port=0) — grabs next free allocation from node pool- Creates server via
POST /api/servers - Triggers installation via
POST /api/servers/{id}/install - Stores service ↔ server mapping (upsert for idempotent recreation)
- Optionally auto-starts the server
When auto-sync is enabled, every time an admin opens product configuration:
- Fetches all templates, nodes, and nests from Catalyst API
- Updates local cache tables (creates new, updates changed, removes deleted)
- Logs the sync operation with stats to
catalyst_sync_logs
- Fetches all nodes via
GET /api/nodes - Filters by configured location, skips offline nodes (
isOnline === false) - Gets real-time stats via
GET /api/nodes/{id}/stats(resources.availableMemoryMb,resources.actualDiskUsageMb) - Checks free RAM ≥ required and free disk ≥ required
- Ranks by most available memory, picks the best
| Mode | Behavior |
|---|---|
| Bridge | Uses allocationId from node's allocation pool; port mapping via host |
| MC-VLAN | Sets CATALYST_NETWORK_IP in environment from allocation IP; container gets direct IP |
ensureServerExists() runs on every getActions() / getControlPanelUrl() call:
- Verifies mapped server exists on Catalyst (
GET /api/servers/{id}) - If 404: searches all servers by name for admin pre-created match → links to it
- If not found anywhere: recreates the server automatically via
createServer()
| Mode | Behavior |
|---|---|
| Auto | Creates account with random password. User sets password via Catalyst SSO. |
| Auto + Email | Same as auto, but emails credentials to the customer. |
| Manual | Does not create accounts. Admin must pre-create them in Catalyst. |
User lookup searches GET /api/admin/users by email (Catalyst has no GET /admin/users/:id endpoint).
The extension includes a fully self-contained OAuth2/OIDC provider. No Passport, no external packages — just Laravel Cache + HS256 JWTs.
| Endpoint | Purpose |
|---|---|
/.well-known/openid-configuration |
OIDC discovery document |
/sso/authorize |
Authorization — redirects to login if needed, auto-approves |
/sso/token |
Token exchange — code → access_token + id_token (HS256 JWT) |
/sso/userinfo |
User profile — returns sub, email, name, email_verified |
- Install the extension — SSO credentials are auto-generated on install
- Copy the 3 SSO values from the Catalyst extension config page:
PAYMENTER_OIDC_CLIENT_IDPAYMENTER_OIDC_CLIENT_SECRETPAYMENTER_OIDC_DISCOVERY_URL
- Configure Catalyst — paste values into Catalyst's admin panel under OIDC Settings (stored in Catalyst DB as
ThemeSettings.metadata.oidcProviders.paymenter) - Restart Catalyst so it loads the OIDC provider from DB
- User clicks "Login with Paymenter" on Catalyst
- Catalyst's
better-authgenericOAuthfetches OIDC discovery document - Browser redirects to
/sso/authorizeon Paymenter - If not logged in → Paymenter login page (return URL preserved)
- After login → authorization auto-approved (no consent screen)
- Browser redirects back to Catalyst with authorization code
- Catalyst exchanges code for tokens at
/sso/token - Catalyst parses HS256
id_tokenJWT to get user identity - Catalyst creates/links user and starts session
- Auth codes expire in 10 minutes; access tokens expire in 1 hour
- All state stored in Laravel's cache driver
- The
id_tokenis signed with HS256 using the client secret as HMAC key - Livewire navigate CORS handled via
Sec-Fetch-Modeheader detection
| Table | Purpose |
|---|---|
catalyst_templates |
Cached template data (name, variables, images, supported ports) |
catalyst_nodes |
Cached node data (name, location, memory, disk, hostname) |
catalyst_nests |
Cached nest/category data |
catalyst_service_servers |
Maps Paymenter service → Catalyst server (name, node, connection info, resources) |
catalyst_user_accounts |
Maps Paymenter user → Catalyst user (email, username, auth method) |
catalyst_sync_logs |
Sync operation history (type, status, counts, duration) |
The theme defines fallback colors in layouts/colors.blade.php that get overridden by catalyst-sync.js when auto-sync is enabled. All views use these variables via hsl(var(--color-*)):
| Variable | Purpose |
|---|---|
--color-primary |
Branding / accent color |
--color-secondary |
Secondary brand |
--color-neutral |
Borders, dividers |
--color-base |
Primary text |
--color-muted |
Secondary text |
--color-inverted |
Text on dark backgrounds |
--color-success |
Success states |
--color-error |
Error / danger states |
--color-warning |
Warning states |
--color-info |
Info states |
--color-background |
Page background |
--color-background-secondary |
Elevated surfaces |
--color-card |
Card backgrounds |
--color-surface2 |
Nested card / inset backgrounds |
--color-surface3 |
Deepest surface level |
All 26 Catalyst theme colors are synced (primary, secondary, accent, light/dark background, foreground, card, surface1/2/3, border, muted, success, warning, danger, info, borderRadius) for both light and dark modes.
| Problem | Solution |
|---|---|
| "Catalyst is not configured" | Set Backend URL and API Key in extension settings |
| "No suitable node found" | Ensure a node is online with enough free resources |
| "No free port allocations" | Add more allocations to the node in Catalyst |
| Server appears twice | Delete orphan row in catalyst_service_servers |
| Templates not showing | Enable auto-sync or verify templates exist on Catalyst |
| cURL error | Verify Backend URL is correct and reachable from Paymenter |
| "No Catalyst account found" | Switch user mode to auto or create account in Catalyst first |
| SSO not working | Check discovery URL is reachable from Catalyst, verify credentials match |
| Theme colors not syncing | Check Catalyst Panel URL in theme settings, open browser console for errors |
- Admin Panel → Extensions → Servers → Catalyst → Disable
- Click Uninstall (drops all 6 tables)
- Delete
extensions/Servers/Catalyst/ - Optionally delete
themes/catalyst/if the theme was installed
MIT