Mesvilo documentation

Self-hosted, multi-tenant WhatsApp Cloud API messaging platform · Version 1.0.0

1. Overview

Mesvilo lets you run your own WhatsApp messaging service. You install it once on your server; your customers sign up, get their own workspace, connect their own WhatsApp Business number through Meta's official Cloud API, and pay you a monthly subscription through Stripe or PayPal.

Each workspace gets a shared inbox, contacts with consent tracking, Meta message templates, campaigns with delivery reports, keyword and out-of-office auto replies, and team roles. You manage everything from the platform admin area: workspaces, plans and limits, subscriptions, languages and settings.

Mesvilo never uses unofficial WhatsApp connections or QR-code pairing. Meta bills messaging charges directly to each workspace's own WhatsApp Business account.

2. Server requirements

ItemRequirement
PHP8.3 or newer with pdo_mysql, mbstring, openssl, curl, fileinfo, xml, ctype, tokenizer, sodium (enabled by default on most hosts)
DatabaseMySQL 8 or MariaDB 10.6+, one empty database
Web serverApache (with mod_rewrite) or Nginx
HTTPSRequired. Meta only delivers webhooks to HTTPS URLs. A free Let's Encrypt certificate is fine.
CronOne cron entry that runs every minute. No queue server, Redis or Node.js needed.
Outgoing connectionsThe server must be able to reach graph.facebook.com (Meta), mesvilo.com (license) and your payment providers.

Shared hosting works for the base package as long as it meets the list above and lets you add a cron job. The Personalized Video add-on needs a VPS with ffmpeg.

3. What's in the package

mesvilo-1.0.0/
├── mesvilo/          ← the application: upload the contents of this folder
│   ├── public/       ← the web root (point your domain here)
│   ├── app/, config/, database/, resources/, routes/, lang/, vendor/ …
│   └── .htaccess     ← for hosts where the domain can't point to public/
└── documentation/    ← this file

The vendor/ folder is included, so you don't need Composer. Compiled CSS and JavaScript are in public/build, so you don't need Node.js.

4. Installation

4.1 Upload the files

  1. Create an empty MySQL/MariaDB database and a user with full rights on it. Note the host, database name, user and password.
  2. Upload the contents of the mesvilo folder to your server, e.g. /home/you/mesvilo.
  3. Point your domain's document root to the public folder (e.g. /home/you/mesvilo/public). In cPanel: Domains → Manage → Document Root.
    If your host doesn't let you change the document root, upload everything into the domain's folder; the included root .htaccess forwards requests to public/ and blocks access to the other folders.
  4. Make these writable by the web server (usually 755 folders / 644 files is enough; use 775 if needed): storage/, bootstrap/cache/, lang/ and the application folder itself (so the installer can create .env).

4.2 Run the installer

  1. Open your domain in a browser. You're redirected to /install.
  2. Requirements: every line must be green. Fix any red item and refresh.
  3. Database: enter the database details and your site address (with https://). The installer creates the tables.
  4. Admin & license: enter your platform name, your admin account and your license key (MSV-… from your Mesvilo account) or your Envato purchase code. Click Finish installation.
  5. Sign in at /login with the admin account. The platform admin area is at /admin.
Leave Public demo installation unchecked. It loads sample data and blocks real messaging; it's only for showcase sites.

4.3 Nginx

server {
    server_name chat.example.com;
    root /home/you/mesvilo/public;
    index index.php;
    location / { try_files $uri $uri/ /index.php?$query_string; }
    location ~ \.php$ {
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
        fastcgi_pass unix:/run/php/php8.3-fpm.sock;
    }
    location ~ /\.(?!well-known) { deny all; }
}

5. Cron job

Add one cron entry (cPanel: Advanced → Cron Jobs, every minute):

* * * * * cd /home/you/mesvilo && php artisan schedule:run >> /dev/null 2>&1

It processes incoming WhatsApp events, sends scheduled campaigns at the configured rate, honors quiet hours, refreshes number health every hour and checks the license once a week. Admin → Settings → Server shows when it last ran.

If your host's PHP for the command line isn't 8.3, use the full path, e.g. /usr/local/bin/php8.3 or /opt/cpanel/ea-php83/root/usr/bin/php.

6. License activation

7. Email (SMTP)

Mesvilo sends invitations, password resets and notices by email. Go to Admin → Settings → Email (SMTP), enter your SMTP host, port, user, password and sender, save, then click Send test email. Any SMTP service works (your host's mail server, Amazon SES, Resend, Postmark, Mailgun…).

8. Connecting a WhatsApp number

Each workspace connects its own number. As platform owner you can share these steps with your customers.

8.1 In Meta

  1. Go to developers.facebook.com/apps and create an app of type Business, then add the WhatsApp product.
  2. Under WhatsApp → API Setup, add and verify your business phone number. Note the Phone number ID and the WhatsApp Business Account ID.
  3. In Business Settings → System users, create a system user, assign the app and the WhatsApp account, and generate a permanent token with whatsapp_business_messaging and whatsapp_business_management permissions.
  4. Copy the App secret from App settings → Basic (recommended: enables signature checks).

8.2 In Mesvilo

  1. Open the workspace → WhatsApp → Connect number, and paste the Phone number ID, Business Account ID, token and App secret.
  2. Mesvilo shows a Callback URL and Verify token. In Meta, open WhatsApp → Configuration → Webhook → Edit, paste both and click Verify and save.
  3. Under Webhook fields, subscribe to messages.
  4. Back in Mesvilo, the health checks should turn green. Send a WhatsApp message to the number; it appears in the inbox within a minute.

9. Message templates

Outside the 24-hour customer service window, WhatsApp only allows approved templates. Create them under Templates: choose a category (Marketing, Utility, Authentication), language and body with variables like {{1}}, map each variable to a contact field, preview, and Submit to Meta. Approval usually takes minutes to a few hours; Sync pulls the latest status and any templates created directly in Meta.

10. Campaigns

  1. Audience: pick segments or tags. Only contacts who opted in are counted; blocked and opted-out contacts are always excluded.
  2. Message: choose an approved template and map its variables.
  3. Schedule: send now or at a time in the workspace's timezone; set the send rate and optional quiet hours.
  4. Review: confirm counts and start.

The report shows sent, delivered, read and failed counts. Every failure keeps Meta's original error code and response. Export the report as CSV.

11. Inbox, contacts and auto replies

12. Plans and customer billing

12.1 Plans

Admin → Plans: set monthly and yearly prices, trial days and limits (team members, WhatsApp numbers, contacts, monthly messages). Choose which plan new sign-ups get under Admin → Settings, or turn public sign-ups off and create workspaces yourself.

12.2 Stripe

  1. In Stripe, copy your secret key (Developers → API keys).
  2. Add a webhook endpoint https://your-domain/webhooks/stripe with events checkout.session.completed, invoice.paid, invoice.payment_failed, customer.subscription.deleted, and copy the signing secret.
  3. Paste both under Admin → Subscriptions → Payment providers. Optionally set a Stripe price ID on each plan; otherwise the plan's price is used.

12.3 PayPal

  1. Create a REST app at developer.paypal.com and copy the client ID and secret.
  2. Add a webhook https://your-domain/webhooks/paypal with events BILLING.SUBSCRIPTION.ACTIVATED, PAYMENT.SALE.COMPLETED, BILLING.SUBSCRIPTION.CANCELLED, BILLING.SUBSCRIPTION.SUSPENDED, and copy the webhook ID.
  3. Paste them under Admin → Subscriptions and set a PayPal plan ID on each plan.

You can also record manual subscriptions (bank transfer, invoices) from the same page.

13. Languages

The interface ships in English. lang/en_US.json is the source file. Under Admin → Localization you can download it, translate it and upload it as a new language, or translate in the built-in editor. Coverage is shown per language; missing strings fall back to English. Users choose their language in their profile.

14. Add-ons

Optional add-ons (AI Smart Reader, Personalized Video, Flow Builder and others, sold separately) are installed by uploading their folder into addons/, then enabling them and entering their license key under Admin → Add-ons. Each add-on has its own license key and instructions.

15. Updating

  1. Back up your database and the .env file.
  2. Admin → Settings → Check for updates shows the latest version and its changes, and lets you download the package (while your support period is active). You can also download it from your Mesvilo account or Envato.
  3. Upload the new files over the old ones. Don't overwrite .env, storage/ or your own files in lang/ and addons/.
  4. Run the database updates — from SSH:
    cd /home/you/mesvilo && php artisan migrate --force && php artisan optimize:clear
    Without SSH, add a temporary cron job with the same command, wait one minute, then remove it.

16. Troubleshooting

ProblemFix
Blank page or 500 errorCheck storage/logs/laravel.log. Usually a folder isn't writable or the PHP version is below 8.3.
404 on every page except the home pageApache mod_rewrite is off or AllowOverride All isn't set for the folder.
Meta says "The callback URL or verify token couldn't be validated"The site must be on HTTPS with a valid certificate and reachable from the internet. Copy the URL and token again from the WhatsApp page.
Messages arrive in Meta but not in the inboxThe cron job isn't running. Check Admin → Settings → Server.
Campaign stays "Sending"Same: the cron job sends messages. Also check quiet hours and the number's messaging limit.
Error 131030 / 131047 in reports131030: recipient isn't allowed (test numbers only in development mode). 131047: the 24-hour window closed; use a template.
"Could not reach the license server"Your server can't connect to mesvilo.com over HTTPS. Ask your host to allow outgoing connections. The app keeps working meanwhile.
"This license is already active on another domain"Remove the old domain in your Mesvilo account and try again.

17. Support

Contact us through mesvilo.com/contact with your license key or purchase code, your Mesvilo version and a short description (screenshots and the relevant lines from storage/logs/laravel.log help a lot). Support covers installation help, bugs and questions about features; it doesn't include customization or server administration. Updates and support are included for six months from purchase.

WhatsApp is a trademark of Meta Platforms, Inc. Mesvilo is an independent product and is not affiliated with or endorsed by Meta.