Running, configuring and maintaining the platform.
1. What it needs to run
PHP 8.2 or newer, MySQL or MariaDB, and these PHP extensions:
pdo_mysql, mbstring, openssl,
tokenizer, ctype, json,
fileinfo, curl, bcmath.
The installer checks all of them and tells you which are missing.
Where the files go
This deployment has no public/ docroot. Unlike a stock
Laravel install, index.php and the public assets sit at the top level of the
project, and your domain points straight at that folder. If you have moved a Laravel site
before, this is the one thing most likely to catch you out.
Two directories must be writable by the web server, usually 755:
storage/ and bootstrap/cache/. Uploaded logos, KYC documents and
payment proofs are written under storage/app/public/.
Upload the hidden files
The site ships with .htaccess files that keep its configuration and logs off
the web, and most zip tools and file managers skip dot-files unless told otherwise. If
they do not arrive, the site is exposed.
2. Installing
With the installer
Upload the files and create an empty database in your hosting panel.
Visit /install.
It writes a token to storage/install-token.txt. Open that file in your
file manager and paste the value in. This is what stops a stranger running the
installer against your site — only someone who can read the server's files can
get past it.
Work through the steps: server check, database, site details, email, then install.
Copy the payment passphrase and cron token from the
last screen. They are shown once.
The installer can be run again whenever you need to — to change your mail server,
rotate the cron token, or point a restored backup at a new database. Each run issues a
fresh token, so knowing the address is never enough.
By hand
Import database/install.sql into an empty database.
Copy .env.example to .env and fill in the values below.
Generate an application key: php artisan key:generate
Invent a PAYMENT_PASSPHRASE and a CRON_TOKEN. Long and random.
Set up the cron job (section 4), then sign in at /adminlogin/dashboard.
database/install.sql is generated from the migrations by
php artisan install:dump, so it always matches the code. It deliberately
contains no administrator account — a default login with a known
password would be an open door. Create one through the installer, or with
php artisan tinker.
Moving to another server
Copy the files, export and import the database, then run the installer against the
restored database. It will see an existing site, leave every row alone, and only write
.env.
Your saved payment destinations will need entering again
Wallet addresses, bank details and payment QR codes are encrypted with
APP_KEY. A new server means a new key, so those values cannot be read back
and must be re-entered under Settings → Payment Settings. Nothing else is affected,
and customers cannot deposit to a method whose details cannot be read — so nobody
is shown a wrong address in the meantime. The admin dashboard shows a banner until you
have done it.
3. Configuration reference
Everything here lives in .env at the top of the project. After changing it,
clear the cache (Settings → Config → Clear cache), or the old values keep being
served.
Core
APP_NAME
Shown in the browser tab and as the default mail sender name.
APP_URL
The full public address, with https:// and no trailing slash. Password-reset and verification links are built from this — get it wrong and they point somewhere the customer cannot reach.
APP_ENV
production on a live site.
APP_DEBUG
false on a live site. true shows full stack traces to visitors, credentials included.
APP_KEY
Encrypts your payment destinations. Generated once at install.
Changing it makes every saved wallet address, bank detail and payment QR
unreadable — keep a copy of .env with your backups.
TIMEZONE
Decides when a day rolls over for daily returns. Match the market you trade against.
Database
DB_HOST
Usually localhost on shared hosting.
DB_PORT
3306 unless your host says otherwise.
DB_DATABASE, DB_USERNAME, DB_PASSWORD
From your hosting panel. The user needs full rights on that database.
Secrets
PAYMENT_PASSPHRASE
Asked for whenever a payment method is added or changed in the admin. A second pair of hands on the one setting that decides where money goes.
CRON_TOKEN
Protects the scheduled-task URL. Leave it empty and anyone who guesses the address can trigger a payout run.
Mail
MAIL_MAILER
smtp for a normal mail server.
MAIL_HOST, MAIL_PORT
From your mail provider. 587 with TLS is the usual pair.
MAIL_ENCRYPTION
tls, ssl, or empty for none.
MAIL_USERNAME, MAIL_PASSWORD
The mailbox credentials.
MAIL_FROM_ADDRESS, MAIL_FROM_NAME
The from-address should be the mailbox above. Authenticating as one address and claiming to be another is the quickest way to have every message treated as spam.
Optional services
STRIPE_KEY, STRIPE_SECRET
Card deposits. Kept here rather than in the database so they stay out of database backups.
NOCAPTCHA_SITEKEY, NOCAPTCHA_SECRET
Required if you switch on Google reCAPTCHA. Without them, sign-up fails for everyone.
FINNHUB_API_KEY
Powers the Market Insights card on the customer dashboard. Free key at finnhub.io. Leave blank to hide the card.
4. The scheduled task
Everything time-based runs from one URL: profit payouts, plan maturity, and the check that
your payment destinations are still readable. Until this is scheduled, none of
them happen — and the only symptom is that nobody gets paid.
In cPanel: Advanced → Cron Jobs, "Once an hour". Hourly suits most
sites; if your plans pay more often than that, match the shortest payout period you offer.
Settings → Config shows when it last completed. If that says Overdue or
Never run, the job is not firing — check the token matches
.env exactly.
5. Settings, tab by tab
Settings → App Settings. Five tabs.
General
Site name, contact email, currency symbol and code, timezone, the optional homepage
redirect, and the announcement banner. The contact email is where the site writes to you
about payment problems and cron warnings.
Features
Switches. Four have consequences worth knowing before you touch them:
Auto profit
Off stops ROI accruing for everyone. Nothing is lost; it resumes when you switch it back on.
Weekend returns
Off skips Saturday and Sunday when profit is paid.
Verify at registration
Blocks a new account from doing anything at all until its documents are approved. Switch it on only if someone is reviewing them promptly.
Google reCAPTCHA
Set your keys in .env first, or sign-up fails for everyone.
Below them, Modules switch whole features on and off — loans,
wallet connect, account status, withdrawal confirmation codes. Turning one off hides it
from every customer dashboard; existing records are kept, not deleted. These save as you
click them, and have no Save button of their own.
Appearance
Logo, favicon, the three logo sizes, and your brand colours. Each colour you pick is
expanded into a full light-to-dark scale used across the customer dashboard, the sign-in
pages and the admin.
Email
Reports the mail connection from .env — it is not editable here, by
design — and sends a test message so a broken setup shows up on this page rather
than on somebody's password reset.
Config
Cron status, the Finnhub API key, and Clear cache. Run that after any
.env change; it is safe at any time and only costs one slower page load.
6. Investment plans
Investment → Plans. Each plan needs four things to pay anything at all:
Minimum / maximum
The range a customer may put in.
Increment amount
The rate. Set to 0, the plan pays nothing — it will run to maturity and return the stake having earned zero.
Increment interval
How often it pays: Daily, Weekly, Monthly.
Duration
How long it runs before maturing.
The interval must be shorter than the duration
A plan paying Monthly that matures in 14 days pays once, or never. The plan
cards in the admin show an amber band on any plan with no return set.
Writing the duration
The format is strict: a digit, a space, then the unit capitalised and plural —
even for one.
1 Days 3 Weeks 48 Hours 6 Months 1 Years
Anything else and the plan will not mature.
7. Payment methods
Settings → Payment Settings. Each method is where money comes in or goes out, so
changing one asks for the payment passphrase from .env.
If a destination cannot be read
A method whose details cannot be read back is hidden from the deposit page rather
than shown with the wrong ones, the admin dashboard raises a banner, and the site
emails your contact address. Re-enter the details under Settings → Payment
Settings and it returns.
This is what you will see after moving to another server. The QR image behaves the
same way as the address beside it.
8. Email
Mail is in two halves: the wording, which is what you will usually want
to change, and the templates, which decide how a message looks.
The wording
Most transactional messages have their text in one file:
app/Helpers/MailCopy.php. One method per message, each returning the subject
and body. Nineteen messages live there — transfers, investments, loans, cards, KYC
and the withdrawal code — so the whole voice of the product's mail can be read and
changed in one sitting, and two places announcing the same event cannot drift apart.
To change what one of those says, edit its method in MailCopy.php. You do not
need to touch a template: they all render through the same one.
The templates
Blade files in resources/views/emails/. Most are frames rather than content.
action.blade.php
Renders everything MailCopy produces. Change this to restyle the majority of your mail at once.
layout.blade.php
The shared frame carrying your logo and colours.
NewNotification.blade.php
A general-purpose template whose text is passed in by the caller.
Messages whose text is still in their own template
These predate MailCopy and keep their wording inline, so to change one of
these you edit the Blade file itself.
welcome.blade.php
Sent on registration.
verify-code.blade.php
Email verification code.
2fa.blade.php
Two-factor code.
success-deposit.blade.php
A deposit was approved.
withdrawal-status.blade.php
A withdrawal was approved or rejected.
newroi.blade.php
Profit was credited.
endplan.blade.php
A plan matured.
Testing a change
Clear the cache after editing, so the compiled views are rebuilt, then use
Settings → Email → Send test. It delivers through the real connection and
reports what happened, so a broken setup shows up there rather than on somebody's
password reset.
9. How money moves
Deposits
A customer submits an amount and a proof image. Nothing is credited until an admin approves it under Deposits. Rejecting asks for a reason, which the customer is told.
Withdrawals
The customer requests, the balance is held, and an admin releases it under Withdrawals. The screen shows the requested amount, the fee, and the total actually deducted.
Investments
Bought from the customer dashboard. The cron pays profit at each interval and closes the plan at maturity. Profit can also be added by hand from a user's Actions menu — only for a plan that has not yet matured.
Loans
Applied for, approved with an interest rate and optional down payment, then disbursed. Money only counts toward a loan once a payment is confirmed under Loans → Repayments, and confirming a down payment is what releases the loan.
Referrals
A flat percentage of a referred customer's deposit, set under Settings → Referral & Bonus.
Every one of these leaves a row in the customer's transaction history with a reference
— DEP-, WDR- or TXN- — which they can
open as a printable receipt.
Do not run php artisan config:cache on this site. It makes environment
values unreadable outside config files, and the payment passphrase is read directly —
caching the config would break saving a payment method.
Common symptoms
Changed .env and nothing happened
The old configuration is cached. Clear the cache.
Nobody is being paid
The cron is not running. Settings → Config shows when it last completed.
A payment method vanished from the deposit page
Its details cannot be decrypted — usually a changed APP_KEY. Re-enter them.
Emails are not arriving
Settings → Email → Send test. Check the from-address belongs to the mailbox you authenticate as.
Uploads fail silently
post_max_size is below upload_max_filesize; PHP ignores the larger and the request arrives empty. Raise both.
A plan never matures
The duration is written in the wrong format. See section 6.
500 error after a deploy
Check storage/ and bootstrap/cache/ are writable, then clear the cache. The log is in storage/logs/.
11. Keeping it safe
The application ships configured to protect itself. These are the parts that depend
on you:
Serve the site over HTTPS. Customers enter payment details here.
Keep APP_DEBUG=false in production.
Set CRON_TOKEN, and keep the cron URL to yourself.
Back up the database and.env together — without the
key, the backup's payment details cannot be read.
Rotate any credential that has ever been shared in a message or a screenshot.
Upload the site with hidden files included. Your host's file manager may skip them by default.