Getting started
Upload the project contents to the final domain or subdomain, create an empty MariaDB/MySQL database in DirectAdmin, select PHP 8.2 or newer, then open /install.php.
- Enter the final HTTPS application URL.
- Enter the database credentials created in DirectAdmin.
- Create the owner account.
- Sign in to
/backoffice/. - Delete or rename
install.phpafter setup.
Catalogue and releases
Products start as drafts. Upload a current release and then set the product to published. The public catalogue intentionally hides published products that do not yet have a current release, and checkout repeats the same server-side check.
Version ZIP files are stored under storage/private/products, blocked from direct web access. Customers receive short-lived, signed download URLs only after the server confirms a paid order.
Payment providers
All provider secret keys belong in the server-side .env file. Never place them in index.html, JavaScript, screenshots, support tickets or public repositories.
Stripe
STRIPE_ENABLED=true STRIPE_SECRET_KEY=sk_test_... STRIPE_WEBHOOK_SECRET=whsec_...
The backend creates a hosted Checkout Session. Configure the webhook endpoint shown below and subscribe to checkout completion events.
PayPal
PAYPAL_ENABLED=true PAYPAL_MODE=sandbox PAYPAL_CLIENT_ID=... PAYPAL_CLIENT_SECRET=... PAYPAL_WEBHOOK_ID=...
The server creates an Orders API order, redirects the customer for approval and captures it server-side on return. The webhook remains the independent source of confirmation.
Revolut Pay
REVOLUT_ENABLED=true REVOLUT_MODE=sandbox REVOLUT_SECRET_KEY=sk_... REVOLUT_WEBHOOK_SECRET=... REVOLUT_API_VERSION=2026-04-20
The backend creates a Merchant API order and redirects to Revolut Hosted Checkout. A Merchant account, accepted business verification and provider-side payment method activation are required.
Webhook endpoints
POST https://your-domain.example/api/v1/webhooks/stripe POST https://your-domain.example/api/v1/webhooks/paypal POST https://your-domain.example/api/v1/webhooks/revolut
Webhook handlers verify provider signatures, reject invalid events, deduplicate event IDs and fulfil the matching local order idempotently. Checkout amounts are created from the server-side product price rather than browser input.
Licensing API
Every fulfilled order receives a unique license. The raw key is encrypted at rest while lookup uses a one-way SHA-256 hash. Activation responses are signed with Ed25519 when Sodium is available; installations without Sodium use an HMAC-SHA256 fallback.
Activate
POST /api/v1/licenses/activate
Content-Type: application/json
{
"license_key": "APX-XXXXXX-XXXXXX-XXXXXX-XXXXXX",
"product_slug": "server-organizer",
"instance_id": "stable-panel-instance-id",
"domain": "panel.example.com",
"panel_version": "1.11.11",
"addon_version": "1.0.0"
}
Heartbeat
POST /api/v1/licenses/heartbeat
Use the same body as activation. Store the returned server time, license state and signature. Apply a limited offline grace period in the addon rather than permanently trusting a cached response.
Deactivate
POST /api/v1/licenses/deactivate
{
"license_key": "APX-...",
"instance_id": "stable-panel-instance-id"
}
Public signing key
GET /api/v1/licenses/public-key
Protected downloads
The customer portal first asks the API for a signed token. download.php
Team roles
Owner has complete access. Admin manages commerce and most team roles. Developer manages products and releases. Support can review customers, products, orders and licenses. Viewer has read-only operational access.
Scheduled cleanup
Add a daily DirectAdmin cron job. Replace the path with the absolute path to the project:
15 3 * * * /usr/local/bin/php /home/USER/domains/DOMAIN/public_html/cron/cleanup.php
The task removes expired rate-limit buckets, old processed webhook records and stale cache files.
Security checklist
- Force HTTPS and keep PHP updated.
- Delete or rename
install.phpafter installation. - Keep
.envstorage/private - Use sandbox credentials during testing and separate live webhook secrets.
- Enable two-factor authentication on Stripe, PayPal, Revolut Business and DirectAdmin.
- Back up the database and private product archives.
- Test a full purchase, webhook, license and download flow before launch.
Support and customization
Brand text, navigation and footer content are in assets/js/core.js. Design tokens are at the top of assets/css/app.css. Provider credentials and server settings are in .env.