Documentation

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

  1. Upload the files and create an empty database in your hosting panel.
  2. Visit /install.
  3. 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.
  4. Work through the steps: server check, database, site details, email, then install.
  5. 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

  1. Import database/install.sql into an empty database.
  2. Copy .env.example to .env and fill in the values below.
  3. Generate an application key: php artisan key:generate
  4. Invent a PAYMENT_PASSPHRASE and a CRON_TOKEN. Long and random.
  5. 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_NAMEShown in the browser tab and as the default mail sender name.
APP_URLThe 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_ENVproduction on a live site.
APP_DEBUGfalse 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.
TIMEZONEDecides when a day rolls over for daily returns. Match the market you trade against.

Database

DB_HOSTUsually localhost on shared hosting.
DB_PORT3306 unless your host says otherwise.
DB_DATABASE, DB_USERNAME, DB_PASSWORDFrom 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_MAILERsmtp for a normal mail server.
MAIL_HOST, MAIL_PORTFrom your mail provider. 587 with TLS is the usual pair.
MAIL_ENCRYPTIONtls, ssl, or empty for none.
MAIL_USERNAME, MAIL_PASSWORDThe 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_SECRETCard deposits. Kept here rather than in the database so they stay out of database backups.
NOCAPTCHA_SITEKEY, NOCAPTCHA_SECRETRequired if you switch on Google reCAPTCHA. Without them, sign-up fails for everyone.
FINNHUB_API_KEYPowers 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.

0 * * * * curl -s "https://yoursite.com/cron?token=YOUR_CRON_TOKEN" > /dev/null

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 / maximumThe range a customer may put in.
Increment amountThe rate. Set to 0, the plan pays nothing — it will run to maturity and return the stake having earned zero.
Increment intervalHow often it pays: Daily, Weekly, Monthly.
DurationHow 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.phpSent on registration.
verify-code.blade.phpEmail verification code.
2fa.blade.phpTwo-factor code.
success-deposit.blade.phpA deposit was approved.
withdrawal-status.blade.phpA withdrawal was approved or rejected.
newroi.blade.phpProfit was credited.
endplan.blade.phpA 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.

10. Maintenance and troubleshooting

Clearing the cache

Settings → Config → Clear cache, or over SSH:

php artisan config:clear && php artisan cache:clear && php artisan view:clear && php artisan route:clear

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: