RedFamosa — SMM Panel Script
A complete Social Media Marketing panel you install on your own hosting: sell followers, likes and views through a branded storefront, buy them wholesale from upstream providers, and open child panels for your own resellers — each on their own domain.
RedFamosa is a self-hosted PHP script. You upload one ZIP to your server, run a six-step web wizard and end up with a working panel — no console, no Composer, no build step. Your customers top up a prepaid balance and place orders; the panel routes those orders to your upstream providers and keeps your margin.
- Six-step web installer, Production or Demo data
- Upstream provider manager (standard SMM API)
- Catalogue: platforms → categories → services
- Order pipeline with drip-feed, refill and cancel
- Immutable, auditable wallet ledger
- Payment methods: manual transfer, Stripe, PayPal
- Top-up bonus tiers and multi-currency display
- Reseller child panels on their own domain
- Reseller subscription plans billed from the wallet
- Plan-gated own provider for resellers
- Public API in the standard SMM format
- Omnichannel CRM with seven channels
- AI agents with a knowledge base, plus automations
- Embeddable web-chat widget
- Tickets, blog, FAQ, news and landing page
- Blacklists for IP, link and e-mail
- Owner and reseller dashboards with charts
- Three client skins and three landing skins
- English and Spanish, light and dark mode
1.1 Who it is for
RedFamosa is built for the entrepreneur who wants to run an SMM reselling business rather than write one. The typical owner:
- Connects one or more upstream SMM providers and buys services wholesale.
- Adds a markup and sells to end clients through their own branded panel.
- Optionally recruits resellers — child panels that do the same thing one tier down, each with their own domain, branding and clients.
- Optionally charges those resellers a subscription plan (§10) on top of the wholesale margin.
1.2 The three roles
| Role | Area | What they can do |
|---|---|---|
| Owner + staff | /admin |
Full administration: providers, catalogue, pricing, payments, child panels, plans, users, tickets, CRM, settings and reports. Staff get a role with granular permissions, so you can hire an operator without handing over the keys to the business. |
| Reseller | /panel |
Runs a child panel on their own domain. Buys from you at your price, sets their own resale price, manages their own clients, keeps their own CRM inbox, and tops up their balance by paying you. |
| Client | /app |
The end buyer. Tops up a balance, places orders, follows their progress, opens support tickets and automates through the public API. |
1.3 How to read this manual
Chapters 2 to 4 get you installed and configured — read them in order the first time. Chapters 5 to 8 cover day-to-day operation. Chapters 9 and 10 are the reseller business. Chapters 11 and 12 are the integrations: the public API and the CRM. Chapter 13 is the background worker every panel needs, and chapter 14 collects the things that go wrong, with the fix for each.
Throughout the manual, {APP_URL} means the address of your panel as you entered
it during installation, for example https://panel.example.com. Screens are written
as Menu → Sub-menu, matching the sidebar of the admin area. All example
domains, e-mail addresses and keys are fictitious.
public/ folder, open it in a browser and complete the
wizard (§3). Then add a provider and sync its catalogue
(§5), enable a payment method (§8) and
choose how background work runs (§13). Everything else is optional.2. Server requirements
RedFamosa ships with its PHP dependencies and compiled front-end assets already bundled, so the server needs neither Composer nor Node.js. A standard PHP + MySQL hosting account is enough.
PHP
PHP 8.2 or newer (8.3 and 8.4 are supported). The installer compares your version against 8.2.0 and refuses to continue below it.
Required PHP extensions
These thirteen extensions are exactly what the installer checks, one row per line on screen:
| Extension | Used for |
|---|---|
bcmath | Exact arithmetic in the wallet ledger and price calculations. |
ctype | Character checks used by the framework and by input validation. |
curl | Outbound calls to providers, payment gateways and webhooks. |
fileinfo | Real MIME-type detection for uploaded files. |
gd | Image processing for avatars and payment proofs. |
intl | Number, date and currency formatting. |
json | Encoding of API payloads and stored settings. |
mbstring | Multi-byte strings and translations. |
openssl | Encryption of provider keys, gateway secrets and channel tokens. |
pdo_mysql | MySQL / MariaDB driver. |
tokenizer | Required by the framework itself. |
xml | Parsing XML responses from some gateways. |
zip | Archive handling used by exports and updates. |
On cPanel these live in MultiPHP Extensions (or Select PHP Version → Extensions). Nearly every host enables all thirteen by default.
Database
- MySQL 8.0+ or MariaDB 10.3+.
- InnoDB storage engine — the default everywhere. MyISAM is not supported: the schema relies on foreign keys and transactions.
- The database user needs
SELECT,INSERT,UPDATE,DELETE,CREATE,ALTER,INDEXandDROPon its own database. On cPanel, "All privileges" covers exactly that. - Start from an empty database — the installer creates every table.
Write permissions
The user that runs PHP must be able to write to these five paths. They are the same five the wizard verifies in step 2:
| Path | Why |
|---|---|
storage/app | Uploads and the installation lock file. |
storage/framework | Compiled views, sessions and cache. |
storage/logs | The application log. |
bootstrap/cache | Compiled configuration and routes. |
.env | The installer writes your settings into this file. If the file does not exist yet, the project root itself must be writable so it can be created. |
On cPanel the PHP user is the account owner, so uploading through File Manager already gives
the right ownership. If a check fails, set directories to 755 and the
.env file to 644.
Web server
Apache 2.4+ with mod_rewrite and AllowOverride All (the cPanel
default), or Nginx with the usual try_files rule for a front controller. In both
cases the document root must point at the public/ sub-folder,
never at the project root.
vendor/ (every PHP package) and
public/build/ (compiled CSS and JavaScript). You never run
composer install or npm install on the server.http://, type the address with http:// in the
wizard: §14.1 explains what breaks when the two disagree.3. Installation
RedFamosa installs through a browser wizard of six steps. Each step validates before it lets you continue, and tells you exactly what to fix without leaving the screen. A normal installation takes about five minutes, most of it spent creating the database in your hosting panel.
.env configuration file, creates every database table, seeds the data
you choose, creates your owner account and finally writes
storage/app/installed.lock — the file that marks the panel as installed and
permanently closes the wizard.3.1 Prepare your hosting
Do this before opening the wizard. The instructions are written for cPanel because that is what most buyers have; on a VPS the same five points apply with your own tooling.
- Upload the product ZIP to your account through File Manager or FTP, and
extract it. You get a folder containing
app/,public/,vendor/and the rest of the script. - In cPanel → Domains (or Subdomains), set the
document root of the domain to the
publicfolder inside that directory. This is the step people skip and the reason most "it does not work" tickets exist: requests must land inpublic/, never in the project root. - In cPanel → MySQL Databases, create an empty database and a database user, then add the user to the database with All privileges. Write down the database name, user and password.
- Issue an SSL certificate for the domain (cPanel → SSL/TLS Status → Run AutoSSL) if you have not already.
- Open your domain in a browser. Because the panel is not installed yet, every address
redirects to
/installand the wizard opens by itself.
.env
On the very first request the panel notices there is no .env file, copies
.env.example over it and generates a fresh APP_KEY for you. That is why
the project root must be writable. If you prefer to prepare it yourself, copying
.env.example to .env by hand before the first visit works just as
well.3.2 Step 1 — Welcome
The opening screen states what the wizard is about to do and lists the three things you were asked to prepare. Click Get started to continue.
3.3 Step 2 — Requirements
The wizard inspects the server and shows the result in three blocks: your PHP version, the thirteen required extensions, and the five paths that must be writable. Everything must be green before Continue does anything.
| Failing check | What to do |
|---|---|
| PHP version below 8.2 | Switch the PHP version of the domain in cPanel → MultiPHP Manager (or Select PHP Version), then reload the page. |
| An extension is missing | Enable it in cPanel → MultiPHP
Extensions. On a VPS, install the matching php8.x-* package and restart
PHP-FPM. |
| A path is not writable | Set the folder to 755 and make sure it belongs to the account that runs PHP. On a VPS: chown -R www-data:www-data storage bootstrap/cache. |
.env is not writable | Set the file to 644. If the file does not exist at all, the project root must be writable so it can be created. |
3.4 Step 3 — Database
Enter the credentials of the empty database you created. Test connection opens a real connection and reports either success or the exact driver error; the Continue button stays disabled until that test passes, and the server checks the connection again before saving, so a copy-paste mistake cannot get through.
localhost or 127.0.0.1 and the port
3306.localhost on nearly every shared host. Managed platforms sometimes give you a separate database hostname.3306 unless your host says otherwise.myaccount_redfamosa.3.5 Step 4 — Application
Four values that define the panel itself.
http:// or https:// prefix. Enter the
address exactly as visitors will type it, with no trailing slash.https://panel.example.com. Stored as APP_URL.APP_TIMEZONE. Reports and scheduled work follow it.3.6 Step 5 — Admin account
Create the owner account: the super admin with unrestricted access to the panel.
3.7 Step 6 — Install: Production or Demo
The last step asks one question: how much data should the panel start with. Pick a card and press Install now.
| Mode | What gets inserted | Choose it when |
|---|---|---|
| Production | Only the essentials: roles and permissions, the currency list, the language list with English and Spanish enabled, the platform taxonomy, the default settings, the starter reseller plans, your owner panel with its domain, and your admin account. The service catalogue is empty — you fill it from your own providers. | Any real site. This is the recommended choice: nothing to clean up later, and no invented catalogue to confuse a customer. |
| Demo | Everything above, plus a full sample business: example providers, dozens of categories and services, sample clients and staff, orders in every state including drip-feed, payment methods and bonus tiers, support tickets, blacklist entries, a second panel that acts as a reseller with its own clients and an active subscription, and a populated CRM with channels, labels, quick replies, AI agents and conversations. | You want to explore the product with populated screens, or you are recording a demo. Not for a live site — the sample records are indistinguishable from real ones once you start working. |
While the progress bar runs, the wizard verifies the database once more, creates every table, seeds the data for the mode you chose, creates your admin user, checks the writable paths and finally writes the configuration file and the lock file. When it finishes you land on the confirmation screen.
/install redirects to the home page,
because storage/app/installed.lock now exists.What the wizard writes into .env
Only these sixteen values — everything else in the file keeps the documented default and can be changed by editing the file (§4.4):
| Key | Value it writes |
|---|---|
APP_NAME | The panel name from step 4. |
APP_URL | The panel URL from step 4. |
APP_TIMEZONE | The timezone from step 4. |
RF_DISPLAY_TIMEZONE | The timezone from step 4 as well. This one decides how dates are shown to your users, while APP_TIMEZONE decides how the server stores them. The wizard sets both to the same value, so the panel reads correctly from the first minute. |
APP_ENV / APP_DEBUG | Always production and false. |
DB_CONNECTION, DB_HOST, DB_PORT, DB_DATABASE, DB_USERNAME, DB_PASSWORD | The connection from step 3. |
SESSION_DRIVER | database |
CACHE_STORE | file |
QUEUE_CONNECTION | database |
AUTOMATION_MODE | middleware — the setting that works without any server configuration (§13). |
APP_KEY is not written here: it was generated on the very first request, before
the wizard even opened.
3.8 First login
Sign in with the e-mail and password from step 5 and you land in the admin dashboard. On a Production install every counter is zero — that is correct, the panel is waiting for you to fill it.
A sensible order for the first hour:
- Add your upstream provider and sync its catalogue — §5.
- Review prices and hide the services you do not want to sell — §6.
- Configure SMTP so account and order e-mail actually leaves the server — §4.2.
- Enable at least one payment method — §8.2.
- Decide how background work runs and confirm it is running — §13.
- If you will sell reseller panels, set the reseller domain variables — §4.5.
3.9 Updating the script
- Back up your database and your
.envfile. Do not skip this. - Upload and extract the new release over the existing installation, keeping
your
.envfile and yourstorage/directory. - Run the database migrations. With SSH or cPanel Terminal: php artisan migrate --force.
- Clear the compiled caches: php artisan optimize:clear.
.env or storage/
.env holds your database credentials and your APP_KEY. Replacing the
key makes every encrypted value in the database — provider API keys, gateway secrets,
messaging tokens — permanently unreadable. storage/ holds uploaded files and
installed.lock; deleting the lock file re-opens the installer on a live site.4. Configuration
RedFamosa is configured in two places, and knowing which is which saves a lot of searching:
| Where | What lives there | Applies |
|---|---|---|
| Admin → Settings | Everything an operator changes while running the business: branding, e-mail, payment methods, security options, CRM settings. Stored in the database, per panel — each reseller has their own copy. | Immediately. |
The .env file |
Everything the installation needs: database credentials, the panel address, the reseller-domain targets, tuning for background work and for the provider client. One file for the whole installation, no screen to edit it. | On the next request. Restart the queue worker or scheduler if you use them. |
4.1 General settings
Admin → Settings is a single screen with a row of tabs. Changes apply immediately — there is nothing to restart.
| Tab | What you set there |
|---|---|
| General | Site title, support e-mail address, timezone and date format. |
| Branding | Logo, favicon and the panel's primary colour — the accent that drives the whole interface. |
| SEO | Meta title, description and the image used when your address is shared. |
| Social media | The profile links shown in the public footer. |
| Analytics | Google Analytics, Tag Manager, Meta Pixel and a free-form snippet. |
| Social login | Google (including One Tap) and Facebook sign-in, with the app credentials. |
| Security & access | See §4.3. |
| Maintenance | Maintenance mode with its own heading, message and a list of IPs still allowed in. |
| Currency | The base currency of this panel. |
| SMTP credentials and the test send — §4.2. | |
| Default setting | Operational defaults: whether visitors may sign up, whether the service list is public, whether the API is enabled, rows per page, reCAPTCHA keys, the ticket limit per client and the average order time shown to clients. |
Where things actually live
Not everything an operator thinks of as "a setting" is inside this screen. The frequent searches:
| Looking for | It is here |
|---|---|
| Allow / block new client registration | Settings → Default setting |
| Base currency of the panel | Settings → Currency |
| Exchange rates and the list of currencies | Admin → Currencies (§8.4) |
| Default language, adding a language | Admin → Languages |
| Payment methods and their keys | Admin → Payments (§8.2) |
| Top-up bonus tiers | Admin → Payment Bonuses (§8.3) |
| Blocked IPs, links and e-mails | Admin → Blacklist |
| Outgoing order webhooks | Admin → Webhooks (§11.5) |
| How background work runs, and when it last ran | Admin → Cron Jobs (§13) |
| The public address of the panel | APP_URL in .env (§4.4) — there is no admin field for it |
| Minimum and maximum order quantity | Per service, in Admin → Services — there is no global minimum |
4.2 Email (SMTP)
The panel sends account e-mail, password resets, payment confirmations, ticket replies and the reseller billing notices. Until SMTP is configured, none of that leaves the server. Open Settings → Email:
587 with TLS or 465 with SSL. Avoid port 25 — shared hosts usually block it.tls, ssl or none. Match it to the port.Use Send test before you save your work as done: it sends a real message to the address you type, using the values currently on screen, and reports the exact SMTP error if the server refuses.
4.3 Security
Settings → Security & access holds four controls:
Two more protections are always on and need no configuration: failed sign-ins are throttled automatically (five attempts per minute for a given account and address), and every form is protected against cross-site request forgery.
http:// to
https:// belongs in your web server or in .htaccess, where it is more
reliable. What the panel does need is a matching APP_URL and
SESSION_SECURE_COOKIE=true once you are on HTTPS — see
§4.4.4.4 The .env file
.env sits in the project root, next to artisan — one level
above public/. It is created for you on the first request by copying the fully
commented .env.example that ships with the product, and the installer then fills in
fifteen values (§3.7). Every other setting keeps its
documented default until you edit the file.
This is the part of the product that has no user interface, so it is worth knowing what is in there. Open it with the cPanel File Manager editor (enable "show hidden files" — the name starts with a dot) or over SSH. The file is organised in commented blocks:
| Block | Contains | Touch it when |
|---|---|---|
| Application | APP_NAME, APP_KEY, APP_ENV, APP_DEBUG, APP_URL, locales, APP_TIMEZONE | You move the panel to another address or change its name. |
| Database | DB_* | You move the database to another server. |
| Sessions, cache and queue | SESSION_DRIVER, SESSION_LIFETIME, SESSION_SECURE_COOKIE, SESSION_DOMAIN, CACHE_STORE, QUEUE_CONNECTION | You add Redis, or you serve resellers from sub-domains of one domain. |
| Background work | AUTOMATION_* | See §4.6. |
MAIL_* | You prefer to set SMTP in the file instead of in Settings. | |
| Panel branding and reseller domains | RF_BRAND_PRIMARY, RF_PANEL_*, RF_DISPLAY_TIMEZONE, RF_ROUNDING_DECIMALS, RF_DEFAULT_MARKUP | See §4.5. |
| Upstream providers | RF_PROVIDER_*, RF_BREAKER_*, dispatch and polling batches | See §4.7. |
| Public API | RF_API_*, RF_WEBHOOK_* | See §4.7 and §11. |
| CRM and messaging | CRM_* | You use the omnichannel inbox (§12). |
| Social sign-in | GOOGLE_*, FACEBOOK_* | You want "continue with" buttons on the sign-in page. |
| Logging | LOG_CHANNEL, LOG_STACK, LOG_DAILY_DAYS, LOG_LEVEL | You are diagnosing a problem. Put LOG_LEVEL back to error afterwards. |
| Redis | REDIS_* | You actually have a Redis server. |
| Demo mode | RF_DEMO_MODE | See §4.8. |
The five values that matter most
APP_URLAPP_KEYAPP_DEBUGfalse on a public site. Set to true and any visitor who triggers an error sees file paths and configuration.SESSION_SECURE_COOKIEtrue only when the site really is on HTTPS. Set it on a plain-HTTP site and nobody can stay signed in, because the browser never sends the cookie back.AUTOMATION_MODEAPP_URL is not cosmetic
The panel generates every link, form action and redirect with the scheme written in
APP_URL. If it starts with https:// while the site is still served over
plain http://, the wizard's own buttons and every internal link point at an address
the server does not answer, and the panel looks broken. Use https:// only once the
certificate is really installed. See §14.1..env must never be reachable from the web
It holds your database password and your encryption key. Because the document root points at
public/, the file sits outside it and cannot be requested — which is another
reason the document root must be set correctly. After editing the file, run
php artisan optimize:clear if you have SSH, or simply reload the site.4.5 Reseller domains: the variables with no screen
These three lines are what turn reseller panels (§9) from a
concept into a working feature. There is no admin screen for them — they
can only be set in .env, and they ship empty on purpose, because promising an
address your hosting does not actually serve is worse than not offering the option.
| Variable | What it enables | Example |
|---|---|---|
RF_PANEL_BASE_HOST |
Free sub-domains for your resellers. With panels.example.com, a reseller
called max is served at max.panels.example.com. Leave it empty and
the admin refuses to assign sub-domains at all — it tells you to set this variable
first. |
panels.example.com |
RF_PANEL_IP |
The A record target a reseller publishes to point their own domain at
your server. Needed for apex domains such as example.com, which cannot use a
CNAME. |
203.0.113.10 |
RF_PANEL_CNAME_TARGET |
The CNAME target for the same purpose, normally the host name of your own panel. Empty means the CNAME route is simply not offered. | panel.example.com |
Both DNS targets are printed to the reseller on their own Domains screen, so fill in at least one — otherwise the reseller is told to point their domain somewhere and is given nothing to point it at.
RF_PANEL_BASE_HOST only works if a wildcard DNS record
(*.panels.example.com) resolves to this server and the web server answers
for that wildcard with the same document root as the main panel. On cPanel that means a wildcard
sub-domain; on a VPS, a server_name *.panels.example.com block. A wildcard TLS
certificate is what keeps those sub-domains on HTTPS. RedFamosa never issues certificates
— that is your hosting's job.Two more lines in the same block are worth knowing:
RF_BRAND_PRIMARYRF_DISPLAY_TIMEZONEAPP_TIMEZONE is left at UTC. Set it to the timezone you actually think in, or your "today" will not line up with your working day.4.6 Background work
AUTOMATION_MODE chooses how recurring work runs; the intervals below
choose how often. The three modes and how to set each one up are covered in
§13.
| Variable | Shipped value | Meaning |
|---|---|---|
AUTOMATION_MODE | middleware | middleware, queue or scheduler. See §13.1. |
AUTOMATION_THROTTLE | 60 | Minimum seconds between two runs of the same recurring task. |
AUTOMATION_SYNC_INTERVAL | 3600 | Seconds between automatic provider catalogue syncs. |
AUTOMATION_SCRAPE_INTERVAL | 86400 | Seconds between metadata scrapes of a provider's public page. Deliberately slow: one provider per tick. |
AUTOMATION_AVGTIME_INTERVAL | 3600 | Seconds between recalculations of average delivery times. |
AUTOMATION_SUBSCRIPTIONS_INTERVAL | 3600 | Seconds between reseller-plan billing passes when there is no real cron (§10.7). |
AUTOMATION_MAX_JOBS | 25 | Most jobs a single piggybacked pass may run, so a visitor's page never hangs. |
AUTOMATION_MAX_SECONDS | 10 | Hard time limit for that same pass. |
.env line the installation default rather than the last word. The intervals above
are read from .env only.4.7 Providers, orders and the public API
Sensible defaults ship for all of these. Change them when a provider is slow, when you run a high volume of orders, or when you want the public API to be stricter.
Talking to upstream providers
| Variable | Shipped value | Meaning |
|---|---|---|
RF_PROVIDER_TIMEOUT | 30 | Seconds to wait for a provider's API before giving up. |
RF_PROVIDER_RETRIES | 2 | Retries after a failed call. |
RF_PROVIDER_RETRY_DELAY_MS | 500 | Milliseconds to wait between those retries. |
RF_BREAKER_THRESHOLD | 5 | Consecutive failures before the circuit breaker opens and the provider is paused. |
RF_BREAKER_COOLDOWN | 300 | Seconds a tripped provider stays paused before it is tried again. |
RF_CATALOG_CACHE_MINUTES | 60 | How long a fetched provider catalogue is cached. |
RF_BREAKER_THRESHOLD consecutive failures the panel stops calling that provider for
RF_BREAKER_COOLDOWN seconds and keeps working on the rest.Order pipeline
| Variable | Shipped value | Meaning |
|---|---|---|
RF_DISPATCH_BATCH | 25 | Orders sent upstream per dispatch pass. |
RF_MULTISTATUS_BATCH | 100 | Orders queried per multi-status call. |
RF_POLL_MIN_SECONDS / RF_POLL_MAX_SECONDS | 60 / 3600 | The window the panel spaces status checks across: fresh orders are polled often, long-running ones progressively less. |
RF_REFILL_WINDOW_DAYS | 30 | Days a client may request a refill after an order completes (§7.4). |
RF_DEFAULT_MARKUP | 20 | Percentage added over a provider's cost when importing a new service. |
RF_ROUNDING_DECIMALS | 4 | Decimal places kept for prices. Per-unit amounts are tiny, so 4 is the safe default. |
Public API and outgoing webhooks
| Variable | Shipped value | Meaning |
|---|---|---|
RF_API_RATE_LIMIT | 120 | Requests per minute per API key. 0 removes the limit (§11.4). |
RF_API_IDEMPOTENCY_TTL | 1440 = 24 h | Minutes a repeated add request carrying the same Idempotency-Key replays the original answer instead of creating a second order (§11.3). |
RF_WEBHOOK_TIMEOUT | 10 | Seconds the panel waits for your webhook endpoint to answer. |
RF_WEBHOOK_MAX_ATTEMPTS | 5 | Delivery attempts before a webhook is abandoned (§11.5). |
CRM
| Variable | Shipped value | Meaning |
|---|---|---|
CRM_META_GRAPH_VERSION | v21.0 | Graph API version used for WhatsApp, Messenger and Instagram. Change it only when Meta asks you to. |
CRM_EMAIL_INTERVAL | 60 | Seconds between mailbox polls for e-mail channels. |
CRM_TOKEN_HEALTH_INTERVAL | 3600 | Seconds between channel-token health checks. |
CRM_TOKEN_WARN_DAYS / CRM_TOKEN_EXTEND_DAYS / CRM_TOKEN_IG_REFRESH_DAYS | 14 / 21 / 30 | How many days ahead of expiry the panel warns you, tries to extend a token, and refreshes an Instagram token. |
CRM_INBOX_PAGE_SIZE | 25 | Conversations per page in the inbox. |
CRM_MEDIA_DISK | public | Where inbound attachments are stored. |
4.8 Demo mode
RF_DEMO_MODE=false ships in the file and should stay that way on any real site.
Setting it to true does two specific things, both aimed at a public demo you want
strangers to walk into:
- The sign-in page shows quick-login buttons so a visitor can enter without credentials.
- The captcha is disabled, so nobody is stopped on the way in.
false unless
the site exists purely to be looked at. Note that demo mode is unrelated to the
Demo data option in the installer (§3.7), which only
chooses what gets seeded.5. Providers (upstream SMM)
A provider is the wholesale SMM service you buy from. Your panel is the shop window; the provider does the actual delivery. RedFamosa talks to any provider that implements the standard SMM API — the key + action format, widely known as the Perfect Panel API, that virtually the whole industry has settled on.
5.1 The provider protocol
Every call is a single request carrying your API key and the name of the action:
POST https://provider.example.com/api/v2
Content-Type: application/x-www-form-urlencoded
key=YOUR_API_KEY&action=ACTION[&...additional parameters]
RedFamosa uses these actions against your providers:
| Action | When RedFamosa calls it |
|---|---|
services | When you sync a catalogue — it returns the provider's full service list with IDs, names, rates and limits. |
add | When an order is dispatched. The provider answers with its own order ID, which the panel stores. |
status | To follow a single order. |
multi-status | To follow many orders in one call — the efficient path used by the polling pass. |
balance | To read your credit at the provider, and as the connection test. |
refill | When a refill is requested for an order that lost quantity. |
cancel | When a cancellation is requested for an order not yet delivered. |
services, add, status and balance are
universal. Refill and cancel are per-service capabilities: the catalogue sync reads those flags
from the provider and only the services that really support them offer the buttons to your
clients.5.2 Adding a provider
Go to Admin → Providers → Add provider:
/api/v2.40 means you sell at 1.4× the wholesale price. Individual services can be re-priced afterwards.After saving, open the row's menu and run Test connection. It calls the
provider's balance action, so a success proves both that the URL is right and that
the key is accepted.
5.3 Syncing the catalogue
Sync services on the provider row imports the provider's list into your catalogue. The dialog controls exactly what the sync is allowed to touch:
5.4 Balance, metadata and reliability
Provider balance
The provider list shows your current credit at each active provider, refreshed by the background worker. That is your buying power: when it runs out, orders start failing at the provider even though your own clients paid you. Top it up with the provider directly, and keep an eye on the figure — it is the single most common cause of a panel that "stopped delivering".
Metadata scraping
Many providers publish a public services page with descriptions and average delivery times
that their API does not return. Enable scrape metadata on a provider and give it
that public URL: a background task reads the page on a slow schedule — one provider per
tick, at most once per AUTOMATION_SCRAPE_INTERVAL — and fills in the
description and average time that your clients then see on the order form. The fetch is capped
in time and size and is not allowed to reach private addresses.
When a provider misbehaves
Calls carry a timeout and a small number of retries, and a circuit breaker sits in front of every provider: after a run of consecutive failures the panel stops calling it for a cooldown period and moves on to the others, so one broken provider cannot hold up everybody else's orders. The thresholds are in §4.7.
APP_KEY. They are never returned by the API and
never written to the log. This is also why replacing APP_KEY on a live panel is
destructive: nothing already encrypted can be read back.6. Catalogue
The catalogue is the three-level structure your clients browse: platforms → categories → services. Providers fill it; you curate it.
6.1 Platforms
Platforms are the social networks — Instagram, TikTok, YouTube, Facebook, X, Telegram and so on. RedFamosa ships with twenty-four definitions plus an Other catch-all, created the moment the panel is installed. They do two jobs: they group categories in the admin, and they power the network selector at the top of the client order form.
You do not create platforms by hand. When a category is imported, the panel infers its platform from the category name; anything it cannot place lands in Other, where you can reassign it.
6.2 Categories
Categories sit under a platform and group related services — Instagram Followers, TikTok Views. They are created automatically during a catalogue sync and can be renamed, reassigned or reordered in Admin → Categories. A category name is shared: the same name coming from two different providers is one category, not two, which is what lets you sell the same product from several sources without duplicating your shop.
6.3 Services
A service is what a client actually buys. Manage them in Admin → Services.
| Field | What it does |
|---|---|
| Name | The name clients see. Yours to rewrite — provider names are often unreadable. |
| Category | Where it appears in the storefront. |
| Type | How the order is submitted upstream. See the list below. |
| Cost per 1,000 | What the provider charges you. Filled by the sync. |
| Rate per 1,000 | What you charge. Cost plus your markup; edit it freely. |
| Min / Max | The quantity range accepted. Orders outside it are refused at creation. |
| Provider & provider service ID | Which upstream account fulfils it, and under which ID. |
| Refill | Whether clients may request a refill, within the guarantee window. |
| Cancel | Whether clients may request a cancellation. |
| Drip-feed | Whether the service may be delivered in scheduled instalments (§7.4). |
| Average time | The delivery estimate shown on the order form, from the metadata scrape or typed by you. |
| Description | The detail panel on the order form: what is delivered, quality, guarantees. |
| Status | Active (orderable) or hidden (kept, with its order history, but out of the storefront). |
Service types
The type decides which extra fields the order form asks for and how the order is sent upstream. It is set by the sync from the provider's own type and can be corrected by hand.
| Type | What the client provides |
|---|---|
| Default | A link and a quantity. Almost everything you sell is this type. |
| Package | A link only — the quantity is fixed by the package. |
| Custom comments / custom comments package | A link and the list of comments to post, one per line. The quantity is the number of lines. |
| Mentions (custom list, hashtag, user followers, media likers, with hashtags) | A link plus the source of the people to mention: a list of usernames, a hashtag, another account's followers, or the accounts that liked a given post. |
| Comment likes | A link to the post and the username whose comment should receive the likes. |
| Subscriptions | A profile link plus the rules for future posts: how many units per new post, and the range of posts to cover. |
6.4 Bulk management
A first sync can bring in thousands of services, so the services screen is built for volume. Group the list by category, select rows individually, a whole category, or everything that matches the current filter, and apply one action:
- Activate — make the selection orderable.
- Hide — take it out of the storefront while keeping the record and its history.
- Delete — remove it for good. A service that already has orders is hidden instead of deleted, so order history is never orphaned.
- Re-price — apply a markup to the selection instead of editing rows one at a time.
7. Orders
An order is a quantity of one service against one target link. From creation to completion the whole pipeline runs in the background: the panel dispatches to the provider, follows the order and reports what the provider actually says.
7.1 Placing an order
- The client picks a network from the grid at the top of the form.
- Then a category, then a service. The form shows the description, the average delivery time, the accepted quantity range and the price per 1,000.
- They paste the link and type the quantity; the charge is calculated as they type.
- Place order validates in one pass: the link and their account against the blacklists, the quantity against the service range, and the charge against their balance.
The charge leaves the wallet the moment the order is created — that is what an order in awaiting state means — and the background worker picks it up for dispatch on the next pass.
7.2 Bulk order
Clients who work with many links use the Bulk order tab. One order per line, three values separated by pipes:
service_id|link|quantity
143|https://example.com/profile/one|1000
143|https://example.com/profile/two|2500
207|https://example.com/post/abc|500
Every line is parsed before anything is created. A line with the wrong number of fields, a non-numeric service or quantity, or an empty link is reported with its line number and skipped — the valid lines still go through, so one typo does not cost the whole batch.
7.3 Order states
These are the states an order moves through in the admin. The rule the whole pipeline is built around: an order only becomes Completed when the provider says so.
| State | Meaning |
|---|---|
| Awaiting | Created and paid for; waiting for the next dispatch pass. Nothing has been sent upstream yet. |
| Pending | Accepted by the provider, which returned its own order ID. The panel is now polling it. |
| Processing | The provider reports it is working on the order. |
| In progress | Delivery has started. |
| Active | A drip-feed parent whose instalments are still being released. |
| Completed | The provider confirmed full delivery. |
| Partial | Part of the quantity was delivered and the rest will not be. The undelivered portion is refunded to the wallet. |
| Canceled | Cancelled before delivery. The charge is credited back to the client's wallet. |
| Refunded | Refunded by an administrator after the fact. |
| Error | The provider rejected the order, or the service no longer exists. The provider's own message is stored on the order so you can see why. |
| Simulated | A manual marker meaning "this was never really sent upstream". Only an administrator can set it. |
The public API speaks a slightly different vocabulary, because API clients expect the standard SMM status names. The panel translates on the way out:
| Internal state | Returned by the API |
|---|---|
| Awaiting, Pending, Simulated | Pending |
| Processing | Processing |
| In progress | In progress |
| Active | Active |
| Completed | Completed |
| Partial | Partial |
| Canceled, Error | Canceled |
| Refunded | Refunded |
7.4 Refill, cancel and drip-feed
Refill
When a service has refill enabled and the delivered count later drops, the client gets a
Refill button on the order row for as long as the guarantee window lasts
(RF_REFILL_WINDOW_DAYS, thirty days as shipped). The request is forwarded to the
provider and its refill reference is stored, so the refill can be followed separately from the
original order.
Cancel
When a service has cancel enabled, a client — or you, from the admin — can ask for cancellation while the order is still undelivered. The request goes upstream; on confirmation the charge is credited back to the wallet as a new ledger entry. Cancellations that the client asks for arrive in Admin → Cancel Requests.
Drip-feed
Drip-feed spreads a delivery over time instead of dropping it all at once — the natural way to grow an account. On a drip-feed service the client sets:
The client pays the full amount once, when the parent order is created. From then on the background worker releases one child order per interval, each drawing its share from the amount already paid — no further debit is ever taken. The parent stays Active and shows overall progress; it becomes Completed when the last run has been released. Everything drip-feed related is listed under Admin → Drip-feed.
middleware mode that machinery only moves when someone visits the site, so a panel
with no traffic at 3 a.m. releases its 3 a.m. run late. If you sell drip-feed seriously,
use scheduler or queue mode (§13).7.5 Admin order management
Admin → Orders lists every order in your panel with filters by status, service, provider, client and date. From a row you can open the order, read the provider's raw response, retry a dispatch, and edit the status by hand.
8. Billing
RedFamosa is prepaid. A client adds funds, and orders spend from that balance. Every movement — deposit, bonus, order charge, refund, adjustment, reseller margin, plan charge — is a line in a ledger.
8.1 The ledger
There is no editable "balance" column that could drift out of step with reality. A balance is the sum of that wallet's ledger entries, and entries are only ever appended — never edited, never deleted. That single decision is what makes the money in the panel auditable: you can always answer "where did this figure come from" by reading the lines.
| Entry type | Created when |
|---|---|
deposit | A top-up is confirmed, manually or by a gateway. |
bonus | A top-up qualifies for a bonus tier (§8.3). |
order_debit | An order is created. |
order_refund | An order is cancelled or partially delivered. |
reseller_cost_debit | A reseller's client orders: the reseller pays you your price. |
reseller_margin | The difference the reseller keeps on that same order. |
manual_adjust | An administrator corrects a balance, with a reason. |
chargeback | A confirmed payment is reversed. |
plan_charge / plan_refund | A reseller subscription is billed or refunded (§10). |
You read the ledger in Admin → Transaction Logs; clients see their own
under Transactions in their area. To correct a balance, do not look for an editable
field: use the balance adjustment on the user, which writes a manual_adjust entry
with your reason attached.
8.2 Add Funds and payment methods
Payment methods live in Admin → Payments, where each one is a row you create, configure and enable. Three are available:
Manual / bank transfer
The client picks the manual method, enters an amount, uploads a proof of payment and submits. The deposit waits for you: you review it in the admin and approve or reject it, and approval is what credits the wallet (plus any bonus). You configure the instructions shown before the upload — bank details, a QR image, whatever your customers need — and you can attach an image to them.
Stripe
Card payments through Stripe Checkout.
In your Stripe dashboard, add an endpoint pointing at
{APP_URL}/api/webhooks/stripe.
PayPal
The PayPal webhook endpoint is {APP_URL}/api/webhooks/paypal.
8.3 Payment bonuses
Admin → Payment Bonuses is where you reward bigger top-ups. A tier is three things: the payment method it applies to, the amount from which it applies, and the percentage to add.
Bank transfer from 50 +5 % a 50 top-up credits 52.50
Bank transfer from 100 +10 % a 100 top-up credits 110.00
The bonus is granted when the deposit is confirmed — on approval for a manual payment, on
the gateway's confirmation otherwise — and it is written as its own bonus
ledger entry, so the deposit and the gift you added to it never blur together in the accounts.
8.4 Multi-currency
The base currency you chose during installation is the currency of the ledger: every balance, charge and refund is recorded in it, and it is the only one that matters accounting-wise. Clients may nonetheless read the panel in another currency: they pick a display currency in their profile and every amount is converted for display only.
Admin → Currencies is where the list lives. Each currency carries a rate to base: how much one unit of that currency is worth in your base currency. Your base currency is pinned at 1 and cannot be switched off once there are ledger entries.
9. Resellers (child panels)
A reseller gets a panel of their own: their own address, their own name and colours, their own clients, their own catalogue prices, their own CRM inbox. To their customers it is a product, not a page of yours. Technically it is a child panel inside your installation, and the isolation is enforced at the database level — a reseller cannot read your data or another reseller's.
This chapter covers the reseller as a panel. Charging them a monthly fee for it is chapter 10.
9.1 The price chain
Four prices stack, and each participant only ever sees the two that concern them:
Provider cost what you pay your upstream provider
+ your markup
= Owner price your sale price
+ plan catalogue markup (the cut attached to the reseller's plan, see 10.2)
= Reseller cost what the reseller pays you per order
+ reseller margin
= Client price what the reseller's own client pays
When a client of a reseller places an order, three things happen in one transaction:
- The client's wallet is debited at the reseller's price.
- The reseller's wallet is debited at their cost — your price, plus the plan's catalogue markup if their plan carries one.
- The difference stays with the reseller as their margin, recorded as its own ledger entry.
9.2 Creating a child panel
Admin → Resellers → Resellers lists every child panel with its plan, subscription state, wallet balance and domains. Create reseller provisions everything in one action — the panel, its administrator account with the reseller role, and optionally their first subscription:
max becomes max.panels.example.com. Requires RF_PANEL_BASE_HOST — without it the admin refuses to assign a subdomain and tells you which variable to set (§4.5).From the same screen you can later adjust a reseller's balance, register a payment they made you, change their plan, edit their branding, or deactivate the panel.
9.3 Domains and SSL
A child panel can be served in two ways, and the reseller sees both on their own Domains screen:
| Route | How it works | Requires |
|---|---|---|
| Platform subdomain | You give them name.panels.example.com. Nothing for them to configure; it
works the moment you assign it. |
RF_PANEL_BASE_HOST, a wildcard DNS record and a wildcard certificate on
your side. |
| Their own domain | They add the domain in their panel and point its DNS at your server — an A record
to RF_PANEL_IP for an apex domain, or a CNAME to
RF_PANEL_CNAME_TARGET for a sub-domain. The panel gives them a TXT record to
publish, checks it, and activates the domain once it verifies. |
At least one of the two DNS targets set in .env, and their plan allowing a
custom domain. |
Requests are routed by the Host header: the panel resolves which child panel owns
the incoming host and serves that panel's branding, catalogue and prices.
9.4 Margin management
The reseller sets their own selling prices from Margins & Pricing in their panel — if their plan includes that module (§10.2). They can set a default margin over their cost for everything, override it for a whole category, and override it again for a single service. The most specific rule wins: service, then category, then the default.
Their clients never see your price, the provider's cost or anything else from upstream. They see one price, the reseller's.
9.5 Reseller balance
A reseller pays you the same way a client does: they top up their wallet through the payment methods you have enabled, and every order their clients place draws from it in real time. You can also register a payment manually from the reseller's row when they pay you by transfer.
10. Reseller plans and subscriptions
Plans turn resellers into recurring revenue. A plan defines what a child panel can do and what it costs per period; the fee is taken automatically from the reseller's existing wallet, as a ledger entry, with no card checkout and no second payment gateway to configure.
plan_charge ledger entry. They keep it funded through Add funds exactly as
before. Nothing new to install, and one balance to watch instead of two.10.1 Creating plans
Admin → Resellers → Plans. Three plans are seeded so you have a working commercial structure on day one — Free, Pro and Business — and you can edit, rename or replace them entirely.
0 makes a free tier. The currency must be your base currency, because the charge is a wallet debit.monthly, quarterly, semiannual, annual or lifetime. A lifetime plan is charged once and never renews.0 means no trial.10.2 The feature matrix
A plan does not meter usage. There are no quotas on clients, services or orders per day — a reseller on the smallest tier can grow without hitting a wall, which is the point. What a plan decides is which modules their panel has, what they pay for the catalogue and how many domains they may bring.
Modules that are always included
Six modules can never be switched off, because a panel without them is not a panel: the dashboard, categories and services, orders, clients, the finance area (wallet, top-ups, ledger and plan billing) and settings with branding.
Optional modules
Twelve more are checkboxes on the plan form. All of them are on by default — you switch a module off to build a cheaper tier, never on. A plan created before a module existed still grants it.
| Module | What the reseller loses without it |
|---|---|
| Margins & pricing | The screen where they set their own markup over your catalogue. |
| CRM inbox & channels | The whole omnichannel inbox, contacts and labels. |
| CRM AI agents | Automatic AI replies on their channels. |
| CRM automations | Rule-based flows on their conversations. |
| Support tickets | Their clients can no longer open tickets. |
| Team seats | Sub-accounts with their own permissions. |
| Content & blog | News, FAQs, blog posts and static pages. |
| Landing page studio | Their own editable landing page. |
| Custom domain | The domains screen. It stays visible even on a subdomain-only tier, so they can see what a higher tier would add. |
| Client portal | The storefront their clients buy from. |
| Reseller API | The public API surface for their own clients. |
| Blacklist | Blocking links, domains and words on their panel. |
The commercial dials
| Setting | Meaning | Seeded values |
|---|---|---|
| Catalogue markup % | Your cut over the owner price on every order this tier's resellers place. 0
means they buy at your own price. |
Free +30%, Pro 0%, Business 0% |
| Custom domains | How many domains of their own they may connect. 0 means the platform
subdomain only; -1 means unlimited. |
Free 0, Pro 1, Business 5 |
| Own providers | Whether they may connect their own upstream SMM provider and sell its catalogue alongside yours (§10.9). Off unless you turn it on. | Business only |
| Client and landing skins | Which storefront and landing designs the tier includes. A skin added in a future release is granted to existing plans rather than silently withheld. | All, by default |
10.3 Managing resellers
The reseller list shows plan, subscription status, wallet balance and domain count for every child panel. Provisioning a new one is covered in §9.2; opening a row gives you the subscription controls below.
10.4 Subscription actions
Every action that moves money is permission-gated: comp and refund need their own permissions, which staff do not have unless you grant them.
| Action | Effect |
|---|---|
| Assign or change plan | Starts a new subscription; the previous one is retired to history. Optional price override and trial. |
| Comp | A free subscription: active, priced at zero, never charged. For partners and for making an apology stick. |
| Override price | Future periods bill your figure instead of the plan price. Recorded on the subscription. |
| Extend expiry | Pushes the period end and the next charge forward by N days at no cost — goodwill without touching the price. |
| Suspend / reactivate | Locks or unlocks the reseller area and blocks new orders on their storefront. |
| Cancel now / at period end | Immediate lock, or let them ride out the period they paid for and expire at the end of it. |
| Refund a charge | Credits a plan charge back to the reseller's wallet as a plan_refund. Idempotent: refunding twice does not pay twice. |
10.5 Billing lifecycle
A background pass charges each due subscription exactly once per period. The charge is idempotent and transactional: the period's charge row is unique, the subscription is locked for the attempt, and a period that is already paid short-circuits before any debit. A subscription moves through six states:
trialing --(charge succeeds at trial end)--> active
active --(renewal succeeds)-------------> active
--(not enough balance)-----------> past_due --(top up, charge ok)--> active
past_due --(grace elapsed)----------------> suspended --(pay, reactivate)---> active
cancelled / expired (end of life)
10.6 Dunning and suspension
When a renewal fails for lack of balance the subscription becomes past due and a grace deadline is set from the plan's grace days. The reseller is e-mailed on the first and third failed attempt — enough to be noticed, not enough to be noise. If the grace window runs out the subscription is suspended and a final notice goes out. A trial that is about to convert triggers its own heads-up a few days before the first charge.
10.7 Charge cadence
Billing rides on the same machinery as everything else in §13, so it works with or without a real cron:
- With cron (recommended on a VPS): the scheduler runs the billing command
app:charge-subscriptionshourly. Add the standard cron line (§13.2) and setAUTOMATION_MODE=scheduler. - Without cron (shared hosting): with
AUTOMATION_MODE=middlewarethe charge pass runs off ordinary web traffic, at most once everyAUTOMATION_SUBSCRIPTIONS_INTERVALseconds — one hour as shipped.
Hourly is enough. A period boundary crossed within the hour is charged on the next pass, and a balance only changes when the reseller tops up.
10.8 Reseller self-serve billing
Resellers open Finance → Plan & Billing in their own panel to see their current plan, the next charge and their balance. When something is owed they get the amount due, a Pay now button that collects the period immediately from their wallet, and a link to add funds. They can also upgrade or downgrade to any public plan themselves — the difference is taken from the wallet, with no checkout and no ticket to you.
10.9 Own SMM provider
On a plan with own providers enabled, the reseller gets Storefront → My Providers. There they register their own upstream provider — URL and API key, stored encrypted — test the connection, and import its catalogue into their own services, alongside the catalogue they resell from you.
- Imported services are private to that reseller. They never appear in your catalogue and never leak to another reseller.
- For a service the reseller owns, the sale price is theirs and the provider cost is theirs.
- An order for one of those services is a single wallet debit: their client pays them, and they settle with their own provider directly. There is no leg through your wallet, and no cut for you on that order.
10.10 Plan limits reference
| Setting | Enforced where |
|---|---|
| Optional module on/off | The reseller's sidebar and the routes behind it — a module that is off has no menu entry and no reachable page. |
| Catalogue markup % | Order creation on the reseller's storefront: it is added to the owner price to form the reseller's cost. |
| Custom domains | Reseller → Domains, when they try to add one. |
| Own providers | Reseller → My Providers: the screen only exists on a tier that allows it. |
| Client and landing skins | The template pickers, in the admin and in the reseller's own settings. |
| Subscription usable | The reseller area as a whole, and the storefront order block when they are suspended. |
11. Public API
RedFamosa exposes the standard SMM API, the same key + action contract your own providers speak. Any bot, reseller integration or shop plugin written for that format works against your panel without a single change — which is exactly why your customers will ask for it.
11.1 The endpoint
POST {APP_URL}/api/v2
{APP_URL}/api/v1 is an alias of the same handler, so clients configured for either
version work. Requests may be sent as application/x-www-form-urlencoded, as JSON, or
even as a query string on a GET — the parameters are read the same way. Two are always
required:
keyactionResponses are JSON. Errors come back as {"error": "..."} with a human-readable
message.
11.2 Actions
| Action | Parameters | Returns |
|---|---|---|
services | — | An array of the active services this key may order, each with service,
name, type, category, rate,
min, max, dripfeed, refill and
cancel. rate is the price this caller pays. |
add |
service, link, quantity; plus
runs and interval for drip-feed, comments for custom
comments, and the equivalent extras for the other service types |
{"order": 12345} |
status | order |
{"charge","start_count","status","remains","currency"}. A drip-feed parent
answers with its status, its runs and the list of child order
IDs. |
status (multiple) | orders — comma-separated IDs |
An object keyed by order ID; an unknown ID returns {"error": "..."} in its
own slot instead of failing the whole call. |
balance | — | {"balance","currency"} |
refill | order, or orders for several | {"refill": id}, or one entry per order. |
refill_status | refill, or refills | The state of a refill request. |
cancel | orders — comma-separated IDs | One entry per order with its cancellation ID or an error. |
A complete example
curl -X POST https://panel.example.com/api/v2 \
-d "key=YOUR_API_KEY" \
-d "action=add" \
-d "service=143" \
-d "link=https://example.com/profile/one" \
-d "quantity=1000"
{"order":12345}
11.3 Idempotency-Key
Network calls fail halfway. A client that retries an add without protection buys
the same order twice — and then asks you for a refund. Send a unique key with each order
attempt and the problem disappears:
POST /api/v2
Idempotency-Key: 550e8400-e29b-41d4-a716-446655440000
key=YOUR_API_KEY&action=add&service=143&link=https://example.com/p/1&quantity=1000
The first request creates the order and its answer is stored against the key. A later request
with the same key replays that stored answer instead of creating a second order, for as long as
RF_API_IDEMPOTENCY_TTL allows — 1,440 minutes, that is 24 hours, as shipped. If
a retry arrives while the first one is still being processed, it is told so rather than being let
through.
add only — the other actions are already safe to repeat.11.4 Rate limits
The API is limited per key: RF_API_RATE_LIMIT requests per minute, 120 as
shipped, and 0 removes the limit entirely
(§4.7). Over the limit the answer is HTTP 429
with a Retry-After header telling the client how many seconds to wait. Requests
carrying an invalid key are throttled separately and more tightly, which is what stops someone
guessing keys.
11.5 Outgoing webhooks
Instead of having integrations poll status in a loop, let the panel push. Configure
the endpoint in Admin → Webhooks: the URL to call and the signing secret it
will be signed with.
When an order changes state the panel POSTs JSON:
{
"event": "order.status_changed",
"timestamp": "2026-01-31T10:24:05+00:00",
"data": {
"order": 12345,
"status": "Completed",
"charge": "4.5000",
"start_count": 1200,
"remains": 0,
"currency": "USD",
"service": 143,
"link": "https://example.com/profile/one"
}
}
Every delivery carries an X-Webhook-Signature header: an HMAC-SHA256 of the body
computed with your signing secret. Verify it before you trust a payload —
otherwise anyone who learns your endpoint can invent order updates.
RF_WEBHOOK_MAX_ATTEMPTS, five as shipped.RF_WEBHOOK_TIMEOUT seconds per attempt, ten as shipped. Answer 200 fast and do your work afterwards.11.6 Getting the API key
A client finds their key in their own area under API, where they can issue one and regenerate it. The key is displayed once, at the moment it is created: only a hash of it is stored afterwards, so nobody — including you — can read it back later. A client who loses their key regenerates it, which invalidates the old one.
Each key belongs to one user in one panel. A reseller's client calling the API gets the reseller's catalogue at the reseller's prices, never yours. The API as a whole can be switched off for the panel in Settings → Default setting.
12. CRM — omnichannel
One inbox that turns WhatsApp, Messenger, Instagram, Telegram, e-mail, a web-chat widget and your own support tickets into a single conversation stream — answered by AI when you want, driven by automations, and wired to turn a chat into a paying client of the panel.
12.1 Overview
The CRM is built into the product. There is nothing extra to install: once the panel is
installed it appears as the CRM group in the sidebar of the owner admin
(/admin/crm) and of every reseller panel (/panel/crm).
- A three-pane unified inbox
- Seven channels, including internal tickets
- AI agents with a knowledge base
- A visual automation builder
- The chat-to-client conversion funnel
- An embeddable web-chat widget
- Contacts, labels and quick replies
- Reports, and full isolation per panel
In one paragraph: an operator — you, or one of your resellers — receives messages from every channel in one place. An AI agent can answer automatically using a knowledge base you paste in, and hand over to a human when it is out of its depth. An automation can run a whole flow: greet a prospect, create a client account on the panel, send the credentials over the same chat, force a password change on first sign-in and hand the conversation to a sales agent. That is the full path from a social-media message to a client who tops up and orders.
Roles at a glance
| Role | What they do in the CRM |
|---|---|
| Owner / super admin | Everything. Configures the Meta and Instagram apps, the AI keys and every setting, and sees the internal Support channel. |
| Staff | Works the inbox and manages agents, automations, contacts, labels and reports — but cannot touch channel credentials or CRM settings. |
| Reseller admin | The same CRM, scoped to their own panel: their own channels, their own AI keys, their own inbox. They never see yours. |
| Client | Does not see the operator inbox at all. They chat through the web widget and open support tickets, which reach you as conversations. |
12.2 Permissions and roles
The CRM adds eleven permissions to the panel's role system. They gate both the menu entries and the actions inside each screen.
| Permission | Grants |
|---|---|
crm.view | Baseline access to the CRM area. |
crm.inbox | Open the inbox and read conversations. |
crm.send | Reply, write internal notes, assign and resolve. |
crm.channels.manage | See the Channels screen and the token-health state. |
crm.channels.credentials | Write channel credentials: create, edit or delete a channel, connect through OAuth, sync WhatsApp templates, register the Telegram webhook. |
crm.ai.manage | Create AI agents and manage the knowledge base. |
crm.automations.manage | Build and switch on automations. |
crm.contacts.manage | Manage the contact directory and quick replies. |
crm.labels.manage | Manage labels and quick replies. |
crm.reports.view | View the CRM reports. |
crm.settings.manage | Open CRM Settings: the Meta and Instagram apps, verify token, AI keys, widget and operational toggles. |
Who gets what out of the box
| Role | crm.channels.credentials | crm.settings.manage | The other nine |
|---|---|---|---|
| Super admin | yes | yes | yes |
| Staff | no | no | yes |
| Reseller admin | yes | yes | yes |
| Client | no | no | no |
crm.channels.credentials to their role explicitly.To build a chat-only agent role, create a role with just crm.view,
crm.inbox and crm.send. Whether that agent sees every conversation in
the panel or only their own is the agent visibility setting
(§12.4).
12.3 The unified inbox
Open it at /admin/crm, or /panel/crm in a reseller panel. Three panes
side by side:
| Pane | Contents |
|---|---|
| Left — conversations | The filtered list, most recent first, paginated (twenty-five per page as shipped). Each row shows the contact, the channel, a preview of the last message, how long ago it arrived and an unread badge. |
| Middle — thread | The full history, the channel banner (for example the state of the WhatsApp 24-hour window) and the reply box. |
| Right — context | The contact card, the linked client account if there is one, labels, the assigned AI agent and human, and quick actions. |
Tabs, filters and search
The list refreshes by polling, and the open thread refreshes faster, so new messages appear without touching anything. There are no websockets — deliberately, because that is what makes the inbox work on plain shared hosting.
Working a conversation
- Reply — type and send; the message leaves through that channel's provider and is stored on the thread.
- Internal note — saved on the thread, never sent to the customer, and excluded from the AI context and from reports. For hand-off comments.
- Assign — to yourself or a colleague, which notifies them.
- Resolve — moves it to resolved. A new message reopens it automatically.
- Labels — tag the conversation, for example hot lead or sale.
- AI toggle — pause or resume the bot on this conversation. Replying as a human pauses it for you.
12.4 CRM Settings — the one-time setup
Channels live at CRM → Channels, but before any Meta channel can be connected you must fill in your app details at CRM → CRM Settings. Secrets there are write-only — leaving a secret field blank keeps the stored value — and are encrypted at rest.
Meta app (WhatsApp, Messenger, Instagram messaging)
v21.0 as shipped. Change it only when Meta asks you to.Instagram app
Instagram messaging uses a separate child app with its own credentials — that is Meta's design, not ours. Enter its App ID and App secret here to enable the Connect Instagram button.
The two values you copy into Meta
{APP_URL}/crm/webhooks/meta/{panelUid} — paste it into your Meta app as the callback URL. The identifier at the end belongs to this panel only.{APP_URL}/crm/oauth/callback — add it to the valid OAuth redirect URIs. One redirect serves you and every reseller.Paste your verify token alongside the webhook URL in the same Meta screen.
The rest of the screen
12.5 WhatsApp (Cloud API)
The easy way. Once the App ID, App secret and Embedded Signup configuration ID are saved, a Connect WhatsApp button appears on the Channels screen.
- Click Connect WhatsApp. A Meta window opens.
- Sign in and choose — or create — the WhatsApp Business Account and the phone number to authorise.
- The window returns a code, which the panel exchanges server-side; your App secret never reaches the browser. The WhatsApp account is subscribed to your webhook and the channel is filled in automatically: phone number ID, business account ID and display number.
Manual alternative. If you already have the values from Meta's API setup screen, use Add channel → WhatsApp and fill in the phone number ID (the routing identifier), a permanent access token, the App secret, the WhatsApp Business Account ID and the display number.
12.6 Messenger
- On Channels, click Connect Messenger. Facebook's consent dialog opens, asking for the page-messaging permissions.
- Authorise your page. The panel exchanges the code server-side, subscribes the page to your webhook and creates the channel.
Manual alternative: Add channel → Messenger with the page ID (the routing identifier), a page access token and the App secret.
12.7 Instagram
Enter the separate Instagram app credentials in CRM Settings first, then:
- Click Connect Instagram on the Channels screen.
- Authorise the Instagram business account — Instagram messaging requires a business or creator account linked to a Facebook page.
- The panel completes the token exchange, creates the channel and subscribes it. The long-lived token is stored and refreshed automatically before it expires.
Manual alternative: Add channel → Instagram with the Instagram account ID (the routing identifier), an access token and the App secret.
12.8 Telegram
Telegram needs no Meta app, just a bot.
- In Telegram, ask BotFather for a new bot and copy the bot token and the bot's username.
- On Channels, Add channel → Telegram, paste both and save.
- Open the channel menu and click Register webhook. This tells Telegram to
deliver updates to
{APP_URL}/crm/webhooks/telegram/{channelUid}, with a secret token derived from your bot token so that only Telegram can post to it.
Messages to your bot now land in the inbox, and reply keyboards produced by button steps are rendered natively.
12.9 Email (IMAP and SMTP)
E-mail is pulled over IMAP — there is no webhook — and sent over SMTP. Use Add channel → Email:
A background task polls the mailbox on an interval — every sixty seconds as shipped — so this channel depends on your automation mode actually running (§13). Replies are threaded by message ID, quoted text is trimmed, and automatic replies are filtered out instead of starting conversations with a robot.
12.10 Web Chat and Support
Add channel → Web Chat creates the widget channel:
Saving gives you the script tag to paste into any site — see §12.13 for embedding, branding and security.
The Support channel, by contrast, is created for you: one per panel, not shown in the channel list and not editable. It exists only to bring your internal tickets into the inbox.
12.11 AI agents
Manage them at CRM → AI Agents. An agent is a reusable configuration that answers conversations automatically while the bot is active on them.
- New agent, and give it a name such as "Sales" or "FAQ bot".
- Pick a provider and a model.
- Optionally paste an API key for this agent; leave it blank to use the panel-level key. Test key validates it against the live provider before you save.
- Write the system prompt — the persona, the rules, the goal. This is where the quality of the whole thing is decided.
- Set the temperature and the maximum tokens per reply.
- Decide whether fallback to human is on, and save.
| Provider | Selectable models |
|---|---|
| OpenAI | gpt-4o-mini, gpt-4o, gpt-4.1-mini, gpt-4.1 |
| Anthropic | claude-3-5-haiku-latest, claude-3-5-sonnet-latest, claude-sonnet-4-latest |
| Gemini | gemini-1.5-flash, gemini-1.5-pro, gemini-2.0-flash |
Knowledge base
While editing an agent, add knowledge sources: a title and the text — your FAQs, prices, policies, service descriptions. The panel splits it into chunks and indexes them; when the agent answers, the most relevant chunks are retrieved and injected into the prompt, so replies come from your content instead of from the model's imagination. How many chunks are used is the top K value in CRM Settings, five by default.
Handing over to a human
With fallback to human on, the agent is told it may emit a
[TRANSFER] marker when it cannot help. When it does, the panel strips the marker from
the text, pauses the bot on that conversation and assigns it to the least loaded member of the
team. With the setting off, the agent never hands over by itself — a pure round-the-clock
FAQ bot — though a human can always take over simply by replying.
Switching AI on
- Make default — one agent per panel can be the default; new conversations start with the bot active using it.
- Per conversation — the context pane has an AI toggle and an agent selector, and automations can switch agents mid-flow.
- On support tickets — off until you enable AI on support.
12.12 Automations
Build flows at CRM → Automations. An automation is a trigger plus a flow of steps that you assemble from a palette.
Triggers
| Trigger | Fires when |
|---|---|
| First message | A brand-new conversation starts. A channel-specific flow wins over an all-channels one. |
| Keyword | An incoming message contains the text you specify, matched without case sensitivity. |
| Every message | Any inbound message at all. |
| Conversation assigned | A conversation is assigned to a team member. |
| Label added | A label is attached to a conversation. |
| Conversation resolved | A conversation is marked resolved — useful for a satisfaction follow-up. |
The step palette
| Group | Steps |
|---|---|
| Messaging | Send message (interpolated text) · Send media (image, audio, video or document by URL, with a caption) · Send gallery · Send buttons (rendered natively where the channel supports it) · Ask question (waits for the reply and stores the answer for later steps) |
| Flow | Condition · Branch (wait for a keyword reply and take the matching path) · Wait · Drip follow-up (a deferred message, optionally only if the contact has not replied) |
| Actions | Add label · Remove label · Set status · Assign AI agent · Assign staff · Pause bot · Resume bot · Create client account · Call webhook (an outbound POST or GET with an interpolated body, protected against internal-address abuse and capped at ten seconds) |
Placeholders
Text steps interpolate values from the conversation. The editor offers the common ones as clickable chips:
{{contact.name|there}} the contact's name, or "there" when unknown
{{contact.email}} {{contact.phone}}
{{company.name}} the panel's name
{{agent.name}} the assigned team member
{{answers.email}} an answer captured by an "ask question" step
The engine also resolves {{channel.name}}, {{channel.type}},
{{company.email}} and {{message.content}}, and any
{{answers.<key>}} you defined in an ask question step. The
| syntax supplies the fallback when a value is empty.
Templates
Fourteen ready-made flows ship with the product, so you rarely start from an empty canvas: order funnels and catalogue welcomes for WhatsApp, an Instagram DM welcome, new-customer onboarding, the capture-and-convert funnel, a keyword pricing responder, social-proof conversion and nurture flows, a win-back sequence, web-chat lead capture, an FAQ triage, a Telegram start menu, a Messenger FAQ with hand-off, and a plain welcome. Load one and edit it — it is faster than designing a flow from scratch, and it shows you what the steps do.
The flagship flow: capture and convert
Start a new automation from the Capture & convert template. It builds a first-message flow that welcomes the prospect, creates a client account on your panel, sends a short tour and hands the conversation to a sales agent.
What the create client account step really does:
- Resolves the contact's name, e-mail and phone — captured by an earlier step or by the AI. Without a valid e-mail it takes the failure path.
- Looks for an existing client in this panel with that e-mail. If there is one it links to it; if not it creates a client account with a strong random temporary password, in the same panel as the conversation.
- Links the contact to that user and records the provisioning for auditing.
- Sends the credentials over the same chat — e-mail, temporary password and the panel's sign-in address. On WhatsApp outside the 24-hour window that goes out as an approved template.
- Assigns the sales agent so the bot keeps working towards the first top-up.
Save the automation, then switch it on from the list. The runs counter shows how many times it has executed, and flows are validated server-side on save.
12.13 The web chat widget
The web-chat channel gives you a widget for any external site.
<script src="https://panel.example.com/crm/widget/CHANNEL_UID.js" async></script>
Paste it before </body>. The script injects a floating launcher with your
title, greeting, colour and position. It has no dependencies, keeps its session in the visitor's
browser storage and polls for new messages.
Title, greeting, colour and position come from the channel; the small branding line under the widget comes from CRM Settings — blank hides it, which is what a reseller wants for a white-label site.
Putting it on your own landing page
You do not need to edit a template. Open Settings → Analytics, paste the same
snippet into the free-form field, and save. It is rendered in the <head> of your
landing page and of every public page, so the launcher appears on your own site exactly as it does
on an external one.
Copy the snippet from the channel's own card on the Channels screen: it is generated with your panel address. A snippet copied from another installation — a demo, or a second panel of your own — points at that installation, so the visitor's messages arrive in its inbox and never reach yours.
Security: allowed origins
The widget endpoints enforce a fail-closed list of allowed origins per panel. In CRM Settings → widget allowed origins, list the sites permitted to embed it, one per line:
shop.example.com.example.com — any sub-domain of it* — not recommended in productionThe panel's own domain is always allowed. An origin that is not on the list gets no CORS header
at all, so the embed simply does not work — which is the point. The widget's session is an
opaque server-side token rather than a guessable ID — it travels in an
X-RF-Widget-Session header — and the endpoints are rate-limited.
Signed identity for signed-in visitors
If you embed the widget on a page where the visitor is already signed in to your panel, you can hand the widget a signed identity so their chats attach to their account and survive across sessions. Set a global before the script loads:
<script>
window.RF_WIDGET_IDENTITY = {
user_id: 4821,
name: "Alex Doe",
email: "alex@example.com",
expires: 1750000000, // unix timestamp
sig: "hmac-sha256-hex" // see below
};
</script>
<script src="https://panel.example.com/crm/widget/CHANNEL_UID.js" async></script>
Your server computes the signature as:
sig = HMAC-SHA256( "{channel_uid}|{user_id}|{expires}", APP_KEY )
The panel re-verifies the signature and the expiry on every call and confirms the user belongs to the channel's panel. An invalid or expired signature is treated as an anonymous visitor rather than an error, so a stale page never breaks the chat.
12.14 Webhooks per panel
Each panel has its own inbound endpoints. The Meta channels share one address per panel; Telegram has one per channel:
Meta (WhatsApp + Messenger + Instagram)
{APP_URL}/crm/webhooks/meta/{panelUid} GET and POST
Telegram
{APP_URL}/crm/webhooks/telegram/{channelUid} POST
- The panel is identified by the identifier in the path, never by the host name. That is what routes a reseller's messages to the reseller, and it is why the address is always on your main host even when the reseller has their own domain — message delivery does not depend on their certificate.
- The GET request is Meta's verification challenge, validated against that panel's verify token. Each reseller pastes their own token into their own Meta app.
- The POST carries the messages. Its signature is verified fail-closed against the channel's App secret; an unsigned or wrongly signed request is rejected outright.
Both values to copy are shown on each panel's own CRM Settings screen. E-mail uses no webhook, and the widget resolves its panel from the channel identifier in the script URL.
How the work behind an inbound message is executed — parsing, media download, AI reply,
automations — depends on AUTOMATION_MODE, exactly as for the rest of the panel:
the webhook answers immediately and hands the work to the background. See
§13.
12.15 Security notes
- Encrypted credentials. Channel credentials, AI keys and secret settings are encrypted at rest and never rendered back into a form. Blank means "keep what is stored".
- Fail-closed signatures. Every inbound Meta or Telegram webhook must carry a valid signature. There is no "accept it if no secret is configured" fallback.
- Server-side OAuth. The one-click connect flows use the official JavaScript SDK to open the authorisation window, but the code is always exchanged server-side — the App secret never reaches the browser — and the result is posted back to your own origin only, never to any listener.
- Panel isolation in background jobs. Every queued job pins its panel before touching data, so a job for one panel can never read or write another's. Client lookups in the conversion funnel are always filtered by panel, which is what prevents a cross-panel account takeover.
- Outbound webhook guard. The call webhook step validates its target against internal and metadata addresses, does not follow redirects and times out at ten seconds.
- Avatar proxy. Contact avatars are fetched server-side through a proxy that only allows the providers' own image hosts, checks that the bytes really are an image, does not follow redirects and caches locally.
- Media uploads. Limited to allowed image types, verified against the real file contents rather than the extension, and size-capped.
- Temporary passwords. Accounts provisioned from a chat get a strong random password and a forced change on first sign-in.
13. Cron and automation
A panel is not a website that waits to be clicked. Orders have to be sent upstream, their
status polled, drip-feed runs released, catalogues synced, mailboxes read, channel tokens
refreshed and reseller subscriptions charged. All of that is background work, and
AUTOMATION_MODE decides how it runs.
13.1 The three modes
| Mode | How the work runs | Right for |
|---|---|---|
middleware |
Each incoming web request also drains a little background work, with a lock so two visitors never run the same pass twice and a hard limit on how much one request may do. No cron, no worker, nothing to configure. | Shared hosting, and any panel with steady traffic. This is what the installer sets. |
scheduler |
One cron entry, once a minute, drives everything. Work happens on time whether or not anyone is visiting. | Any host where you can add a cron job. The best value for the least effort. |
queue |
The same once-a-minute cron enqueues the work, and a persistent worker executes it immediately as jobs arrive. Highest throughput and the most responsive. | A VPS with a process supervisor, and panels with real volume. |
middleware mode
It only moves when someone visits your site. A panel with no traffic overnight dispatches nothing
overnight, and a drip-feed run scheduled for 4 a.m. is released when the first visitor
arrives in the morning. It is a perfectly good way to start, and the right answer on hosting
without cron — but the day you sell drip-feed or promise fast delivery, move to
scheduler.You can switch mode without editing files, in Admin → Cron Jobs. That screen also lists each scheduled task with the time it last ran and a Run now button — the fastest way to prove that your background processing actually works.
13.2 Setting up cron on cPanel
In cPanel → Cron Jobs, add a single entry running every minute:
* * * * * /usr/local/bin/php /home/USERNAME/redfamosa/artisan schedule:run >> /dev/null 2>&1
Two things to get right:
- The path to
artisanis the project root, the folder that containsapp/andpublic/— not the document root. If your domain serves/home/USERNAME/redfamosa/public, then artisan is at/home/USERNAME/redfamosa/artisan. - The PHP binary must be version 8.2 or newer. If the job does not fire, find the right binary in cPanel Terminal with which php, or check the path shown in MultiPHP Manager, and use the absolute path.
Then set AUTOMATION_MODE=scheduler. That one cron line drives two scheduled
tasks: the automation tick every minute, and reseller plan billing
every hour.
13.3 Running a queue worker
On a VPS, set AUTOMATION_MODE=queue, keep the once-a-minute cron entry from
§13.2, and run a persistent worker:
php artisan queue:work --sleep=3 --tries=3 --timeout=60 --max-time=3600
Use Supervisor or a systemd unit to keep the worker alive and restart it if it
stops. --max-time=3600 makes it exit once an hour so the supervisor restarts it with
fresh code and fresh memory — also the reason you must restart the worker after an
update.
13.4 What runs in the background
- Dispatch orders — orders waiting in Awaiting are sent to their provider.
- Poll order status — live orders are queried, in batches, to detect completion, partial delivery or cancellation. Fresh orders are checked often, old ones progressively less.
- Drip-feed runs — each due instalment is released as a child order.
- Refills and cancellations — requests are forwarded and their outcome followed.
- Provider catalogue sync and metadata scraping — on their own slower intervals.
- Average delivery times — recalculated from real orders.
- Provider balances — refreshed for the providers list.
- Reseller plan billing — charges, dunning e-mails, suspensions and trial reminders (§10.7).
- CRM work — inbound message processing, mailbox polling, channel token health and refresh, knowledge-base indexing and deferred automation steps.
14. Troubleshooting and FAQ
14.1 Installation
"Please provide a valid cache path"
The application cannot write its compiled views. The storage/framework folder is
missing its sub-folders, or they are not writable. Make sure these exist and are writable by the
user that runs PHP:
storage/framework/cache/data
storage/framework/sessions
storage/framework/views
storage/logs
bootstrap/cache
Some FTP clients and unzip tools silently drop empty directories, which is how the folders go missing in the first place. Create them by hand in File Manager, set them to 755, and reload.
"No application encryption key has been specified"
There is no .env file. RedFamosa creates it on the first request by copying
.env.example and then generating the key — so this message means the copy could
not happen. Check that .env.example is present in the project root (some extraction
tools skip files whose names start with a dot) and that the project root is writable so the new
file can be created. Copying .env.example to .env yourself and reloading
the page fixes it immediately.
The wizard's buttons and links point at https:// but the site is on http://
Everything the panel generates — links, form actions, redirects — uses the scheme
written in APP_URL. If that value starts with https while the site is
still served over plain http, every link points at an address your server does not
answer, and the panel looks broken even though nothing is wrong with it.
Fix it in one of two ways: install the certificate and really serve the site over HTTPS
(recommended), or edit APP_URL in .env to start with
http://. Then reload. If you already finished the installation, also make sure
SESSION_SECURE_COOKIE matches: true on HTTPS, false on
plain HTTP — a secure cookie on an insecure site means nobody can stay signed in.
A requirements check will not turn green
See the table in §3.3. The most common case on shared hosting is that the domain is running an older PHP version than the account's default: change it in MultiPHP Manager for that specific domain, not globally.
A 500 error, or a blank page, right after uploading
- Check that the document root points at
public/, not at the project root. - Check that
public/.htaccesssurvived the upload and that Apache allows it (AllowOverride All). - Check that
storage/andbootstrap/cache/are writable. - Read
storage/logs/laravel.log— the real error is at the end of it.
The installer opens again on a panel that is already installed
storage/app/installed.lock is missing — almost always because
storage/ was overwritten during an update. Do not run the wizard
again: it would try to migrate an existing database. Restore the file from your backup, or create
it with any content, and the panel comes straight back.
14.2 Orders and providers
Orders sit in "Awaiting" and never leave
Nothing is dispatching them. Open Admin → Cron Jobs and look at the last
run of the automation tick. In middleware mode, remember the work only happens when
someone visits the site — open the storefront in another tab and watch the timestamp move.
If it does not move at all, see §13.
Orders end up in "Error"
The provider rejected them, and its own message is stored on the order — open one and read it. The usual causes, in order of likelihood: your balance at the provider is exhausted; the provider changed or removed that service ID; the link does not match what the service expects; the quantity is outside the provider's own limits. Fix the cause, then retry the order or cancel it to refund the client (§7.5).
What does "Simulated" mean?
It is a manual marker meaning "this order never really went upstream". Nothing sets it automatically. It exists so an operator can record the truth about an order instead of quietly marking it complete — and note that setting it does not refund anything: to return the money you cancel the order.
Can I connect more than one provider?
Yes, as many as you like. Any provider speaking the standard SMM API works. Different services can come from different providers, which is also how you build redundancy: keep a second provider configured for your best-selling services and repoint the service if the first one degrades.
A drip-feed order is releasing its runs late
Expected in middleware mode, where runs are released by visitor traffic. Move to
scheduler mode (§13.2).
14.3 Billing and resellers
A client's balance is wrong
Balances are the sum of ledger entries, so there is no field to correct. Open the user in Admin → Users and adjust the balance with a positive or negative amount and a reason: that writes a new ledger entry and the displayed balance updates at once, with the history intact.
A card payment succeeded but the wallet did not move
The gateway's notification is not reaching you. Check that the webhook endpoint is registered
in the gateway dashboard with the right address
({APP_URL}/api/webhooks/stripe or {APP_URL}/api/webhooks/paypal), that
the signing secret in the payment method matches the one the gateway shows, and that
APP_URL is the address the gateway can actually reach.
A reseller's subdomain does not resolve
Three things must all be true: RF_PANEL_BASE_HOST is set in .env, a
wildcard DNS record for that host points at your server, and your web server answers for the
wildcard with the same document root as the main panel. See
§4.5.
A reseller cannot add their own domain
Either their plan does not allow custom domains — check the plan's domain count
(§10.2) — or you have not filled in
RF_PANEL_IP or RF_PANEL_CNAME_TARGET, in which case they are being asked
to point their DNS at nothing.
A reseller says their clients cannot order
Look at two columns in the reseller list: their wallet balance and their subscription status. An empty wallet fails the debit for every order their clients place, and a suspended subscription blocks new orders on their storefront on purpose (§10.6).
14.4 CRM and channels
The "Connect WhatsApp / Messenger / Instagram" button is not there
Those one-click buttons only appear once the panel's app credentials are saved. For WhatsApp and Messenger you need the Meta App ID and App secret — plus the Embedded Signup configuration ID for the WhatsApp one-click flow; Instagram needs its own separate App ID and secret. You can always create the channel manually instead (§12.5–§12.7).
WhatsApp messages will not send
You are almost certainly outside the 24-hour window: free-form messages are only allowed within 24 hours of the customer's last message, and after that you must send an approved template. Run Sync templates on the channel and send one. If that is not it, test the channel's access token from its menu.
The AI does not reply
Check in this order: is there a default agent, or an agent assigned to that conversation; is the bot active and not paused (a human reply pauses it); is there a valid API key on the agent or on the panel; for a support ticket, is AI on support switched on. And remember the agent answers text — a bare image does not trigger a reply.
Telegram messages never arrive
Open the channel's menu and click Register webhook. Until you do, Telegram does not know where to deliver anything.
E-mails never arrive in the inbox
E-mail is pulled on a schedule, so your automation mode has to be running (§13). Then check the IMAP host and port, and make sure you used an app password if the mailbox has two-factor authentication.
The web widget does not connect
Add the site's domain to the widget's allowed origins in CRM Settings (§12.13). Requests from a domain that is not on the list are refused. Also confirm the channel is active and that the script URL carries the right channel identifier.
Messages are landing in the wrong panel
Each panel must copy its own webhook URL and verify token, from its own CRM Settings, into its own Meta app. The panel is chosen by the identifier in the webhook path, so a reseller who reuses your URL receives your routing.
A staff member cannot connect a channel or open CRM Settings
That is intended: staff do not hold crm.channels.credentials or
crm.settings.manage. Grant those to their role if you want them to, or do the
connection yourself (§12.2).
An Instagram channel shows "reconnect"
Instagram's long-lived tokens expire after about sixty days. The panel refreshes them automatically, but a token that was revoked cannot be refreshed — run Connect Instagram again.
Where do clients created from a chat end up?
They become ordinary client accounts on the same panel as the conversation, with a wallet created on their first credit or order. They sign in at that panel's client area, are forced to change their password once, and behave like any other client from then on (§12.12).
14.5 Maintenance
I changed APP_URL and the old address is still used
Clear the compiled configuration: php artisan optimize:clear. Without SSH, deleting
the files inside bootstrap/cache/ has the same effect — they are regenerated on
the next request.
How do I change the panel's language, or add one?
Admin → Languages is where the list lives and where the default is set; individual users choose their own in their profile. English and Spanish ship enabled, with several more locales listed and switched off.
How do I stop new registrations?
Settings → Default setting, and turn client sign-up off. The register link disappears and the route stops accepting registrations; you can still create clients yourself from the admin.
Where are the logs?
storage/logs/. The application log rotates daily and keeps a fortnight by default.
If you are chasing a problem, set LOG_LEVEL=debug in .env, reproduce it,
then put the value back to error — debug logging on a busy panel fills a disk
faster than you would expect.
How do I update to a new version?
See §3.9. In short: back up, upload over the top without
touching .env or storage/, run the migrations, clear the caches, and
restart the queue worker if you use one.
15. Support and changelog
15.1 Getting support
If the manual has not answered your question:
- Open a support request from the item page where you bought RedFamosa. That is the official channel, and it keeps the whole history of your case in one place.
- Read the changelog on that same page first — what you are hitting may already be fixed in a newer release.
storage/logs/laravel.log. A stack trace usually identifies the problem instantly.
Never paste your .env, your APP_KEY or any live API key into a support
message.15.2 What is included
| Module | What it is | Documented in |
|---|---|---|
| SMM panel | Providers, catalogue, orders, wallet and billing — the core business. | §5–§8 |
| Reseller panels | Child panels on their own domains, with their own clients and prices. | §9 |
| Plans & subscriptions | Recurring revenue from resellers, billed from their wallet. | §10 |
| Public API | The standard SMM API for your clients' own tools. | §11 |
| CRM — omnichannel | Unified inbox for seven channels, AI agents, automations and the web widget. | §12 |
| Support tickets | Ticketing for your clients, bridged into the CRM inbox. | §12.3 |
| Content | Blog, static and legal pages, FAQs and news announcements — per panel, including per reseller. | Admin → Blog / Pages / FAQs / News |
| Landing page | An editable public landing page with three designs: Nova, Horizon and Pulse. | Admin → Landing |
| Client storefront skins | Three client-area designs: Aurora, Vibrant and Midnight, selectable per panel. | Settings → Branding |
| Social sign-in | Google (including One Tap) and Facebook, configured per panel. | Settings → Social login |
| Blacklists | Block by IP, link or e-mail, panel-local or global across every panel. | Admin → Blacklist |
| Reports | A year-at-a-glance calendar of payments, orders, tickets or profit. | Admin → Reports |
15.3 Changelog
Version 1.0.2
This release makes every switch, field and dropdown in Settings do what its label says. We reviewed all of them and reconnected each control that was not wired to anything.
- The Currency tab could not be saved at all. Separators, decimals, default markup, rounding and the conversion rate appeared to save but stored nothing. All six fields now save, including a space as the thousands separator.
- Settings → SEO now reaches the home page. A meta title and description entered there applied to the FAQ, Terms, blog and content pages while the home page kept the text it shipped with. The SEO fields inside the Landing editor still win for the home page when filled in; left empty they now inherit the site-wide values. The home page also publishes a canonical address, a share image and the indexing preference, which it did not before.
- robots.txt now follows the indexing switch. A file shipped with the script
was served instead of the live one, so the switch changed the page tags but never the file a
crawler reads. An empty
favicon.icoplaceholder shipped beside it has been removed as well, so a browser follows the icon declared by your Branding settings. - The sitemap and the canonical tags now name the same host when a canonical host is configured.
- “Rows per page” now reaches every list screen. Around twenty screens stayed on fifteen rows whatever you typed. A few whose layout depends on their own page size keep it on purpose.
- “Date format” and “Timezone” now apply everywhere a date is shown, including invoices and PDF exports, with month names in the interface language. A signed-in user’s own timezone takes precedence. Stored data is unchanged.
- A reseller’s “Disable signup” switch now closes their own storefront. Registration on a reseller’s domain was decided by the platform owner’s switch in four places, including the step that creates the account.
- Sign-up links are hidden when signups are closed — on the sign-in page and on the home page, which both kept inviting visitors to register.
- Analytics IDs are validated instead of silently discarded. A malformed GA4, Google Tag Manager or Meta pixel ID saved without complaint and was then never used.
- The “Enable API” switch now closes the API — the public endpoints, the documentation page and the client’s API-key screen, which all stayed open regardless. It is now labelled “Enable public API”.
- “Auto convert currency” is applied when importing a provider catalogue.
- The password hint on the profile screens shows your configured minimum instead of always reading “at least 8 characters”.
- The support e-mail, phone and working hours now appear on the default client skin, which did not include the footer that shows them.
- A quotation mark in the landing page’s font setting was written into the page in a form the browser could not read, so the heading font fell back to a default. Colours, fonts and skin values are now written correctly and checked before use.
- Removed the unused “Orders for average-time calc” field from Settings → Defaults. It fed no calculation in the product.
Version 1.0.1
- Signing in after a session has expired now returns you to the sign-in form. A login page left open longer than the session lifetime — or one whose session the server discarded for any other reason — used to answer the submit with a blank “419 Page Expired” screen with nothing to click. It now reloads the form, keeps the e-mail you typed, and explains that the session expired.
- The session cookie name is written into
.envduring installation instead of being derived from the application name on every request, so renaming the panel later no longer signs everybody out. - The installer no longer corrupts database passwords containing
$followed by a digit when writing them to.env. - If the application cannot write its own
.env, the first page now says so and tells you which permission to change, instead of failing with a generic server error. - The public landing page now uses the favicon uploaded in Settings → Branding.
- The landing page’s video player fills its frame correctly, and no longer ships pointing at a sample clip: the “Watch demo” button appears once you set your own video URL.
Version 1.0.0 — first public release
- Six-step web installer with a live requirements check, a real database test and a choice between Production and Demo seed data.
- Upstream provider manager for the standard SMM API, with connection test, catalogue sync with per-field control, public-page metadata scraping, balance monitoring, retries and a circuit breaker.
- Catalogue of platforms, categories and services with bulk activation, hiding, deletion and re-pricing.
- Order pipeline with honest states, background dispatch and polling, refill, cancellation requests, drip-feed with scheduled runs, and bulk ordering.
- Immutable wallet ledger with ten entry types, manual adjustments, top-up bonus tiers and display currencies.
- Payment methods: manual proof of payment with admin approval, Stripe and PayPal with signed webhooks.
- Reseller child panels with platform subdomains, DNS-verified custom domains, own branding, own skins and cascading margin rules.
- Reseller subscription plans with a module matrix, catalogue markup, domain allowance and the own-provider gate; wallet auto-debit billing with trials, grace, dunning e-mails and automatic suspension; reseller self-service billing and plan switching.
- Plan-gated own external provider for resellers, with isolated services and single-wallet order money.
- Public API compatible with the standard SMM format, with idempotency keys, rate limiting and signed outgoing webhooks.
- Omnichannel CRM: unified inbox, WhatsApp, Messenger, Instagram, Telegram, e-mail, web chat and internal tickets; AI agents with a knowledge base across three providers; a visual automation builder with fourteen ready-made templates; the chat-to-client conversion funnel; an embeddable widget with origin allowlisting and signed identities.
- Three automation modes so the product runs on shared hosting without cron, on cron, or on a queue worker.
- Support tickets, blog, pages, FAQs, news, landing page studio, social sign-in, blacklists and reports.
- English and Spanish translations, light and dark interface, and a fully documented
.env.
Under consideration for future releases
Not part of version 1.0.2 and not a commitment, but the directions the product is most likely to grow in:
- An affiliate and referral system, so clients earn on the top-ups they bring in.
- Coupon codes for Add Funds and for orders.
- Richer subscription services, with rules for automatic refills on new posts.
- Additional interface languages.